@aigne/core 1.63.0 → 1.64.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 (35) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/lib/cjs/agents/chat-model.d.ts +4 -0
  3. package/lib/cjs/agents/chat-model.js +6 -1
  4. package/lib/cjs/agents/image-agent.d.ts +2 -0
  5. package/lib/cjs/agents/image-agent.js +14 -2
  6. package/lib/cjs/aigne/aigne.d.ts +6 -1
  7. package/lib/cjs/aigne/aigne.js +6 -0
  8. package/lib/cjs/aigne/context.d.ts +4 -1
  9. package/lib/cjs/aigne/context.js +4 -0
  10. package/lib/cjs/aigne/type.d.ts +14 -0
  11. package/lib/cjs/loader/agent-yaml.d.ts +2 -0
  12. package/lib/cjs/loader/agent-yaml.js +1 -0
  13. package/lib/cjs/prompt/prompt-builder.d.ts +7 -1
  14. package/lib/cjs/prompt/prompt-builder.js +14 -2
  15. package/lib/dts/agents/chat-model.d.ts +4 -0
  16. package/lib/dts/agents/image-agent.d.ts +2 -0
  17. package/lib/dts/aigne/aigne.d.ts +6 -1
  18. package/lib/dts/aigne/context.d.ts +4 -1
  19. package/lib/dts/aigne/type.d.ts +14 -0
  20. package/lib/dts/loader/agent-yaml.d.ts +2 -0
  21. package/lib/dts/prompt/prompt-builder.d.ts +7 -1
  22. package/lib/esm/agents/chat-model.d.ts +4 -0
  23. package/lib/esm/agents/chat-model.js +6 -1
  24. package/lib/esm/agents/image-agent.d.ts +2 -0
  25. package/lib/esm/agents/image-agent.js +14 -2
  26. package/lib/esm/aigne/aigne.d.ts +6 -1
  27. package/lib/esm/aigne/aigne.js +6 -0
  28. package/lib/esm/aigne/context.d.ts +4 -1
  29. package/lib/esm/aigne/context.js +4 -0
  30. package/lib/esm/aigne/type.d.ts +14 -0
  31. package/lib/esm/loader/agent-yaml.d.ts +2 -0
  32. package/lib/esm/loader/agent-yaml.js +1 -0
  33. package/lib/esm/prompt/prompt-builder.d.ts +7 -1
  34. package/lib/esm/prompt/prompt-builder.js +14 -2
  35. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.64.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0...core-v1.64.0-beta) (2025-10-21)
4
+
5
+
6
+ ### Features
7
+
8
+ * add thinking support to Gemini chat models ([#650](https://github.com/AIGNE-io/aigne-framework/issues/650)) ([09b828b](https://github.com/AIGNE-io/aigne-framework/commit/09b828ba668d90cc6aac68a5e8190adb146b5e45))
9
+ * add user context support to prompt template variables ([#649](https://github.com/AIGNE-io/aigne-framework/issues/649)) ([a02d9b4](https://github.com/AIGNE-io/aigne-framework/commit/a02d9b412878050b8c1e32127b505c0346f19bba))
10
+ * **cli:** add metadata traces including CLI version, app name, and version ([#646](https://github.com/AIGNE-io/aigne-framework/issues/646)) ([c64bd76](https://github.com/AIGNE-io/aigne-framework/commit/c64bd761ba4c9f3854be5feee208c711bff7a170))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **gemini:** handle empty responses when files are present ([#648](https://github.com/AIGNE-io/aigne-framework/issues/648)) ([f4e259c](https://github.com/AIGNE-io/aigne-framework/commit/f4e259c5e5c687c347bb5cf29cbb0b5bf4d0d4a1))
16
+
17
+
18
+ ### Dependencies
19
+
20
+ * The following workspace dependencies were updated
21
+ * dependencies
22
+ * @aigne/observability-api bumped to 0.11.3-beta
23
+
3
24
  ## [1.63.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta.12...core-v1.63.0) (2025-10-19)
4
25
 
5
26
 
@@ -407,6 +407,10 @@ export interface ChatModelOutput extends Message {
407
407
  * Text format response content
408
408
  */
409
409
  text?: string;
410
+ /**
411
+ * Model's internal thoughts (if supported)
412
+ */
413
+ thoughts?: string;
410
414
  /**
411
415
  * JSON format response content
412
416
  */
@@ -38,6 +38,7 @@ const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
38
38
  const zod_1 = require("zod");
39
39
  const zod_from_json_schema_1 = require("zod-from-json-schema");
40
40
  const json_schema_js_1 = require("../utils/json-schema.js");
41
+ const logger_js_1 = require("../utils/logger.js");
41
42
  const type_utils_js_1 = require("../utils/type-utils.js");
42
43
  const agent_js_1 = require("./agent.js");
43
44
  const model_js_1 = require("./model.js");
@@ -215,7 +216,10 @@ class ChatModel extends model_js_1.Model {
215
216
  */
216
217
  async postprocess(input, output, options) {
217
218
  super.postprocess(input, output, options);
218
- const { usage } = output;
219
+ const { usage, thoughts, model } = output;
220
+ if (thoughts) {
221
+ logger_js_1.logger.info(`Model Thoughts (${model}): ${thoughts}`);
222
+ }
219
223
  if (usage) {
220
224
  options.context.usage.outputTokens += usage.outputTokens;
221
225
  options.context.usage.inputTokens += usage.inputTokens;
@@ -360,6 +364,7 @@ exports.chatModelOutputUsageSchema = zod_1.z.object({
360
364
  });
361
365
  const chatModelOutputSchema = zod_1.z.object({
362
366
  text: zod_1.z.string().optional(),
367
+ thoughts: zod_1.z.string().optional(),
363
368
  json: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
364
369
  toolCalls: zod_1.z.array(chatModelOutputToolCallSchema).optional(),
365
370
  usage: exports.chatModelOutputUsageSchema.optional(),
@@ -5,6 +5,7 @@ import { type ImageModelOutput } from "./image-model.js";
5
5
  import { type FileType } from "./model.js";
6
6
  export interface ImageAgentOptions<I extends Message = any, O extends ImageModelOutput = any> extends Omit<AgentOptions<I, O>, "outputSchema"> {
7
7
  instructions: string | PromptBuilder;
8
+ inputFileKey?: string;
8
9
  modelOptions?: Record<string, any>;
9
10
  outputFileType?: FileType;
10
11
  }
@@ -16,6 +17,7 @@ export declare class ImageAgent<I extends Message = any, O extends ImageModelOut
16
17
  static from<I extends Message = any, O extends ImageModelOutput = any>(options: ImageAgentOptions<I, O>): ImageAgent<I, O>;
17
18
  constructor(options: ImageAgentOptions<I, O>);
18
19
  instructions: PromptBuilder;
20
+ inputFileKey?: string;
19
21
  modelOptions?: Record<string, any>;
20
22
  outputFileType?: FileType;
21
23
  process(input: I, options: AgentInvokeOptions): Promise<O>;
@@ -27,18 +27,30 @@ class ImageAgent extends agent_js_1.Agent {
27
27
  typeof options.instructions === "string"
28
28
  ? prompt_builder_js_1.PromptBuilder.from(options.instructions)
29
29
  : options.instructions;
30
+ this.inputFileKey = options.inputFileKey;
30
31
  this.modelOptions = options.modelOptions;
31
32
  this.outputFileType = options.outputFileType;
32
33
  }
33
34
  instructions;
35
+ inputFileKey;
34
36
  modelOptions;
35
37
  outputFileType;
36
38
  async process(input, options) {
37
39
  const imageModel = this.imageModel || options.imageModel || options.context.imageModel;
38
40
  if (!imageModel)
39
41
  throw new Error("image model is required to run ImageAgent");
40
- const { prompt } = await this.instructions.buildImagePrompt({ input });
41
- return (await this.invokeChildAgent(imageModel, { ...input, modelOptions: this.modelOptions, prompt, outputFileType: this.outputFileType }, { ...options, streaming: false }));
42
+ const { prompt, image } = await this.instructions.buildImagePrompt({
43
+ ...options,
44
+ input,
45
+ agent: this,
46
+ });
47
+ return (await this.invokeChildAgent(imageModel, {
48
+ ...input,
49
+ modelOptions: this.modelOptions,
50
+ prompt,
51
+ image,
52
+ outputFileType: this.outputFileType,
53
+ }, { ...options, streaming: false }));
42
54
  }
43
55
  }
44
56
  exports.ImageAgent = ImageAgent;
@@ -6,7 +6,7 @@ import type { UserAgent } from "../agents/user-agent.js";
6
6
  import { type LoadOptions } from "../loader/index.js";
7
7
  import { AIGNEContext, type Context, type InvokeOptions, type UserContext } from "./context.js";
8
8
  import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
9
- import type { AIGNECLIAgents } from "./type.js";
9
+ import type { AIGNECLIAgents, AIGNEMetadata } from "./type.js";
10
10
  import type { ContextLimits } from "./usage.js";
11
11
  /**
12
12
  * Options for the AIGNE class.
@@ -53,6 +53,7 @@ export interface AIGNEOptions {
53
53
  * Observer for the AIGNE instance.
54
54
  */
55
55
  observer?: AIGNEObserver;
56
+ metadata?: AIGNEMetadata;
56
57
  }
57
58
  /**
58
59
  * AIGNE is a class that orchestrates multiple agents to build complex AI applications.
@@ -136,6 +137,10 @@ export declare class AIGNE<U extends UserContext = UserContext> {
136
137
  * Observer for the AIGNE instance.
137
138
  */
138
139
  readonly observer?: AIGNEObserver;
140
+ /**
141
+ * Metadata for the AIGNE instance.
142
+ */
143
+ readonly metadata: AIGNEMetadata;
139
144
  /**
140
145
  * Adds one or more agents to this AIGNE instance.
141
146
  * Each agent is attached to this AIGNE instance, allowing it to access the AIGNE's resources.
@@ -37,6 +37,7 @@ class AIGNE {
37
37
  imageModel,
38
38
  agents: agents.concat(options?.agents ?? []),
39
39
  skills: skills.concat(options?.skills ?? []),
40
+ metadata: options?.metadata,
40
41
  });
41
42
  }
42
43
  /**
@@ -66,6 +67,7 @@ class AIGNE {
66
67
  this.cli = options?.cli ?? {};
67
68
  this.observer?.serve();
68
69
  this.initProcessExitHandler();
70
+ this.metadata = options?.metadata ?? {};
69
71
  }
70
72
  /**
71
73
  * Optional root directory for this AIGNE instance.
@@ -115,6 +117,10 @@ class AIGNE {
115
117
  * Observer for the AIGNE instance.
116
118
  */
117
119
  observer;
120
+ /**
121
+ * Metadata for the AIGNE instance.
122
+ */
123
+ metadata = {};
118
124
  /**
119
125
  * Adds one or more agents to this AIGNE instance.
120
126
  * Each agent is attached to this AIGNE instance, allowing it to access the AIGNE's resources.
@@ -9,6 +9,7 @@ import type { Memory } from "../memory/memory.js";
9
9
  import { type OmitPropertiesFromArrayFirstElement } from "../utils/type-utils.js";
10
10
  import type { Args, Listener, TypedEventEmitter } from "../utils/typed-event-emitter.js";
11
11
  import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
12
+ import type { AIGNEMetadata } from "./type.js";
12
13
  import { type ContextLimits, type ContextUsage } from "./usage.js";
13
14
  /**
14
15
  * @hidden
@@ -78,6 +79,7 @@ export interface Context<U extends UserContext = UserContext> extends TypedEvent
78
79
  skills?: Agent[];
79
80
  agents: Agent[];
80
81
  observer?: AIGNEObserver;
82
+ metadata?: AIGNEMetadata;
81
83
  span?: Span;
82
84
  usage: ContextUsage;
83
85
  limits?: ContextLimits;
@@ -187,7 +189,7 @@ export declare class AIGNEContext implements Context {
187
189
  }
188
190
  declare class AIGNEContextShared {
189
191
  private readonly parent?;
190
- constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer"> & {
192
+ constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer" | "metadata"> & {
191
193
  messageQueue?: MessageQueue;
192
194
  events?: Emitter<any>;
193
195
  }) | undefined);
@@ -198,6 +200,7 @@ declare class AIGNEContextShared {
198
200
  get skills(): Agent<any, any>[] | undefined;
199
201
  get agents(): Agent<any, any>[];
200
202
  get observer(): AIGNEObserver | undefined;
203
+ get metadata(): AIGNEMetadata | undefined;
201
204
  get limits(): ContextLimits | undefined;
202
205
  usage: ContextUsage;
203
206
  userContext: Context["userContext"];
@@ -217,6 +217,7 @@ class AIGNEContext {
217
217
  if (this.parentId) {
218
218
  span.setAttribute("custom.parent_id", this.parentId);
219
219
  }
220
+ span.setAttribute("metadata", JSON.stringify(this.internal.metadata ?? {}));
220
221
  span.setAttribute("custom.started_at", b.timestamp);
221
222
  span.setAttribute("input", JSON.stringify(input));
222
223
  span.setAttribute("agentTag", agent.tag ?? "UnknownAgent");
@@ -300,6 +301,9 @@ class AIGNEContextShared {
300
301
  get observer() {
301
302
  return this.parent?.observer;
302
303
  }
304
+ get metadata() {
305
+ return this.parent?.metadata;
306
+ }
303
307
  get limits() {
304
308
  return this.parent?.limits;
305
309
  }
@@ -10,3 +10,17 @@ export interface AIGNECLIAgent {
10
10
  description?: string;
11
11
  agents?: AIGNECLIAgent[];
12
12
  }
13
+ export interface AIGNEMetadata {
14
+ /**
15
+ * CLI version (e.g., "1.51.0")
16
+ */
17
+ cliVersion?: string;
18
+ /**
19
+ * Application name (e.g., "docsmith", "websmith")
20
+ */
21
+ appName?: string;
22
+ /**
23
+ * Application version (e.g., "2.3.4")
24
+ */
25
+ appVersion?: string;
26
+ }
@@ -59,6 +59,7 @@ export interface AIAgentSchema extends BaseAgentSchema {
59
59
  inputKey?: string;
60
60
  inputFileKey?: string;
61
61
  outputKey?: string;
62
+ outputFileKey?: string;
62
63
  toolChoice?: AIAgentToolChoice;
63
64
  toolCallsConcurrency?: number;
64
65
  keepTextInToolUses?: boolean;
@@ -66,6 +67,7 @@ export interface AIAgentSchema extends BaseAgentSchema {
66
67
  export interface ImageAgentSchema extends BaseAgentSchema {
67
68
  type: "image";
68
69
  instructions: Instructions;
70
+ inputFileKey?: string;
69
71
  modelOptions?: Record<string, any>;
70
72
  }
71
73
  export interface MCPAgentSchema extends BaseAgentSchema {
@@ -128,6 +128,7 @@ async function parseAgentFile(path, data) {
128
128
  .object({
129
129
  type: zod_1.z.literal("image"),
130
130
  instructions: instructionsSchema,
131
+ inputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
131
132
  modelOptions: (0, schema_js_1.optionalize)((0, schema_js_1.camelizeSchema)(zod_1.z.record(zod_1.z.any()))),
132
133
  })
133
134
  .extend(baseAgentSchema.shape),
@@ -2,6 +2,8 @@ import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
2
  import { Agent, type AgentInvokeOptions, type Message } from "../agents/agent.js";
3
3
  import { type AIAgent } from "../agents/ai-agent.js";
4
4
  import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
5
+ import type { ImageAgent } from "../agents/image-agent.js";
6
+ import { type FileUnionContent } from "../agents/model.js";
5
7
  import { ChatMessagesTemplate } from "./template.js";
6
8
  export interface PromptBuilderOptions {
7
9
  instructions?: string | ChatMessagesTemplate;
@@ -27,9 +29,13 @@ export declare class PromptBuilder {
27
29
  build(options: PromptBuildOptions): Promise<ChatModelInput & {
28
30
  toolAgents?: Agent[];
29
31
  }>;
30
- buildImagePrompt(options: Pick<PromptBuildOptions, "input">): Promise<{
32
+ buildImagePrompt(options: Pick<PromptBuildOptions, "input" | "context"> & {
33
+ agent: ImageAgent;
34
+ }): Promise<{
31
35
  prompt: string;
36
+ image?: FileUnionContent[];
32
37
  }>;
38
+ private getTemplateVariables;
33
39
  private buildMessages;
34
40
  private refineMessages;
35
41
  private convertMemoriesToMessages;
@@ -78,9 +78,21 @@ class PromptBuilder {
78
78
  async buildImagePrompt(options) {
79
79
  const messages = (await (typeof this.instructions === "string"
80
80
  ? template_js_1.ChatMessagesTemplate.from([template_js_1.SystemMessageTemplate.from(this.instructions)])
81
- : this.instructions)?.format(options.input, { workingDir: this.workingDir })) ?? [];
81
+ : this.instructions)?.format(this.getTemplateVariables(options), { workingDir: this.workingDir })) ?? [];
82
+ const inputFileKey = options.agent?.inputFileKey;
83
+ const files = (0, type_utils_js_1.flat)(inputFileKey
84
+ ? (0, type_utils_js_1.checkArguments)("Check input files", (0, schema_js_1.optionalize)(model_js_1.fileUnionContentsSchema), options.input?.[inputFileKey])
85
+ : null);
82
86
  return {
83
87
  prompt: messages.map((i) => i.content).join("\n"),
88
+ image: files.length ? files : undefined,
89
+ };
90
+ }
91
+ getTemplateVariables(options) {
92
+ return {
93
+ userContext: options.context?.userContext,
94
+ ...options.context?.userContext,
95
+ ...options.input,
84
96
  };
85
97
  }
86
98
  async buildMessages(options) {
@@ -89,7 +101,7 @@ class PromptBuilder {
89
101
  const message = inputKey && typeof input?.[inputKey] === "string" ? input[inputKey] : undefined;
90
102
  const [messages, otherCustomMessages] = (0, type_utils_js_1.partition)((await (typeof this.instructions === "string"
91
103
  ? template_js_1.ChatMessagesTemplate.from([template_js_1.SystemMessageTemplate.from(this.instructions)])
92
- : this.instructions)?.format(options.input, { workingDir: this.workingDir })) ?? [], (i) => i.role === "system");
104
+ : this.instructions)?.format(this.getTemplateVariables(options), { workingDir: this.workingDir })) ?? [], (i) => i.role === "system");
93
105
  const inputFileKey = options.agent?.inputFileKey;
94
106
  const files = (0, type_utils_js_1.flat)(inputFileKey
95
107
  ? (0, type_utils_js_1.checkArguments)("Check input files", (0, schema_js_1.optionalize)(model_js_1.fileUnionContentsSchema), input?.[inputFileKey])
@@ -407,6 +407,10 @@ export interface ChatModelOutput extends Message {
407
407
  * Text format response content
408
408
  */
409
409
  text?: string;
410
+ /**
411
+ * Model's internal thoughts (if supported)
412
+ */
413
+ thoughts?: string;
410
414
  /**
411
415
  * JSON format response content
412
416
  */
@@ -5,6 +5,7 @@ import { type ImageModelOutput } from "./image-model.js";
5
5
  import { type FileType } from "./model.js";
6
6
  export interface ImageAgentOptions<I extends Message = any, O extends ImageModelOutput = any> extends Omit<AgentOptions<I, O>, "outputSchema"> {
7
7
  instructions: string | PromptBuilder;
8
+ inputFileKey?: string;
8
9
  modelOptions?: Record<string, any>;
9
10
  outputFileType?: FileType;
10
11
  }
@@ -16,6 +17,7 @@ export declare class ImageAgent<I extends Message = any, O extends ImageModelOut
16
17
  static from<I extends Message = any, O extends ImageModelOutput = any>(options: ImageAgentOptions<I, O>): ImageAgent<I, O>;
17
18
  constructor(options: ImageAgentOptions<I, O>);
18
19
  instructions: PromptBuilder;
20
+ inputFileKey?: string;
19
21
  modelOptions?: Record<string, any>;
20
22
  outputFileType?: FileType;
21
23
  process(input: I, options: AgentInvokeOptions): Promise<O>;
@@ -6,7 +6,7 @@ import type { UserAgent } from "../agents/user-agent.js";
6
6
  import { type LoadOptions } from "../loader/index.js";
7
7
  import { AIGNEContext, type Context, type InvokeOptions, type UserContext } from "./context.js";
8
8
  import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
9
- import type { AIGNECLIAgents } from "./type.js";
9
+ import type { AIGNECLIAgents, AIGNEMetadata } from "./type.js";
10
10
  import type { ContextLimits } from "./usage.js";
11
11
  /**
12
12
  * Options for the AIGNE class.
@@ -53,6 +53,7 @@ export interface AIGNEOptions {
53
53
  * Observer for the AIGNE instance.
54
54
  */
55
55
  observer?: AIGNEObserver;
56
+ metadata?: AIGNEMetadata;
56
57
  }
57
58
  /**
58
59
  * AIGNE is a class that orchestrates multiple agents to build complex AI applications.
@@ -136,6 +137,10 @@ export declare class AIGNE<U extends UserContext = UserContext> {
136
137
  * Observer for the AIGNE instance.
137
138
  */
138
139
  readonly observer?: AIGNEObserver;
140
+ /**
141
+ * Metadata for the AIGNE instance.
142
+ */
143
+ readonly metadata: AIGNEMetadata;
139
144
  /**
140
145
  * Adds one or more agents to this AIGNE instance.
141
146
  * Each agent is attached to this AIGNE instance, allowing it to access the AIGNE's resources.
@@ -9,6 +9,7 @@ import type { Memory } from "../memory/memory.js";
9
9
  import { type OmitPropertiesFromArrayFirstElement } from "../utils/type-utils.js";
10
10
  import type { Args, Listener, TypedEventEmitter } from "../utils/typed-event-emitter.js";
11
11
  import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
12
+ import type { AIGNEMetadata } from "./type.js";
12
13
  import { type ContextLimits, type ContextUsage } from "./usage.js";
13
14
  /**
14
15
  * @hidden
@@ -78,6 +79,7 @@ export interface Context<U extends UserContext = UserContext> extends TypedEvent
78
79
  skills?: Agent[];
79
80
  agents: Agent[];
80
81
  observer?: AIGNEObserver;
82
+ metadata?: AIGNEMetadata;
81
83
  span?: Span;
82
84
  usage: ContextUsage;
83
85
  limits?: ContextLimits;
@@ -187,7 +189,7 @@ export declare class AIGNEContext implements Context {
187
189
  }
188
190
  declare class AIGNEContextShared {
189
191
  private readonly parent?;
190
- constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer"> & {
192
+ constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer" | "metadata"> & {
191
193
  messageQueue?: MessageQueue;
192
194
  events?: Emitter<any>;
193
195
  }) | undefined);
@@ -198,6 +200,7 @@ declare class AIGNEContextShared {
198
200
  get skills(): Agent<any, any>[] | undefined;
199
201
  get agents(): Agent<any, any>[];
200
202
  get observer(): AIGNEObserver | undefined;
203
+ get metadata(): AIGNEMetadata | undefined;
201
204
  get limits(): ContextLimits | undefined;
202
205
  usage: ContextUsage;
203
206
  userContext: Context["userContext"];
@@ -10,3 +10,17 @@ export interface AIGNECLIAgent {
10
10
  description?: string;
11
11
  agents?: AIGNECLIAgent[];
12
12
  }
13
+ export interface AIGNEMetadata {
14
+ /**
15
+ * CLI version (e.g., "1.51.0")
16
+ */
17
+ cliVersion?: string;
18
+ /**
19
+ * Application name (e.g., "docsmith", "websmith")
20
+ */
21
+ appName?: string;
22
+ /**
23
+ * Application version (e.g., "2.3.4")
24
+ */
25
+ appVersion?: string;
26
+ }
@@ -59,6 +59,7 @@ export interface AIAgentSchema extends BaseAgentSchema {
59
59
  inputKey?: string;
60
60
  inputFileKey?: string;
61
61
  outputKey?: string;
62
+ outputFileKey?: string;
62
63
  toolChoice?: AIAgentToolChoice;
63
64
  toolCallsConcurrency?: number;
64
65
  keepTextInToolUses?: boolean;
@@ -66,6 +67,7 @@ export interface AIAgentSchema extends BaseAgentSchema {
66
67
  export interface ImageAgentSchema extends BaseAgentSchema {
67
68
  type: "image";
68
69
  instructions: Instructions;
70
+ inputFileKey?: string;
69
71
  modelOptions?: Record<string, any>;
70
72
  }
71
73
  export interface MCPAgentSchema extends BaseAgentSchema {
@@ -2,6 +2,8 @@ import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
2
  import { Agent, type AgentInvokeOptions, type Message } from "../agents/agent.js";
3
3
  import { type AIAgent } from "../agents/ai-agent.js";
4
4
  import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
5
+ import type { ImageAgent } from "../agents/image-agent.js";
6
+ import { type FileUnionContent } from "../agents/model.js";
5
7
  import { ChatMessagesTemplate } from "./template.js";
6
8
  export interface PromptBuilderOptions {
7
9
  instructions?: string | ChatMessagesTemplate;
@@ -27,9 +29,13 @@ export declare class PromptBuilder {
27
29
  build(options: PromptBuildOptions): Promise<ChatModelInput & {
28
30
  toolAgents?: Agent[];
29
31
  }>;
30
- buildImagePrompt(options: Pick<PromptBuildOptions, "input">): Promise<{
32
+ buildImagePrompt(options: Pick<PromptBuildOptions, "input" | "context"> & {
33
+ agent: ImageAgent;
34
+ }): Promise<{
31
35
  prompt: string;
36
+ image?: FileUnionContent[];
32
37
  }>;
38
+ private getTemplateVariables;
33
39
  private buildMessages;
34
40
  private refineMessages;
35
41
  private convertMemoriesToMessages;
@@ -407,6 +407,10 @@ export interface ChatModelOutput extends Message {
407
407
  * Text format response content
408
408
  */
409
409
  text?: string;
410
+ /**
411
+ * Model's internal thoughts (if supported)
412
+ */
413
+ thoughts?: string;
410
414
  /**
411
415
  * JSON format response content
412
416
  */
@@ -2,6 +2,7 @@ import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
2
2
  import { z } from "zod";
3
3
  import { convertJsonSchemaToZod } from "zod-from-json-schema";
4
4
  import { wrapAutoParseJsonSchema } from "../utils/json-schema.js";
5
+ import { logger } from "../utils/logger.js";
5
6
  import { checkArguments, isNil, omitByDeep } from "../utils/type-utils.js";
6
7
  import { agentOptionsSchema, } from "./agent.js";
7
8
  import { fileContentSchema, fileUnionContentSchema, localContentSchema, Model, urlContentSchema, } from "./model.js";
@@ -178,7 +179,10 @@ export class ChatModel extends Model {
178
179
  */
179
180
  async postprocess(input, output, options) {
180
181
  super.postprocess(input, output, options);
181
- const { usage } = output;
182
+ const { usage, thoughts, model } = output;
183
+ if (thoughts) {
184
+ logger.info(`Model Thoughts (${model}): ${thoughts}`);
185
+ }
182
186
  if (usage) {
183
187
  options.context.usage.outputTokens += usage.outputTokens;
184
188
  options.context.usage.inputTokens += usage.inputTokens;
@@ -322,6 +326,7 @@ export const chatModelOutputUsageSchema = z.object({
322
326
  });
323
327
  const chatModelOutputSchema = z.object({
324
328
  text: z.string().optional(),
329
+ thoughts: z.string().optional(),
325
330
  json: z.record(z.string(), z.unknown()).optional(),
326
331
  toolCalls: z.array(chatModelOutputToolCallSchema).optional(),
327
332
  usage: chatModelOutputUsageSchema.optional(),
@@ -5,6 +5,7 @@ import { type ImageModelOutput } from "./image-model.js";
5
5
  import { type FileType } from "./model.js";
6
6
  export interface ImageAgentOptions<I extends Message = any, O extends ImageModelOutput = any> extends Omit<AgentOptions<I, O>, "outputSchema"> {
7
7
  instructions: string | PromptBuilder;
8
+ inputFileKey?: string;
8
9
  modelOptions?: Record<string, any>;
9
10
  outputFileType?: FileType;
10
11
  }
@@ -16,6 +17,7 @@ export declare class ImageAgent<I extends Message = any, O extends ImageModelOut
16
17
  static from<I extends Message = any, O extends ImageModelOutput = any>(options: ImageAgentOptions<I, O>): ImageAgent<I, O>;
17
18
  constructor(options: ImageAgentOptions<I, O>);
18
19
  instructions: PromptBuilder;
20
+ inputFileKey?: string;
19
21
  modelOptions?: Record<string, any>;
20
22
  outputFileType?: FileType;
21
23
  process(input: I, options: AgentInvokeOptions): Promise<O>;
@@ -21,17 +21,29 @@ export class ImageAgent extends Agent {
21
21
  typeof options.instructions === "string"
22
22
  ? PromptBuilder.from(options.instructions)
23
23
  : options.instructions;
24
+ this.inputFileKey = options.inputFileKey;
24
25
  this.modelOptions = options.modelOptions;
25
26
  this.outputFileType = options.outputFileType;
26
27
  }
27
28
  instructions;
29
+ inputFileKey;
28
30
  modelOptions;
29
31
  outputFileType;
30
32
  async process(input, options) {
31
33
  const imageModel = this.imageModel || options.imageModel || options.context.imageModel;
32
34
  if (!imageModel)
33
35
  throw new Error("image model is required to run ImageAgent");
34
- const { prompt } = await this.instructions.buildImagePrompt({ input });
35
- return (await this.invokeChildAgent(imageModel, { ...input, modelOptions: this.modelOptions, prompt, outputFileType: this.outputFileType }, { ...options, streaming: false }));
36
+ const { prompt, image } = await this.instructions.buildImagePrompt({
37
+ ...options,
38
+ input,
39
+ agent: this,
40
+ });
41
+ return (await this.invokeChildAgent(imageModel, {
42
+ ...input,
43
+ modelOptions: this.modelOptions,
44
+ prompt,
45
+ image,
46
+ outputFileType: this.outputFileType,
47
+ }, { ...options, streaming: false }));
36
48
  }
37
49
  }
@@ -6,7 +6,7 @@ import type { UserAgent } from "../agents/user-agent.js";
6
6
  import { type LoadOptions } from "../loader/index.js";
7
7
  import { AIGNEContext, type Context, type InvokeOptions, type UserContext } from "./context.js";
8
8
  import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
9
- import type { AIGNECLIAgents } from "./type.js";
9
+ import type { AIGNECLIAgents, AIGNEMetadata } from "./type.js";
10
10
  import type { ContextLimits } from "./usage.js";
11
11
  /**
12
12
  * Options for the AIGNE class.
@@ -53,6 +53,7 @@ export interface AIGNEOptions {
53
53
  * Observer for the AIGNE instance.
54
54
  */
55
55
  observer?: AIGNEObserver;
56
+ metadata?: AIGNEMetadata;
56
57
  }
57
58
  /**
58
59
  * AIGNE is a class that orchestrates multiple agents to build complex AI applications.
@@ -136,6 +137,10 @@ export declare class AIGNE<U extends UserContext = UserContext> {
136
137
  * Observer for the AIGNE instance.
137
138
  */
138
139
  readonly observer?: AIGNEObserver;
140
+ /**
141
+ * Metadata for the AIGNE instance.
142
+ */
143
+ readonly metadata: AIGNEMetadata;
139
144
  /**
140
145
  * Adds one or more agents to this AIGNE instance.
141
146
  * Each agent is attached to this AIGNE instance, allowing it to access the AIGNE's resources.
@@ -34,6 +34,7 @@ export class AIGNE {
34
34
  imageModel,
35
35
  agents: agents.concat(options?.agents ?? []),
36
36
  skills: skills.concat(options?.skills ?? []),
37
+ metadata: options?.metadata,
37
38
  });
38
39
  }
39
40
  /**
@@ -63,6 +64,7 @@ export class AIGNE {
63
64
  this.cli = options?.cli ?? {};
64
65
  this.observer?.serve();
65
66
  this.initProcessExitHandler();
67
+ this.metadata = options?.metadata ?? {};
66
68
  }
67
69
  /**
68
70
  * Optional root directory for this AIGNE instance.
@@ -112,6 +114,10 @@ export class AIGNE {
112
114
  * Observer for the AIGNE instance.
113
115
  */
114
116
  observer;
117
+ /**
118
+ * Metadata for the AIGNE instance.
119
+ */
120
+ metadata = {};
115
121
  /**
116
122
  * Adds one or more agents to this AIGNE instance.
117
123
  * Each agent is attached to this AIGNE instance, allowing it to access the AIGNE's resources.
@@ -9,6 +9,7 @@ import type { Memory } from "../memory/memory.js";
9
9
  import { type OmitPropertiesFromArrayFirstElement } from "../utils/type-utils.js";
10
10
  import type { Args, Listener, TypedEventEmitter } from "../utils/typed-event-emitter.js";
11
11
  import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
12
+ import type { AIGNEMetadata } from "./type.js";
12
13
  import { type ContextLimits, type ContextUsage } from "./usage.js";
13
14
  /**
14
15
  * @hidden
@@ -78,6 +79,7 @@ export interface Context<U extends UserContext = UserContext> extends TypedEvent
78
79
  skills?: Agent[];
79
80
  agents: Agent[];
80
81
  observer?: AIGNEObserver;
82
+ metadata?: AIGNEMetadata;
81
83
  span?: Span;
82
84
  usage: ContextUsage;
83
85
  limits?: ContextLimits;
@@ -187,7 +189,7 @@ export declare class AIGNEContext implements Context {
187
189
  }
188
190
  declare class AIGNEContextShared {
189
191
  private readonly parent?;
190
- constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer"> & {
192
+ constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer" | "metadata"> & {
191
193
  messageQueue?: MessageQueue;
192
194
  events?: Emitter<any>;
193
195
  }) | undefined);
@@ -198,6 +200,7 @@ declare class AIGNEContextShared {
198
200
  get skills(): Agent<any, any>[] | undefined;
199
201
  get agents(): Agent<any, any>[];
200
202
  get observer(): AIGNEObserver | undefined;
203
+ get metadata(): AIGNEMetadata | undefined;
201
204
  get limits(): ContextLimits | undefined;
202
205
  usage: ContextUsage;
203
206
  userContext: Context["userContext"];
@@ -211,6 +211,7 @@ export class AIGNEContext {
211
211
  if (this.parentId) {
212
212
  span.setAttribute("custom.parent_id", this.parentId);
213
213
  }
214
+ span.setAttribute("metadata", JSON.stringify(this.internal.metadata ?? {}));
214
215
  span.setAttribute("custom.started_at", b.timestamp);
215
216
  span.setAttribute("input", JSON.stringify(input));
216
217
  span.setAttribute("agentTag", agent.tag ?? "UnknownAgent");
@@ -293,6 +294,9 @@ class AIGNEContextShared {
293
294
  get observer() {
294
295
  return this.parent?.observer;
295
296
  }
297
+ get metadata() {
298
+ return this.parent?.metadata;
299
+ }
296
300
  get limits() {
297
301
  return this.parent?.limits;
298
302
  }
@@ -10,3 +10,17 @@ export interface AIGNECLIAgent {
10
10
  description?: string;
11
11
  agents?: AIGNECLIAgent[];
12
12
  }
13
+ export interface AIGNEMetadata {
14
+ /**
15
+ * CLI version (e.g., "1.51.0")
16
+ */
17
+ cliVersion?: string;
18
+ /**
19
+ * Application name (e.g., "docsmith", "websmith")
20
+ */
21
+ appName?: string;
22
+ /**
23
+ * Application version (e.g., "2.3.4")
24
+ */
25
+ appVersion?: string;
26
+ }
@@ -59,6 +59,7 @@ export interface AIAgentSchema extends BaseAgentSchema {
59
59
  inputKey?: string;
60
60
  inputFileKey?: string;
61
61
  outputKey?: string;
62
+ outputFileKey?: string;
62
63
  toolChoice?: AIAgentToolChoice;
63
64
  toolCallsConcurrency?: number;
64
65
  keepTextInToolUses?: boolean;
@@ -66,6 +67,7 @@ export interface AIAgentSchema extends BaseAgentSchema {
66
67
  export interface ImageAgentSchema extends BaseAgentSchema {
67
68
  type: "image";
68
69
  instructions: Instructions;
70
+ inputFileKey?: string;
69
71
  modelOptions?: Record<string, any>;
70
72
  }
71
73
  export interface MCPAgentSchema extends BaseAgentSchema {
@@ -124,6 +124,7 @@ export async function parseAgentFile(path, data) {
124
124
  .object({
125
125
  type: z.literal("image"),
126
126
  instructions: instructionsSchema,
127
+ inputFileKey: optionalize(z.string()),
127
128
  modelOptions: optionalize(camelizeSchema(z.record(z.any()))),
128
129
  })
129
130
  .extend(baseAgentSchema.shape),
@@ -2,6 +2,8 @@ import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
2
  import { Agent, type AgentInvokeOptions, type Message } from "../agents/agent.js";
3
3
  import { type AIAgent } from "../agents/ai-agent.js";
4
4
  import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
5
+ import type { ImageAgent } from "../agents/image-agent.js";
6
+ import { type FileUnionContent } from "../agents/model.js";
5
7
  import { ChatMessagesTemplate } from "./template.js";
6
8
  export interface PromptBuilderOptions {
7
9
  instructions?: string | ChatMessagesTemplate;
@@ -27,9 +29,13 @@ export declare class PromptBuilder {
27
29
  build(options: PromptBuildOptions): Promise<ChatModelInput & {
28
30
  toolAgents?: Agent[];
29
31
  }>;
30
- buildImagePrompt(options: Pick<PromptBuildOptions, "input">): Promise<{
32
+ buildImagePrompt(options: Pick<PromptBuildOptions, "input" | "context"> & {
33
+ agent: ImageAgent;
34
+ }): Promise<{
31
35
  prompt: string;
36
+ image?: FileUnionContent[];
32
37
  }>;
38
+ private getTemplateVariables;
33
39
  private buildMessages;
34
40
  private refineMessages;
35
41
  private convertMemoriesToMessages;
@@ -75,9 +75,21 @@ export class PromptBuilder {
75
75
  async buildImagePrompt(options) {
76
76
  const messages = (await (typeof this.instructions === "string"
77
77
  ? ChatMessagesTemplate.from([SystemMessageTemplate.from(this.instructions)])
78
- : this.instructions)?.format(options.input, { workingDir: this.workingDir })) ?? [];
78
+ : this.instructions)?.format(this.getTemplateVariables(options), { workingDir: this.workingDir })) ?? [];
79
+ const inputFileKey = options.agent?.inputFileKey;
80
+ const files = flat(inputFileKey
81
+ ? checkArguments("Check input files", optionalize(fileUnionContentsSchema), options.input?.[inputFileKey])
82
+ : null);
79
83
  return {
80
84
  prompt: messages.map((i) => i.content).join("\n"),
85
+ image: files.length ? files : undefined,
86
+ };
87
+ }
88
+ getTemplateVariables(options) {
89
+ return {
90
+ userContext: options.context?.userContext,
91
+ ...options.context?.userContext,
92
+ ...options.input,
81
93
  };
82
94
  }
83
95
  async buildMessages(options) {
@@ -86,7 +98,7 @@ export class PromptBuilder {
86
98
  const message = inputKey && typeof input?.[inputKey] === "string" ? input[inputKey] : undefined;
87
99
  const [messages, otherCustomMessages] = partition((await (typeof this.instructions === "string"
88
100
  ? ChatMessagesTemplate.from([SystemMessageTemplate.from(this.instructions)])
89
- : this.instructions)?.format(options.input, { workingDir: this.workingDir })) ?? [], (i) => i.role === "system");
101
+ : this.instructions)?.format(this.getTemplateVariables(options), { workingDir: this.workingDir })) ?? [], (i) => i.role === "system");
90
102
  const inputFileKey = options.agent?.inputFileKey;
91
103
  const files = flat(inputFileKey
92
104
  ? checkArguments("Check input files", optionalize(fileUnionContentsSchema), input?.[inputFileKey])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.63.0",
3
+ "version": "1.64.0-beta",
4
4
  "description": "The functional core of agentic AI",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -91,9 +91,9 @@
91
91
  "zod": "^3.25.67",
92
92
  "zod-from-json-schema": "^0.0.5",
93
93
  "zod-to-json-schema": "^3.24.6",
94
- "@aigne/afs": "^1.1.0",
95
- "@aigne/observability-api": "^0.11.2",
96
- "@aigne/platform-helpers": "^0.6.3"
94
+ "@aigne/observability-api": "^0.11.3-beta",
95
+ "@aigne/platform-helpers": "^0.6.3",
96
+ "@aigne/afs": "^1.1.0"
97
97
  },
98
98
  "devDependencies": {
99
99
  "@types/bun": "^1.2.22",