@ai-sdk/replicate 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+
2
+ > @ai-sdk/replicate@0.0.1 build /home/runner/work/ai/ai/packages/replicate
3
+ > tsup
4
+
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.3.0
8
+ CLI Using tsup config: /home/runner/work/ai/ai/packages/replicate/tsup.config.ts
9
+ CLI Target: es2018
10
+ CJS Build start
11
+ ESM Build start
12
+ ESM dist/index.mjs 3.13 KB
13
+ ESM dist/index.mjs.map 7.22 KB
14
+ ESM ⚡️ Build success in 74ms
15
+ CJS dist/index.js 4.37 KB
16
+ CJS dist/index.js.map 7.46 KB
17
+ CJS ⚡️ Build success in 88ms
18
+ DTS Build start
19
+ DTS ⚡️ Build success in 18826ms
20
+ DTS dist/index.d.ts 3.08 KB
21
+ DTS dist/index.d.mts 3.08 KB
@@ -0,0 +1,4 @@
1
+
2
+ > @ai-sdk/replicate@0.0.1 clean /home/runner/work/ai/ai/packages/replicate
3
+ > rm -rf dist
4
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # @ai-sdk/replicate
2
+
3
+ ## 0.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 6636db6: feat (provider/replicate): add replicate image provider
8
+ - 90fb95a: chore (provider-utils): switch to unified test server
9
+ - Updated dependencies [90fb95a]
10
+ - Updated dependencies [e6dfef4]
11
+ - Updated dependencies [6636db6]
12
+ - @ai-sdk/provider-utils@2.0.7
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2023 Vercel, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # AI SDK - Replicate Provider
2
+
3
+ The **[Replicate provider](https://sdk.vercel.ai/providers/ai-sdk-providers/replicate)** for the [AI SDK](https://sdk.vercel.ai/docs) contains image model support for the Replicate API.
4
+
5
+ ## Setup
6
+
7
+ The Replicate provider is available in the `@ai-sdk/replicate` module. You can install it with
8
+
9
+ ```bash
10
+ npm i @ai-sdk/replicate
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { replicate } from '@ai-sdk/replicate';
17
+ import { experimental_generateImage as generateImage } from 'ai';
18
+
19
+ const { image } = await generateImage({
20
+ model: replicate.image('black-forest-labs/flux-schnell'),
21
+ prompt: 'The Loch Ness Monster getting a manicure',
22
+ });
23
+
24
+ const filename = `image-${Date.now()}.png`;
25
+ fs.writeFileSync(filename, image.uint8Array);
26
+ console.log(`Image saved to ${filename}`);
27
+ ```
28
+
29
+ If you want to pass additional inputs to the model besides the prompt, use the `providerOptions.replicate` property:
30
+
31
+ ```ts
32
+ const { image } = await generateImage({
33
+ model: replicate.image('recraft-ai/recraft-v3'),
34
+ prompt: 'The Loch Ness Monster getting a manicure',
35
+ size: '1365x1024',
36
+ providerOptions: {
37
+ replicate: {
38
+ style: 'realistic_image',
39
+ },
40
+ },
41
+ });
42
+ ```
43
+
44
+ ## Documentation
45
+
46
+ Please check out the **[Replicate provider](https://sdk.vercel.ai/providers/ai-sdk-providers/replicate)** for more information.
@@ -0,0 +1,65 @@
1
+ import { Resolvable, FetchFunction } from '@ai-sdk/provider-utils';
2
+ import { ImageModelV1 } from '@ai-sdk/provider';
3
+
4
+ type ReplicateImageModelId = 'black-forest-labs/flux-1.1-pro' | 'black-forest-labs/flux-1.1-pro-ultra' | 'black-forest-labs/flux-dev' | 'black-forest-labs/flux-pro' | 'black-forest-labs/flux-schnell' | 'bytedance/sdxl-lightning-4step' | 'fofr/aura-flow' | 'fofr/latent-consistency-model' | 'fofr/realvisxl-v3-multi-controlnet-lora' | 'fofr/sdxl-emoji' | 'fofr/sdxl-multi-controlnet-lora' | 'ideogram-ai/ideogram-v2' | 'ideogram-ai/ideogram-v2-turbo' | 'lucataco/dreamshaper-xl-turbo' | 'lucataco/open-dalle-v1.1' | 'lucataco/realvisxl-v2.0' | 'lucataco/realvisxl2-lcm' | 'luma/photon' | 'luma/photon-flash' | 'nvidia/sana' | 'playgroundai/playground-v2.5-1024px-aesthetic' | 'recraft-ai/recraft-v3' | 'recraft-ai/recraft-v3-svg' | 'stability-ai/stable-diffusion-3.5-large' | 'stability-ai/stable-diffusion-3.5-large-turbo' | 'stability-ai/stable-diffusion-3.5-medium' | 'tstramer/material-diffusion' | (string & {});
5
+ interface ReplicateImageSettings {
6
+ /**
7
+ Override the maximum number of images per call (default 1)
8
+ */
9
+ maxImagesPerCall?: number;
10
+ }
11
+
12
+ interface ReplicateImageModelConfig {
13
+ provider: string;
14
+ baseURL: string;
15
+ headers?: Resolvable<Record<string, string | undefined>>;
16
+ fetch?: FetchFunction;
17
+ }
18
+ declare class ReplicateImageModel implements ImageModelV1 {
19
+ readonly specificationVersion = "v1";
20
+ readonly modelId: ReplicateImageModelId;
21
+ readonly settings: ReplicateImageSettings;
22
+ private readonly config;
23
+ get provider(): string;
24
+ get maxImagesPerCall(): number;
25
+ constructor(modelId: ReplicateImageModelId, settings: ReplicateImageSettings, config: ReplicateImageModelConfig);
26
+ doGenerate({ prompt, n, aspectRatio, size, seed, providerOptions, headers, abortSignal, }: Parameters<ImageModelV1['doGenerate']>[0]): Promise<Awaited<ReturnType<ImageModelV1['doGenerate']>>>;
27
+ }
28
+
29
+ interface ReplicateProviderSettings {
30
+ /**
31
+ API token that is being send using the `Authorization` header.
32
+ It defaults to the `REPLICATE_API_TOKEN` environment variable.
33
+ */
34
+ apiToken?: string;
35
+ /**
36
+ Use a different URL prefix for API calls, e.g. to use proxy servers.
37
+ The default prefix is `https://api.replicate.com/v1`.
38
+ */
39
+ baseURL?: string;
40
+ /**
41
+ Custom headers to include in the requests.
42
+ */
43
+ headers?: Record<string, string>;
44
+ /**
45
+ Custom fetch implementation. You can use it as a middleware to intercept requests,
46
+ or to provide a custom fetch implementation for e.g. testing.
47
+ */
48
+ fetch?: FetchFunction;
49
+ }
50
+ interface ReplicateProvider {
51
+ /**
52
+ * Creates a Replicate image generation model.
53
+ */
54
+ image(modelId: ReplicateImageModelId, settings?: ReplicateImageSettings): ReplicateImageModel;
55
+ }
56
+ /**
57
+ * Create a Replicate provider instance.
58
+ */
59
+ declare function createReplicate(options?: ReplicateProviderSettings): ReplicateProvider;
60
+ /**
61
+ * Default Replicate provider instance.
62
+ */
63
+ declare const replicate: ReplicateProvider;
64
+
65
+ export { type ReplicateProvider, type ReplicateProviderSettings, createReplicate, replicate };
@@ -0,0 +1,65 @@
1
+ import { Resolvable, FetchFunction } from '@ai-sdk/provider-utils';
2
+ import { ImageModelV1 } from '@ai-sdk/provider';
3
+
4
+ type ReplicateImageModelId = 'black-forest-labs/flux-1.1-pro' | 'black-forest-labs/flux-1.1-pro-ultra' | 'black-forest-labs/flux-dev' | 'black-forest-labs/flux-pro' | 'black-forest-labs/flux-schnell' | 'bytedance/sdxl-lightning-4step' | 'fofr/aura-flow' | 'fofr/latent-consistency-model' | 'fofr/realvisxl-v3-multi-controlnet-lora' | 'fofr/sdxl-emoji' | 'fofr/sdxl-multi-controlnet-lora' | 'ideogram-ai/ideogram-v2' | 'ideogram-ai/ideogram-v2-turbo' | 'lucataco/dreamshaper-xl-turbo' | 'lucataco/open-dalle-v1.1' | 'lucataco/realvisxl-v2.0' | 'lucataco/realvisxl2-lcm' | 'luma/photon' | 'luma/photon-flash' | 'nvidia/sana' | 'playgroundai/playground-v2.5-1024px-aesthetic' | 'recraft-ai/recraft-v3' | 'recraft-ai/recraft-v3-svg' | 'stability-ai/stable-diffusion-3.5-large' | 'stability-ai/stable-diffusion-3.5-large-turbo' | 'stability-ai/stable-diffusion-3.5-medium' | 'tstramer/material-diffusion' | (string & {});
5
+ interface ReplicateImageSettings {
6
+ /**
7
+ Override the maximum number of images per call (default 1)
8
+ */
9
+ maxImagesPerCall?: number;
10
+ }
11
+
12
+ interface ReplicateImageModelConfig {
13
+ provider: string;
14
+ baseURL: string;
15
+ headers?: Resolvable<Record<string, string | undefined>>;
16
+ fetch?: FetchFunction;
17
+ }
18
+ declare class ReplicateImageModel implements ImageModelV1 {
19
+ readonly specificationVersion = "v1";
20
+ readonly modelId: ReplicateImageModelId;
21
+ readonly settings: ReplicateImageSettings;
22
+ private readonly config;
23
+ get provider(): string;
24
+ get maxImagesPerCall(): number;
25
+ constructor(modelId: ReplicateImageModelId, settings: ReplicateImageSettings, config: ReplicateImageModelConfig);
26
+ doGenerate({ prompt, n, aspectRatio, size, seed, providerOptions, headers, abortSignal, }: Parameters<ImageModelV1['doGenerate']>[0]): Promise<Awaited<ReturnType<ImageModelV1['doGenerate']>>>;
27
+ }
28
+
29
+ interface ReplicateProviderSettings {
30
+ /**
31
+ API token that is being send using the `Authorization` header.
32
+ It defaults to the `REPLICATE_API_TOKEN` environment variable.
33
+ */
34
+ apiToken?: string;
35
+ /**
36
+ Use a different URL prefix for API calls, e.g. to use proxy servers.
37
+ The default prefix is `https://api.replicate.com/v1`.
38
+ */
39
+ baseURL?: string;
40
+ /**
41
+ Custom headers to include in the requests.
42
+ */
43
+ headers?: Record<string, string>;
44
+ /**
45
+ Custom fetch implementation. You can use it as a middleware to intercept requests,
46
+ or to provide a custom fetch implementation for e.g. testing.
47
+ */
48
+ fetch?: FetchFunction;
49
+ }
50
+ interface ReplicateProvider {
51
+ /**
52
+ * Creates a Replicate image generation model.
53
+ */
54
+ image(modelId: ReplicateImageModelId, settings?: ReplicateImageSettings): ReplicateImageModel;
55
+ }
56
+ /**
57
+ * Create a Replicate provider instance.
58
+ */
59
+ declare function createReplicate(options?: ReplicateProviderSettings): ReplicateProvider;
60
+ /**
61
+ * Default Replicate provider instance.
62
+ */
63
+ declare const replicate: ReplicateProvider;
64
+
65
+ export { type ReplicateProvider, type ReplicateProviderSettings, createReplicate, replicate };
package/dist/index.js ADDED
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ createReplicate: () => createReplicate,
24
+ replicate: () => replicate
25
+ });
26
+ module.exports = __toCommonJS(src_exports);
27
+
28
+ // src/replicate-provider.ts
29
+ var import_provider_utils3 = require("@ai-sdk/provider-utils");
30
+
31
+ // src/replicate-image-model.ts
32
+ var import_provider_utils2 = require("@ai-sdk/provider-utils");
33
+ var import_zod2 = require("zod");
34
+
35
+ // src/replicate-error.ts
36
+ var import_provider_utils = require("@ai-sdk/provider-utils");
37
+ var import_zod = require("zod");
38
+ var replicateErrorSchema = import_zod.z.object({
39
+ detail: import_zod.z.string().optional(),
40
+ error: import_zod.z.string().optional()
41
+ });
42
+ var replicateFailedResponseHandler = (0, import_provider_utils.createJsonErrorResponseHandler)({
43
+ errorSchema: replicateErrorSchema,
44
+ errorToMessage: (error) => {
45
+ var _a, _b;
46
+ return (_b = (_a = error.detail) != null ? _a : error.error) != null ? _b : "Unknown Replicate error";
47
+ }
48
+ });
49
+
50
+ // src/replicate-image-model.ts
51
+ var ReplicateImageModel = class {
52
+ constructor(modelId, settings, config) {
53
+ this.specificationVersion = "v1";
54
+ this.modelId = modelId;
55
+ this.settings = settings;
56
+ this.config = config;
57
+ }
58
+ get provider() {
59
+ return this.config.provider;
60
+ }
61
+ get maxImagesPerCall() {
62
+ var _a;
63
+ return (_a = this.settings.maxImagesPerCall) != null ? _a : 1;
64
+ }
65
+ async doGenerate({
66
+ prompt,
67
+ n,
68
+ aspectRatio,
69
+ size,
70
+ seed,
71
+ providerOptions,
72
+ headers,
73
+ abortSignal
74
+ }) {
75
+ var _a;
76
+ const warnings = [];
77
+ const {
78
+ value: { output }
79
+ } = await (0, import_provider_utils2.postJsonToApi)({
80
+ url: `${this.config.baseURL}/models/${this.modelId}/predictions`,
81
+ headers: (0, import_provider_utils2.combineHeaders)(await (0, import_provider_utils2.resolve)(this.config.headers), headers, {
82
+ prefer: "wait"
83
+ }),
84
+ body: {
85
+ input: {
86
+ prompt,
87
+ aspect_ratio: aspectRatio,
88
+ size,
89
+ seed,
90
+ num_outputs: n,
91
+ ...(_a = providerOptions.replicate) != null ? _a : {}
92
+ }
93
+ },
94
+ failedResponseHandler: replicateFailedResponseHandler,
95
+ successfulResponseHandler: (0, import_provider_utils2.createJsonResponseHandler)(
96
+ replicateImageResponseSchema
97
+ ),
98
+ abortSignal,
99
+ fetch: this.config.fetch
100
+ });
101
+ const outputArray = Array.isArray(output) ? output : [output];
102
+ const images = await Promise.all(
103
+ outputArray.map(async (url) => {
104
+ const response = await fetch(url);
105
+ return new Uint8Array(await response.arrayBuffer());
106
+ })
107
+ );
108
+ return { images, warnings };
109
+ }
110
+ };
111
+ var replicateImageResponseSchema = import_zod2.z.object({
112
+ output: import_zod2.z.union([import_zod2.z.array(import_zod2.z.string()), import_zod2.z.string()])
113
+ });
114
+
115
+ // src/replicate-provider.ts
116
+ function createReplicate(options = {}) {
117
+ return {
118
+ image: (modelId, settings) => {
119
+ var _a;
120
+ return new ReplicateImageModel(modelId, settings != null ? settings : {}, {
121
+ provider: "replicate",
122
+ baseURL: (_a = options.baseURL) != null ? _a : "https://api.replicate.com/v1",
123
+ headers: {
124
+ Authorization: `Bearer ${(0, import_provider_utils3.loadApiKey)({
125
+ apiKey: options.apiToken,
126
+ environmentVariableName: "REPLICATE_API_TOKEN",
127
+ description: "Replicate"
128
+ })}`,
129
+ ...options.headers
130
+ },
131
+ fetch: options.fetch
132
+ });
133
+ }
134
+ };
135
+ }
136
+ var replicate = createReplicate();
137
+ // Annotate the CommonJS export names for ESM import in node:
138
+ 0 && (module.exports = {
139
+ createReplicate,
140
+ replicate
141
+ });
142
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/replicate-provider.ts","../src/replicate-image-model.ts","../src/replicate-error.ts"],"sourcesContent":["export { createReplicate, replicate } from './replicate-provider';\nexport type {\n ReplicateProvider,\n ReplicateProviderSettings,\n} from './replicate-provider';\n","import type { FetchFunction } from '@ai-sdk/provider-utils';\nimport { loadApiKey } from '@ai-sdk/provider-utils';\nimport { ReplicateImageModel } from './replicate-image-model';\nimport {\n ReplicateImageModelId,\n ReplicateImageSettings,\n} from './replicate-image-settings';\n\nexport interface ReplicateProviderSettings {\n /**\nAPI token that is being send using the `Authorization` header.\nIt defaults to the `REPLICATE_API_TOKEN` environment variable.\n */\n apiToken?: string;\n\n /**\nUse a different URL prefix for API calls, e.g. to use proxy servers.\nThe default prefix is `https://api.replicate.com/v1`.\n */\n baseURL?: string;\n\n /**\nCustom headers to include in the requests.\n */\n headers?: Record<string, string>;\n\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface ReplicateProvider {\n /**\n * Creates a Replicate image generation model.\n */\n image(\n modelId: ReplicateImageModelId,\n settings?: ReplicateImageSettings,\n ): ReplicateImageModel;\n}\n\n/**\n * Create a Replicate provider instance.\n */\nexport function createReplicate(\n options: ReplicateProviderSettings = {},\n): ReplicateProvider {\n return {\n image: (\n modelId: ReplicateImageModelId,\n settings?: ReplicateImageSettings,\n ) =>\n new ReplicateImageModel(modelId, settings ?? {}, {\n provider: 'replicate',\n baseURL: options.baseURL ?? 'https://api.replicate.com/v1',\n headers: {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiToken,\n environmentVariableName: 'REPLICATE_API_TOKEN',\n description: 'Replicate',\n })}`,\n ...options.headers,\n },\n fetch: options.fetch,\n }),\n };\n}\n\n/**\n * Default Replicate provider instance.\n */\nexport const replicate = createReplicate();\n","import type { ImageModelV1, ImageModelV1CallWarning } from '@ai-sdk/provider';\nimport type { Resolvable } from '@ai-sdk/provider-utils';\nimport {\n FetchFunction,\n combineHeaders,\n createJsonResponseHandler,\n postJsonToApi,\n resolve,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod';\nimport { replicateFailedResponseHandler } from './replicate-error';\nimport {\n ReplicateImageModelId,\n ReplicateImageSettings,\n} from './replicate-image-settings';\n\ninterface ReplicateImageModelConfig {\n provider: string;\n baseURL: string;\n headers?: Resolvable<Record<string, string | undefined>>;\n fetch?: FetchFunction;\n}\n\nexport class ReplicateImageModel implements ImageModelV1 {\n readonly specificationVersion = 'v1';\n\n readonly modelId: ReplicateImageModelId;\n readonly settings: ReplicateImageSettings;\n\n private readonly config: ReplicateImageModelConfig;\n\n get provider(): string {\n return this.config.provider;\n }\n\n get maxImagesPerCall(): number {\n return this.settings.maxImagesPerCall ?? 1;\n }\n\n constructor(\n modelId: ReplicateImageModelId,\n settings: ReplicateImageSettings,\n config: ReplicateImageModelConfig,\n ) {\n this.modelId = modelId;\n this.settings = settings;\n this.config = config;\n }\n\n async doGenerate({\n prompt,\n n,\n aspectRatio,\n size,\n seed,\n providerOptions,\n headers,\n abortSignal,\n }: Parameters<ImageModelV1['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV1['doGenerate']>>\n > {\n const warnings: Array<ImageModelV1CallWarning> = [];\n\n const {\n value: { output },\n } = await postJsonToApi({\n url: `${this.config.baseURL}/models/${this.modelId}/predictions`,\n headers: combineHeaders(await resolve(this.config.headers), headers, {\n prefer: 'wait',\n }),\n body: {\n input: {\n prompt,\n aspect_ratio: aspectRatio,\n size,\n seed,\n num_outputs: n,\n ...(providerOptions.replicate ?? {}),\n },\n },\n failedResponseHandler: replicateFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n replicateImageResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n // download the images:\n const outputArray = Array.isArray(output) ? output : [output];\n const images = await Promise.all(\n outputArray.map(async url => {\n const response = await fetch(url);\n return new Uint8Array(await response.arrayBuffer());\n }),\n );\n\n return { images, warnings };\n }\n}\n\nconst replicateImageResponseSchema = z.object({\n output: z.union([z.array(z.string()), z.string()]),\n});\n","import { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';\nimport { z } from 'zod';\n\nconst replicateErrorSchema = z.object({\n detail: z.string().optional(),\n error: z.string().optional(),\n});\n\nexport const replicateFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: replicateErrorSchema,\n errorToMessage: error =>\n error.detail ?? error.error ?? 'Unknown Replicate error',\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,IAAAA,yBAA2B;;;ACC3B,IAAAC,yBAMO;AACP,IAAAC,cAAkB;;;ACTlB,4BAA+C;AAC/C,iBAAkB;AAElB,IAAM,uBAAuB,aAAE,OAAO;AAAA,EACpC,QAAQ,aAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,aAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AAEM,IAAM,qCAAiC,sDAA+B;AAAA,EAC3E,aAAa;AAAA,EACb,gBAAgB,WAAM;AAVxB;AAWI,6BAAM,WAAN,YAAgB,MAAM,UAAtB,YAA+B;AAAA;AACnC,CAAC;;;ADWM,IAAM,sBAAN,MAAkD;AAAA,EAgBvD,YACE,SACA,UACA,QACA;AAnBF,SAAS,uBAAuB;AAoB9B,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,SAAS;AAAA,EAChB;AAAA,EAhBA,IAAI,WAAmB;AACrB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,mBAA2B;AAnCjC;AAoCI,YAAO,UAAK,SAAS,qBAAd,YAAkC;AAAA,EAC3C;AAAA,EAYA,MAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAEE;AA5DJ;AA6DI,UAAM,WAA2C,CAAC;AAElD,UAAM;AAAA,MACJ,OAAO,EAAE,OAAO;AAAA,IAClB,IAAI,UAAM,sCAAc;AAAA,MACtB,KAAK,GAAG,KAAK,OAAO,OAAO,WAAW,KAAK,OAAO;AAAA,MAClD,aAAS,uCAAe,UAAM,gCAAQ,KAAK,OAAO,OAAO,GAAG,SAAS;AAAA,QACnE,QAAQ;AAAA,MACV,CAAC;AAAA,MACD,MAAM;AAAA,QACJ,OAAO;AAAA,UACL;AAAA,UACA,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UACA,aAAa;AAAA,UACb,IAAI,qBAAgB,cAAhB,YAA6B,CAAC;AAAA,QACpC;AAAA,MACF;AAAA,MACA,uBAAuB;AAAA,MACvB,+BAA2B;AAAA,QACzB;AAAA,MACF;AAAA,MACA;AAAA,MACA,OAAO,KAAK,OAAO;AAAA,IACrB,CAAC;AAGD,UAAM,cAAc,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAC5D,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,YAAY,IAAI,OAAM,QAAO;AAC3B,cAAM,WAAW,MAAM,MAAM,GAAG;AAChC,eAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AAAA,MACpD,CAAC;AAAA,IACH;AAEA,WAAO,EAAE,QAAQ,SAAS;AAAA,EAC5B;AACF;AAEA,IAAM,+BAA+B,cAAE,OAAO;AAAA,EAC5C,QAAQ,cAAE,MAAM,CAAC,cAAE,MAAM,cAAE,OAAO,CAAC,GAAG,cAAE,OAAO,CAAC,CAAC;AACnD,CAAC;;;ADzDM,SAAS,gBACd,UAAqC,CAAC,GACnB;AACnB,SAAO;AAAA,IACL,OAAO,CACL,SACA,aACA;AArDN;AAsDM,iBAAI,oBAAoB,SAAS,8BAAY,CAAC,GAAG;AAAA,QAC/C,UAAU;AAAA,QACV,UAAS,aAAQ,YAAR,YAAmB;AAAA,QAC5B,SAAS;AAAA,UACP,eAAe,cAAU,mCAAW;AAAA,YAClC,QAAQ,QAAQ;AAAA,YAChB,yBAAyB;AAAA,YACzB,aAAa;AAAA,UACf,CAAC,CAAC;AAAA,UACF,GAAG,QAAQ;AAAA,QACb;AAAA,QACA,OAAO,QAAQ;AAAA,MACjB,CAAC;AAAA;AAAA,EACL;AACF;AAKO,IAAM,YAAY,gBAAgB;","names":["import_provider_utils","import_provider_utils","import_zod"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,119 @@
1
+ // src/replicate-provider.ts
2
+ import { loadApiKey } from "@ai-sdk/provider-utils";
3
+
4
+ // src/replicate-image-model.ts
5
+ import {
6
+ combineHeaders,
7
+ createJsonResponseHandler,
8
+ postJsonToApi,
9
+ resolve
10
+ } from "@ai-sdk/provider-utils";
11
+ import { z as z2 } from "zod";
12
+
13
+ // src/replicate-error.ts
14
+ import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
15
+ import { z } from "zod";
16
+ var replicateErrorSchema = z.object({
17
+ detail: z.string().optional(),
18
+ error: z.string().optional()
19
+ });
20
+ var replicateFailedResponseHandler = createJsonErrorResponseHandler({
21
+ errorSchema: replicateErrorSchema,
22
+ errorToMessage: (error) => {
23
+ var _a, _b;
24
+ return (_b = (_a = error.detail) != null ? _a : error.error) != null ? _b : "Unknown Replicate error";
25
+ }
26
+ });
27
+
28
+ // src/replicate-image-model.ts
29
+ var ReplicateImageModel = class {
30
+ constructor(modelId, settings, config) {
31
+ this.specificationVersion = "v1";
32
+ this.modelId = modelId;
33
+ this.settings = settings;
34
+ this.config = config;
35
+ }
36
+ get provider() {
37
+ return this.config.provider;
38
+ }
39
+ get maxImagesPerCall() {
40
+ var _a;
41
+ return (_a = this.settings.maxImagesPerCall) != null ? _a : 1;
42
+ }
43
+ async doGenerate({
44
+ prompt,
45
+ n,
46
+ aspectRatio,
47
+ size,
48
+ seed,
49
+ providerOptions,
50
+ headers,
51
+ abortSignal
52
+ }) {
53
+ var _a;
54
+ const warnings = [];
55
+ const {
56
+ value: { output }
57
+ } = await postJsonToApi({
58
+ url: `${this.config.baseURL}/models/${this.modelId}/predictions`,
59
+ headers: combineHeaders(await resolve(this.config.headers), headers, {
60
+ prefer: "wait"
61
+ }),
62
+ body: {
63
+ input: {
64
+ prompt,
65
+ aspect_ratio: aspectRatio,
66
+ size,
67
+ seed,
68
+ num_outputs: n,
69
+ ...(_a = providerOptions.replicate) != null ? _a : {}
70
+ }
71
+ },
72
+ failedResponseHandler: replicateFailedResponseHandler,
73
+ successfulResponseHandler: createJsonResponseHandler(
74
+ replicateImageResponseSchema
75
+ ),
76
+ abortSignal,
77
+ fetch: this.config.fetch
78
+ });
79
+ const outputArray = Array.isArray(output) ? output : [output];
80
+ const images = await Promise.all(
81
+ outputArray.map(async (url) => {
82
+ const response = await fetch(url);
83
+ return new Uint8Array(await response.arrayBuffer());
84
+ })
85
+ );
86
+ return { images, warnings };
87
+ }
88
+ };
89
+ var replicateImageResponseSchema = z2.object({
90
+ output: z2.union([z2.array(z2.string()), z2.string()])
91
+ });
92
+
93
+ // src/replicate-provider.ts
94
+ function createReplicate(options = {}) {
95
+ return {
96
+ image: (modelId, settings) => {
97
+ var _a;
98
+ return new ReplicateImageModel(modelId, settings != null ? settings : {}, {
99
+ provider: "replicate",
100
+ baseURL: (_a = options.baseURL) != null ? _a : "https://api.replicate.com/v1",
101
+ headers: {
102
+ Authorization: `Bearer ${loadApiKey({
103
+ apiKey: options.apiToken,
104
+ environmentVariableName: "REPLICATE_API_TOKEN",
105
+ description: "Replicate"
106
+ })}`,
107
+ ...options.headers
108
+ },
109
+ fetch: options.fetch
110
+ });
111
+ }
112
+ };
113
+ }
114
+ var replicate = createReplicate();
115
+ export {
116
+ createReplicate,
117
+ replicate
118
+ };
119
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/replicate-provider.ts","../src/replicate-image-model.ts","../src/replicate-error.ts"],"sourcesContent":["import type { FetchFunction } from '@ai-sdk/provider-utils';\nimport { loadApiKey } from '@ai-sdk/provider-utils';\nimport { ReplicateImageModel } from './replicate-image-model';\nimport {\n ReplicateImageModelId,\n ReplicateImageSettings,\n} from './replicate-image-settings';\n\nexport interface ReplicateProviderSettings {\n /**\nAPI token that is being send using the `Authorization` header.\nIt defaults to the `REPLICATE_API_TOKEN` environment variable.\n */\n apiToken?: string;\n\n /**\nUse a different URL prefix for API calls, e.g. to use proxy servers.\nThe default prefix is `https://api.replicate.com/v1`.\n */\n baseURL?: string;\n\n /**\nCustom headers to include in the requests.\n */\n headers?: Record<string, string>;\n\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface ReplicateProvider {\n /**\n * Creates a Replicate image generation model.\n */\n image(\n modelId: ReplicateImageModelId,\n settings?: ReplicateImageSettings,\n ): ReplicateImageModel;\n}\n\n/**\n * Create a Replicate provider instance.\n */\nexport function createReplicate(\n options: ReplicateProviderSettings = {},\n): ReplicateProvider {\n return {\n image: (\n modelId: ReplicateImageModelId,\n settings?: ReplicateImageSettings,\n ) =>\n new ReplicateImageModel(modelId, settings ?? {}, {\n provider: 'replicate',\n baseURL: options.baseURL ?? 'https://api.replicate.com/v1',\n headers: {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiToken,\n environmentVariableName: 'REPLICATE_API_TOKEN',\n description: 'Replicate',\n })}`,\n ...options.headers,\n },\n fetch: options.fetch,\n }),\n };\n}\n\n/**\n * Default Replicate provider instance.\n */\nexport const replicate = createReplicate();\n","import type { ImageModelV1, ImageModelV1CallWarning } from '@ai-sdk/provider';\nimport type { Resolvable } from '@ai-sdk/provider-utils';\nimport {\n FetchFunction,\n combineHeaders,\n createJsonResponseHandler,\n postJsonToApi,\n resolve,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod';\nimport { replicateFailedResponseHandler } from './replicate-error';\nimport {\n ReplicateImageModelId,\n ReplicateImageSettings,\n} from './replicate-image-settings';\n\ninterface ReplicateImageModelConfig {\n provider: string;\n baseURL: string;\n headers?: Resolvable<Record<string, string | undefined>>;\n fetch?: FetchFunction;\n}\n\nexport class ReplicateImageModel implements ImageModelV1 {\n readonly specificationVersion = 'v1';\n\n readonly modelId: ReplicateImageModelId;\n readonly settings: ReplicateImageSettings;\n\n private readonly config: ReplicateImageModelConfig;\n\n get provider(): string {\n return this.config.provider;\n }\n\n get maxImagesPerCall(): number {\n return this.settings.maxImagesPerCall ?? 1;\n }\n\n constructor(\n modelId: ReplicateImageModelId,\n settings: ReplicateImageSettings,\n config: ReplicateImageModelConfig,\n ) {\n this.modelId = modelId;\n this.settings = settings;\n this.config = config;\n }\n\n async doGenerate({\n prompt,\n n,\n aspectRatio,\n size,\n seed,\n providerOptions,\n headers,\n abortSignal,\n }: Parameters<ImageModelV1['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV1['doGenerate']>>\n > {\n const warnings: Array<ImageModelV1CallWarning> = [];\n\n const {\n value: { output },\n } = await postJsonToApi({\n url: `${this.config.baseURL}/models/${this.modelId}/predictions`,\n headers: combineHeaders(await resolve(this.config.headers), headers, {\n prefer: 'wait',\n }),\n body: {\n input: {\n prompt,\n aspect_ratio: aspectRatio,\n size,\n seed,\n num_outputs: n,\n ...(providerOptions.replicate ?? {}),\n },\n },\n failedResponseHandler: replicateFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n replicateImageResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n // download the images:\n const outputArray = Array.isArray(output) ? output : [output];\n const images = await Promise.all(\n outputArray.map(async url => {\n const response = await fetch(url);\n return new Uint8Array(await response.arrayBuffer());\n }),\n );\n\n return { images, warnings };\n }\n}\n\nconst replicateImageResponseSchema = z.object({\n output: z.union([z.array(z.string()), z.string()]),\n});\n","import { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';\nimport { z } from 'zod';\n\nconst replicateErrorSchema = z.object({\n detail: z.string().optional(),\n error: z.string().optional(),\n});\n\nexport const replicateFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: replicateErrorSchema,\n errorToMessage: error =>\n error.detail ?? error.error ?? 'Unknown Replicate error',\n});\n"],"mappings":";AACA,SAAS,kBAAkB;;;ACC3B;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,KAAAA,UAAS;;;ACTlB,SAAS,sCAAsC;AAC/C,SAAS,SAAS;AAElB,IAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,EAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AAEM,IAAM,iCAAiC,+BAA+B;AAAA,EAC3E,aAAa;AAAA,EACb,gBAAgB,WAAM;AAVxB;AAWI,6BAAM,WAAN,YAAgB,MAAM,UAAtB,YAA+B;AAAA;AACnC,CAAC;;;ADWM,IAAM,sBAAN,MAAkD;AAAA,EAgBvD,YACE,SACA,UACA,QACA;AAnBF,SAAS,uBAAuB;AAoB9B,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,SAAS;AAAA,EAChB;AAAA,EAhBA,IAAI,WAAmB;AACrB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,mBAA2B;AAnCjC;AAoCI,YAAO,UAAK,SAAS,qBAAd,YAAkC;AAAA,EAC3C;AAAA,EAYA,MAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAEE;AA5DJ;AA6DI,UAAM,WAA2C,CAAC;AAElD,UAAM;AAAA,MACJ,OAAO,EAAE,OAAO;AAAA,IAClB,IAAI,MAAM,cAAc;AAAA,MACtB,KAAK,GAAG,KAAK,OAAO,OAAO,WAAW,KAAK,OAAO;AAAA,MAClD,SAAS,eAAe,MAAM,QAAQ,KAAK,OAAO,OAAO,GAAG,SAAS;AAAA,QACnE,QAAQ;AAAA,MACV,CAAC;AAAA,MACD,MAAM;AAAA,QACJ,OAAO;AAAA,UACL;AAAA,UACA,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UACA,aAAa;AAAA,UACb,IAAI,qBAAgB,cAAhB,YAA6B,CAAC;AAAA,QACpC;AAAA,MACF;AAAA,MACA,uBAAuB;AAAA,MACvB,2BAA2B;AAAA,QACzB;AAAA,MACF;AAAA,MACA;AAAA,MACA,OAAO,KAAK,OAAO;AAAA,IACrB,CAAC;AAGD,UAAM,cAAc,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAC5D,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,YAAY,IAAI,OAAM,QAAO;AAC3B,cAAM,WAAW,MAAM,MAAM,GAAG;AAChC,eAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AAAA,MACpD,CAAC;AAAA,IACH;AAEA,WAAO,EAAE,QAAQ,SAAS;AAAA,EAC5B;AACF;AAEA,IAAM,+BAA+BC,GAAE,OAAO;AAAA,EAC5C,QAAQA,GAAE,MAAM,CAACA,GAAE,MAAMA,GAAE,OAAO,CAAC,GAAGA,GAAE,OAAO,CAAC,CAAC;AACnD,CAAC;;;ADzDM,SAAS,gBACd,UAAqC,CAAC,GACnB;AACnB,SAAO;AAAA,IACL,OAAO,CACL,SACA,aACA;AArDN;AAsDM,iBAAI,oBAAoB,SAAS,8BAAY,CAAC,GAAG;AAAA,QAC/C,UAAU;AAAA,QACV,UAAS,aAAQ,YAAR,YAAmB;AAAA,QAC5B,SAAS;AAAA,UACP,eAAe,UAAU,WAAW;AAAA,YAClC,QAAQ,QAAQ;AAAA,YAChB,yBAAyB;AAAA,YACzB,aAAa;AAAA,UACf,CAAC,CAAC;AAAA,UACF,GAAG,QAAQ;AAAA,QACb;AAAA,QACA,OAAO,QAAQ;AAAA,MACjB,CAAC;AAAA;AAAA,EACL;AACF;AAKO,IAAM,YAAY,gBAAgB;","names":["z","z"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@ai-sdk/replicate",
3
+ "version": "0.0.1",
4
+ "license": "Apache-2.0",
5
+ "sideEffects": false,
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ "./package.json": "./package.json",
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ }
16
+ },
17
+ "dependencies": {
18
+ "@ai-sdk/provider": "1.0.4",
19
+ "@ai-sdk/provider-utils": "2.0.7"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^18",
23
+ "tsup": "^8",
24
+ "typescript": "5.6.3",
25
+ "zod": "3.23.8",
26
+ "@vercel/ai-tsconfig": "0.0.0"
27
+ },
28
+ "peerDependencies": {
29
+ "zod": "^3.0.0"
30
+ },
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "build:watch": "tsup --watch",
40
+ "clean": "rm -rf dist",
41
+ "lint": "eslint \"./**/*.ts*\"",
42
+ "type-check": "tsc --noEmit",
43
+ "prettier-check": "prettier --check \"./**/*.ts*\"",
44
+ "test": "pnpm test:node && pnpm test:edge",
45
+ "test:edge": "vitest --config vitest.edge.config.js --run",
46
+ "test:node": "vitest --config vitest.node.config.js --run"
47
+ }
48
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { createReplicate, replicate } from './replicate-provider';
2
+ export type {
3
+ ReplicateProvider,
4
+ ReplicateProviderSettings,
5
+ } from './replicate-provider';
@@ -0,0 +1,13 @@
1
+ import { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';
2
+ import { z } from 'zod';
3
+
4
+ const replicateErrorSchema = z.object({
5
+ detail: z.string().optional(),
6
+ error: z.string().optional(),
7
+ });
8
+
9
+ export const replicateFailedResponseHandler = createJsonErrorResponseHandler({
10
+ errorSchema: replicateErrorSchema,
11
+ errorToMessage: error =>
12
+ error.detail ?? error.error ?? 'Unknown Replicate error',
13
+ });
@@ -0,0 +1,177 @@
1
+ import { createTestServer } from '@ai-sdk/provider-utils/test';
2
+ import { createReplicate } from './replicate-provider';
3
+
4
+ const prompt = 'The Loch Ness monster getting a manicure';
5
+
6
+ const provider = createReplicate({ apiToken: 'test-api-token' });
7
+ const model = provider.image('black-forest-labs/flux-schnell');
8
+
9
+ describe('doGenerate', () => {
10
+ const server = createTestServer({
11
+ 'https://api.replicate.com/*': {},
12
+ 'https://replicate.delivery/*': {
13
+ response: {
14
+ type: 'binary',
15
+ body: Buffer.from('test-binary-content'),
16
+ },
17
+ },
18
+ });
19
+
20
+ function prepareResponse({
21
+ output = ['https://replicate.delivery/xezq/abc/out-0.webp'],
22
+ }: { output?: string | Array<string> } = {}) {
23
+ server.urls['https://api.replicate.com/*'].response = {
24
+ type: 'json-value',
25
+ body: {
26
+ id: 's7x1e3dcmhrmc0cm8rbatcneec',
27
+ model: 'black-forest-labs/flux-schnell',
28
+ version: 'dp-4d0bcc010b3049749a251855f12800be',
29
+ input: {
30
+ num_outputs: 1,
31
+ prompt: 'The Loch Ness Monster getting a manicure',
32
+ },
33
+ logs: '',
34
+ output,
35
+ data_removed: false,
36
+ error: null,
37
+ status: 'processing',
38
+ created_at: '2025-01-08T13:24:38.692Z',
39
+ urls: {
40
+ cancel:
41
+ 'https://api.replicate.com/v1/predictions/s7x1e3dcmhrmc0cm8rbatcneec/cancel',
42
+ get: 'https://api.replicate.com/v1/predictions/s7x1e3dcmhrmc0cm8rbatcneec',
43
+ stream:
44
+ 'https://stream.replicate.com/v1/files/bcwr-3okdfv3o2wehstv5f2okyftwxy57hhypqsi6osiim5iaq5k7u24a',
45
+ },
46
+ },
47
+ };
48
+ }
49
+
50
+ it('should pass the model and the settings', async () => {
51
+ prepareResponse();
52
+
53
+ await model.doGenerate({
54
+ prompt,
55
+ n: 1,
56
+ size: '1024x768',
57
+ aspectRatio: '3:4',
58
+ seed: 123,
59
+ providerOptions: {
60
+ replicate: {
61
+ style: 'realistic_image',
62
+ },
63
+ other: {
64
+ something: 'else',
65
+ },
66
+ },
67
+ });
68
+
69
+ expect(await server.calls[0].requestBody).toStrictEqual({
70
+ input: {
71
+ prompt,
72
+ num_outputs: 1,
73
+ aspect_ratio: '3:4',
74
+ size: '1024x768',
75
+ seed: 123,
76
+ style: 'realistic_image',
77
+ },
78
+ });
79
+ });
80
+
81
+ it('should call the correct url', async () => {
82
+ prepareResponse();
83
+
84
+ await model.doGenerate({
85
+ prompt,
86
+ n: 1,
87
+ size: undefined,
88
+ aspectRatio: undefined,
89
+ seed: undefined,
90
+ providerOptions: {},
91
+ });
92
+
93
+ expect(server.calls[0].requestMethod).toStrictEqual('POST');
94
+ expect(server.calls[0].requestUrl).toStrictEqual(
95
+ 'https://api.replicate.com/v1/models/black-forest-labs/flux-schnell/predictions',
96
+ );
97
+ });
98
+
99
+ it('should pass headers and set the prefer header', async () => {
100
+ prepareResponse();
101
+
102
+ const provider = createReplicate({
103
+ apiToken: 'test-api-token',
104
+ headers: {
105
+ 'Custom-Provider-Header': 'provider-header-value',
106
+ },
107
+ });
108
+
109
+ await provider.image('black-forest-labs/flux-schnell').doGenerate({
110
+ prompt,
111
+ n: 1,
112
+ size: undefined,
113
+ aspectRatio: undefined,
114
+ seed: undefined,
115
+ providerOptions: {},
116
+ headers: {
117
+ 'Custom-Request-Header': 'request-header-value',
118
+ },
119
+ });
120
+
121
+ expect(server.calls[0].requestHeaders).toStrictEqual({
122
+ authorization: 'Bearer test-api-token',
123
+ 'content-type': 'application/json',
124
+ 'custom-provider-header': 'provider-header-value',
125
+ 'custom-request-header': 'request-header-value',
126
+ prefer: 'wait',
127
+ });
128
+ });
129
+
130
+ it('should extract the generated image from array response', async () => {
131
+ prepareResponse({
132
+ output: ['https://replicate.delivery/xezq/abc/out-0.webp'],
133
+ });
134
+
135
+ const result = await model.doGenerate({
136
+ prompt,
137
+ n: 1,
138
+ size: undefined,
139
+ aspectRatio: undefined,
140
+ seed: undefined,
141
+ providerOptions: {},
142
+ });
143
+
144
+ expect(result.images).toStrictEqual([
145
+ new Uint8Array(Buffer.from('test-binary-content')),
146
+ ]);
147
+
148
+ expect(server.calls[1].requestMethod).toStrictEqual('GET');
149
+ expect(server.calls[1].requestUrl).toStrictEqual(
150
+ 'https://replicate.delivery/xezq/abc/out-0.webp',
151
+ );
152
+ });
153
+
154
+ it('should extract the generated image from string response', async () => {
155
+ prepareResponse({
156
+ output: 'https://replicate.delivery/xezq/abc/out-0.webp',
157
+ });
158
+
159
+ const result = await model.doGenerate({
160
+ prompt,
161
+ n: 1,
162
+ size: undefined,
163
+ aspectRatio: undefined,
164
+ seed: undefined,
165
+ providerOptions: {},
166
+ });
167
+
168
+ expect(result.images).toStrictEqual([
169
+ new Uint8Array(Buffer.from('test-binary-content')),
170
+ ]);
171
+
172
+ expect(server.calls[1].requestMethod).toStrictEqual('GET');
173
+ expect(server.calls[1].requestUrl).toStrictEqual(
174
+ 'https://replicate.delivery/xezq/abc/out-0.webp',
175
+ );
176
+ });
177
+ });
@@ -0,0 +1,104 @@
1
+ import type { ImageModelV1, ImageModelV1CallWarning } from '@ai-sdk/provider';
2
+ import type { Resolvable } from '@ai-sdk/provider-utils';
3
+ import {
4
+ FetchFunction,
5
+ combineHeaders,
6
+ createJsonResponseHandler,
7
+ postJsonToApi,
8
+ resolve,
9
+ } from '@ai-sdk/provider-utils';
10
+ import { z } from 'zod';
11
+ import { replicateFailedResponseHandler } from './replicate-error';
12
+ import {
13
+ ReplicateImageModelId,
14
+ ReplicateImageSettings,
15
+ } from './replicate-image-settings';
16
+
17
+ interface ReplicateImageModelConfig {
18
+ provider: string;
19
+ baseURL: string;
20
+ headers?: Resolvable<Record<string, string | undefined>>;
21
+ fetch?: FetchFunction;
22
+ }
23
+
24
+ export class ReplicateImageModel implements ImageModelV1 {
25
+ readonly specificationVersion = 'v1';
26
+
27
+ readonly modelId: ReplicateImageModelId;
28
+ readonly settings: ReplicateImageSettings;
29
+
30
+ private readonly config: ReplicateImageModelConfig;
31
+
32
+ get provider(): string {
33
+ return this.config.provider;
34
+ }
35
+
36
+ get maxImagesPerCall(): number {
37
+ return this.settings.maxImagesPerCall ?? 1;
38
+ }
39
+
40
+ constructor(
41
+ modelId: ReplicateImageModelId,
42
+ settings: ReplicateImageSettings,
43
+ config: ReplicateImageModelConfig,
44
+ ) {
45
+ this.modelId = modelId;
46
+ this.settings = settings;
47
+ this.config = config;
48
+ }
49
+
50
+ async doGenerate({
51
+ prompt,
52
+ n,
53
+ aspectRatio,
54
+ size,
55
+ seed,
56
+ providerOptions,
57
+ headers,
58
+ abortSignal,
59
+ }: Parameters<ImageModelV1['doGenerate']>[0]): Promise<
60
+ Awaited<ReturnType<ImageModelV1['doGenerate']>>
61
+ > {
62
+ const warnings: Array<ImageModelV1CallWarning> = [];
63
+
64
+ const {
65
+ value: { output },
66
+ } = await postJsonToApi({
67
+ url: `${this.config.baseURL}/models/${this.modelId}/predictions`,
68
+ headers: combineHeaders(await resolve(this.config.headers), headers, {
69
+ prefer: 'wait',
70
+ }),
71
+ body: {
72
+ input: {
73
+ prompt,
74
+ aspect_ratio: aspectRatio,
75
+ size,
76
+ seed,
77
+ num_outputs: n,
78
+ ...(providerOptions.replicate ?? {}),
79
+ },
80
+ },
81
+ failedResponseHandler: replicateFailedResponseHandler,
82
+ successfulResponseHandler: createJsonResponseHandler(
83
+ replicateImageResponseSchema,
84
+ ),
85
+ abortSignal,
86
+ fetch: this.config.fetch,
87
+ });
88
+
89
+ // download the images:
90
+ const outputArray = Array.isArray(output) ? output : [output];
91
+ const images = await Promise.all(
92
+ outputArray.map(async url => {
93
+ const response = await fetch(url);
94
+ return new Uint8Array(await response.arrayBuffer());
95
+ }),
96
+ );
97
+
98
+ return { images, warnings };
99
+ }
100
+ }
101
+
102
+ const replicateImageResponseSchema = z.object({
103
+ output: z.union([z.array(z.string()), z.string()]),
104
+ });
@@ -0,0 +1,36 @@
1
+ export type ReplicateImageModelId =
2
+ | 'black-forest-labs/flux-1.1-pro'
3
+ | 'black-forest-labs/flux-1.1-pro-ultra'
4
+ | 'black-forest-labs/flux-dev'
5
+ | 'black-forest-labs/flux-pro'
6
+ | 'black-forest-labs/flux-schnell'
7
+ | 'bytedance/sdxl-lightning-4step'
8
+ | 'fofr/aura-flow'
9
+ | 'fofr/latent-consistency-model'
10
+ | 'fofr/realvisxl-v3-multi-controlnet-lora'
11
+ | 'fofr/sdxl-emoji'
12
+ | 'fofr/sdxl-multi-controlnet-lora'
13
+ | 'ideogram-ai/ideogram-v2'
14
+ | 'ideogram-ai/ideogram-v2-turbo'
15
+ | 'lucataco/dreamshaper-xl-turbo'
16
+ | 'lucataco/open-dalle-v1.1'
17
+ | 'lucataco/realvisxl-v2.0'
18
+ | 'lucataco/realvisxl2-lcm'
19
+ | 'luma/photon'
20
+ | 'luma/photon-flash'
21
+ | 'nvidia/sana'
22
+ | 'playgroundai/playground-v2.5-1024px-aesthetic'
23
+ | 'recraft-ai/recraft-v3'
24
+ | 'recraft-ai/recraft-v3-svg'
25
+ | 'stability-ai/stable-diffusion-3.5-large'
26
+ | 'stability-ai/stable-diffusion-3.5-large-turbo'
27
+ | 'stability-ai/stable-diffusion-3.5-medium'
28
+ | 'tstramer/material-diffusion'
29
+ | (string & {});
30
+
31
+ export interface ReplicateImageSettings {
32
+ /**
33
+ Override the maximum number of images per call (default 1)
34
+ */
35
+ maxImagesPerCall?: number;
36
+ }
@@ -0,0 +1,24 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { createReplicate } from './replicate-provider';
3
+ import { ReplicateImageModel } from './replicate-image-model';
4
+
5
+ describe('createReplicate', () => {
6
+ it('creates a provider with required settings', () => {
7
+ const provider = createReplicate({ apiToken: 'test-token' });
8
+ expect(provider.image).toBeDefined();
9
+ });
10
+
11
+ it('creates a provider with custom settings', () => {
12
+ const provider = createReplicate({
13
+ apiToken: 'test-token',
14
+ baseURL: 'https://custom.replicate.com',
15
+ });
16
+ expect(provider.image).toBeDefined();
17
+ });
18
+
19
+ it('creates an image model instance', () => {
20
+ const provider = createReplicate({ apiToken: 'test-token' });
21
+ const model = provider.image('black-forest-labs/flux-schnell');
22
+ expect(model).toBeInstanceOf(ReplicateImageModel);
23
+ });
24
+ });
@@ -0,0 +1,74 @@
1
+ import type { FetchFunction } from '@ai-sdk/provider-utils';
2
+ import { loadApiKey } from '@ai-sdk/provider-utils';
3
+ import { ReplicateImageModel } from './replicate-image-model';
4
+ import {
5
+ ReplicateImageModelId,
6
+ ReplicateImageSettings,
7
+ } from './replicate-image-settings';
8
+
9
+ export interface ReplicateProviderSettings {
10
+ /**
11
+ API token that is being send using the `Authorization` header.
12
+ It defaults to the `REPLICATE_API_TOKEN` environment variable.
13
+ */
14
+ apiToken?: string;
15
+
16
+ /**
17
+ Use a different URL prefix for API calls, e.g. to use proxy servers.
18
+ The default prefix is `https://api.replicate.com/v1`.
19
+ */
20
+ baseURL?: string;
21
+
22
+ /**
23
+ Custom headers to include in the requests.
24
+ */
25
+ headers?: Record<string, string>;
26
+
27
+ /**
28
+ Custom fetch implementation. You can use it as a middleware to intercept requests,
29
+ or to provide a custom fetch implementation for e.g. testing.
30
+ */
31
+ fetch?: FetchFunction;
32
+ }
33
+
34
+ export interface ReplicateProvider {
35
+ /**
36
+ * Creates a Replicate image generation model.
37
+ */
38
+ image(
39
+ modelId: ReplicateImageModelId,
40
+ settings?: ReplicateImageSettings,
41
+ ): ReplicateImageModel;
42
+ }
43
+
44
+ /**
45
+ * Create a Replicate provider instance.
46
+ */
47
+ export function createReplicate(
48
+ options: ReplicateProviderSettings = {},
49
+ ): ReplicateProvider {
50
+ return {
51
+ image: (
52
+ modelId: ReplicateImageModelId,
53
+ settings?: ReplicateImageSettings,
54
+ ) =>
55
+ new ReplicateImageModel(modelId, settings ?? {}, {
56
+ provider: 'replicate',
57
+ baseURL: options.baseURL ?? 'https://api.replicate.com/v1',
58
+ headers: {
59
+ Authorization: `Bearer ${loadApiKey({
60
+ apiKey: options.apiToken,
61
+ environmentVariableName: 'REPLICATE_API_TOKEN',
62
+ description: 'Replicate',
63
+ })}`,
64
+ ...options.headers,
65
+ },
66
+ fetch: options.fetch,
67
+ }),
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Default Replicate provider instance.
73
+ */
74
+ export const replicate = createReplicate();
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "./node_modules/@vercel/ai-tsconfig/ts-library.json",
3
+ "include": ["."],
4
+ "exclude": ["*/dist", "dist", "build", "node_modules"]
5
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'tsup';
2
+
3
+ export default defineConfig([
4
+ {
5
+ entry: ['src/index.ts'],
6
+ format: ['cjs', 'esm'],
7
+ dts: true,
8
+ sourcemap: true,
9
+ },
10
+ ]);
package/turbo.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": [
3
+ "//"
4
+ ],
5
+ "tasks": {
6
+ "build": {
7
+ "outputs": [
8
+ "**/dist/**"
9
+ ]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'vite';
2
+
3
+ // https://vitejs.dev/config/
4
+ export default defineConfig({
5
+ test: {
6
+ environment: 'edge-runtime',
7
+ globals: true,
8
+ include: ['**/*.test.ts', '**/*.test.tsx'],
9
+ },
10
+ });
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'vite';
2
+
3
+ // https://vitejs.dev/config/
4
+ export default defineConfig({
5
+ test: {
6
+ environment: 'node',
7
+ globals: true,
8
+ include: ['**/*.test.ts', '**/*.test.tsx'],
9
+ },
10
+ });