@aigne/openai 0.16.16 → 1.74.0-beta

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.
Files changed (59) hide show
  1. package/README.md +11 -11
  2. package/dist/_virtual/rolldown_runtime.cjs +29 -0
  3. package/dist/index.cjs +10 -0
  4. package/dist/index.d.cts +4 -0
  5. package/dist/index.d.mts +4 -0
  6. package/dist/index.mjs +5 -0
  7. package/dist/openai-chat-model.cjs +371 -0
  8. package/dist/openai-chat-model.d.cts +165 -0
  9. package/dist/openai-chat-model.d.cts.map +1 -0
  10. package/dist/openai-chat-model.d.mts +165 -0
  11. package/dist/openai-chat-model.d.mts.map +1 -0
  12. package/dist/openai-chat-model.mjs +368 -0
  13. package/dist/openai-chat-model.mjs.map +1 -0
  14. package/dist/openai-image-model.cjs +123 -0
  15. package/dist/openai-image-model.d.cts +57 -0
  16. package/dist/openai-image-model.d.cts.map +1 -0
  17. package/dist/openai-image-model.d.mts +57 -0
  18. package/dist/openai-image-model.d.mts.map +1 -0
  19. package/dist/openai-image-model.mjs +123 -0
  20. package/dist/openai-image-model.mjs.map +1 -0
  21. package/dist/openai-video-model.cjs +112 -0
  22. package/dist/openai-video-model.d.cts +95 -0
  23. package/dist/openai-video-model.d.cts.map +1 -0
  24. package/dist/openai-video-model.d.mts +95 -0
  25. package/dist/openai-video-model.d.mts.map +1 -0
  26. package/dist/openai-video-model.mjs +112 -0
  27. package/dist/openai-video-model.mjs.map +1 -0
  28. package/dist/openai.cjs +14 -0
  29. package/dist/openai.mjs +13 -0
  30. package/dist/openai.mjs.map +1 -0
  31. package/package.json +29 -30
  32. package/CHANGELOG.md +0 -2448
  33. package/lib/cjs/index.d.ts +0 -3
  34. package/lib/cjs/index.js +0 -19
  35. package/lib/cjs/openai-chat-model.d.ts +0 -160
  36. package/lib/cjs/openai-chat-model.js +0 -465
  37. package/lib/cjs/openai-image-model.d.ts +0 -55
  38. package/lib/cjs/openai-image-model.js +0 -110
  39. package/lib/cjs/openai-video-model.d.ts +0 -92
  40. package/lib/cjs/openai-video-model.js +0 -118
  41. package/lib/cjs/openai.d.ts +0 -4
  42. package/lib/cjs/openai.js +0 -17
  43. package/lib/cjs/package.json +0 -3
  44. package/lib/dts/index.d.ts +0 -3
  45. package/lib/dts/openai-chat-model.d.ts +0 -160
  46. package/lib/dts/openai-image-model.d.ts +0 -55
  47. package/lib/dts/openai-video-model.d.ts +0 -92
  48. package/lib/dts/openai.d.ts +0 -4
  49. package/lib/esm/index.d.ts +0 -3
  50. package/lib/esm/index.js +0 -3
  51. package/lib/esm/openai-chat-model.d.ts +0 -160
  52. package/lib/esm/openai-chat-model.js +0 -459
  53. package/lib/esm/openai-image-model.d.ts +0 -55
  54. package/lib/esm/openai-image-model.js +0 -106
  55. package/lib/esm/openai-video-model.d.ts +0 -92
  56. package/lib/esm/openai-video-model.js +0 -114
  57. package/lib/esm/openai.d.ts +0 -4
  58. package/lib/esm/openai.js +0 -10
  59. package/lib/esm/package.json +0 -3
@@ -0,0 +1,123 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const require_openai = require('./openai.cjs');
3
+ let _aigne_core = require("@aigne/core");
4
+ let _aigne_core_utils_type_utils = require("@aigne/core/utils/type-utils");
5
+ let zod = require("zod");
6
+ let _aigne_core_utils_camelize = require("@aigne/core/utils/camelize");
7
+
8
+ //#region src/openai-image-model.ts
9
+ const DEFAULT_MODEL = "dall-e-2";
10
+ const OUTPUT_MIME_TYPE = "image/png";
11
+ const SUPPORTED_PARAMS = {
12
+ "dall-e-2": [
13
+ "prompt",
14
+ "size",
15
+ "n"
16
+ ],
17
+ "dall-e-3": [
18
+ "prompt",
19
+ "size",
20
+ "n",
21
+ "quality",
22
+ "style",
23
+ "user"
24
+ ],
25
+ "gpt-image-1": [
26
+ "prompt",
27
+ "size",
28
+ "background",
29
+ "moderation",
30
+ "outputCompression",
31
+ "outputFormat",
32
+ "quality",
33
+ "user",
34
+ "stream"
35
+ ]
36
+ };
37
+ const SUPPORT_EDIT_MODELS = ["gpt-image-1"];
38
+ const openAIImageModelInputSchema = _aigne_core.imageModelInputSchema.extend({});
39
+ const openAIImageModelOptionsSchema = zod.z.object({
40
+ apiKey: zod.z.string().optional(),
41
+ baseURL: zod.z.string().optional(),
42
+ model: zod.z.string().optional(),
43
+ modelOptions: zod.z.object({}).optional(),
44
+ clientOptions: zod.z.object({}).optional()
45
+ });
46
+ var OpenAIImageModel = class extends _aigne_core.ImageModel {
47
+ constructor(options) {
48
+ super({
49
+ ...options,
50
+ inputSchema: openAIImageModelInputSchema,
51
+ description: options?.description ?? "Draw or edit image by OpenAI image models"
52
+ });
53
+ this.options = options;
54
+ if (options) (0, _aigne_core_utils_type_utils.checkArguments)(this.name, openAIImageModelOptionsSchema, options);
55
+ }
56
+ _client;
57
+ apiKeyEnvName = "OPENAI_API_KEY";
58
+ get client() {
59
+ if (this._client) return this._client;
60
+ const { apiKey, url } = this.credential;
61
+ if (!apiKey) throw new Error(`${this.name} requires an API key. Please provide it via \`options.apiKey\`, or set the \`${this.apiKeyEnvName}\` environment variable`);
62
+ this._client ??= new require_openai.CustomOpenAI({
63
+ baseURL: url,
64
+ apiKey,
65
+ ...this.options?.clientOptions
66
+ });
67
+ return this._client;
68
+ }
69
+ get credential() {
70
+ return {
71
+ url: this.options?.baseURL || process.env.OPENAI_BASE_URL,
72
+ apiKey: this.options?.apiKey || process.env[this.apiKeyEnvName],
73
+ model: this.options?.model || DEFAULT_MODEL
74
+ };
75
+ }
76
+ get modelOptions() {
77
+ return this.options?.modelOptions;
78
+ }
79
+ /**
80
+ * Process the input and generate a response
81
+ * @param input The input to process
82
+ * @returns The generated response
83
+ */
84
+ async process(input, _options) {
85
+ const model = input.modelOptions?.model || this.credential.model;
86
+ if (input.image?.length && !SUPPORT_EDIT_MODELS.includes(model)) throw new Error(`Model ${model} does not support image editing`);
87
+ const body = {
88
+ ...(0, _aigne_core_utils_camelize.snakelize)((0, _aigne_core_utils_type_utils.pick)({
89
+ ...this.modelOptions,
90
+ ...input.modelOptions,
91
+ ...input
92
+ }, SUPPORTED_PARAMS[model] || SUPPORTED_PARAMS[DEFAULT_MODEL])),
93
+ model
94
+ };
95
+ const response = input.image?.length ? await this.client.images.edit({
96
+ ...body,
97
+ image: await Promise.all(input.image.map((image) => this.transformFileType("file", image).then((file) => new File([Buffer.from(file.data, "base64")], file.filename || "image.png", { type: file.mimeType }))))
98
+ }, { stream: false }) : await this.client.images.generate({ ...body }, { stream: false });
99
+ return {
100
+ images: (response.data ?? []).map((image) => {
101
+ if (image.url) return {
102
+ type: "url",
103
+ url: image.url,
104
+ mimeType: OUTPUT_MIME_TYPE
105
+ };
106
+ if (image.b64_json) return {
107
+ type: "file",
108
+ data: image.b64_json,
109
+ mimeType: OUTPUT_MIME_TYPE
110
+ };
111
+ throw new Error("Image response does not contain a valid URL or base64 data");
112
+ }),
113
+ usage: {
114
+ inputTokens: response.usage?.input_tokens || 0,
115
+ outputTokens: response.usage?.output_tokens || 0
116
+ },
117
+ model
118
+ };
119
+ }
120
+ };
121
+
122
+ //#endregion
123
+ exports.OpenAIImageModel = OpenAIImageModel;
@@ -0,0 +1,57 @@
1
+ import { AgentInvokeOptions, ImageModel, ImageModelInput, ImageModelOptions, ImageModelOutput } from "@aigne/core";
2
+ import OpenAI, { ClientOptions } from "openai";
3
+ import { Camelize } from "@aigne/core/utils/camelize";
4
+
5
+ //#region src/openai-image-model.d.ts
6
+ interface OpenAIImageModelInput extends ImageModelInput, Camelize<Omit<OpenAI.ImageGenerateParams | OpenAI.ImageEditParams, "prompt" | "model" | "n" | "response_format">> {}
7
+ interface OpenAIImageModelOutput extends ImageModelOutput {}
8
+ interface OpenAIImageModelOptions extends ImageModelOptions<OpenAIImageModelInput, OpenAIImageModelOutput> {
9
+ /**
10
+ * API key for OpenAI API
11
+ *
12
+ * If not provided, will look for OPENAI_API_KEY in environment variables
13
+ */
14
+ apiKey?: string;
15
+ /**
16
+ * Base URL for OpenAI API
17
+ *
18
+ * Useful for proxies or alternate endpoints
19
+ */
20
+ baseURL?: string;
21
+ /**
22
+ * OpenAI model to use
23
+ *
24
+ * Defaults to 'dall-e-2'
25
+ */
26
+ model?: string;
27
+ /**
28
+ * Additional model options to control behavior
29
+ */
30
+ modelOptions?: Omit<Partial<OpenAIImageModelInput>, "model">;
31
+ /**
32
+ * Client options for OpenAI API
33
+ */
34
+ clientOptions?: Partial<ClientOptions>;
35
+ }
36
+ declare class OpenAIImageModel extends ImageModel<OpenAIImageModelInput, OpenAIImageModelOutput> {
37
+ options?: OpenAIImageModelOptions | undefined;
38
+ constructor(options?: OpenAIImageModelOptions | undefined);
39
+ protected _client?: OpenAI;
40
+ protected apiKeyEnvName: string;
41
+ get client(): OpenAI;
42
+ get credential(): {
43
+ url: string | undefined;
44
+ apiKey: string | undefined;
45
+ model: string;
46
+ };
47
+ get modelOptions(): Omit<Partial<OpenAIImageModelInput>, "model"> | undefined;
48
+ /**
49
+ * Process the input and generate a response
50
+ * @param input The input to process
51
+ * @returns The generated response
52
+ */
53
+ process(input: OpenAIImageModelInput, _options: AgentInvokeOptions): Promise<OpenAIImageModelOutput>;
54
+ }
55
+ //#endregion
56
+ export { OpenAIImageModel, OpenAIImageModelInput, OpenAIImageModelOptions, OpenAIImageModelOutput };
57
+ //# sourceMappingURL=openai-image-model.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-image-model.d.cts","names":[],"sources":["../src/openai-image-model.ts"],"mappings":";;;;;UAqCiB,qBAAA,SACP,eAAA,EACN,QAAA,CACE,IAAA,CACE,MAAA,CAAO,mBAAA,GAAsB,MAAA,CAAO,eAAA;AAAA,UAK3B,sBAAA,SAA+B,gBAAA;AAAA,UAE/B,uBAAA,SACP,iBAAA,CAAkB,qBAAA,EAAuB,sBAAA;EAAA;;;;;EAAA,MAAA;EAAA;;;;;EAAA,OAAA;EAAA;;;;;EAAA,KAAA;EAAA;;;EAAA,YAAA,GAyBlC,IAAA,CAAK,OAAA,CAAQ,qBAAA;EAAA;;;EAAA,aAAA,GAKZ,OAAA,CAAQ,aAAA;AAAA;AAAA,cAeb,gBAAA,SAAyB,UAAA,CAAW,qBAAA,EAAuB,sBAAA;EAAA,OAAA,GAChC,uBAAA;EAAA,YAAA,OAAA,GAAA,uBAAA;EAAA,UAAA,OAAA,GASlB,MAAA;EAAA,UAAA,aAAA;EAAA,IAAA,OAAA,GAIV,MAAA;EAAA,IAAA,WAAA;IAAA,GAAA;IAAA,MAAA;IAAA,KAAA;EAAA;EAAA,IAAA,aAAA,GA2BM,IAAA,CAAA,OAAA,CAAA,qBAAA;EAAA;;;;;EAAA,QAAA,KAAA,EAUP,qBAAA,EAAA,QAAA,EACG,kBAAA,GACT,OAAA,CAAQ,sBAAA;AAAA"}
@@ -0,0 +1,57 @@
1
+ import { AgentInvokeOptions, ImageModel, ImageModelInput, ImageModelOptions, ImageModelOutput } from "@aigne/core";
2
+ import OpenAI, { ClientOptions } from "openai";
3
+ import { Camelize } from "@aigne/core/utils/camelize";
4
+
5
+ //#region src/openai-image-model.d.ts
6
+ interface OpenAIImageModelInput extends ImageModelInput, Camelize<Omit<OpenAI.ImageGenerateParams | OpenAI.ImageEditParams, "prompt" | "model" | "n" | "response_format">> {}
7
+ interface OpenAIImageModelOutput extends ImageModelOutput {}
8
+ interface OpenAIImageModelOptions extends ImageModelOptions<OpenAIImageModelInput, OpenAIImageModelOutput> {
9
+ /**
10
+ * API key for OpenAI API
11
+ *
12
+ * If not provided, will look for OPENAI_API_KEY in environment variables
13
+ */
14
+ apiKey?: string;
15
+ /**
16
+ * Base URL for OpenAI API
17
+ *
18
+ * Useful for proxies or alternate endpoints
19
+ */
20
+ baseURL?: string;
21
+ /**
22
+ * OpenAI model to use
23
+ *
24
+ * Defaults to 'dall-e-2'
25
+ */
26
+ model?: string;
27
+ /**
28
+ * Additional model options to control behavior
29
+ */
30
+ modelOptions?: Omit<Partial<OpenAIImageModelInput>, "model">;
31
+ /**
32
+ * Client options for OpenAI API
33
+ */
34
+ clientOptions?: Partial<ClientOptions>;
35
+ }
36
+ declare class OpenAIImageModel extends ImageModel<OpenAIImageModelInput, OpenAIImageModelOutput> {
37
+ options?: OpenAIImageModelOptions | undefined;
38
+ constructor(options?: OpenAIImageModelOptions | undefined);
39
+ protected _client?: OpenAI;
40
+ protected apiKeyEnvName: string;
41
+ get client(): OpenAI;
42
+ get credential(): {
43
+ url: string | undefined;
44
+ apiKey: string | undefined;
45
+ model: string;
46
+ };
47
+ get modelOptions(): Omit<Partial<OpenAIImageModelInput>, "model"> | undefined;
48
+ /**
49
+ * Process the input and generate a response
50
+ * @param input The input to process
51
+ * @returns The generated response
52
+ */
53
+ process(input: OpenAIImageModelInput, _options: AgentInvokeOptions): Promise<OpenAIImageModelOutput>;
54
+ }
55
+ //#endregion
56
+ export { OpenAIImageModel, OpenAIImageModelInput, OpenAIImageModelOptions, OpenAIImageModelOutput };
57
+ //# sourceMappingURL=openai-image-model.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-image-model.d.mts","names":[],"sources":["../src/openai-image-model.ts"],"mappings":";;;;;UAqCiB,qBAAA,SACP,eAAA,EACN,QAAA,CACE,IAAA,CACE,MAAA,CAAO,mBAAA,GAAsB,MAAA,CAAO,eAAA;AAAA,UAK3B,sBAAA,SAA+B,gBAAA;AAAA,UAE/B,uBAAA,SACP,iBAAA,CAAkB,qBAAA,EAAuB,sBAAA;EAAA;;;;;EAAA,MAAA;EAAA;;;;;EAAA,OAAA;EAAA;;;;;EAAA,KAAA;EAAA;;;EAAA,YAAA,GAyBlC,IAAA,CAAK,OAAA,CAAQ,qBAAA;EAAA;;;EAAA,aAAA,GAKZ,OAAA,CAAQ,aAAA;AAAA;AAAA,cAeb,gBAAA,SAAyB,UAAA,CAAW,qBAAA,EAAuB,sBAAA;EAAA,OAAA,GAChC,uBAAA;EAAA,YAAA,OAAA,GAAA,uBAAA;EAAA,UAAA,OAAA,GASlB,MAAA;EAAA,UAAA,aAAA;EAAA,IAAA,OAAA,GAIV,MAAA;EAAA,IAAA,WAAA;IAAA,GAAA;IAAA,MAAA;IAAA,KAAA;EAAA;EAAA,IAAA,aAAA,GA2BM,IAAA,CAAA,OAAA,CAAA,qBAAA;EAAA;;;;;EAAA,QAAA,KAAA,EAUP,qBAAA,EAAA,QAAA,EACG,kBAAA,GACT,OAAA,CAAQ,sBAAA;AAAA"}
@@ -0,0 +1,123 @@
1
+ import { CustomOpenAI } from "./openai.mjs";
2
+ import { ImageModel, imageModelInputSchema } from "@aigne/core";
3
+ import { checkArguments, pick } from "@aigne/core/utils/type-utils";
4
+ import { z } from "zod";
5
+ import { snakelize } from "@aigne/core/utils/camelize";
6
+
7
+ //#region src/openai-image-model.ts
8
+ const DEFAULT_MODEL = "dall-e-2";
9
+ const OUTPUT_MIME_TYPE = "image/png";
10
+ const SUPPORTED_PARAMS = {
11
+ "dall-e-2": [
12
+ "prompt",
13
+ "size",
14
+ "n"
15
+ ],
16
+ "dall-e-3": [
17
+ "prompt",
18
+ "size",
19
+ "n",
20
+ "quality",
21
+ "style",
22
+ "user"
23
+ ],
24
+ "gpt-image-1": [
25
+ "prompt",
26
+ "size",
27
+ "background",
28
+ "moderation",
29
+ "outputCompression",
30
+ "outputFormat",
31
+ "quality",
32
+ "user",
33
+ "stream"
34
+ ]
35
+ };
36
+ const SUPPORT_EDIT_MODELS = ["gpt-image-1"];
37
+ const openAIImageModelInputSchema = imageModelInputSchema.extend({});
38
+ const openAIImageModelOptionsSchema = z.object({
39
+ apiKey: z.string().optional(),
40
+ baseURL: z.string().optional(),
41
+ model: z.string().optional(),
42
+ modelOptions: z.object({}).optional(),
43
+ clientOptions: z.object({}).optional()
44
+ });
45
+ var OpenAIImageModel = class extends ImageModel {
46
+ constructor(options) {
47
+ super({
48
+ ...options,
49
+ inputSchema: openAIImageModelInputSchema,
50
+ description: options?.description ?? "Draw or edit image by OpenAI image models"
51
+ });
52
+ this.options = options;
53
+ if (options) checkArguments(this.name, openAIImageModelOptionsSchema, options);
54
+ }
55
+ _client;
56
+ apiKeyEnvName = "OPENAI_API_KEY";
57
+ get client() {
58
+ if (this._client) return this._client;
59
+ const { apiKey, url } = this.credential;
60
+ if (!apiKey) throw new Error(`${this.name} requires an API key. Please provide it via \`options.apiKey\`, or set the \`${this.apiKeyEnvName}\` environment variable`);
61
+ this._client ??= new CustomOpenAI({
62
+ baseURL: url,
63
+ apiKey,
64
+ ...this.options?.clientOptions
65
+ });
66
+ return this._client;
67
+ }
68
+ get credential() {
69
+ return {
70
+ url: this.options?.baseURL || process.env.OPENAI_BASE_URL,
71
+ apiKey: this.options?.apiKey || process.env[this.apiKeyEnvName],
72
+ model: this.options?.model || DEFAULT_MODEL
73
+ };
74
+ }
75
+ get modelOptions() {
76
+ return this.options?.modelOptions;
77
+ }
78
+ /**
79
+ * Process the input and generate a response
80
+ * @param input The input to process
81
+ * @returns The generated response
82
+ */
83
+ async process(input, _options) {
84
+ const model = input.modelOptions?.model || this.credential.model;
85
+ if (input.image?.length && !SUPPORT_EDIT_MODELS.includes(model)) throw new Error(`Model ${model} does not support image editing`);
86
+ const body = {
87
+ ...snakelize(pick({
88
+ ...this.modelOptions,
89
+ ...input.modelOptions,
90
+ ...input
91
+ }, SUPPORTED_PARAMS[model] || SUPPORTED_PARAMS[DEFAULT_MODEL])),
92
+ model
93
+ };
94
+ const response = input.image?.length ? await this.client.images.edit({
95
+ ...body,
96
+ image: await Promise.all(input.image.map((image) => this.transformFileType("file", image).then((file) => new File([Buffer.from(file.data, "base64")], file.filename || "image.png", { type: file.mimeType }))))
97
+ }, { stream: false }) : await this.client.images.generate({ ...body }, { stream: false });
98
+ return {
99
+ images: (response.data ?? []).map((image) => {
100
+ if (image.url) return {
101
+ type: "url",
102
+ url: image.url,
103
+ mimeType: OUTPUT_MIME_TYPE
104
+ };
105
+ if (image.b64_json) return {
106
+ type: "file",
107
+ data: image.b64_json,
108
+ mimeType: OUTPUT_MIME_TYPE
109
+ };
110
+ throw new Error("Image response does not contain a valid URL or base64 data");
111
+ }),
112
+ usage: {
113
+ inputTokens: response.usage?.input_tokens || 0,
114
+ outputTokens: response.usage?.output_tokens || 0
115
+ },
116
+ model
117
+ };
118
+ }
119
+ };
120
+
121
+ //#endregion
122
+ export { OpenAIImageModel };
123
+ //# sourceMappingURL=openai-image-model.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-image-model.mjs","names":[],"sources":["../src/openai-image-model.ts"],"sourcesContent":["import {\n type AgentInvokeOptions,\n type FileUnionContent,\n ImageModel,\n type ImageModelInput,\n type ImageModelOptions,\n type ImageModelOutput,\n imageModelInputSchema,\n} from \"@aigne/core\";\nimport { type Camelize, snakelize } from \"@aigne/core/utils/camelize\";\nimport { checkArguments, pick } from \"@aigne/core/utils/type-utils\";\nimport type OpenAI from \"openai\";\nimport type { ClientOptions } from \"openai\";\nimport { type ZodType, z } from \"zod\";\nimport { CustomOpenAI } from \"./openai.js\";\n\nconst DEFAULT_MODEL = \"dall-e-2\";\nconst OUTPUT_MIME_TYPE = \"image/png\";\n\nconst SUPPORTED_PARAMS: { [key: string]: any[] } = {\n \"dall-e-2\": [\"prompt\", \"size\", \"n\"],\n \"dall-e-3\": [\"prompt\", \"size\", \"n\", \"quality\", \"style\", \"user\"],\n \"gpt-image-1\": [\n \"prompt\",\n \"size\",\n \"background\",\n \"moderation\",\n \"outputCompression\",\n \"outputFormat\",\n \"quality\",\n \"user\",\n \"stream\",\n ],\n};\n\nconst SUPPORT_EDIT_MODELS = [\"gpt-image-1\"];\n\nexport interface OpenAIImageModelInput\n extends ImageModelInput,\n Camelize<\n Omit<\n OpenAI.ImageGenerateParams | OpenAI.ImageEditParams,\n \"prompt\" | \"model\" | \"n\" | \"response_format\"\n >\n > {}\n\nexport interface OpenAIImageModelOutput extends ImageModelOutput {}\n\nexport interface OpenAIImageModelOptions\n extends ImageModelOptions<OpenAIImageModelInput, OpenAIImageModelOutput> {\n /**\n * API key for OpenAI API\n *\n * If not provided, will look for OPENAI_API_KEY in environment variables\n */\n apiKey?: string;\n\n /**\n * Base URL for OpenAI API\n *\n * Useful for proxies or alternate endpoints\n */\n baseURL?: string;\n\n /**\n * OpenAI model to use\n *\n * Defaults to 'dall-e-2'\n */\n model?: string;\n\n /**\n * Additional model options to control behavior\n */\n modelOptions?: Omit<Partial<OpenAIImageModelInput>, \"model\">;\n\n /**\n * Client options for OpenAI API\n */\n clientOptions?: Partial<ClientOptions>;\n}\n\nconst openAIImageModelInputSchema: ZodType<OpenAIImageModelInput> = imageModelInputSchema.extend(\n {},\n);\n\nconst openAIImageModelOptionsSchema = z.object({\n apiKey: z.string().optional(),\n baseURL: z.string().optional(),\n model: z.string().optional(),\n modelOptions: z.object({}).optional(),\n clientOptions: z.object({}).optional(),\n});\n\nexport class OpenAIImageModel extends ImageModel<OpenAIImageModelInput, OpenAIImageModelOutput> {\n constructor(public override options?: OpenAIImageModelOptions) {\n super({\n ...options,\n inputSchema: openAIImageModelInputSchema,\n description: options?.description ?? \"Draw or edit image by OpenAI image models\",\n });\n if (options) checkArguments(this.name, openAIImageModelOptionsSchema, options);\n }\n\n protected _client?: OpenAI;\n\n protected apiKeyEnvName = \"OPENAI_API_KEY\";\n\n get client() {\n if (this._client) return this._client;\n\n const { apiKey, url } = this.credential;\n\n if (!apiKey)\n throw new Error(\n `${this.name} requires an API key. Please provide it via \\`options.apiKey\\`, or set the \\`${this.apiKeyEnvName}\\` environment variable`,\n );\n\n this._client ??= new CustomOpenAI({\n baseURL: url,\n apiKey,\n ...this.options?.clientOptions,\n });\n\n return this._client;\n }\n\n override get credential() {\n return {\n url: this.options?.baseURL || process.env.OPENAI_BASE_URL,\n apiKey: this.options?.apiKey || process.env[this.apiKeyEnvName],\n model: this.options?.model || DEFAULT_MODEL,\n };\n }\n\n get modelOptions() {\n return this.options?.modelOptions;\n }\n\n /**\n * Process the input and generate a response\n * @param input The input to process\n * @returns The generated response\n */\n override async process(\n input: OpenAIImageModelInput,\n _options: AgentInvokeOptions,\n ): Promise<OpenAIImageModelOutput> {\n const model = input.modelOptions?.model || this.credential.model;\n\n if (input.image?.length && !SUPPORT_EDIT_MODELS.includes(model)) {\n throw new Error(`Model ${model} does not support image editing`);\n }\n\n const body: OpenAI.ImageGenerateParams | OpenAI.ImageEditParams = {\n ...snakelize(\n pick(\n { ...this.modelOptions, ...input.modelOptions, ...input },\n SUPPORTED_PARAMS[model] || SUPPORTED_PARAMS[DEFAULT_MODEL],\n ),\n ),\n model,\n };\n\n const response = input.image?.length\n ? ((await this.client.images.edit(\n {\n ...(body as OpenAI.ImageEditParams),\n image: await Promise.all(\n input.image.map((image) =>\n this.transformFileType(\"file\", image).then(\n (file) =>\n new File([Buffer.from(file.data, \"base64\")], file.filename || \"image.png\", {\n type: file.mimeType,\n }),\n ),\n ),\n ),\n },\n { stream: false },\n )) as OpenAI.ImagesResponse)\n : ((await this.client.images.generate(\n { ...body },\n { stream: false },\n )) as OpenAI.ImagesResponse);\n\n return {\n images: (response.data ?? []).map<FileUnionContent>((image) => {\n if (image.url) return { type: \"url\", url: image.url, mimeType: OUTPUT_MIME_TYPE };\n if (image.b64_json)\n return { type: \"file\", data: image.b64_json, mimeType: OUTPUT_MIME_TYPE };\n throw new Error(\"Image response does not contain a valid URL or base64 data\");\n }),\n usage: {\n inputTokens: response.usage?.input_tokens || 0,\n outputTokens: response.usage?.output_tokens || 0,\n },\n model,\n };\n }\n}\n"],"mappings":";;;;;;;AAgBA,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;AAEzB,MAAM,mBAA6C;CACjD,YAAY;EAAC;EAAU;EAAQ;EAAI;CACnC,YAAY;EAAC;EAAU;EAAQ;EAAK;EAAW;EAAS;EAAO;CAC/D,eAAe;EACb;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACF;AAED,MAAM,sBAAsB,CAAC,cAAc;AA+C3C,MAAM,8BAA8D,sBAAsB,OACxF,EAAE,CACH;AAED,MAAM,gCAAgC,EAAE,OAAO;CAC7C,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,SAAS,EAAE,QAAQ,CAAC,UAAU;CAC9B,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,UAAU;CACrC,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC,UAAU;CACvC,CAAC;AAEF,IAAa,mBAAb,cAAsC,WAA0D;CAC9F,YAAY,AAAgB,SAAmC;AAC7D,QAAM;GACJ,GAAG;GACH,aAAa;GACb,aAAa,SAAS,eAAe;GACtC,CAAC;EALwB;AAM1B,MAAI,QAAS,gBAAe,KAAK,MAAM,+BAA+B,QAAQ;;CAGhF,AAAU;CAEV,AAAU,gBAAgB;CAE1B,IAAI,SAAS;AACX,MAAI,KAAK,QAAS,QAAO,KAAK;EAE9B,MAAM,EAAE,QAAQ,QAAQ,KAAK;AAE7B,MAAI,CAAC,OACH,OAAM,IAAI,MACR,GAAG,KAAK,KAAK,+EAA+E,KAAK,cAAc,yBAChH;AAEH,OAAK,YAAY,IAAI,aAAa;GAChC,SAAS;GACT;GACA,GAAG,KAAK,SAAS;GAClB,CAAC;AAEF,SAAO,KAAK;;CAGd,IAAa,aAAa;AACxB,SAAO;GACL,KAAK,KAAK,SAAS,WAAW,QAAQ,IAAI;GAC1C,QAAQ,KAAK,SAAS,UAAU,QAAQ,IAAI,KAAK;GACjD,OAAO,KAAK,SAAS,SAAS;GAC/B;;CAGH,IAAI,eAAe;AACjB,SAAO,KAAK,SAAS;;;;;;;CAQvB,MAAe,QACb,OACA,UACiC;EACjC,MAAM,QAAQ,MAAM,cAAc,SAAS,KAAK,WAAW;AAE3D,MAAI,MAAM,OAAO,UAAU,CAAC,oBAAoB,SAAS,MAAM,CAC7D,OAAM,IAAI,MAAM,SAAS,MAAM,iCAAiC;EAGlE,MAAM,OAA4D;GAChE,GAAG,UACD,KACE;IAAE,GAAG,KAAK;IAAc,GAAG,MAAM;IAAc,GAAG;IAAO,EACzD,iBAAiB,UAAU,iBAAiB,eAC7C,CACF;GACD;GACD;EAED,MAAM,WAAW,MAAM,OAAO,SACxB,MAAM,KAAK,OAAO,OAAO,KACzB;GACE,GAAI;GACJ,OAAO,MAAM,QAAQ,IACnB,MAAM,MAAM,KAAK,UACf,KAAK,kBAAkB,QAAQ,MAAM,CAAC,MACnC,SACC,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC,EAAE,KAAK,YAAY,aAAa,EACzE,MAAM,KAAK,UACZ,CAAC,CACL,CACF,CACF;GACF,EACD,EAAE,QAAQ,OAAO,CAClB,GACC,MAAM,KAAK,OAAO,OAAO,SACzB,EAAE,GAAG,MAAM,EACX,EAAE,QAAQ,OAAO,CAClB;AAEL,SAAO;GACL,SAAS,SAAS,QAAQ,EAAE,EAAE,KAAuB,UAAU;AAC7D,QAAI,MAAM,IAAK,QAAO;KAAE,MAAM;KAAO,KAAK,MAAM;KAAK,UAAU;KAAkB;AACjF,QAAI,MAAM,SACR,QAAO;KAAE,MAAM;KAAQ,MAAM,MAAM;KAAU,UAAU;KAAkB;AAC3E,UAAM,IAAI,MAAM,6DAA6D;KAC7E;GACF,OAAO;IACL,aAAa,SAAS,OAAO,gBAAgB;IAC7C,cAAc,SAAS,OAAO,iBAAiB;IAChD;GACD;GACD"}
@@ -0,0 +1,112 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const require_openai = require('./openai.cjs');
3
+ let _aigne_core = require("@aigne/core");
4
+ let _aigne_core_utils_logger = require("@aigne/core/utils/logger");
5
+ let _aigne_core_utils_type_utils = require("@aigne/core/utils/type-utils");
6
+ let zod = require("zod");
7
+
8
+ //#region src/openai-video-model.ts
9
+ const DEFAULT_MODEL = "sora-2";
10
+ const DEFAULT_SECONDS = 4;
11
+ const openAIVideoModelInputSchema = _aigne_core.videoModelInputSchema.extend({
12
+ model: zod.z.enum(["sora-2", "sora-2-pro"]).optional(),
13
+ seconds: zod.z.enum([
14
+ "4",
15
+ "8",
16
+ "12"
17
+ ]).optional(),
18
+ size: zod.z.enum([
19
+ "720x1280",
20
+ "1280x720",
21
+ "1024x1792",
22
+ "1792x1024"
23
+ ]).optional()
24
+ });
25
+ const openAIVideoModelOptionsSchema = zod.z.object({
26
+ apiKey: zod.z.string().optional(),
27
+ baseURL: zod.z.string().optional(),
28
+ model: zod.z.string().optional(),
29
+ modelOptions: zod.z.object({}).optional(),
30
+ clientOptions: zod.z.object({}).optional(),
31
+ pollingInterval: zod.z.number().optional()
32
+ });
33
+ var OpenAIVideoModel = class extends _aigne_core.VideoModel {
34
+ constructor(options) {
35
+ super({
36
+ ...options,
37
+ description: options?.description ?? "Generate videos using OpenAI Sora models",
38
+ inputSchema: openAIVideoModelInputSchema
39
+ });
40
+ this.options = options;
41
+ if (options) (0, _aigne_core_utils_type_utils.checkArguments)(this.name, openAIVideoModelOptionsSchema, options);
42
+ }
43
+ /**
44
+ * @hidden
45
+ */
46
+ _client;
47
+ apiKeyEnvName = "OPENAI_API_KEY";
48
+ get client() {
49
+ const { apiKey, url } = this.credential;
50
+ if (!apiKey) throw new Error(`${this.name} requires an API key. Please provide it via \`options.apiKey\`, or set the \`${this.apiKeyEnvName}\` environment variable`);
51
+ this._client ??= new require_openai.CustomOpenAI({
52
+ baseURL: url,
53
+ apiKey,
54
+ ...this.options?.clientOptions
55
+ });
56
+ return this._client;
57
+ }
58
+ get credential() {
59
+ return {
60
+ url: this.options?.baseURL || process.env.OPENAI_BASE_URL,
61
+ apiKey: this.options?.apiKey || process.env[this.apiKeyEnvName],
62
+ model: this.options?.model || DEFAULT_MODEL
63
+ };
64
+ }
65
+ get modelOptions() {
66
+ return this.options?.modelOptions;
67
+ }
68
+ async downloadToFile(videoId) {
69
+ _aigne_core_utils_logger.logger.debug("Downloading video content...");
70
+ const arrayBuffer = await (await this.client.videos.downloadContent(videoId)).arrayBuffer();
71
+ return Buffer.from(arrayBuffer).toString("base64");
72
+ }
73
+ async process(input, _options) {
74
+ const model = input.model ?? input.modelOptions?.model ?? this.credential.model;
75
+ const createParams = {
76
+ model,
77
+ prompt: input.prompt
78
+ };
79
+ if (input.seconds) createParams.seconds = input.seconds;
80
+ if (input.size) createParams.size = input.size;
81
+ if (input.image) createParams.input_reference = await this.transformFileType("file", input.image).then((file) => new File([Buffer.from(file.data, "base64")], file.filename || "image.png", { type: file.mimeType }));
82
+ let video = await this.client.videos.create(createParams);
83
+ _aigne_core_utils_logger.logger.debug(`Video generation started: ${video.id}`);
84
+ const pollingInterval = this.options?.pollingInterval ?? 2e3;
85
+ while (video.status === "in_progress" || video.status === "queued") {
86
+ await new Promise((resolve) => setTimeout(resolve, pollingInterval));
87
+ video = await this.client.videos.retrieve(video.id);
88
+ const progress = video.progress ?? 0;
89
+ const statusText = video.status === "queued" ? "Queued" : "Processing";
90
+ _aigne_core_utils_logger.logger.debug(`${statusText}: ${progress.toFixed(1)}%`);
91
+ }
92
+ if (video.status === "failed") throw new Error(`Video generation failed: ${video.error?.message || "Unknown error"}`);
93
+ if (video.status !== "completed") throw new Error(`Unexpected video status: ${video.status}`);
94
+ return {
95
+ videos: [{
96
+ type: "file",
97
+ data: await this.downloadToFile(video.id),
98
+ mimeType: "video/mp4",
99
+ filename: `${video.id}.mp4`
100
+ }],
101
+ usage: {
102
+ inputTokens: 0,
103
+ outputTokens: 0
104
+ },
105
+ model,
106
+ seconds: input.seconds ? parseInt(input.seconds, 10) : DEFAULT_SECONDS
107
+ };
108
+ }
109
+ };
110
+
111
+ //#endregion
112
+ exports.OpenAIVideoModel = OpenAIVideoModel;
@@ -0,0 +1,95 @@
1
+ import { AgentInvokeOptions, VideoModel, VideoModelInput, VideoModelOptions, VideoModelOutput } from "@aigne/core";
2
+ import OpenAI, { ClientOptions } from "openai";
3
+
4
+ //#region src/openai-video-model.d.ts
5
+ /**
6
+ * Input options for OpenAI Video Model
7
+ */
8
+ interface OpenAIVideoModelInput extends VideoModelInput {
9
+ /**
10
+ * Sora model to use for video generation
11
+ *
12
+ * - `sora-2`: Standard version, lower cost
13
+ * - `sora-2-pro`: Pro version, higher quality
14
+ *
15
+ * @default "sora-2"
16
+ */
17
+ model?: "sora-2" | "sora-2-pro";
18
+ /**
19
+ * Video resolution (width x height)
20
+ *
21
+ * - `720x1280`: Vertical video (9:16)
22
+ * - `1280x720`: Horizontal video (16:9)
23
+ * - `1024x1792`: Vertical video (9:16, higher resolution)
24
+ * - `1792x1024`: Horizontal video (16:9, higher resolution)
25
+ */
26
+ size?: "720x1280" | "1280x720" | "1024x1792" | "1792x1024";
27
+ /**
28
+ * Video duration in seconds
29
+ *
30
+ * @default "4"
31
+ */
32
+ seconds?: "4" | "8" | "12";
33
+ }
34
+ /**
35
+ * Output from OpenAI Video Model
36
+ */
37
+ interface OpenAIVideoModelOutput extends VideoModelOutput {}
38
+ /**
39
+ * Configuration options for OpenAI Video Model
40
+ */
41
+ interface OpenAIVideoModelOptions extends VideoModelOptions<OpenAIVideoModelInput, OpenAIVideoModelOutput> {
42
+ /**
43
+ * API key for OpenAI API
44
+ *
45
+ * If not provided, will look for OPENAI_API_KEY in environment variables
46
+ */
47
+ apiKey?: string;
48
+ /**
49
+ * Base URL for OpenAI API
50
+ *
51
+ * Useful for proxies or alternate endpoints
52
+ */
53
+ baseURL?: string;
54
+ /**
55
+ * OpenAI model to use
56
+ *
57
+ * Defaults to 'sora-2'
58
+ */
59
+ model?: string;
60
+ /**
61
+ * Additional model options to control behavior
62
+ */
63
+ modelOptions?: Omit<Partial<OpenAIVideoModelInput>, "model">;
64
+ /**
65
+ * Client options for OpenAI API
66
+ */
67
+ clientOptions?: Partial<ClientOptions>;
68
+ /**
69
+ * Polling interval in milliseconds for checking video generation status
70
+ *
71
+ * Defaults to 2000ms (2 seconds)
72
+ */
73
+ pollingInterval?: number;
74
+ }
75
+ declare class OpenAIVideoModel extends VideoModel<OpenAIVideoModelInput, OpenAIVideoModelOutput> {
76
+ options?: OpenAIVideoModelOptions | undefined;
77
+ constructor(options?: OpenAIVideoModelOptions | undefined);
78
+ /**
79
+ * @hidden
80
+ */
81
+ protected _client?: OpenAI;
82
+ protected apiKeyEnvName: string;
83
+ get client(): OpenAI;
84
+ get credential(): {
85
+ url: string | undefined;
86
+ apiKey: string | undefined;
87
+ model: string;
88
+ };
89
+ get modelOptions(): Omit<Partial<OpenAIVideoModelInput>, "model"> | undefined;
90
+ downloadToFile(videoId: string): Promise<string>;
91
+ process(input: OpenAIVideoModelInput, _options: AgentInvokeOptions): Promise<OpenAIVideoModelOutput>;
92
+ }
93
+ //#endregion
94
+ export { OpenAIVideoModel, OpenAIVideoModelInput, OpenAIVideoModelOptions, OpenAIVideoModelOutput };
95
+ //# sourceMappingURL=openai-video-model.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-video-model.d.cts","names":[],"sources":["../src/openai-video-model.ts"],"mappings":";;;;;AAqBA;AAgCA;UAhCiB,qBAAA,SAA8B,eAAA;EAAA;AAgC/C;AAKA;;;;;;EArC+C,KAAA;EAAA;AAgC/C;AAKA;;;;;;EArC+C,IAAA;EAAA;AAgC/C;AAKA;;;EArC+C,OAAA;AAAA;AAAA;AAgC/C;AAKA;AArC+C,UAgC9B,sBAAA,SAA+B,gBAAA;AAAA;AAKhD;;AALgD,UAK/B,uBAAA,SACP,iBAAA,CAAkB,qBAAA,EAAuB,sBAAA;EAAA;;;;;EAAA,MAAA;EAAA;;;;;EAAA,OAAA;EAAA;;;;;EAAA,KAAA;EAAA;;;EAAA,YAAA,GAyBlC,IAAA,CAAK,OAAA,CAAQ,qBAAA;EAAA;;;EAAA,aAAA,GAKZ,OAAA,CAAQ,aAAA;EAAA;;;;AAyB1B;EAzB0B,eAAA;AAAA;AAAA,cAyBb,gBAAA,SAAyB,UAAA,CAAW,qBAAA,EAAuB,sBAAA;EAAA,OAAA,GAChC,uBAAA;EAAA,YAAA,OAAA,GAAA,uBAAA;EAAA;;;EAAA,UAAA,OAAA,GAYlB,MAAA;EAAA,UAAA,aAAA;EAAA,IAAA,OAAA,GAIV,MAAA;EAAA,IAAA,WAAA;IAAA,GAAA;IAAA,MAAA;IAAA,KAAA;EAAA;EAAA,IAAA,aAAA,GAuBM,IAAA,CAAA,OAAA,CAAA,qBAAA;EAAA,eAAA,OAAA,WAIuB,OAAA;EAAA,QAAA,KAAA,EAS9B,qBAAA,EAAA,QAAA,EACG,kBAAA,GACT,OAAA,CAAQ,sBAAA;AAAA"}