From a423ddf21d09b4ebab07ddefe5048b3fe09275b5 Mon Sep 17 00:00:00 2001 From: Ajay-Satish-01 Date: Thu, 19 Dec 2024 11:20:43 -0800 Subject: [PATCH 1/4] [Provider] Recraft AI --- src/globals.ts | 2 + src/providers/index.ts | 2 + src/providers/recraft-ai/api.ts | 19 +++++ src/providers/recraft-ai/imageGenerate.ts | 84 +++++++++++++++++++++++ src/providers/recraft-ai/index.ts | 16 +++++ 5 files changed, 123 insertions(+) create mode 100644 src/providers/recraft-ai/api.ts create mode 100644 src/providers/recraft-ai/imageGenerate.ts create mode 100644 src/providers/recraft-ai/index.ts diff --git a/src/globals.ts b/src/globals.ts index dce5f05e4..a98f256b6 100644 --- a/src/globals.ts +++ b/src/globals.ts @@ -77,6 +77,7 @@ export const DASHSCOPE: string = 'dashscope'; export const X_AI: string = 'x-ai'; export const SAGEMAKER: string = 'sagemaker'; export const NEBIUS: string = 'nebius'; +export const RECRAFTAI: string = 'recraft-ai'; export const VALID_PROVIDERS = [ ANTHROPIC, @@ -127,6 +128,7 @@ export const VALID_PROVIDERS = [ X_AI, SAGEMAKER, NEBIUS, + RECRAFTAI, ]; export const CONTENT_TYPES = { diff --git a/src/providers/index.ts b/src/providers/index.ts index ea4f3c242..f01d33bed 100644 --- a/src/providers/index.ts +++ b/src/providers/index.ts @@ -51,6 +51,7 @@ import XAIConfig from './x-ai'; import QdrantConfig from './qdrant'; import SagemakerConfig from './sagemaker'; import NebiusConfig from './nebius'; +import RecraftAIConfig from './recraft-ai'; const Providers: { [key: string]: ProviderConfigs } = { openai: OpenAIConfig, @@ -102,6 +103,7 @@ const Providers: { [key: string]: ProviderConfigs } = { qdrant: QdrantConfig, sagemaker: SagemakerConfig, nebius: NebiusConfig, + 'recraft-ai': RecraftAIConfig, }; export default Providers; diff --git a/src/providers/recraft-ai/api.ts b/src/providers/recraft-ai/api.ts new file mode 100644 index 000000000..2678d244e --- /dev/null +++ b/src/providers/recraft-ai/api.ts @@ -0,0 +1,19 @@ +import { ProviderAPIConfig } from '../types'; + +const RecraftAIAPIConfig: ProviderAPIConfig = { + getBaseURL: () => 'https://external.api.recraft.ai/v1', + headers: ({ providerOptions }) => ({ + Authorization: `Bearer ${providerOptions.apiKey}`, + 'Content-Type': 'application/json', + }), + getEndpoint: ({ fn }) => { + switch (fn) { + case 'imageGenerate': + return '/images/generations'; + default: + return ''; + } + }, +}; + +export default RecraftAIAPIConfig; diff --git a/src/providers/recraft-ai/imageGenerate.ts b/src/providers/recraft-ai/imageGenerate.ts new file mode 100644 index 000000000..3417b54c3 --- /dev/null +++ b/src/providers/recraft-ai/imageGenerate.ts @@ -0,0 +1,84 @@ +import { RECRAFTAI } from '../../globals'; +import { ErrorResponse, ImageGenerateResponse, ProviderConfig } from '../types'; + +export const RecraftAIImageGenerateConfig: ProviderConfig = { + prompt: { + param: 'prompt', + required: true, + }, + style: { + param: 'style', + default: 'digital_illustration', + }, + width: { + param: 'width', + default: 1024, + min: 256, + max: 2048, + }, + height: { + param: 'height', + default: 1024, + min: 256, + max: 2048, + }, + num_images: { + param: 'num_images', + default: 1, + min: 1, + max: 4, + }, +}; + +interface RecraftApiResponse { + created: number; + data: { url: string }[]; + error?: { + message: string; + type?: string; + param?: string; + code?: string; + }; +} + +export const RecraftAIImageGenerateResponseTransform = ( + response: RecraftApiResponse, + responseStatus: number +): ImageGenerateResponse | ErrorResponse => { + if (responseStatus !== 200 || response.error) { + const error = response.error || { + message: 'Unknown error occurred', + type: null, + param: null, + code: null, + }; + + return { + error: { + message: error.message, + type: error.type || null, + param: error.param || null, + code: error.code || null, + }, + provider: RECRAFTAI, + }; + } + + if (!response.data || !Array.isArray(response.data)) { + return { + error: { + message: 'Invalid response format from Recraft API', + type: 'invalid_response', + param: null, + code: null, + }, + provider: RECRAFTAI, + }; + } + + return { + created: response.created, + data: response.data, + provider: RECRAFTAI, + }; +}; diff --git a/src/providers/recraft-ai/index.ts b/src/providers/recraft-ai/index.ts new file mode 100644 index 000000000..44fc085bc --- /dev/null +++ b/src/providers/recraft-ai/index.ts @@ -0,0 +1,16 @@ +import { ProviderConfigs } from '../types'; +import RecraftAIAPIConfig from './api'; +import { + RecraftAIImageGenerateConfig, + RecraftAIImageGenerateResponseTransform, +} from './imageGenerate'; + +const RecraftAIConfig: ProviderConfigs = { + imageGenerate: RecraftAIImageGenerateConfig, + api: RecraftAIAPIConfig, + responseTransforms: { + imageGenerate: RecraftAIImageGenerateResponseTransform, + }, +}; + +export default RecraftAIConfig; From d13d0fef91a855f3e382c193cf8fecfe52a2cf74 Mon Sep 17 00:00:00 2001 From: Ajay-Satish-01 Date: Fri, 20 Dec 2024 01:09:56 -0800 Subject: [PATCH 2/4] Add openAI standard code --- src/providers/recraft-ai/imageGenerate.ts | 159 +++++++++++++--------- src/providers/recraft-ai/utils.ts | 17 +++ 2 files changed, 115 insertions(+), 61 deletions(-) create mode 100644 src/providers/recraft-ai/utils.ts diff --git a/src/providers/recraft-ai/imageGenerate.ts b/src/providers/recraft-ai/imageGenerate.ts index 3417b54c3..25c961629 100644 --- a/src/providers/recraft-ai/imageGenerate.ts +++ b/src/providers/recraft-ai/imageGenerate.ts @@ -1,5 +1,15 @@ import { RECRAFTAI } from '../../globals'; import { ErrorResponse, ImageGenerateResponse, ProviderConfig } from '../types'; +import { generateErrorResponse } from '../utils'; + +interface RecraftAIImageObject { + b64_json?: string; + url?: string; +} + +interface RecraftAIImageGenerateResponse extends ImageGenerateResponse { + data: RecraftAIImageObject[]; +} export const RecraftAIImageGenerateConfig: ProviderConfig = { prompt: { @@ -8,77 +18,104 @@ export const RecraftAIImageGenerateConfig: ProviderConfig = { }, style: { param: 'style', - default: 'digital_illustration', - }, - width: { - param: 'width', - default: 1024, - min: 256, - max: 2048, + default: 'realistic_image', }, - height: { - param: 'height', - default: 1024, - min: 256, - max: 2048, + style_id: { + param: 'style_id', }, - num_images: { - param: 'num_images', + n: { + param: 'n', default: 1, min: 1, - max: 4, + max: 2, + }, + size: { + param: 'size', + default: '1024x1024', + }, + response_format: { + param: 'response_format', + default: 'url', + }, + controls: { + param: 'controls', }, }; -interface RecraftApiResponse { - created: number; - data: { url: string }[]; - error?: { - message: string; - type?: string; - param?: string; - code?: string; - }; -} +// const validateStyleParams = ( +// style: string | undefined, +// style_id: string | undefined +// ) => { +// if (style && style_id) { +// throw new Error( +// "Parameters 'style' and 'style_id' are mutually exclusive. Please provide only one." +// ); +// } +// }; -export const RecraftAIImageGenerateResponseTransform = ( - response: RecraftApiResponse, - responseStatus: number -): ImageGenerateResponse | ErrorResponse => { - if (responseStatus !== 200 || response.error) { - const error = response.error || { - message: 'Unknown error occurred', - type: null, - param: null, - code: null, - }; +// const determineStyleParams = ( +// style: string | undefined, +// style_id: string | undefined +// ): string | null => { +// validateStyleParams(style, style_id); - return { - error: { - message: error.message, - type: error.type || null, - param: error.param || null, - code: error.code || null, - }, - provider: RECRAFTAI, - }; - } +// if (!style && !style_id) { +// return 'realistic_image'; +// } + +// if (style) { +// return style; +// } + +// return null; +// }; + +// export const generateImageRequest = ( +// prompt: string, +// style?: string, +// style_id?: string, +// n: number = 1, +// size: string = '1024x1024', +// controls?: any +// ) => { +// const finalStyle = determineStyleParams(style, style_id); - if (!response.data || !Array.isArray(response.data)) { - return { - error: { - message: 'Invalid response format from Recraft API', - type: 'invalid_response', - param: null, - code: null, - }, - provider: RECRAFTAI, - }; +// const payload = { +// prompt, +// style: finalStyle, +// style_id, +// n, +// size, +// controls, +// }; + +// return payload; +// }; + +export const RecraftAIImageGenerateResponseTransform: ( + response: RecraftAIImageGenerateResponse | ErrorResponse, + responseStatus: number +) => ImageGenerateResponse | ErrorResponse = (response, responseStatus) => { + if (responseStatus !== 200 || 'error' in response) { + return RecraftAIErrorResponseTransform( + response as ErrorResponse, + RECRAFTAI + ); } + return response; +}; - return { - created: response.created, - data: response.data, - provider: RECRAFTAI, - }; +export const RecraftAIErrorResponseTransform: ( + response: ErrorResponse, + provider: string +) => ErrorResponse = (response, provider) => { + return generateErrorResponse( + { + message: response.error?.message || 'Unknown error occurred', + type: response.error?.type || null, + param: response.error?.param || null, + code: response.error?.code || null, + }, + provider + ); }; diff --git a/src/providers/recraft-ai/utils.ts b/src/providers/recraft-ai/utils.ts new file mode 100644 index 000000000..394625a9a --- /dev/null +++ b/src/providers/recraft-ai/utils.ts @@ -0,0 +1,17 @@ +import { ErrorResponse } from '../types'; +import { generateErrorResponse } from '../utils'; + +export const RecraftAIErrorResponseTransform: ( + response: ErrorResponse, + provider: string +) => ErrorResponse = (response, provider) => { + return generateErrorResponse( + { + message: response.error?.message || 'Unknown error occurred', + type: response.error?.type || null, + param: response.error?.param || null, + code: response.error?.code || null, + }, + provider + ); +}; From 7a24648db97f580908cd2626a60d02d18f9ab86c Mon Sep 17 00:00:00 2001 From: Ajay-Satish-01 Date: Fri, 20 Dec 2024 02:19:09 -0800 Subject: [PATCH 3/4] Remove commented code based on validation --- src/providers/recraft-ai/imageGenerate.ts | 50 ----------------------- 1 file changed, 50 deletions(-) diff --git a/src/providers/recraft-ai/imageGenerate.ts b/src/providers/recraft-ai/imageGenerate.ts index 25c961629..3150aa8f0 100644 --- a/src/providers/recraft-ai/imageGenerate.ts +++ b/src/providers/recraft-ai/imageGenerate.ts @@ -42,56 +42,6 @@ export const RecraftAIImageGenerateConfig: ProviderConfig = { }, }; -// const validateStyleParams = ( -// style: string | undefined, -// style_id: string | undefined -// ) => { -// if (style && style_id) { -// throw new Error( -// "Parameters 'style' and 'style_id' are mutually exclusive. Please provide only one." -// ); -// } -// }; - -// const determineStyleParams = ( -// style: string | undefined, -// style_id: string | undefined -// ): string | null => { -// validateStyleParams(style, style_id); - -// if (!style && !style_id) { -// return 'realistic_image'; -// } - -// if (style) { -// return style; -// } - -// return null; -// }; - -// export const generateImageRequest = ( -// prompt: string, -// style?: string, -// style_id?: string, -// n: number = 1, -// size: string = '1024x1024', -// controls?: any -// ) => { -// const finalStyle = determineStyleParams(style, style_id); - -// const payload = { -// prompt, -// style: finalStyle, -// style_id, -// n, -// size, -// controls, -// }; - -// return payload; -// }; - export const RecraftAIImageGenerateResponseTransform: ( response: RecraftAIImageGenerateResponse | ErrorResponse, responseStatus: number From f80d22e2a348a384d5405322416f8b0020bc5bee Mon Sep 17 00:00:00 2001 From: Ajay-Satish-01 Date: Tue, 24 Dec 2024 12:28:06 -0800 Subject: [PATCH 4/4] add extra params for recraft config --- src/providers/recraft-ai/imageGenerate.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/providers/recraft-ai/imageGenerate.ts b/src/providers/recraft-ai/imageGenerate.ts index 3150aa8f0..a3f371758 100644 --- a/src/providers/recraft-ai/imageGenerate.ts +++ b/src/providers/recraft-ai/imageGenerate.ts @@ -40,6 +40,15 @@ export const RecraftAIImageGenerateConfig: ProviderConfig = { controls: { param: 'controls', }, + model: { + param: 'model', + }, + artistic_level: { + param: 'artistic_level', + }, + substyle: { + param: 'substyle', + }, }; export const RecraftAIImageGenerateResponseTransform: (