@aigne/doubao 1.0.39 → 1.1.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.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/doubao-v1.0.40...doubao-v1.1.0-beta) (2025-09-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* improve image model architecture and file handling ([#527](https://github.com/AIGNE-io/aigne-framework/issues/527)) ([4db50aa](https://github.com/AIGNE-io/aigne-framework/commit/4db50aa0387a1a0f045ca11aaa61613e36ca7597))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @aigne/openai bumped to 0.16.0-beta
|
|
16
|
+
* devDependencies
|
|
17
|
+
* @aigne/core bumped to 1.61.0-beta
|
|
18
|
+
* @aigne/test-utils bumped to 0.5.53-beta
|
|
19
|
+
|
|
20
|
+
## [1.0.40](https://github.com/AIGNE-io/aigne-framework/compare/doubao-v1.0.39...doubao-v1.0.40) (2025-09-18)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* support the correct 3.0 model ([#514](https://github.com/AIGNE-io/aigne-framework/issues/514)) ([98e0d44](https://github.com/AIGNE-io/aigne-framework/commit/98e0d44ce2c4c7b043d5fc934c6e312ffa821521))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Dependencies
|
|
29
|
+
|
|
30
|
+
* The following workspace dependencies were updated
|
|
31
|
+
* dependencies
|
|
32
|
+
* @aigne/openai bumped to 0.15.4
|
|
33
|
+
* devDependencies
|
|
34
|
+
* @aigne/core bumped to 1.60.3
|
|
35
|
+
* @aigne/test-utils bumped to 0.5.52
|
|
36
|
+
|
|
3
37
|
## [1.0.39](https://github.com/AIGNE-io/aigne-framework/compare/doubao-v1.0.38...doubao-v1.0.39) (2025-09-16)
|
|
4
38
|
|
|
5
39
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ImageModel, type ImageModelInput, type ImageModelOptions, type ImageModelOutput } from "@aigne/core";
|
|
1
|
+
import { type AgentInvokeOptions, ImageModel, type ImageModelInput, type ImageModelOptions, type ImageModelOutput } from "@aigne/core";
|
|
2
2
|
export interface DoubaoImageModelInput extends ImageModelInput {
|
|
3
3
|
size?: string;
|
|
4
4
|
seed?: number;
|
|
@@ -30,5 +30,5 @@ export declare class DoubaoImageModel extends ImageModel<DoubaoImageModelInput,
|
|
|
30
30
|
};
|
|
31
31
|
get modelOptions(): Omit<Partial<DoubaoImageModelInput>, "model"> | undefined;
|
|
32
32
|
private extractDataObjects;
|
|
33
|
-
process(input: DoubaoImageModelInput): Promise<ImageModelOutput>;
|
|
33
|
+
process(input: DoubaoImageModelInput, options: AgentInvokeOptions): Promise<ImageModelOutput>;
|
|
34
34
|
}
|
|
@@ -8,6 +8,7 @@ const ufo_1 = require("ufo");
|
|
|
8
8
|
const zod_1 = require("zod");
|
|
9
9
|
const DOUBAO_DEFAULT_IMAGE_MODEL = "doubao-seedream-4-0-250828";
|
|
10
10
|
const DOUBAO_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3";
|
|
11
|
+
const OUTPUT_MIME_TYPE = "image/jpeg";
|
|
11
12
|
const doubaoImageModelInputSchema = core_1.imageModelInputSchema.extend({});
|
|
12
13
|
const doubaoImageModelOptionsSchema = zod_1.z.object({
|
|
13
14
|
apiKey: zod_1.z.string().optional(),
|
|
@@ -59,7 +60,7 @@ class DoubaoImageModel extends core_1.ImageModel {
|
|
|
59
60
|
}
|
|
60
61
|
return dataObjects;
|
|
61
62
|
}
|
|
62
|
-
async process(input) {
|
|
63
|
+
async process(input, options) {
|
|
63
64
|
const model = input.model || this.credential.model;
|
|
64
65
|
const { url, apiKey } = this.credential;
|
|
65
66
|
if (!apiKey) {
|
|
@@ -69,7 +70,6 @@ class DoubaoImageModel extends core_1.ImageModel {
|
|
|
69
70
|
"doubao-seedream-4": [
|
|
70
71
|
"model",
|
|
71
72
|
"prompt",
|
|
72
|
-
"image",
|
|
73
73
|
"size",
|
|
74
74
|
"sequentialImageGeneration",
|
|
75
75
|
"sequentialImageGenerationOptions",
|
|
@@ -77,7 +77,7 @@ class DoubaoImageModel extends core_1.ImageModel {
|
|
|
77
77
|
"responseFormat",
|
|
78
78
|
"watermark",
|
|
79
79
|
],
|
|
80
|
-
"doubao-seedream-3
|
|
80
|
+
"doubao-seedream-3-0-t2i": [
|
|
81
81
|
"model",
|
|
82
82
|
"prompt",
|
|
83
83
|
"size",
|
|
@@ -86,10 +86,9 @@ class DoubaoImageModel extends core_1.ImageModel {
|
|
|
86
86
|
"responseFormat",
|
|
87
87
|
"watermark",
|
|
88
88
|
],
|
|
89
|
-
"doubao-seededit-3
|
|
89
|
+
"doubao-seededit-3-0-i2i": [
|
|
90
90
|
"model",
|
|
91
91
|
"prompt",
|
|
92
|
-
"image",
|
|
93
92
|
"size",
|
|
94
93
|
"seed",
|
|
95
94
|
"guidanceScale",
|
|
@@ -105,9 +104,14 @@ class DoubaoImageModel extends core_1.ImageModel {
|
|
|
105
104
|
throw new Error(`${this.name} only support ${Object.keys(map).join(", ")}`);
|
|
106
105
|
}
|
|
107
106
|
const mergeInput = { ...this.modelOptions, ...input };
|
|
108
|
-
const
|
|
109
|
-
body
|
|
110
|
-
|
|
107
|
+
const image = await Promise.all((0, type_utils_js_1.flat)(input.image).map((image) => this.transformFileOutput(core_1.FileOutputType.file, image, options).then((file) => `data:${file.mimeType || "image/png"};base64,${file.data}`)));
|
|
108
|
+
const body = {
|
|
109
|
+
...(0, camelize_js_1.snakelize)((0, type_utils_js_1.pick)(mergeInput, map[key])),
|
|
110
|
+
model,
|
|
111
|
+
response_format: "b64_json",
|
|
112
|
+
watermark: mergeInput.watermark ?? false,
|
|
113
|
+
image: image.length ? image : undefined,
|
|
114
|
+
};
|
|
111
115
|
const response = await fetch((0, ufo_1.joinURL)(url, `/images/generations`), {
|
|
112
116
|
method: "POST",
|
|
113
117
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
@@ -141,10 +145,11 @@ class DoubaoImageModel extends core_1.ImageModel {
|
|
|
141
145
|
images: dataObjects
|
|
142
146
|
.filter((i) => i.type === "image_generation.partial_succeeded")
|
|
143
147
|
.map((i) => {
|
|
144
|
-
|
|
145
|
-
url: i.url,
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
if (typeof i.url === "string")
|
|
149
|
+
return { type: "url", url: i.url, mimeType: OUTPUT_MIME_TYPE };
|
|
150
|
+
if (typeof i.b64_json === "string")
|
|
151
|
+
return { type: "file", data: i.b64_json, mimeType: OUTPUT_MIME_TYPE };
|
|
152
|
+
throw new Error("Image response does not contain a valid URL or base64 data");
|
|
148
153
|
}),
|
|
149
154
|
usage: { inputTokens: 0, outputTokens: completed?.usage.output_tokens || 0 },
|
|
150
155
|
model: model,
|
|
@@ -155,10 +160,13 @@ class DoubaoImageModel extends core_1.ImageModel {
|
|
|
155
160
|
throw new Error(`Doubao API error: ${data.error.message}`);
|
|
156
161
|
}
|
|
157
162
|
return {
|
|
158
|
-
images: data.data.map((item) =>
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
images: data.data.map((item) => {
|
|
164
|
+
if (item.url)
|
|
165
|
+
return { type: "url", url: item.url, mimeType: OUTPUT_MIME_TYPE };
|
|
166
|
+
if (item.b64_json)
|
|
167
|
+
return { type: "file", data: item.b64_json, mimeType: OUTPUT_MIME_TYPE };
|
|
168
|
+
throw new Error("Image response does not contain a valid URL or base64 data");
|
|
169
|
+
}),
|
|
162
170
|
usage: {
|
|
163
171
|
inputTokens: 0,
|
|
164
172
|
outputTokens: data?.usage?.output_tokens || 0,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ImageModel, type ImageModelInput, type ImageModelOptions, type ImageModelOutput } from "@aigne/core";
|
|
1
|
+
import { type AgentInvokeOptions, ImageModel, type ImageModelInput, type ImageModelOptions, type ImageModelOutput } from "@aigne/core";
|
|
2
2
|
export interface DoubaoImageModelInput extends ImageModelInput {
|
|
3
3
|
size?: string;
|
|
4
4
|
seed?: number;
|
|
@@ -30,5 +30,5 @@ export declare class DoubaoImageModel extends ImageModel<DoubaoImageModelInput,
|
|
|
30
30
|
};
|
|
31
31
|
get modelOptions(): Omit<Partial<DoubaoImageModelInput>, "model"> | undefined;
|
|
32
32
|
private extractDataObjects;
|
|
33
|
-
process(input: DoubaoImageModelInput): Promise<ImageModelOutput>;
|
|
33
|
+
process(input: DoubaoImageModelInput, options: AgentInvokeOptions): Promise<ImageModelOutput>;
|
|
34
34
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ImageModel, type ImageModelInput, type ImageModelOptions, type ImageModelOutput } from "@aigne/core";
|
|
1
|
+
import { type AgentInvokeOptions, ImageModel, type ImageModelInput, type ImageModelOptions, type ImageModelOutput } from "@aigne/core";
|
|
2
2
|
export interface DoubaoImageModelInput extends ImageModelInput {
|
|
3
3
|
size?: string;
|
|
4
4
|
seed?: number;
|
|
@@ -30,5 +30,5 @@ export declare class DoubaoImageModel extends ImageModel<DoubaoImageModelInput,
|
|
|
30
30
|
};
|
|
31
31
|
get modelOptions(): Omit<Partial<DoubaoImageModelInput>, "model"> | undefined;
|
|
32
32
|
private extractDataObjects;
|
|
33
|
-
process(input: DoubaoImageModelInput): Promise<ImageModelOutput>;
|
|
33
|
+
process(input: DoubaoImageModelInput, options: AgentInvokeOptions): Promise<ImageModelOutput>;
|
|
34
34
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { ImageModel, imageModelInputSchema, } from "@aigne/core";
|
|
1
|
+
import { FileOutputType, ImageModel, imageModelInputSchema, } from "@aigne/core";
|
|
2
2
|
import { snakelize } from "@aigne/core/utils/camelize.js";
|
|
3
|
-
import { checkArguments, pick } from "@aigne/core/utils/type-utils.js";
|
|
3
|
+
import { checkArguments, flat, pick } from "@aigne/core/utils/type-utils.js";
|
|
4
4
|
import { joinURL } from "ufo";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
const DOUBAO_DEFAULT_IMAGE_MODEL = "doubao-seedream-4-0-250828";
|
|
7
7
|
const DOUBAO_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3";
|
|
8
|
+
const OUTPUT_MIME_TYPE = "image/jpeg";
|
|
8
9
|
const doubaoImageModelInputSchema = imageModelInputSchema.extend({});
|
|
9
10
|
const doubaoImageModelOptionsSchema = z.object({
|
|
10
11
|
apiKey: z.string().optional(),
|
|
@@ -56,7 +57,7 @@ export class DoubaoImageModel extends ImageModel {
|
|
|
56
57
|
}
|
|
57
58
|
return dataObjects;
|
|
58
59
|
}
|
|
59
|
-
async process(input) {
|
|
60
|
+
async process(input, options) {
|
|
60
61
|
const model = input.model || this.credential.model;
|
|
61
62
|
const { url, apiKey } = this.credential;
|
|
62
63
|
if (!apiKey) {
|
|
@@ -66,7 +67,6 @@ export class DoubaoImageModel extends ImageModel {
|
|
|
66
67
|
"doubao-seedream-4": [
|
|
67
68
|
"model",
|
|
68
69
|
"prompt",
|
|
69
|
-
"image",
|
|
70
70
|
"size",
|
|
71
71
|
"sequentialImageGeneration",
|
|
72
72
|
"sequentialImageGenerationOptions",
|
|
@@ -74,7 +74,7 @@ export class DoubaoImageModel extends ImageModel {
|
|
|
74
74
|
"responseFormat",
|
|
75
75
|
"watermark",
|
|
76
76
|
],
|
|
77
|
-
"doubao-seedream-3
|
|
77
|
+
"doubao-seedream-3-0-t2i": [
|
|
78
78
|
"model",
|
|
79
79
|
"prompt",
|
|
80
80
|
"size",
|
|
@@ -83,10 +83,9 @@ export class DoubaoImageModel extends ImageModel {
|
|
|
83
83
|
"responseFormat",
|
|
84
84
|
"watermark",
|
|
85
85
|
],
|
|
86
|
-
"doubao-seededit-3
|
|
86
|
+
"doubao-seededit-3-0-i2i": [
|
|
87
87
|
"model",
|
|
88
88
|
"prompt",
|
|
89
|
-
"image",
|
|
90
89
|
"size",
|
|
91
90
|
"seed",
|
|
92
91
|
"guidanceScale",
|
|
@@ -102,9 +101,14 @@ export class DoubaoImageModel extends ImageModel {
|
|
|
102
101
|
throw new Error(`${this.name} only support ${Object.keys(map).join(", ")}`);
|
|
103
102
|
}
|
|
104
103
|
const mergeInput = { ...this.modelOptions, ...input };
|
|
105
|
-
const
|
|
106
|
-
body
|
|
107
|
-
mergeInput
|
|
104
|
+
const image = await Promise.all(flat(input.image).map((image) => this.transformFileOutput(FileOutputType.file, image, options).then((file) => `data:${file.mimeType || "image/png"};base64,${file.data}`)));
|
|
105
|
+
const body = {
|
|
106
|
+
...snakelize(pick(mergeInput, map[key])),
|
|
107
|
+
model,
|
|
108
|
+
response_format: "b64_json",
|
|
109
|
+
watermark: mergeInput.watermark ?? false,
|
|
110
|
+
image: image.length ? image : undefined,
|
|
111
|
+
};
|
|
108
112
|
const response = await fetch(joinURL(url, `/images/generations`), {
|
|
109
113
|
method: "POST",
|
|
110
114
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
@@ -138,10 +142,11 @@ export class DoubaoImageModel extends ImageModel {
|
|
|
138
142
|
images: dataObjects
|
|
139
143
|
.filter((i) => i.type === "image_generation.partial_succeeded")
|
|
140
144
|
.map((i) => {
|
|
141
|
-
|
|
142
|
-
url: i.url,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
+
if (typeof i.url === "string")
|
|
146
|
+
return { type: "url", url: i.url, mimeType: OUTPUT_MIME_TYPE };
|
|
147
|
+
if (typeof i.b64_json === "string")
|
|
148
|
+
return { type: "file", data: i.b64_json, mimeType: OUTPUT_MIME_TYPE };
|
|
149
|
+
throw new Error("Image response does not contain a valid URL or base64 data");
|
|
145
150
|
}),
|
|
146
151
|
usage: { inputTokens: 0, outputTokens: completed?.usage.output_tokens || 0 },
|
|
147
152
|
model: model,
|
|
@@ -152,10 +157,13 @@ export class DoubaoImageModel extends ImageModel {
|
|
|
152
157
|
throw new Error(`Doubao API error: ${data.error.message}`);
|
|
153
158
|
}
|
|
154
159
|
return {
|
|
155
|
-
images: data.data.map((item) =>
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
images: data.data.map((item) => {
|
|
161
|
+
if (item.url)
|
|
162
|
+
return { type: "url", url: item.url, mimeType: OUTPUT_MIME_TYPE };
|
|
163
|
+
if (item.b64_json)
|
|
164
|
+
return { type: "file", data: item.b64_json, mimeType: OUTPUT_MIME_TYPE };
|
|
165
|
+
throw new Error("Image response does not contain a valid URL or base64 data");
|
|
166
|
+
}),
|
|
159
167
|
usage: {
|
|
160
168
|
inputTokens: 0,
|
|
161
169
|
outputTokens: data?.usage?.output_tokens || 0,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/doubao",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0-beta",
|
|
4
4
|
"description": "AIGNE doubao SDK for integrating with doubao AI models",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"ufo": "^1.6.1",
|
|
39
39
|
"zod": "^3.25.67",
|
|
40
|
-
"@aigne/openai": "^0.
|
|
40
|
+
"@aigne/openai": "^0.16.0-beta"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@types/bun": "^1.2.
|
|
44
|
-
"@types/node": "^24.
|
|
43
|
+
"@types/bun": "^1.2.22",
|
|
44
|
+
"@types/node": "^24.5.1",
|
|
45
45
|
"detect-port": "^2.1.0",
|
|
46
46
|
"hono": "^4.9.7",
|
|
47
47
|
"npm-run-all": "^4.1.5",
|
|
48
48
|
"rimraf": "^6.0.1",
|
|
49
|
-
"typescript": "^5.
|
|
50
|
-
"@aigne/core": "^1.
|
|
51
|
-
"@aigne/test-utils": "^0.5.
|
|
49
|
+
"typescript": "^5.9.2",
|
|
50
|
+
"@aigne/core": "^1.61.0-beta",
|
|
51
|
+
"@aigne/test-utils": "^0.5.53-beta"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"lint": "tsc --noEmit",
|