@aigne/core 1.59.0 → 1.60.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/lib/cjs/agents/agent.d.ts +9 -0
  3. package/lib/cjs/agents/agent.js +13 -3
  4. package/lib/cjs/agents/ai-agent.d.ts +0 -12
  5. package/lib/cjs/agents/ai-agent.js +4 -11
  6. package/lib/cjs/agents/chat-model.d.ts +1 -1
  7. package/lib/cjs/agents/chat-model.js +1 -0
  8. package/lib/cjs/agents/image-agent.d.ts +1 -3
  9. package/lib/cjs/agents/image-agent.js +3 -6
  10. package/lib/cjs/agents/image-model.d.ts +1 -1
  11. package/lib/cjs/agents/team-agent.js +6 -3
  12. package/lib/cjs/agents/user-agent.js +2 -1
  13. package/lib/cjs/aigne/context.js +2 -0
  14. package/lib/cjs/loader/agent-yaml.d.ts +5 -2
  15. package/lib/cjs/loader/agent-yaml.js +6 -1
  16. package/lib/cjs/loader/index.d.ts +23 -33
  17. package/lib/cjs/loader/index.js +12 -24
  18. package/lib/cjs/loader/schema.d.ts +29 -0
  19. package/lib/cjs/loader/schema.js +21 -1
  20. package/lib/dts/agents/agent.d.ts +9 -0
  21. package/lib/dts/agents/ai-agent.d.ts +0 -12
  22. package/lib/dts/agents/chat-model.d.ts +1 -1
  23. package/lib/dts/agents/image-agent.d.ts +1 -3
  24. package/lib/dts/agents/image-model.d.ts +1 -1
  25. package/lib/dts/loader/agent-yaml.d.ts +5 -2
  26. package/lib/dts/loader/index.d.ts +23 -33
  27. package/lib/dts/loader/schema.d.ts +29 -0
  28. package/lib/esm/agents/agent.d.ts +9 -0
  29. package/lib/esm/agents/agent.js +13 -3
  30. package/lib/esm/agents/ai-agent.d.ts +0 -12
  31. package/lib/esm/agents/ai-agent.js +4 -11
  32. package/lib/esm/agents/chat-model.d.ts +1 -1
  33. package/lib/esm/agents/chat-model.js +1 -0
  34. package/lib/esm/agents/image-agent.d.ts +1 -3
  35. package/lib/esm/agents/image-agent.js +3 -6
  36. package/lib/esm/agents/image-model.d.ts +1 -1
  37. package/lib/esm/agents/team-agent.js +6 -3
  38. package/lib/esm/agents/user-agent.js +2 -1
  39. package/lib/esm/aigne/context.js +2 -0
  40. package/lib/esm/loader/agent-yaml.d.ts +5 -2
  41. package/lib/esm/loader/agent-yaml.js +7 -2
  42. package/lib/esm/loader/index.d.ts +23 -33
  43. package/lib/esm/loader/index.js +14 -26
  44. package/lib/esm/loader/schema.d.ts +29 -0
  45. package/lib/esm/loader/schema.js +20 -0
  46. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.60.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.60.0...core-v1.60.1) (2025-09-11)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * dependencies
10
+ * @aigne/observability-api bumped to 0.10.4
11
+
12
+ ## [1.60.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.59.0...core-v1.60.0) (2025-09-10)
13
+
14
+
15
+ ### Features
16
+
17
+ * support custom model for every agents ([#472](https://github.com/AIGNE-io/aigne-framework/issues/472)) ([0bda78a](https://github.com/AIGNE-io/aigne-framework/commit/0bda78a2ebf537e953d855882d68cb37d94d1d10))
18
+
19
+
20
+ ### Dependencies
21
+
22
+ * The following workspace dependencies were updated
23
+ * dependencies
24
+ * @aigne/observability-api bumped to 0.10.3
25
+
3
26
  ## [1.59.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.58.3...core-v1.59.0) (2025-09-09)
4
27
 
5
28
 
@@ -8,7 +8,9 @@ import type { Memory, MemoryAgent } from "../memory/memory.js";
8
8
  import type { MemoryRecorderInput } from "../memory/recorder.js";
9
9
  import type { MemoryRetrieverInput } from "../memory/retriever.js";
10
10
  import { type Nullish, type PromiseOrValue, type XOr } from "../utils/type-utils.js";
11
+ import type { ChatModel } from "./chat-model.js";
11
12
  import type { GuideRailAgent, GuideRailAgentOutput } from "./guide-rail-agent.js";
13
+ import type { ImageModel } from "./image-model.js";
12
14
  import { type TransferAgentOutput } from "./types.js";
13
15
  export * from "./types.js";
14
16
  export declare const DEFAULT_INPUT_ACTION_GET = "$get";
@@ -73,6 +75,8 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
73
75
  * for documentation and debugging
74
76
  */
75
77
  description?: string;
78
+ model?: ChatModel;
79
+ imageModel?: ImageModel;
76
80
  taskTitle?: string | ((input: I) => PromiseOrValue<string | undefined>);
77
81
  taskRenderMode?: TaskRenderMode;
78
82
  /**
@@ -142,6 +146,8 @@ export interface AgentInvokeOptions<U extends UserContext = UserContext> {
142
146
  * agent system and maintain proper isolation and resource control.
143
147
  */
144
148
  context: Context<U>;
149
+ model?: ChatModel;
150
+ imageModel?: ImageModel;
145
151
  /**
146
152
  * Whether to enable streaming response
147
153
  *
@@ -269,6 +275,8 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
269
275
  * each other's roles in a multi-agent system
270
276
  */
271
277
  readonly description?: string;
278
+ model?: ChatModel;
279
+ imageModel?: ImageModel;
272
280
  taskTitle?: string | ((input: Message) => PromiseOrValue<string | undefined>);
273
281
  renderTaskTitle(input: I): Promise<string | undefined>;
274
282
  taskRenderMode?: TaskRenderMode;
@@ -422,6 +430,7 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
422
430
  private callHooks;
423
431
  private mergeDefaultInput;
424
432
  protected invokeSkill<I extends Message, O extends Message>(skill: Agent<I, O>, input: I & Message, options: AgentInvokeOptions): Promise<O>;
433
+ protected invokeChildAgent: Context["invoke"];
425
434
  /**
426
435
  * Process agent output
427
436
  *
@@ -128,6 +128,8 @@ class Agent {
128
128
  this.name = options.name || this.constructor.name;
129
129
  this.alias = options.alias;
130
130
  this.description = options.description;
131
+ this.model = options.model;
132
+ this.imageModel = options.imageModel;
131
133
  this.taskTitle = options.taskTitle;
132
134
  this.taskRenderMode = options.taskRenderMode;
133
135
  if (inputSchema)
@@ -228,6 +230,8 @@ class Agent {
228
230
  * each other's roles in a multi-agent system
229
231
  */
230
232
  description;
233
+ model;
234
+ imageModel;
231
235
  taskTitle;
232
236
  async renderTaskTitle(input) {
233
237
  if (!this.taskTitle)
@@ -493,10 +497,9 @@ class Agent {
493
497
  return input;
494
498
  }
495
499
  async invokeSkill(skill, input, options) {
496
- const { context } = options;
497
500
  await this.callHooks("onSkillStart", { skill, input }, options);
498
501
  try {
499
- const output = await context.invoke(skill, input);
502
+ const output = await this.invokeChildAgent(skill, input, { ...options, streaming: false });
500
503
  await this.callHooks("onSkillEnd", { skill, input, output }, options);
501
504
  return output;
502
505
  }
@@ -505,6 +508,13 @@ class Agent {
505
508
  throw error;
506
509
  }
507
510
  }
511
+ invokeChildAgent = ((agent, input, options) => {
512
+ return options.context.invoke(agent, input, {
513
+ ...options,
514
+ model: this.model || options.model,
515
+ imageModel: this.imageModel || options.imageModel,
516
+ });
517
+ });
508
518
  /**
509
519
  * Process agent output
510
520
  *
@@ -599,7 +609,7 @@ class Agent {
599
609
  return { ...(await this.onGuideRailError(error)), $status: "GuideRailError" };
600
610
  }
601
611
  async runGuideRails(input, output, options) {
602
- const result = await Promise.all((this.guideRails ?? []).map((i) => options.context.invoke(i, { input, output })));
612
+ const result = await Promise.all((this.guideRails ?? []).map((i) => this.invokeChildAgent(i, { input, output }, { ...options, streaming: false })));
603
613
  return result.find((i) => !!i.abort);
604
614
  }
605
615
  /**
@@ -15,12 +15,6 @@ export declare const DEFAULT_FILE_OUTPUT_KEY = "files";
15
15
  * @template O The output message type the agent returns
16
16
  */
17
17
  export interface AIAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
18
- /**
19
- * The language model to use for this agent
20
- *
21
- * If not provided, the agent will use the model from the context
22
- */
23
- model?: ChatModel;
24
18
  /**
25
19
  * Instructions to guide the AI model's behavior
26
20
  *
@@ -200,12 +194,6 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
200
194
  * @param options Configuration options for the AI agent
201
195
  */
202
196
  constructor(options: AIAgentOptions<I, O>);
203
- /**
204
- * The language model used by this agent
205
- *
206
- * If not set on the agent, the model from the context will be used
207
- */
208
- model?: ChatModel;
209
197
  /**
210
198
  * Instructions for the language model
211
199
  *
@@ -106,7 +106,6 @@ class AIAgent extends agent_js_1.Agent {
106
106
  constructor(options) {
107
107
  super(options);
108
108
  (0, type_utils_js_1.checkArguments)("AIAgent", exports.aiAgentOptionsSchema, options);
109
- this.model = options.model;
110
109
  this.instructions =
111
110
  typeof options.instructions === "string"
112
111
  ? prompt_builder_js_1.PromptBuilder.from(options.instructions)
@@ -134,12 +133,6 @@ class AIAgent extends agent_js_1.Agent {
134
133
  throw new Error("AIAgent requires either inputKey or instructions to be set");
135
134
  }
136
135
  }
137
- /**
138
- * The language model used by this agent
139
- *
140
- * If not set on the agent, the model from the context will be used
141
- */
142
- model;
143
136
  /**
144
137
  * Instructions for the language model
145
138
  *
@@ -237,7 +230,7 @@ class AIAgent extends agent_js_1.Agent {
237
230
  * @protected
238
231
  */
239
232
  async *process(input, options) {
240
- const model = this.model ?? options.context.model;
233
+ const model = this.model || options.model || options.context.model;
241
234
  if (!model)
242
235
  throw new Error("model is required to run AIAgent");
243
236
  const { toolAgents, ...modelInput } = await this.instructions.build({
@@ -254,7 +247,7 @@ class AIAgent extends agent_js_1.Agent {
254
247
  const outputKey = this.outputKey;
255
248
  for (;;) {
256
249
  const modelOutput = {};
257
- let stream = await options.context.invoke(model, { ...modelInput, messages: modelInput.messages.concat(toolCallMessages) }, { ...options, streaming: true });
250
+ let stream = await this.invokeChildAgent(model, { ...modelInput, messages: modelInput.messages.concat(toolCallMessages) }, { ...options, streaming: true });
258
251
  if (this.structuredStreamMode) {
259
252
  const { metadataStart, metadataEnd, parse } = this.customStructuredStreamInstructions || structured_stream_instructions_js_1.STRUCTURED_STREAM_INSTRUCTIONS;
260
253
  stream = stream.pipeThrough(new structured_stream_extractor_js_1.ExtractMetadataTransform({ start: metadataStart, end: metadataEnd, parse }));
@@ -339,7 +332,7 @@ class AIAgent extends agent_js_1.Agent {
339
332
  * @protected
340
333
  */
341
334
  async *_processRouter(input, model, modelInput, options, toolsMap) {
342
- const { toolCalls: [call] = [] } = await options.context.invoke(model, modelInput, {
335
+ const { toolCalls: [call] = [] } = await this.invokeChildAgent(model, modelInput, {
343
336
  ...options,
344
337
  streaming: false,
345
338
  });
@@ -349,7 +342,7 @@ class AIAgent extends agent_js_1.Agent {
349
342
  const tool = toolsMap.get(call.function.name);
350
343
  if (!tool)
351
344
  throw new Error(`Tool not found: ${call.function.name}`);
352
- const stream = await options.context.invoke(tool, { ...call.function.arguments, ...input }, { ...options, streaming: true, sourceAgent: this });
345
+ const stream = await this.invokeChildAgent(tool, { ...call.function.arguments, ...input }, { ...options, streaming: true, sourceAgent: this });
353
346
  return yield* stream;
354
347
  }
355
348
  }
@@ -3,7 +3,7 @@ import { type PromiseOrValue } from "../utils/type-utils.js";
3
3
  import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type AgentResponse, type AgentResponseStream, type Message } from "./agent.js";
4
4
  export declare class StructuredOutputError extends Error {
5
5
  }
6
- export interface ChatModelOptions extends Omit<AgentOptions<ChatModelInput, ChatModelOutput>, "inputSchema" | "outputSchema"> {
6
+ export interface ChatModelOptions extends Omit<AgentOptions<ChatModelInput, ChatModelOutput>, "model" | "inputSchema" | "outputSchema"> {
7
7
  model?: string;
8
8
  modelOptions?: Omit<ModelOptions, "model">;
9
9
  }
@@ -94,6 +94,7 @@ class ChatModel extends agent_js_1.Agent {
94
94
  inputSchema: chatModelInputSchema,
95
95
  outputSchema: chatModelOutputSchema,
96
96
  retryOnError,
97
+ model: undefined,
97
98
  });
98
99
  this.options = options;
99
100
  }
@@ -1,9 +1,8 @@
1
1
  import { type ZodObject, type ZodType } from "zod";
2
2
  import { PromptBuilder } from "../prompt/prompt-builder.js";
3
3
  import { Agent, type AgentInvokeOptions, type AgentOptions, type Message } from "./agent.js";
4
- import { type ImageModel, type ImageModelOutput } from "./image-model.js";
4
+ import { type ImageModelOutput } from "./image-model.js";
5
5
  export interface ImageAgentOptions<I extends Message = any, O extends ImageModelOutput = any> extends Omit<AgentOptions<I, O>, "outputSchema"> {
6
- model?: ImageModel;
7
6
  instructions: string | PromptBuilder;
8
7
  modelOptions?: Record<string, any>;
9
8
  }
@@ -14,7 +13,6 @@ export declare class ImageAgent<I extends Message = any, O extends ImageModelOut
14
13
  tag: string;
15
14
  static from<I extends Message = any, O extends ImageModelOutput = any>(options: ImageAgentOptions<I, O>): ImageAgent<I, O>;
16
15
  constructor(options: ImageAgentOptions<I, O>);
17
- model?: ImageModel;
18
16
  instructions: PromptBuilder;
19
17
  modelOptions?: Record<string, any>;
20
18
  process(input: I, options: AgentInvokeOptions): Promise<O>;
@@ -10,7 +10,6 @@ const type_utils_js_1 = require("../utils/type-utils.js");
10
10
  const agent_js_1 = require("./agent.js");
11
11
  const image_model_js_1 = require("./image-model.js");
12
12
  exports.imageAgentOptionsSchema = agent_js_1.agentOptionsSchema.extend({
13
- model: zod_1.default.custom().optional(),
14
13
  instructions: zod_1.default.union([zod_1.default.string(), zod_1.default.custom()]),
15
14
  modelOptions: zod_1.default.record(zod_1.default.any()).optional(),
16
15
  });
@@ -22,22 +21,20 @@ class ImageAgent extends agent_js_1.Agent {
22
21
  constructor(options) {
23
22
  super({ ...options, outputSchema: image_model_js_1.imageModelOutputSchema });
24
23
  (0, type_utils_js_1.checkArguments)("ImageAgent", exports.imageAgentOptionsSchema, options);
25
- this.model = options.model;
26
24
  this.instructions =
27
25
  typeof options.instructions === "string"
28
26
  ? prompt_builder_js_1.PromptBuilder.from(options.instructions)
29
27
  : options.instructions;
30
28
  this.modelOptions = options.modelOptions;
31
29
  }
32
- model;
33
30
  instructions;
34
31
  modelOptions;
35
32
  async process(input, options) {
36
- const model = this.model ?? options.context.imageModel;
37
- if (!model)
33
+ const imageModel = this.imageModel || options.imageModel || options.context.imageModel;
34
+ if (!imageModel)
38
35
  throw new Error("image model is required to run ImageAgent");
39
36
  const { prompt } = await this.instructions.buildImagePrompt({ input });
40
- return (await options.context.invoke(model, { ...input, ...this.modelOptions, prompt }, { ...options, streaming: false }));
37
+ return (await this.invokeChildAgent(imageModel, { ...input, ...this.modelOptions, prompt }, { ...options, streaming: false }));
41
38
  }
42
39
  }
43
40
  exports.ImageAgent = ImageAgent;
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import type { PromiseOrValue } from "../utils/type-utils.js";
3
3
  import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type Message } from "./agent.js";
4
4
  import { type ChatModelOutputUsage } from "./chat-model.js";
5
- export interface ImageModelOptions<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends AgentOptions<I, O> {
5
+ export interface ImageModelOptions<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends Omit<AgentOptions<I, O>, "model"> {
6
6
  }
7
7
  export declare abstract class ImageModel<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends Agent<I, O> {
8
8
  tag: string;
@@ -177,7 +177,10 @@ class TeamAgent extends agent_js_1.Agent {
177
177
  for (;;) {
178
178
  const output = await (0, agent_js_1.agentProcessResultToObject)(await this._processNonReflection(previousOutput, options));
179
179
  Object.assign(previousOutput, output);
180
- const reviewOutput = await options.context.invoke(this.reflection.reviewer, previousOutput);
180
+ const reviewOutput = await this.invokeChildAgent(this.reflection.reviewer, previousOutput, {
181
+ ...options,
182
+ streaming: false,
183
+ });
181
184
  Object.assign(previousOutput, reviewOutput);
182
185
  const { isApproved } = this.reflection;
183
186
  const approved = typeof isApproved === "string" ? reviewOutput[isApproved] : await isApproved(reviewOutput);
@@ -252,7 +255,7 @@ class TeamAgent extends agent_js_1.Agent {
252
255
  async *_processSequential(input, options) {
253
256
  const output = {};
254
257
  for (const agent of this.skills) {
255
- const o = await options.context.invoke(agent, { ...input, ...output }, { ...options, streaming: true });
258
+ const o = await this.invokeChildAgent(agent, { ...input, ...output }, { ...options, streaming: true });
256
259
  const isLast = agent === this.skills[this.skills.length - 1];
257
260
  for await (const chunk of o) {
258
261
  // Only yield the chunk if it is the last agent in the sequence
@@ -278,7 +281,7 @@ class TeamAgent extends agent_js_1.Agent {
278
281
  * @private
279
282
  */
280
283
  async *_processParallel(input, options) {
281
- const streams = await Promise.all(this.skills.map((agent) => options.context.invoke(agent, input, { ...options, streaming: true })));
284
+ const streams = await Promise.all(this.skills.map((agent) => this.invokeChildAgent(agent, input, { ...options, streaming: true })));
282
285
  const read = async (index, reader) => {
283
286
  const promise = reader.read();
284
287
  return promise.then((result) => ({ ...result, reader, index }));
@@ -35,7 +35,8 @@ class UserAgent extends agent_js_1.Agent {
35
35
  return this._process(input, options);
36
36
  }
37
37
  if (this.activeAgent) {
38
- const [output, agent] = await options.context.invoke(this.activeAgent, input, {
38
+ const [output, agent] = await this.invokeChildAgent(this.activeAgent, input, {
39
+ ...options,
39
40
  returnActiveAgent: true,
40
41
  streaming: true,
41
42
  // Do not create a new context for the nested agent invocation,
@@ -354,6 +354,8 @@ class AIGNEContextShared {
354
354
  hooks: options.hooks,
355
355
  context,
356
356
  streaming: true,
357
+ model: options.model,
358
+ imageModel: options.imageModel,
357
359
  });
358
360
  for await (const value of stream) {
359
361
  if ((0, agent_js_1.isAgentResponseDelta)(value)) {
@@ -1,7 +1,8 @@
1
- import { type ZodType } from "zod";
1
+ import { type ZodType, z } from "zod";
2
2
  import type { AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
3
3
  import { AIAgentToolChoice } from "../agents/ai-agent.js";
4
4
  import { ProcessMode, type ReflectionMode } from "../agents/team-agent.js";
5
+ import { chatModelSchema, imageModelSchema } from "./schema.js";
5
6
  export interface HooksSchema {
6
7
  priority?: AgentHooks["priority"];
7
8
  onStart?: NestAgentSchema;
@@ -20,6 +21,8 @@ export type NestAgentSchema = string | {
20
21
  export interface BaseAgentSchema {
21
22
  name?: string;
22
23
  description?: string;
24
+ model?: z.infer<typeof chatModelSchema>;
25
+ imageModel?: z.infer<typeof imageModelSchema>;
23
26
  taskTitle?: string;
24
27
  taskRenderMode?: TaskRenderMode;
25
28
  inputSchema?: ZodType<Record<string, any>>;
@@ -74,5 +77,5 @@ export interface FunctionAgentSchema extends BaseAgentSchema {
74
77
  process: FunctionAgentFn;
75
78
  }
76
79
  export type AgentSchema = AIAgentSchema | ImageAgentSchema | MCPAgentSchema | TeamAgentSchema | TransformAgentSchema | FunctionAgentSchema;
77
- export declare function parseAgentFile(path: string, data: object): Promise<AgentSchema>;
80
+ export declare function parseAgentFile(path: string, data: any): Promise<AgentSchema>;
78
81
  export declare function loadAgentFromYamlFile(path: string): Promise<AgentSchema>;
@@ -35,6 +35,8 @@ async function parseAgentFile(path, data) {
35
35
  name: (0, schema_js_1.optionalize)(zod_1.z.string()),
36
36
  alias: (0, schema_js_1.optionalize)(zod_1.z.array(zod_1.z.string())),
37
37
  description: (0, schema_js_1.optionalize)(zod_1.z.string()),
38
+ model: (0, schema_js_1.optionalize)(schema_js_1.chatModelSchema),
39
+ imageModel: (0, schema_js_1.optionalize)(schema_js_1.imageModelSchema),
38
40
  taskTitle: (0, schema_js_1.optionalize)(zod_1.z.string()),
39
41
  taskRenderMode: (0, schema_js_1.optionalize)(zod_1.z.union([zod_1.z.literal("hide"), zod_1.z.literal("collapse")])),
40
42
  inputSchema: (0, schema_js_1.optionalize)((0, schema_js_1.inputOutputSchema)({ path })).transform((v) => v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined),
@@ -118,7 +120,10 @@ async function parseAgentFile(path, data) {
118
120
  .extend(baseAgentSchema.shape),
119
121
  ]));
120
122
  });
121
- return agentSchema.parseAsync(data);
123
+ return agentSchema.parseAsync({
124
+ ...data,
125
+ model: data.model || data.chatModel || data.chat_model,
126
+ });
122
127
  }
123
128
  async function loadAgentFromYamlFile(path) {
124
129
  const raw = await (0, type_utils_js_1.tryOrThrow)(() => index_js_1.nodejs.fs.readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
@@ -9,7 +9,7 @@ export interface LoadOptions {
9
9
  memories?: {
10
10
  new (parameters?: MemoryAgentOptions): MemoryAgent;
11
11
  }[];
12
- model?: ChatModel | ((model?: z.infer<typeof aigneFileSchema>["chatModel"]) => PromiseOrValue<ChatModel | undefined>);
12
+ model?: ChatModel | ((model?: z.infer<typeof aigneFileSchema>["model"]) => PromiseOrValue<ChatModel | undefined>);
13
13
  imageModel?: ImageModel | ((model?: z.infer<typeof aigneFileSchema>["imageModel"]) => PromiseOrValue<ImageModel | undefined>);
14
14
  key?: string | number;
15
15
  }
@@ -18,38 +18,22 @@ export declare function loadAgent(path: string, options?: LoadOptions, agentOpti
18
18
  declare const aigneFileSchema: z.ZodObject<{
19
19
  name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
20
20
  description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
21
- chatModel: z.ZodEffects<z.ZodEffects<z.ZodType<string | {
21
+ model: z.ZodType<{
22
22
  model?: string | undefined;
23
23
  temperature?: number | undefined;
24
24
  topP?: number | undefined;
25
25
  frequencyPenalty?: number | undefined;
26
26
  presencePenalty?: number | undefined;
27
- } | undefined, z.ZodTypeDef, string | {
28
- model?: string | undefined;
29
- temperature?: number | undefined;
30
- topP?: number | undefined;
31
- frequencyPenalty?: number | undefined;
32
- presencePenalty?: number | undefined;
33
- } | undefined>, string | {
34
- model?: string | undefined;
35
- temperature?: number | undefined;
36
- topP?: number | undefined;
37
- frequencyPenalty?: number | undefined;
38
- presencePenalty?: number | undefined;
39
- } | undefined, unknown>, {
27
+ } | undefined, z.ZodTypeDef, {
40
28
  model?: string | undefined;
41
29
  temperature?: number | undefined;
42
30
  topP?: number | undefined;
43
31
  frequencyPenalty?: number | undefined;
44
32
  presencePenalty?: number | undefined;
45
- } | undefined, unknown>;
46
- imageModel: z.ZodEffects<z.ZodType<string | {
47
- model?: string | undefined;
48
- } | undefined, z.ZodTypeDef, string | {
49
- model?: string | undefined;
50
- } | undefined>, {
33
+ } | undefined>;
34
+ imageModel: z.ZodType<{
51
35
  model?: string | undefined;
52
- } | undefined, string | {
36
+ } | undefined, z.ZodTypeDef, {
53
37
  model?: string | undefined;
54
38
  } | undefined>;
55
39
  agents: z.ZodType<string[] | undefined, z.ZodTypeDef, string[] | undefined>;
@@ -67,20 +51,20 @@ declare const aigneFileSchema: z.ZodObject<{
67
51
  chat?: string | undefined;
68
52
  } | undefined>;
69
53
  }, "strip", z.ZodTypeAny, {
70
- name?: string | undefined;
71
- description?: string | undefined;
72
- skills?: string[] | undefined;
73
- imageModel?: {
74
- model?: string | undefined;
75
- } | undefined;
76
- agents?: string[] | undefined;
77
- chatModel?: {
54
+ model?: {
78
55
  model?: string | undefined;
79
56
  temperature?: number | undefined;
80
57
  topP?: number | undefined;
81
58
  frequencyPenalty?: number | undefined;
82
59
  presencePenalty?: number | undefined;
83
60
  } | undefined;
61
+ name?: string | undefined;
62
+ description?: string | undefined;
63
+ imageModel?: {
64
+ model?: string | undefined;
65
+ } | undefined;
66
+ skills?: string[] | undefined;
67
+ agents?: string[] | undefined;
84
68
  mcpServer?: {
85
69
  agents?: string[] | undefined;
86
70
  } | undefined;
@@ -89,14 +73,20 @@ declare const aigneFileSchema: z.ZodObject<{
89
73
  chat?: string | undefined;
90
74
  } | undefined;
91
75
  }, {
76
+ model?: {
77
+ model?: string | undefined;
78
+ temperature?: number | undefined;
79
+ topP?: number | undefined;
80
+ frequencyPenalty?: number | undefined;
81
+ presencePenalty?: number | undefined;
82
+ } | undefined;
92
83
  name?: string | undefined;
93
84
  description?: string | undefined;
94
- skills?: string[] | undefined;
95
- imageModel?: string | {
85
+ imageModel?: {
96
86
  model?: string | undefined;
97
87
  } | undefined;
88
+ skills?: string[] | undefined;
98
89
  agents?: string[] | undefined;
99
- chatModel?: unknown;
100
90
  mcpServer?: {
101
91
  agents?: string[] | undefined;
102
92
  } | undefined;
@@ -27,7 +27,7 @@ async function load(path, options = {}) {
27
27
  return {
28
28
  ...aigne,
29
29
  rootDir,
30
- model: typeof options.model === "function" ? await options.model(aigne.chatModel) : options.model,
30
+ model: typeof options.model === "function" ? await options.model(aigne.model) : options.model,
31
31
  imageModel: typeof options.imageModel === "function"
32
32
  ? await options.imageModel(aigne.imageModel)
33
33
  : options.imageModel,
@@ -92,9 +92,17 @@ async function parseAgent(path, agent, options, agentOptions) {
92
92
  const memory = "memory" in agent && options?.memories?.length
93
93
  ? await loadMemory(options.memories, typeof agent.memory === "object" ? agent.memory.provider : undefined, typeof agent.memory === "object" ? agent.memory : {})
94
94
  : undefined;
95
+ const model = agent.model && typeof options?.model === "function"
96
+ ? await options.model(agent.model)
97
+ : undefined;
98
+ const imageModel = agent.imageModel && typeof options?.imageModel === "function"
99
+ ? await options.imageModel(agent.imageModel)
100
+ : undefined;
95
101
  const baseOptions = {
96
102
  ...agentOptions,
97
103
  ...agent,
104
+ model,
105
+ imageModel,
98
106
  skills,
99
107
  memory,
100
108
  hooks: [
@@ -175,28 +183,8 @@ async function loadMemory(memories, provider, options) {
175
183
  const aigneFileSchema = (0, schema_js_1.camelizeSchema)(zod_1.z.object({
176
184
  name: (0, schema_js_1.optionalize)(zod_1.z.string()),
177
185
  description: (0, schema_js_1.optionalize)(zod_1.z.string()),
178
- chatModel: zod_1.z
179
- .preprocess((v) => {
180
- if (!(0, type_utils_js_1.isRecord)(v))
181
- return v;
182
- return { ...v, model: v.model || `${v.provider || ""}:${v.name || ""}` };
183
- }, (0, schema_js_1.optionalize)(zod_1.z.union([
184
- zod_1.z.string(),
185
- (0, schema_js_1.camelizeSchema)(zod_1.z.object({
186
- model: (0, schema_js_1.optionalize)(zod_1.z.string()),
187
- temperature: (0, schema_js_1.optionalize)(zod_1.z.number().min(0).max(2)),
188
- topP: (0, schema_js_1.optionalize)(zod_1.z.number().min(0)),
189
- frequencyPenalty: (0, schema_js_1.optionalize)(zod_1.z.number().min(-2).max(2)),
190
- presencePenalty: (0, schema_js_1.optionalize)(zod_1.z.number().min(-2).max(2)),
191
- })),
192
- ])))
193
- .transform((v) => (typeof v === "string" ? { model: v } : v)),
194
- imageModel: (0, schema_js_1.optionalize)(zod_1.z.union([
195
- zod_1.z.string(),
196
- (0, schema_js_1.camelizeSchema)(zod_1.z.object({
197
- model: (0, schema_js_1.optionalize)(zod_1.z.string()),
198
- })),
199
- ])).transform((v) => (typeof v === "string" ? { model: v } : v)),
186
+ model: (0, schema_js_1.optionalize)(schema_js_1.chatModelSchema),
187
+ imageModel: (0, schema_js_1.optionalize)(schema_js_1.imageModelSchema),
200
188
  agents: (0, schema_js_1.optionalize)(zod_1.z.array(zod_1.z.string())),
201
189
  skills: (0, schema_js_1.optionalize)(zod_1.z.array(zod_1.z.string())),
202
190
  mcpServer: (0, schema_js_1.optionalize)(zod_1.z.object({
@@ -211,7 +199,7 @@ async function loadAIGNEFile(path) {
211
199
  const file = await findAIGNEFile(path);
212
200
  const raw = await (0, type_utils_js_1.tryOrThrow)(() => index_js_1.nodejs.fs.readFile(file, "utf8"), (error) => new Error(`Failed to load aigne.yaml from ${file}: ${error.message}`));
213
201
  const json = (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse aigne.yaml from ${file}: ${error.message}`));
214
- const aigne = (0, type_utils_js_1.tryOrThrow)(() => aigneFileSchema.parse(json), (error) => new Error(`Failed to validate aigne.yaml from ${file}: ${error.message}`));
202
+ const aigne = (0, type_utils_js_1.tryOrThrow)(() => aigneFileSchema.parse({ ...json, model: json.model || json.chatModel || json.chat_model }), (error) => new Error(`Failed to validate aigne.yaml from ${file}: ${error.message}`));
215
203
  return { aigne, rootDir: index_js_1.nodejs.path.dirname(file) };
216
204
  }
217
205
  async function findAIGNEFile(path) {
@@ -29,7 +29,36 @@ export declare const defaultInputSchema: z.ZodRecord<z.ZodString, z.ZodUnion<[z.
29
29
  }, {
30
30
  $get: string;
31
31
  }>, z.ZodUnknown]>>;
32
+ declare const chatModelObjectSchema: z.ZodObject<{
33
+ model: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
34
+ temperature: ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
35
+ topP: ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
36
+ frequencyPenalty: ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
37
+ presencePenalty: ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
38
+ }, "strip", z.ZodTypeAny, {
39
+ model?: string | undefined;
40
+ temperature?: number | undefined;
41
+ topP?: number | undefined;
42
+ frequencyPenalty?: number | undefined;
43
+ presencePenalty?: number | undefined;
44
+ }, {
45
+ model?: string | undefined;
46
+ temperature?: number | undefined;
47
+ topP?: number | undefined;
48
+ frequencyPenalty?: number | undefined;
49
+ presencePenalty?: number | undefined;
50
+ }>;
51
+ export declare const chatModelSchema: typeof chatModelObjectSchema;
52
+ declare const imageModelObjectSchema: z.ZodObject<{
53
+ model: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
54
+ }, "strip", z.ZodTypeAny, {
55
+ model?: string | undefined;
56
+ }, {
57
+ model?: string | undefined;
58
+ }>;
59
+ export declare const imageModelSchema: typeof imageModelObjectSchema;
32
60
  export declare function optionalize<T>(schema: ZodType<T>): ZodType<T | undefined>;
33
61
  export declare function camelizeSchema<T extends ZodType>(schema: T, { shallow }?: {
34
62
  shallow?: boolean;
35
63
  }): T;
64
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultInputSchema = exports.inputOutputSchema = void 0;
3
+ exports.imageModelSchema = exports.chatModelSchema = exports.defaultInputSchema = exports.inputOutputSchema = void 0;
4
4
  exports.optionalize = optionalize;
5
5
  exports.camelizeSchema = camelizeSchema;
6
6
  const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
@@ -60,6 +60,26 @@ exports.defaultInputSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.union([
60
60
  }),
61
61
  zod_1.z.unknown(),
62
62
  ]));
63
+ const chatModelObjectSchema = camelizeSchema(zod_1.z.object({
64
+ model: optionalize(zod_1.z.string()),
65
+ temperature: optionalize(zod_1.z.number().min(0).max(2)),
66
+ topP: optionalize(zod_1.z.number().min(0)),
67
+ frequencyPenalty: optionalize(zod_1.z.number().min(-2).max(2)),
68
+ presencePenalty: optionalize(zod_1.z.number().min(-2).max(2)),
69
+ }));
70
+ exports.chatModelSchema = zod_1.z
71
+ .preprocess((v) => {
72
+ if (!(0, type_utils_js_1.isRecord)(v))
73
+ return v;
74
+ return { ...v, model: v.model || `${v.provider || ""}:${v.name || ""}` };
75
+ }, zod_1.z.union([zod_1.z.string(), chatModelObjectSchema]))
76
+ .transform((v) => typeof v === "string" ? { model: v } : v);
77
+ const imageModelObjectSchema = camelizeSchema(zod_1.z.object({
78
+ model: optionalize(zod_1.z.string()),
79
+ }));
80
+ exports.imageModelSchema = zod_1.z
81
+ .union([zod_1.z.string(), imageModelObjectSchema])
82
+ .transform((v) => typeof v === "string" ? { model: v } : v);
63
83
  function optionalize(schema) {
64
84
  return schema.nullish().transform((v) => v ?? undefined);
65
85
  }