@aigne/ideogram 0.3.15 → 0.4.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,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/ideogram-v0.3.15...ideogram-v0.4.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/core bumped to 1.61.0-beta
16
+
3
17
  ## [0.3.15](https://github.com/AIGNE-io/aigne-framework/compare/ideogram-v0.3.14...ideogram-v0.3.15) (2025-09-18)
4
18
 
5
19
 
@@ -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 IdeogramImageModelInput extends ImageModelInput {
3
3
  seed?: number;
4
4
  resolution?: string;
@@ -34,5 +34,5 @@ export declare class IdeogramImageModel extends ImageModel<IdeogramImageModelInp
34
34
  * @param input The input to process
35
35
  * @returns The generated response
36
36
  */
37
- process(input: IdeogramImageModelInput): Promise<ImageModelOutput>;
37
+ process(input: IdeogramImageModelInput, options: AgentInvokeOptions): Promise<ImageModelOutput>;
38
38
  }
@@ -43,7 +43,7 @@ class IdeogramImageModel extends core_1.ImageModel {
43
43
  * @param input The input to process
44
44
  * @returns The generated response
45
45
  */
46
- async process(input) {
46
+ async process(input, options) {
47
47
  const model = input.model || this.credential.model;
48
48
  const formData = new FormData();
49
49
  if (model !== "ideogram-v3") {
@@ -62,18 +62,28 @@ class IdeogramImageModel extends core_1.ImageModel {
62
62
  "styleType",
63
63
  ];
64
64
  const mergedInput = (0, camelize_js_1.snakelize)((0, type_utils_js_1.pick)({ ...this.modelOptions, ...input }, inputKeys));
65
- if (input.n) {
66
- formData.append("num_images", input.n.toString());
67
- }
68
65
  Object.keys(mergedInput).forEach((key) => {
69
66
  if (mergedInput[key]) {
70
67
  formData.append(key, mergedInput[key]);
71
68
  }
72
69
  });
70
+ if (input.n) {
71
+ formData.append("num_images", input.n.toString());
72
+ }
73
+ const inputImages = (0, type_utils_js_1.flat)(input.image);
74
+ const image = inputImages.at(0);
75
+ if (image) {
76
+ if (inputImages.length > 1) {
77
+ throw new Error(`${this.name} only support one image for editing`);
78
+ }
79
+ const { data } = await this.transformFileOutput(core_1.FileOutputType.file, image, options);
80
+ formData.append("image", new Blob([Buffer.from(data, "base64")]));
81
+ }
73
82
  const { url, apiKey } = this.credential;
74
83
  if (!apiKey)
75
84
  throw new Error(`${this.name} requires an API key. Please provide it via \`options.apiKey\`, or set the \`${this.apiKeyEnvName}\` environment variable`);
76
- const response = await fetch((0, ufo_1.joinURL)(new URL(url).origin, `/v1/${model}/generate`), {
85
+ const apiURL = (0, ufo_1.joinURL)(new URL(url).origin, "v1", model, image ? "remix" : "generate");
86
+ const response = await fetch(apiURL, {
77
87
  method: "POST",
78
88
  headers: { "api-key": apiKey },
79
89
  body: formData,
@@ -84,7 +94,7 @@ class IdeogramImageModel extends core_1.ImageModel {
84
94
  }
85
95
  const data = await response.json();
86
96
  return {
87
- images: data.data.map((item) => ({ url: item.url })),
97
+ images: data.data.map((item) => ({ type: "url", url: item.url, mimeType: "image/png" })),
88
98
  usage: {
89
99
  inputTokens: 0,
90
100
  outputTokens: 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 IdeogramImageModelInput extends ImageModelInput {
3
3
  seed?: number;
4
4
  resolution?: string;
@@ -34,5 +34,5 @@ export declare class IdeogramImageModel extends ImageModel<IdeogramImageModelInp
34
34
  * @param input The input to process
35
35
  * @returns The generated response
36
36
  */
37
- process(input: IdeogramImageModelInput): Promise<ImageModelOutput>;
37
+ process(input: IdeogramImageModelInput, options: AgentInvokeOptions): Promise<ImageModelOutput>;
38
38
  }
@@ -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 IdeogramImageModelInput extends ImageModelInput {
3
3
  seed?: number;
4
4
  resolution?: string;
@@ -34,5 +34,5 @@ export declare class IdeogramImageModel extends ImageModel<IdeogramImageModelInp
34
34
  * @param input The input to process
35
35
  * @returns The generated response
36
36
  */
37
- process(input: IdeogramImageModelInput): Promise<ImageModelOutput>;
37
+ process(input: IdeogramImageModelInput, options: AgentInvokeOptions): Promise<ImageModelOutput>;
38
38
  }
@@ -1,6 +1,6 @@
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 IDEOGRAM_BASE_URL = "https://api.ideogram.ai";
@@ -40,7 +40,7 @@ export class IdeogramImageModel extends ImageModel {
40
40
  * @param input The input to process
41
41
  * @returns The generated response
42
42
  */
43
- async process(input) {
43
+ async process(input, options) {
44
44
  const model = input.model || this.credential.model;
45
45
  const formData = new FormData();
46
46
  if (model !== "ideogram-v3") {
@@ -59,18 +59,28 @@ export class IdeogramImageModel extends ImageModel {
59
59
  "styleType",
60
60
  ];
61
61
  const mergedInput = snakelize(pick({ ...this.modelOptions, ...input }, inputKeys));
62
- if (input.n) {
63
- formData.append("num_images", input.n.toString());
64
- }
65
62
  Object.keys(mergedInput).forEach((key) => {
66
63
  if (mergedInput[key]) {
67
64
  formData.append(key, mergedInput[key]);
68
65
  }
69
66
  });
67
+ if (input.n) {
68
+ formData.append("num_images", input.n.toString());
69
+ }
70
+ const inputImages = flat(input.image);
71
+ const image = inputImages.at(0);
72
+ if (image) {
73
+ if (inputImages.length > 1) {
74
+ throw new Error(`${this.name} only support one image for editing`);
75
+ }
76
+ const { data } = await this.transformFileOutput(FileOutputType.file, image, options);
77
+ formData.append("image", new Blob([Buffer.from(data, "base64")]));
78
+ }
70
79
  const { url, apiKey } = this.credential;
71
80
  if (!apiKey)
72
81
  throw new Error(`${this.name} requires an API key. Please provide it via \`options.apiKey\`, or set the \`${this.apiKeyEnvName}\` environment variable`);
73
- const response = await fetch(joinURL(new URL(url).origin, `/v1/${model}/generate`), {
82
+ const apiURL = joinURL(new URL(url).origin, "v1", model, image ? "remix" : "generate");
83
+ const response = await fetch(apiURL, {
74
84
  method: "POST",
75
85
  headers: { "api-key": apiKey },
76
86
  body: formData,
@@ -81,7 +91,7 @@ export class IdeogramImageModel extends ImageModel {
81
91
  }
82
92
  const data = await response.json();
83
93
  return {
84
- images: data.data.map((item) => ({ url: item.url })),
94
+ images: data.data.map((item) => ({ type: "url", url: item.url, mimeType: "image/png" })),
85
95
  usage: {
86
96
  inputTokens: 0,
87
97
  outputTokens: 0,
package/package.json CHANGED
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "ufo": "^1.6.1",
38
- "@aigne/core": "1.60.3"
38
+ "@aigne/core": "1.61.0-beta"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/bun": "^1.2.22",
@@ -47,7 +47,7 @@
47
47
  "typescript": "^5.9.2",
48
48
  "zod": "3.25.67"
49
49
  },
50
- "version": "0.3.15",
50
+ "version": "0.4.0-beta",
51
51
  "scripts": {
52
52
  "lint": "tsc --noEmit",
53
53
  "build": "tsc --build scripts/tsconfig.build.json",