@aigne/core 1.7.0 → 1.8.0

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
@@ -22,6 +22,19 @@
22
22
  * rename @aigne/core-next to @aigne/core ([3a81009](https://github.com/AIGNE-io/aigne-framework/commit/3a8100962c81813217b687ae28e8de604419c622))
23
23
  * use text resource from MCP correctly ([8b9eba8](https://github.com/AIGNE-io/aigne-framework/commit/8b9eba83352ec096a2a5d4f410d4c4bde7420bce))
24
24
 
25
+ ## [1.8.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.7.0...core-v1.8.0) (2025-04-17)
26
+
27
+
28
+ ### Features
29
+
30
+ * **ci:** support coverage examples with model matrix ([#59](https://github.com/AIGNE-io/aigne-framework/issues/59)) ([1edd704](https://github.com/AIGNE-io/aigne-framework/commit/1edd70426b80a69e3751b2d5fe818297711d0777))
31
+ * **cli:** support model and download customization for aigne run ([#61](https://github.com/AIGNE-io/aigne-framework/issues/61)) ([51f6619](https://github.com/AIGNE-io/aigne-framework/commit/51f6619e6c591a84f1f2339b26ef66d89fa9486e))
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * **mcp:** set default timeout to 60s ([#67](https://github.com/AIGNE-io/aigne-framework/issues/67)) ([40dc029](https://github.com/AIGNE-io/aigne-framework/commit/40dc029b7795650283a505fd71b9566e5f0a4471))
37
+
25
38
  ## [1.7.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.6.0...core-v1.7.0) (2025-04-15)
26
39
 
27
40
 
@@ -22,7 +22,7 @@ export type SSEServerParameters = {
22
22
  opts?: SSEClientTransportOptions;
23
23
  /**
24
24
  * The timeout for requests to the server, in milliseconds.
25
- * @default 10000
25
+ * @default 60000
26
26
  */
27
27
  timeout?: number;
28
28
  /**
@@ -41,7 +41,7 @@ export declare class MCPAgent extends Agent {
41
41
  static from(options: MCPAgentOptions): MCPAgent;
42
42
  private static fromTransport;
43
43
  constructor(options: MCPAgentOptions);
44
- private client;
44
+ client: Client;
45
45
  readonly prompts: MCPPrompt[] & {
46
46
  [key: string]: MCPPrompt;
47
47
  };
@@ -71,7 +71,6 @@ export interface MCPBaseOptions<I extends Message = Message, O extends Message =
71
71
  export declare abstract class MCPBase<I extends Message, O extends Message> extends Agent<I, O> {
72
72
  constructor(options: MCPBaseOptions<I, O>);
73
73
  protected client: ClientWithReconnect;
74
- protected get mcpServer(): string | undefined;
75
74
  }
76
75
  export declare class MCPTool extends MCPBase<Message, CallToolResult> {
77
76
  process(input: Message): Promise<CallToolResult>;
@@ -17,6 +17,11 @@ const agent_js_1 = require("./agent.js");
17
17
  const MCP_AGENT_CLIENT_NAME = "MCPAgent";
18
18
  const MCP_AGENT_CLIENT_VERSION = "0.0.1";
19
19
  const DEFAULT_MAX_RECONNECTS = 10;
20
+ const DEFAULT_TIMEOUT = () => zod_1.z.coerce
21
+ .number()
22
+ .int()
23
+ .min(0)
24
+ .safeParse(process.env.MCP_TIMEOUT || process.env.TIMEOUT).data || 60e3;
20
25
  function isSSEServerParameters(options) {
21
26
  return "url" in options && typeof options.url === "string";
22
27
  }
@@ -140,7 +145,9 @@ class ClientWithReconnect extends index_js_1.Client {
140
145
  throw new Error("reconnect requires a transportCreator");
141
146
  await (0, p_retry_1.default)(async () => {
142
147
  await this.close();
143
- await this.connect(await transportCreator());
148
+ await this.connect(await transportCreator(), {
149
+ timeout: this.reconnectOptions?.timeout ?? DEFAULT_TIMEOUT(),
150
+ });
144
151
  }, {
145
152
  retries: this.reconnectOptions?.maxReconnects ?? DEFAULT_MAX_RECONNECTS,
146
153
  shouldRetry: this.shouldReconnect,
@@ -149,8 +156,8 @@ class ClientWithReconnect extends index_js_1.Client {
149
156
  }
150
157
  async request(request, resultSchema, options) {
151
158
  const mergedOptions = {
152
- ...(options ?? {}),
153
- timeout: options?.timeout ?? this.reconnectOptions?.timeout ?? 10000,
159
+ ...options,
160
+ timeout: options?.timeout ?? DEFAULT_TIMEOUT(),
154
161
  };
155
162
  try {
156
163
  return await super.request(request, resultSchema, mergedOptions);
@@ -171,9 +178,6 @@ class MCPBase extends agent_js_1.Agent {
171
178
  this.client = options.client;
172
179
  }
173
180
  client;
174
- get mcpServer() {
175
- return getMCPServerName(this.client);
176
- }
177
181
  }
178
182
  exports.MCPBase = MCPBase;
179
183
  class MCPTool extends MCPBase {
@@ -12,8 +12,8 @@ class ExecutionEngine {
12
12
  static async load({ path, ...options }) {
13
13
  const { model, agents, tools, ...aigne } = await (0, index_js_1.load)({ path });
14
14
  return new ExecutionEngine({
15
- model,
16
15
  ...options,
16
+ model: options.model || model,
17
17
  name: options.name || aigne.name || undefined,
18
18
  description: options.description || aigne.description || undefined,
19
19
  agents: agents.concat(options.agents ?? []),
@@ -58,7 +58,7 @@ async function loadAgentFromJsFile(path) {
58
58
  throw new Error(`Agent file ${path} must export a default function, but got ${typeof agent}`);
59
59
  }
60
60
  return (0, type_utils_js_1.tryOrThrow)(() => agentJsFileSchema.parse({
61
- name: agent.name,
61
+ name: agent.agent_name || agent.name,
62
62
  description: agent.description,
63
63
  input_schema: agent.input_schema,
64
64
  output_schema: agent.output_schema,
@@ -10,6 +10,7 @@ export declare function loadAgentFromYamlFile(path: string): Promise<{
10
10
  }, {
11
11
  [x: string]: any;
12
12
  }> | undefined;
13
+ tool_choice?: "auto" | "none" | "required" | "router" | undefined;
13
14
  output_schema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
14
15
  [x: string]: any;
15
16
  }, {
@@ -33,6 +33,10 @@ const agentFileSchema = zod_1.z.discriminatedUnion("type", [
33
33
  .array(zod_1.z.string())
34
34
  .nullish()
35
35
  .transform((v) => v ?? undefined),
36
+ tool_choice: zod_1.z
37
+ .union([zod_1.z.literal("auto"), zod_1.z.literal("none"), zod_1.z.literal("required"), zod_1.z.literal("router")])
38
+ .nullish()
39
+ .transform((v) => v ?? undefined),
36
40
  }),
37
41
  zod_1.z.object({
38
42
  type: zod_1.z.literal("mcp"),
@@ -1,5 +1,6 @@
1
+ import { z } from "zod";
1
2
  import { type Agent } from "../agents/agent.js";
2
- import type { ChatModel } from "../models/chat-model.js";
3
+ import type { ChatModel, ChatModelOptions } from "../models/chat-model.js";
3
4
  export interface LoadOptions {
4
5
  path: string;
5
6
  }
@@ -19,6 +20,75 @@ export declare function load(options: LoadOptions): Promise<{
19
20
  } | null | undefined;
20
21
  }>;
21
22
  export declare function loadAgent(path: string): Promise<Agent>;
23
+ export declare function loadModel(model?: z.infer<typeof aigneFileSchema>["chat_model"], modelOptions?: ChatModelOptions): Promise<ChatModel | undefined>;
24
+ declare const aigneFileSchema: z.ZodObject<{
25
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
26
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
27
+ chat_model: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodString, z.ZodObject<{
28
+ provider: z.ZodOptional<z.ZodNullable<z.ZodString>>;
29
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
30
+ temperature: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
31
+ top_p: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
32
+ frequent_penalty: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
33
+ presence_penalty: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
34
+ }, "strip", z.ZodTypeAny, {
35
+ name?: string | null | undefined;
36
+ temperature?: number | null | undefined;
37
+ provider?: string | null | undefined;
38
+ top_p?: number | null | undefined;
39
+ frequent_penalty?: number | null | undefined;
40
+ presence_penalty?: number | null | undefined;
41
+ }, {
42
+ name?: string | null | undefined;
43
+ temperature?: number | null | undefined;
44
+ provider?: string | null | undefined;
45
+ top_p?: number | null | undefined;
46
+ frequent_penalty?: number | null | undefined;
47
+ presence_penalty?: number | null | undefined;
48
+ }>]>>>, {
49
+ name?: string | null | undefined;
50
+ temperature?: number | null | undefined;
51
+ provider?: string | null | undefined;
52
+ top_p?: number | null | undefined;
53
+ frequent_penalty?: number | null | undefined;
54
+ presence_penalty?: number | null | undefined;
55
+ } | null | undefined, string | {
56
+ name?: string | null | undefined;
57
+ temperature?: number | null | undefined;
58
+ provider?: string | null | undefined;
59
+ top_p?: number | null | undefined;
60
+ frequent_penalty?: number | null | undefined;
61
+ presence_penalty?: number | null | undefined;
62
+ } | null | undefined>;
63
+ agents: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
64
+ tools: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
65
+ }, "strip", z.ZodTypeAny, {
66
+ description?: string | null | undefined;
67
+ tools?: string[] | null | undefined;
68
+ name?: string | null | undefined;
69
+ chat_model?: {
70
+ name?: string | null | undefined;
71
+ temperature?: number | null | undefined;
72
+ provider?: string | null | undefined;
73
+ top_p?: number | null | undefined;
74
+ frequent_penalty?: number | null | undefined;
75
+ presence_penalty?: number | null | undefined;
76
+ } | null | undefined;
77
+ agents?: string[] | null | undefined;
78
+ }, {
79
+ description?: string | null | undefined;
80
+ tools?: string[] | null | undefined;
81
+ name?: string | null | undefined;
82
+ chat_model?: string | {
83
+ name?: string | null | undefined;
84
+ temperature?: number | null | undefined;
85
+ provider?: string | null | undefined;
86
+ top_p?: number | null | undefined;
87
+ frequent_penalty?: number | null | undefined;
88
+ presence_penalty?: number | null | undefined;
89
+ } | null | undefined;
90
+ agents?: string[] | null | undefined;
91
+ }>;
22
92
  export declare function loadAIGNEFile(path: string): Promise<{
23
93
  description?: string | null | undefined;
24
94
  tools?: string[] | null | undefined;
@@ -33,3 +103,4 @@ export declare function loadAIGNEFile(path: string): Promise<{
33
103
  } | null | undefined;
34
104
  agents?: string[] | null | undefined;
35
105
  }>;
106
+ export {};
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.load = load;
4
4
  exports.loadAgent = loadAgent;
5
+ exports.loadModel = loadModel;
5
6
  exports.loadAIGNEFile = loadAIGNEFile;
6
7
  const promises_1 = require("node:fs/promises");
7
8
  const node_path_1 = require("node:path");
@@ -16,7 +17,6 @@ const xai_chat_model_js_1 = require("../models/xai-chat-model.js");
16
17
  const type_utils_js_1 = require("../utils/type-utils.js");
17
18
  const agent_js_js_1 = require("./agent-js.js");
18
19
  const agent_yaml_js_1 = require("./agent-yaml.js");
19
- const DEFAULT_MODEL_PROVIDER = "openai";
20
20
  const AIGNE_FILE_NAME = ["aigne.yaml", "aigne.yml"];
21
21
  async function load(options) {
22
22
  const { path } = options;
@@ -54,6 +54,7 @@ async function loadAgent(path) {
54
54
  outputSchema: agent.output_schema,
55
55
  outputKey: agent.output_key,
56
56
  tools: await Promise.all((agent.tools ?? []).map((filename) => loadAgent((0, node_path_1.join)((0, node_path_1.dirname)(path), filename)))),
57
+ toolChoice: agent.tool_choice,
57
58
  });
58
59
  }
59
60
  if (agent.type === "mcp") {
@@ -73,21 +74,20 @@ async function loadAgent(path) {
73
74
  }
74
75
  throw new Error(`Unsupported agent file type: ${path}`);
75
76
  }
76
- async function loadModel(model) {
77
- if (!model?.name)
78
- return undefined;
77
+ const { MODEL_PROVIDER = "openai", MODEL_NAME = "gpt-4o-mini" } = process.env;
78
+ async function loadModel(model, modelOptions) {
79
79
  const params = {
80
- model: model.name,
81
- temperature: model.temperature ?? undefined,
82
- topP: model.top_p ?? undefined,
83
- frequencyPenalty: model.frequent_penalty ?? undefined,
84
- presencePenalty: model.presence_penalty ?? undefined,
80
+ model: model?.name ?? MODEL_NAME,
81
+ temperature: model?.temperature ?? undefined,
82
+ topP: model?.top_p ?? undefined,
83
+ frequencyPenalty: model?.frequent_penalty ?? undefined,
84
+ presencePenalty: model?.presence_penalty ?? undefined,
85
85
  };
86
86
  const availableModels = [openai_chat_model_js_1.OpenAIChatModel, claude_chat_model_js_1.ClaudeChatModel, xai_chat_model_js_1.XAIChatModel];
87
- const M = availableModels.find((m) => m.name.toLowerCase().includes(model.provider || DEFAULT_MODEL_PROVIDER));
87
+ const M = availableModels.find((m) => m.name.toLowerCase().includes(model?.provider || MODEL_PROVIDER));
88
88
  if (!M)
89
- throw new Error(`Unsupported model: ${model.provider} ${model.name}`);
90
- return new M(params);
89
+ throw new Error(`Unsupported model: ${model?.provider} ${model?.name}`);
90
+ return new M({ model: params.model, modelOptions: { ...params, ...modelOptions } });
91
91
  }
92
92
  const aigneFileSchema = zod_1.z.object({
93
93
  name: zod_1.z.string().nullish(),
@@ -36,7 +36,7 @@ class ClaudeChatModel extends chat_model_js_1.ChatModel {
36
36
  }
37
37
  _client;
38
38
  get client() {
39
- const apiKey = this.options?.apiKey || process.env.CLAUDE_API_KEY;
39
+ const apiKey = this.options?.apiKey || process.env.ANTHROPIC_API_KEY || process.env.CLAUDE_API_KEY;
40
40
  if (!apiKey)
41
41
  throw new Error("Api Key is required for ClaudeChatModel");
42
42
  this._client ??= new sdk_1.default({ apiKey });
@@ -22,7 +22,7 @@ export type SSEServerParameters = {
22
22
  opts?: SSEClientTransportOptions;
23
23
  /**
24
24
  * The timeout for requests to the server, in milliseconds.
25
- * @default 10000
25
+ * @default 60000
26
26
  */
27
27
  timeout?: number;
28
28
  /**
@@ -41,7 +41,7 @@ export declare class MCPAgent extends Agent {
41
41
  static from(options: MCPAgentOptions): MCPAgent;
42
42
  private static fromTransport;
43
43
  constructor(options: MCPAgentOptions);
44
- private client;
44
+ client: Client;
45
45
  readonly prompts: MCPPrompt[] & {
46
46
  [key: string]: MCPPrompt;
47
47
  };
@@ -71,7 +71,6 @@ export interface MCPBaseOptions<I extends Message = Message, O extends Message =
71
71
  export declare abstract class MCPBase<I extends Message, O extends Message> extends Agent<I, O> {
72
72
  constructor(options: MCPBaseOptions<I, O>);
73
73
  protected client: ClientWithReconnect;
74
- protected get mcpServer(): string | undefined;
75
74
  }
76
75
  export declare class MCPTool extends MCPBase<Message, CallToolResult> {
77
76
  process(input: Message): Promise<CallToolResult>;
@@ -10,6 +10,7 @@ export declare function loadAgentFromYamlFile(path: string): Promise<{
10
10
  }, {
11
11
  [x: string]: any;
12
12
  }> | undefined;
13
+ tool_choice?: "auto" | "none" | "required" | "router" | undefined;
13
14
  output_schema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
14
15
  [x: string]: any;
15
16
  }, {
@@ -1,5 +1,6 @@
1
+ import { z } from "zod";
1
2
  import { type Agent } from "../agents/agent.js";
2
- import type { ChatModel } from "../models/chat-model.js";
3
+ import type { ChatModel, ChatModelOptions } from "../models/chat-model.js";
3
4
  export interface LoadOptions {
4
5
  path: string;
5
6
  }
@@ -19,6 +20,75 @@ export declare function load(options: LoadOptions): Promise<{
19
20
  } | null | undefined;
20
21
  }>;
21
22
  export declare function loadAgent(path: string): Promise<Agent>;
23
+ export declare function loadModel(model?: z.infer<typeof aigneFileSchema>["chat_model"], modelOptions?: ChatModelOptions): Promise<ChatModel | undefined>;
24
+ declare const aigneFileSchema: z.ZodObject<{
25
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
26
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
27
+ chat_model: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodString, z.ZodObject<{
28
+ provider: z.ZodOptional<z.ZodNullable<z.ZodString>>;
29
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
30
+ temperature: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
31
+ top_p: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
32
+ frequent_penalty: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
33
+ presence_penalty: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
34
+ }, "strip", z.ZodTypeAny, {
35
+ name?: string | null | undefined;
36
+ temperature?: number | null | undefined;
37
+ provider?: string | null | undefined;
38
+ top_p?: number | null | undefined;
39
+ frequent_penalty?: number | null | undefined;
40
+ presence_penalty?: number | null | undefined;
41
+ }, {
42
+ name?: string | null | undefined;
43
+ temperature?: number | null | undefined;
44
+ provider?: string | null | undefined;
45
+ top_p?: number | null | undefined;
46
+ frequent_penalty?: number | null | undefined;
47
+ presence_penalty?: number | null | undefined;
48
+ }>]>>>, {
49
+ name?: string | null | undefined;
50
+ temperature?: number | null | undefined;
51
+ provider?: string | null | undefined;
52
+ top_p?: number | null | undefined;
53
+ frequent_penalty?: number | null | undefined;
54
+ presence_penalty?: number | null | undefined;
55
+ } | null | undefined, string | {
56
+ name?: string | null | undefined;
57
+ temperature?: number | null | undefined;
58
+ provider?: string | null | undefined;
59
+ top_p?: number | null | undefined;
60
+ frequent_penalty?: number | null | undefined;
61
+ presence_penalty?: number | null | undefined;
62
+ } | null | undefined>;
63
+ agents: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
64
+ tools: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
65
+ }, "strip", z.ZodTypeAny, {
66
+ description?: string | null | undefined;
67
+ tools?: string[] | null | undefined;
68
+ name?: string | null | undefined;
69
+ chat_model?: {
70
+ name?: string | null | undefined;
71
+ temperature?: number | null | undefined;
72
+ provider?: string | null | undefined;
73
+ top_p?: number | null | undefined;
74
+ frequent_penalty?: number | null | undefined;
75
+ presence_penalty?: number | null | undefined;
76
+ } | null | undefined;
77
+ agents?: string[] | null | undefined;
78
+ }, {
79
+ description?: string | null | undefined;
80
+ tools?: string[] | null | undefined;
81
+ name?: string | null | undefined;
82
+ chat_model?: string | {
83
+ name?: string | null | undefined;
84
+ temperature?: number | null | undefined;
85
+ provider?: string | null | undefined;
86
+ top_p?: number | null | undefined;
87
+ frequent_penalty?: number | null | undefined;
88
+ presence_penalty?: number | null | undefined;
89
+ } | null | undefined;
90
+ agents?: string[] | null | undefined;
91
+ }>;
22
92
  export declare function loadAIGNEFile(path: string): Promise<{
23
93
  description?: string | null | undefined;
24
94
  tools?: string[] | null | undefined;
@@ -33,3 +103,4 @@ export declare function loadAIGNEFile(path: string): Promise<{
33
103
  } | null | undefined;
34
104
  agents?: string[] | null | undefined;
35
105
  }>;
106
+ export {};
@@ -22,7 +22,7 @@ export type SSEServerParameters = {
22
22
  opts?: SSEClientTransportOptions;
23
23
  /**
24
24
  * The timeout for requests to the server, in milliseconds.
25
- * @default 10000
25
+ * @default 60000
26
26
  */
27
27
  timeout?: number;
28
28
  /**
@@ -41,7 +41,7 @@ export declare class MCPAgent extends Agent {
41
41
  static from(options: MCPAgentOptions): MCPAgent;
42
42
  private static fromTransport;
43
43
  constructor(options: MCPAgentOptions);
44
- private client;
44
+ client: Client;
45
45
  readonly prompts: MCPPrompt[] & {
46
46
  [key: string]: MCPPrompt;
47
47
  };
@@ -71,7 +71,6 @@ export interface MCPBaseOptions<I extends Message = Message, O extends Message =
71
71
  export declare abstract class MCPBase<I extends Message, O extends Message> extends Agent<I, O> {
72
72
  constructor(options: MCPBaseOptions<I, O>);
73
73
  protected client: ClientWithReconnect;
74
- protected get mcpServer(): string | undefined;
75
74
  }
76
75
  export declare class MCPTool extends MCPBase<Message, CallToolResult> {
77
76
  process(input: Message): Promise<CallToolResult>;
@@ -11,6 +11,11 @@ import { Agent } from "./agent.js";
11
11
  const MCP_AGENT_CLIENT_NAME = "MCPAgent";
12
12
  const MCP_AGENT_CLIENT_VERSION = "0.0.1";
13
13
  const DEFAULT_MAX_RECONNECTS = 10;
14
+ const DEFAULT_TIMEOUT = () => z.coerce
15
+ .number()
16
+ .int()
17
+ .min(0)
18
+ .safeParse(process.env.MCP_TIMEOUT || process.env.TIMEOUT).data || 60e3;
14
19
  function isSSEServerParameters(options) {
15
20
  return "url" in options && typeof options.url === "string";
16
21
  }
@@ -133,7 +138,9 @@ class ClientWithReconnect extends Client {
133
138
  throw new Error("reconnect requires a transportCreator");
134
139
  await pRetry(async () => {
135
140
  await this.close();
136
- await this.connect(await transportCreator());
141
+ await this.connect(await transportCreator(), {
142
+ timeout: this.reconnectOptions?.timeout ?? DEFAULT_TIMEOUT(),
143
+ });
137
144
  }, {
138
145
  retries: this.reconnectOptions?.maxReconnects ?? DEFAULT_MAX_RECONNECTS,
139
146
  shouldRetry: this.shouldReconnect,
@@ -142,8 +149,8 @@ class ClientWithReconnect extends Client {
142
149
  }
143
150
  async request(request, resultSchema, options) {
144
151
  const mergedOptions = {
145
- ...(options ?? {}),
146
- timeout: options?.timeout ?? this.reconnectOptions?.timeout ?? 10000,
152
+ ...options,
153
+ timeout: options?.timeout ?? DEFAULT_TIMEOUT(),
147
154
  };
148
155
  try {
149
156
  return await super.request(request, resultSchema, mergedOptions);
@@ -164,9 +171,6 @@ export class MCPBase extends Agent {
164
171
  this.client = options.client;
165
172
  }
166
173
  client;
167
- get mcpServer() {
168
- return getMCPServerName(this.client);
169
- }
170
174
  }
171
175
  export class MCPTool extends MCPBase {
172
176
  async process(input) {
@@ -9,8 +9,8 @@ export class ExecutionEngine {
9
9
  static async load({ path, ...options }) {
10
10
  const { model, agents, tools, ...aigne } = await load({ path });
11
11
  return new ExecutionEngine({
12
- model,
13
12
  ...options,
13
+ model: options.model || model,
14
14
  name: options.name || aigne.name || undefined,
15
15
  description: options.description || aigne.description || undefined,
16
16
  agents: agents.concat(options.agents ?? []),
@@ -22,7 +22,7 @@ export async function loadAgentFromJsFile(path) {
22
22
  throw new Error(`Agent file ${path} must export a default function, but got ${typeof agent}`);
23
23
  }
24
24
  return tryOrThrow(() => agentJsFileSchema.parse({
25
- name: agent.name,
25
+ name: agent.agent_name || agent.name,
26
26
  description: agent.description,
27
27
  input_schema: agent.input_schema,
28
28
  output_schema: agent.output_schema,
@@ -10,6 +10,7 @@ export declare function loadAgentFromYamlFile(path: string): Promise<{
10
10
  }, {
11
11
  [x: string]: any;
12
12
  }> | undefined;
13
+ tool_choice?: "auto" | "none" | "required" | "router" | undefined;
13
14
  output_schema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
14
15
  [x: string]: any;
15
16
  }, {
@@ -30,6 +30,10 @@ const agentFileSchema = z.discriminatedUnion("type", [
30
30
  .array(z.string())
31
31
  .nullish()
32
32
  .transform((v) => v ?? undefined),
33
+ tool_choice: z
34
+ .union([z.literal("auto"), z.literal("none"), z.literal("required"), z.literal("router")])
35
+ .nullish()
36
+ .transform((v) => v ?? undefined),
33
37
  }),
34
38
  z.object({
35
39
  type: z.literal("mcp"),
@@ -1,5 +1,6 @@
1
+ import { z } from "zod";
1
2
  import { type Agent } from "../agents/agent.js";
2
- import type { ChatModel } from "../models/chat-model.js";
3
+ import type { ChatModel, ChatModelOptions } from "../models/chat-model.js";
3
4
  export interface LoadOptions {
4
5
  path: string;
5
6
  }
@@ -19,6 +20,75 @@ export declare function load(options: LoadOptions): Promise<{
19
20
  } | null | undefined;
20
21
  }>;
21
22
  export declare function loadAgent(path: string): Promise<Agent>;
23
+ export declare function loadModel(model?: z.infer<typeof aigneFileSchema>["chat_model"], modelOptions?: ChatModelOptions): Promise<ChatModel | undefined>;
24
+ declare const aigneFileSchema: z.ZodObject<{
25
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
26
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
27
+ chat_model: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodString, z.ZodObject<{
28
+ provider: z.ZodOptional<z.ZodNullable<z.ZodString>>;
29
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
30
+ temperature: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
31
+ top_p: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
32
+ frequent_penalty: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
33
+ presence_penalty: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
34
+ }, "strip", z.ZodTypeAny, {
35
+ name?: string | null | undefined;
36
+ temperature?: number | null | undefined;
37
+ provider?: string | null | undefined;
38
+ top_p?: number | null | undefined;
39
+ frequent_penalty?: number | null | undefined;
40
+ presence_penalty?: number | null | undefined;
41
+ }, {
42
+ name?: string | null | undefined;
43
+ temperature?: number | null | undefined;
44
+ provider?: string | null | undefined;
45
+ top_p?: number | null | undefined;
46
+ frequent_penalty?: number | null | undefined;
47
+ presence_penalty?: number | null | undefined;
48
+ }>]>>>, {
49
+ name?: string | null | undefined;
50
+ temperature?: number | null | undefined;
51
+ provider?: string | null | undefined;
52
+ top_p?: number | null | undefined;
53
+ frequent_penalty?: number | null | undefined;
54
+ presence_penalty?: number | null | undefined;
55
+ } | null | undefined, string | {
56
+ name?: string | null | undefined;
57
+ temperature?: number | null | undefined;
58
+ provider?: string | null | undefined;
59
+ top_p?: number | null | undefined;
60
+ frequent_penalty?: number | null | undefined;
61
+ presence_penalty?: number | null | undefined;
62
+ } | null | undefined>;
63
+ agents: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
64
+ tools: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
65
+ }, "strip", z.ZodTypeAny, {
66
+ description?: string | null | undefined;
67
+ tools?: string[] | null | undefined;
68
+ name?: string | null | undefined;
69
+ chat_model?: {
70
+ name?: string | null | undefined;
71
+ temperature?: number | null | undefined;
72
+ provider?: string | null | undefined;
73
+ top_p?: number | null | undefined;
74
+ frequent_penalty?: number | null | undefined;
75
+ presence_penalty?: number | null | undefined;
76
+ } | null | undefined;
77
+ agents?: string[] | null | undefined;
78
+ }, {
79
+ description?: string | null | undefined;
80
+ tools?: string[] | null | undefined;
81
+ name?: string | null | undefined;
82
+ chat_model?: string | {
83
+ name?: string | null | undefined;
84
+ temperature?: number | null | undefined;
85
+ provider?: string | null | undefined;
86
+ top_p?: number | null | undefined;
87
+ frequent_penalty?: number | null | undefined;
88
+ presence_penalty?: number | null | undefined;
89
+ } | null | undefined;
90
+ agents?: string[] | null | undefined;
91
+ }>;
22
92
  export declare function loadAIGNEFile(path: string): Promise<{
23
93
  description?: string | null | undefined;
24
94
  tools?: string[] | null | undefined;
@@ -33,3 +103,4 @@ export declare function loadAIGNEFile(path: string): Promise<{
33
103
  } | null | undefined;
34
104
  agents?: string[] | null | undefined;
35
105
  }>;
106
+ export {};
@@ -11,7 +11,6 @@ import { XAIChatModel } from "../models/xai-chat-model.js";
11
11
  import { tryOrThrow } from "../utils/type-utils.js";
12
12
  import { loadAgentFromJsFile } from "./agent-js.js";
13
13
  import { loadAgentFromYamlFile } from "./agent-yaml.js";
14
- const DEFAULT_MODEL_PROVIDER = "openai";
15
14
  const AIGNE_FILE_NAME = ["aigne.yaml", "aigne.yml"];
16
15
  export async function load(options) {
17
16
  const { path } = options;
@@ -49,6 +48,7 @@ export async function loadAgent(path) {
49
48
  outputSchema: agent.output_schema,
50
49
  outputKey: agent.output_key,
51
50
  tools: await Promise.all((agent.tools ?? []).map((filename) => loadAgent(join(dirname(path), filename)))),
51
+ toolChoice: agent.tool_choice,
52
52
  });
53
53
  }
54
54
  if (agent.type === "mcp") {
@@ -68,21 +68,20 @@ export async function loadAgent(path) {
68
68
  }
69
69
  throw new Error(`Unsupported agent file type: ${path}`);
70
70
  }
71
- async function loadModel(model) {
72
- if (!model?.name)
73
- return undefined;
71
+ const { MODEL_PROVIDER = "openai", MODEL_NAME = "gpt-4o-mini" } = process.env;
72
+ export async function loadModel(model, modelOptions) {
74
73
  const params = {
75
- model: model.name,
76
- temperature: model.temperature ?? undefined,
77
- topP: model.top_p ?? undefined,
78
- frequencyPenalty: model.frequent_penalty ?? undefined,
79
- presencePenalty: model.presence_penalty ?? undefined,
74
+ model: model?.name ?? MODEL_NAME,
75
+ temperature: model?.temperature ?? undefined,
76
+ topP: model?.top_p ?? undefined,
77
+ frequencyPenalty: model?.frequent_penalty ?? undefined,
78
+ presencePenalty: model?.presence_penalty ?? undefined,
80
79
  };
81
80
  const availableModels = [OpenAIChatModel, ClaudeChatModel, XAIChatModel];
82
- const M = availableModels.find((m) => m.name.toLowerCase().includes(model.provider || DEFAULT_MODEL_PROVIDER));
81
+ const M = availableModels.find((m) => m.name.toLowerCase().includes(model?.provider || MODEL_PROVIDER));
83
82
  if (!M)
84
- throw new Error(`Unsupported model: ${model.provider} ${model.name}`);
85
- return new M(params);
83
+ throw new Error(`Unsupported model: ${model?.provider} ${model?.name}`);
84
+ return new M({ model: params.model, modelOptions: { ...params, ...modelOptions } });
86
85
  }
87
86
  const aigneFileSchema = z.object({
88
87
  name: z.string().nullish(),
@@ -30,7 +30,7 @@ export class ClaudeChatModel extends ChatModel {
30
30
  }
31
31
  _client;
32
32
  get client() {
33
- const apiKey = this.options?.apiKey || process.env.CLAUDE_API_KEY;
33
+ const apiKey = this.options?.apiKey || process.env.ANTHROPIC_API_KEY || process.env.CLAUDE_API_KEY;
34
34
  if (!apiKey)
35
35
  throw new Error("Api Key is required for ClaudeChatModel");
36
36
  this._client ??= new Anthropic({ apiKey });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "AIGNE core library for building AI-powered applications",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -47,6 +47,9 @@
47
47
  "execution-engine/*": [
48
48
  "./lib/dts/execution-engine/*"
49
49
  ],
50
+ "loader/*": [
51
+ "./lib/dts/loader/*"
52
+ ],
50
53
  "models/*": [
51
54
  "./lib/dts/models/*"
52
55
  ],
@@ -83,11 +86,11 @@
83
86
  "@types/bun": "^1.2.9",
84
87
  "@types/express": "^5.0.1",
85
88
  "@types/mustache": "^4.2.5",
86
- "@types/node": "^22.14.0",
89
+ "@types/node": "^22.14.1",
87
90
  "detect-port": "^2.1.0",
88
91
  "express": "^5.1.0",
89
92
  "npm-run-all": "^4.1.5",
90
- "openai": "^4.93.0",
93
+ "openai": "^4.94.0",
91
94
  "rimraf": "^6.0.1",
92
95
  "typescript": "^5.8.3"
93
96
  },