@aigne/core 1.3.1 → 1.4.1-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.
Files changed (68) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/lib/cjs/agents/agent.d.ts +7 -4
  3. package/lib/cjs/agents/agent.js +25 -8
  4. package/lib/cjs/agents/ai-agent.d.ts +49 -1
  5. package/lib/cjs/agents/ai-agent.js +27 -1
  6. package/lib/cjs/agents/mcp-agent.js +30 -4
  7. package/lib/cjs/agents/memory.js +7 -0
  8. package/lib/cjs/execution-engine/execution-engine.d.ts +1 -1
  9. package/lib/cjs/execution-engine/execution-engine.js +48 -0
  10. package/lib/cjs/execution-engine/utils.d.ts +1 -1
  11. package/lib/cjs/execution-engine/utils.js +6 -0
  12. package/lib/cjs/index.d.ts +3 -0
  13. package/lib/cjs/index.js +3 -0
  14. package/lib/cjs/models/chat-model.d.ts +1 -0
  15. package/lib/cjs/models/chat-model.js +1 -0
  16. package/lib/cjs/models/claude-chat-model.d.ts +58 -9
  17. package/lib/cjs/models/claude-chat-model.js +78 -42
  18. package/lib/cjs/models/openai-chat-model.d.ts +62 -9
  19. package/lib/cjs/models/openai-chat-model.js +38 -11
  20. package/lib/cjs/models/xai-chat-model.d.ts +12 -0
  21. package/lib/cjs/models/xai-chat-model.js +18 -0
  22. package/lib/cjs/package.json +1 -0
  23. package/lib/cjs/prompt/prompt-builder.d.ts +2 -2
  24. package/lib/cjs/utils/json-schema.d.ts +9 -1
  25. package/lib/cjs/utils/json-schema.js +14 -0
  26. package/lib/cjs/utils/run-chat-loop.js +10 -5
  27. package/lib/cjs/utils/type-utils.d.ts +2 -0
  28. package/lib/cjs/utils/type-utils.js +44 -0
  29. package/lib/dts/agents/agent.d.ts +7 -4
  30. package/lib/dts/agents/ai-agent.d.ts +49 -1
  31. package/lib/dts/execution-engine/execution-engine.d.ts +1 -1
  32. package/lib/dts/execution-engine/utils.d.ts +1 -1
  33. package/lib/dts/index.d.ts +3 -0
  34. package/lib/dts/models/chat-model.d.ts +1 -0
  35. package/lib/dts/models/claude-chat-model.d.ts +58 -9
  36. package/lib/dts/models/openai-chat-model.d.ts +62 -9
  37. package/lib/dts/models/xai-chat-model.d.ts +12 -0
  38. package/lib/dts/prompt/prompt-builder.d.ts +2 -2
  39. package/lib/dts/utils/json-schema.d.ts +9 -1
  40. package/lib/dts/utils/type-utils.d.ts +2 -0
  41. package/lib/esm/agents/agent.d.ts +7 -4
  42. package/lib/esm/agents/agent.js +25 -8
  43. package/lib/esm/agents/ai-agent.d.ts +49 -1
  44. package/lib/esm/agents/ai-agent.js +26 -0
  45. package/lib/esm/agents/mcp-agent.js +31 -5
  46. package/lib/esm/agents/memory.js +8 -1
  47. package/lib/esm/execution-engine/execution-engine.d.ts +1 -1
  48. package/lib/esm/execution-engine/execution-engine.js +48 -0
  49. package/lib/esm/execution-engine/utils.d.ts +1 -1
  50. package/lib/esm/execution-engine/utils.js +6 -0
  51. package/lib/esm/index.d.ts +3 -0
  52. package/lib/esm/index.js +3 -0
  53. package/lib/esm/models/chat-model.d.ts +1 -0
  54. package/lib/esm/models/chat-model.js +1 -0
  55. package/lib/esm/models/claude-chat-model.d.ts +58 -9
  56. package/lib/esm/models/claude-chat-model.js +78 -42
  57. package/lib/esm/models/openai-chat-model.d.ts +62 -9
  58. package/lib/esm/models/openai-chat-model.js +38 -11
  59. package/lib/esm/models/xai-chat-model.d.ts +12 -0
  60. package/lib/esm/models/xai-chat-model.js +14 -0
  61. package/lib/esm/package.json +1 -0
  62. package/lib/esm/prompt/prompt-builder.d.ts +2 -2
  63. package/lib/esm/utils/json-schema.d.ts +9 -1
  64. package/lib/esm/utils/json-schema.js +13 -0
  65. package/lib/esm/utils/run-chat-loop.js +10 -5
  66. package/lib/esm/utils/type-utils.d.ts +2 -0
  67. package/lib/esm/utils/type-utils.js +43 -0
  68. package/package.json +7 -6
@@ -1,16 +1,65 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
- import { ChatModel, type ChatModelInput, type ChatModelOutput } from "./chat-model.js";
3
- export declare class ClaudeChatModel extends ChatModel {
4
- config?: {
5
- apiKey?: string;
6
- model?: string;
2
+ import { z } from "zod";
3
+ import { ChatModel, type ChatModelInput, type ChatModelOptions, type ChatModelOutput } from "./chat-model.js";
4
+ export interface ClaudeChatModelOptions {
5
+ apiKey?: string;
6
+ model?: string;
7
+ modelOptions?: ChatModelOptions;
8
+ }
9
+ export declare const claudeChatModelOptionsSchema: z.ZodObject<{
10
+ apiKey: z.ZodOptional<z.ZodString>;
11
+ model: z.ZodOptional<z.ZodString>;
12
+ modelOptions: z.ZodOptional<z.ZodObject<{
13
+ model: z.ZodOptional<z.ZodString>;
14
+ temperature: z.ZodOptional<z.ZodNumber>;
15
+ topP: z.ZodOptional<z.ZodNumber>;
16
+ frequencyPenalty: z.ZodOptional<z.ZodNumber>;
17
+ presencePenalty: z.ZodOptional<z.ZodNumber>;
18
+ parallelToolCalls: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ parallelToolCalls: boolean;
21
+ model?: string | undefined;
22
+ temperature?: number | undefined;
23
+ topP?: number | undefined;
24
+ frequencyPenalty?: number | undefined;
25
+ presencePenalty?: number | undefined;
26
+ }, {
27
+ model?: string | undefined;
28
+ temperature?: number | undefined;
29
+ topP?: number | undefined;
30
+ frequencyPenalty?: number | undefined;
31
+ presencePenalty?: number | undefined;
32
+ parallelToolCalls?: boolean | undefined;
33
+ }>>;
34
+ }, "strip", z.ZodTypeAny, {
35
+ modelOptions?: {
36
+ parallelToolCalls: boolean;
37
+ model?: string | undefined;
38
+ temperature?: number | undefined;
39
+ topP?: number | undefined;
40
+ frequencyPenalty?: number | undefined;
41
+ presencePenalty?: number | undefined;
7
42
  } | undefined;
8
- constructor(config?: {
9
- apiKey?: string;
10
- model?: string;
11
- } | undefined);
43
+ model?: string | undefined;
44
+ apiKey?: string | undefined;
45
+ }, {
46
+ modelOptions?: {
47
+ model?: string | undefined;
48
+ temperature?: number | undefined;
49
+ topP?: number | undefined;
50
+ frequencyPenalty?: number | undefined;
51
+ presencePenalty?: number | undefined;
52
+ parallelToolCalls?: boolean | undefined;
53
+ } | undefined;
54
+ model?: string | undefined;
55
+ apiKey?: string | undefined;
56
+ }>;
57
+ export declare class ClaudeChatModel extends ChatModel {
58
+ options?: ClaudeChatModelOptions | undefined;
59
+ constructor(options?: ClaudeChatModelOptions | undefined);
12
60
  private _client?;
13
61
  get client(): Anthropic;
62
+ get modelOptions(): ChatModelOptions | undefined;
14
63
  process(input: ChatModelInput): Promise<ChatModelOutput>;
15
64
  private extractResultFromClaudeStream;
16
65
  private requestStructuredOutput;
@@ -1,14 +1,67 @@
1
- import { ChatModel, type ChatModelInput, type ChatModelOutput } from "./chat-model.js";
2
- export declare class OpenAIChatModel extends ChatModel {
3
- config?: {
4
- apiKey?: string;
5
- model?: string;
1
+ import { z } from "zod";
2
+ import { ChatModel, type ChatModelInput, type ChatModelOptions, type ChatModelOutput } from "./chat-model.js";
3
+ export interface OpenAIChatModelOptions {
4
+ apiKey?: string;
5
+ baseURL?: string;
6
+ model?: string;
7
+ modelOptions?: ChatModelOptions;
8
+ }
9
+ export declare const openAIChatModelOptionsSchema: z.ZodObject<{
10
+ apiKey: z.ZodOptional<z.ZodString>;
11
+ baseURL: z.ZodOptional<z.ZodString>;
12
+ model: z.ZodOptional<z.ZodString>;
13
+ modelOptions: z.ZodOptional<z.ZodObject<{
14
+ model: z.ZodOptional<z.ZodString>;
15
+ temperature: z.ZodOptional<z.ZodNumber>;
16
+ topP: z.ZodOptional<z.ZodNumber>;
17
+ frequencyPenalty: z.ZodOptional<z.ZodNumber>;
18
+ presencePenalty: z.ZodOptional<z.ZodNumber>;
19
+ parallelToolCalls: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ parallelToolCalls: boolean;
22
+ model?: string | undefined;
23
+ temperature?: number | undefined;
24
+ topP?: number | undefined;
25
+ frequencyPenalty?: number | undefined;
26
+ presencePenalty?: number | undefined;
27
+ }, {
28
+ model?: string | undefined;
29
+ temperature?: number | undefined;
30
+ topP?: number | undefined;
31
+ frequencyPenalty?: number | undefined;
32
+ presencePenalty?: number | undefined;
33
+ parallelToolCalls?: boolean | undefined;
34
+ }>>;
35
+ }, "strip", z.ZodTypeAny, {
36
+ modelOptions?: {
37
+ parallelToolCalls: boolean;
38
+ model?: string | undefined;
39
+ temperature?: number | undefined;
40
+ topP?: number | undefined;
41
+ frequencyPenalty?: number | undefined;
42
+ presencePenalty?: number | undefined;
6
43
  } | undefined;
7
- constructor(config?: {
8
- apiKey?: string;
9
- model?: string;
10
- } | undefined);
44
+ model?: string | undefined;
45
+ apiKey?: string | undefined;
46
+ baseURL?: string | undefined;
47
+ }, {
48
+ modelOptions?: {
49
+ model?: string | undefined;
50
+ temperature?: number | undefined;
51
+ topP?: number | undefined;
52
+ frequencyPenalty?: number | undefined;
53
+ presencePenalty?: number | undefined;
54
+ parallelToolCalls?: boolean | undefined;
55
+ } | undefined;
56
+ model?: string | undefined;
57
+ apiKey?: string | undefined;
58
+ baseURL?: string | undefined;
59
+ }>;
60
+ export declare class OpenAIChatModel extends ChatModel {
61
+ options?: OpenAIChatModelOptions | undefined;
62
+ constructor(options?: OpenAIChatModelOptions | undefined);
11
63
  private _client?;
12
64
  private get client();
65
+ get modelOptions(): ChatModelOptions | undefined;
13
66
  process(input: ChatModelInput): Promise<ChatModelOutput>;
14
67
  }
@@ -0,0 +1,12 @@
1
+ import type { ChatModelOptions } from "./chat-model.js";
2
+ import { OpenAIChatModel } from "./openai-chat-model.js";
3
+ export interface XAIChatModelOptions {
4
+ apiKey?: string;
5
+ model?: string;
6
+ modelOptions?: ChatModelOptions;
7
+ baseURL?: string;
8
+ }
9
+ export declare class XAIChatModel extends OpenAIChatModel {
10
+ options?: XAIChatModelOptions | undefined;
11
+ constructor(options?: XAIChatModelOptions | undefined);
12
+ }
@@ -1,5 +1,5 @@
1
1
  import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
- import { Agent, type AgentOptions, type Message } from "../agents/agent.js";
2
+ import { Agent, type Message } from "../agents/agent.js";
3
3
  import type { AIAgent } from "../agents/ai-agent.js";
4
4
  import type { AgentMemory } from "../agents/memory.js";
5
5
  import type { Context } from "../execution-engine/context.js";
@@ -18,7 +18,7 @@ export interface PromptBuilderBuildOptions {
18
18
  agent?: AIAgent;
19
19
  input?: Message;
20
20
  model?: ChatModel;
21
- outputSchema?: AgentOptions["outputSchema"];
21
+ outputSchema?: Agent["outputSchema"];
22
22
  }
23
23
  export declare class PromptBuilder {
24
24
  static from(instructions: string): PromptBuilder;
@@ -1,4 +1,12 @@
1
- import type { ZodType } from "zod";
1
+ import type { ZodType, z } from "zod";
2
2
  import type { Message } from "../agents/agent.js";
3
3
  export declare function outputSchemaToResponseFormatSchema(agentOutput: ZodType<Message>): Record<string, unknown>;
4
4
  export declare function parseJSON(json: string): any;
5
+ /**
6
+ * Ensure that the union array has at least 1 item.
7
+ * NOTE: the zod union requires at least 2 items (just type definition, not runtime behavior)
8
+ * so we need to ensure that the union has at least 1 item.
9
+ * @param union - The union array
10
+ * @returns The union array with at least 1 item (but the type is at least 2 items for z.union)
11
+ */
12
+ export declare function ensureZodUnionArray<T extends z.ZodType>(union: T[]): [T, T, ...T[]];
@@ -1,3 +1,4 @@
1
+ import { type ZodType } from "zod";
1
2
  export type PromiseOrValue<T> = T | Promise<T>;
2
3
  export type Nullish<T> = T | null | undefined;
3
4
  export declare function isNonNullable<T>(value: T): value is NonNullable<T>;
@@ -9,3 +10,4 @@ export declare function get(obj: unknown, path: string | string[], type: "number
9
10
  export declare function createAccessorArray<T>(array: T[], accessor: (array: T[], name: string) => T | undefined): T[] & {
10
11
  [key: string]: T;
11
12
  };
13
+ export declare function checkArguments<T>(prefix: string, schema: ZodType<T>, args: T): void;
@@ -11,8 +11,8 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
11
11
  publishTopic?: PublishTopic<O>;
12
12
  name?: string;
13
13
  description?: string;
14
- inputSchema?: ZodType<I>;
15
- outputSchema?: ZodType<O>;
14
+ inputSchema?: AgentInputOutputSchema<I>;
15
+ outputSchema?: AgentInputOutputSchema<O>;
16
16
  includeInputInOutput?: boolean;
17
17
  tools?: (Agent | FunctionAgentFn)[];
18
18
  disableLogging?: boolean;
@@ -27,8 +27,10 @@ export declare abstract class Agent<I extends Message = Message, O extends Messa
27
27
  */
28
28
  get topic(): string;
29
29
  readonly description?: string;
30
- readonly inputSchema: ZodType<I>;
31
- readonly outputSchema: ZodType<O>;
30
+ private readonly _inputSchema?;
31
+ private readonly _outputSchema?;
32
+ get inputSchema(): ZodType<I>;
33
+ get outputSchema(): ZodType<O>;
32
34
  readonly includeInputInOutput?: boolean;
33
35
  readonly subscribeTopic?: SubscribeTopic;
34
36
  readonly publishTopic?: PublishTopic<Message>;
@@ -49,6 +51,7 @@ export declare abstract class Agent<I extends Message = Message, O extends Messa
49
51
  abstract process(input: I, context?: Context): Promise<O | TransferAgentOutput>;
50
52
  shutdown(): Promise<void>;
51
53
  }
54
+ export type AgentInputOutputSchema<I extends Message = Message> = ZodType<I> | ((agent: Agent) => ZodType<I>);
52
55
  export interface FunctionAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
53
56
  fn?: FunctionAgentFn<I, O>;
54
57
  }
@@ -8,12 +8,12 @@ export class Agent {
8
8
  constructor({ inputSchema, outputSchema, ...options }) {
9
9
  this.name = options.name || this.constructor.name;
10
10
  this.description = options.description;
11
- if ((inputSchema && !(inputSchema instanceof ZodObject)) ||
12
- (outputSchema && !(outputSchema instanceof ZodObject))) {
13
- throw new Error("inputSchema must be a Zod object");
14
- }
15
- this.inputSchema = (inputSchema || z.object({})).passthrough();
16
- this.outputSchema = (outputSchema || z.object({})).passthrough();
11
+ if (inputSchema)
12
+ checkAgentInputOutputSchema(inputSchema);
13
+ if (outputSchema)
14
+ checkAgentInputOutputSchema(outputSchema);
15
+ this._inputSchema = inputSchema;
16
+ this._outputSchema = outputSchema;
17
17
  this.includeInputInOutput = options.includeInputInOutput;
18
18
  this.subscribeTopic = options.subscribeTopic;
19
19
  this.publishTopic = options.publishTopic;
@@ -38,8 +38,20 @@ export class Agent {
38
38
  return `$agent_${this.name}`;
39
39
  }
40
40
  description;
41
- inputSchema;
42
- outputSchema;
41
+ _inputSchema;
42
+ _outputSchema;
43
+ get inputSchema() {
44
+ const s = this._inputSchema;
45
+ const schema = typeof s === "function" ? s(this) : s || z.object({});
46
+ checkAgentInputOutputSchema(schema);
47
+ return schema.passthrough();
48
+ }
49
+ get outputSchema() {
50
+ const s = this._outputSchema;
51
+ const schema = typeof s === "function" ? s(this) : s || z.object({});
52
+ checkAgentInputOutputSchema(schema);
53
+ return schema.passthrough();
54
+ }
43
55
  includeInputInOutput;
44
56
  subscribeTopic;
45
57
  publishTopic;
@@ -94,6 +106,11 @@ export class Agent {
94
106
  this.memory?.detach();
95
107
  }
96
108
  }
109
+ function checkAgentInputOutputSchema(schema) {
110
+ if (!(schema instanceof ZodObject) && typeof schema !== "function") {
111
+ throw new Error("schema must be a zod object or function return a zod object ");
112
+ }
113
+ }
97
114
  export class FunctionAgent extends Agent {
98
115
  static from(options) {
99
116
  return typeof options === "function" ? functionToAgent(options) : new FunctionAgent(options);
@@ -1,5 +1,6 @@
1
+ import { z } from "zod";
1
2
  import type { Context } from "../execution-engine/context.js";
2
- import type { ChatModel } from "../models/chat-model.js";
3
+ import { ChatModel } from "../models/chat-model.js";
3
4
  import { PromptBuilder } from "../prompt/prompt-builder.js";
4
5
  import { Agent, type AgentOptions, type Message } from "./agent.js";
5
6
  export interface AIAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
@@ -9,6 +10,53 @@ export interface AIAgentOptions<I extends Message = Message, O extends Message =
9
10
  toolChoice?: AIAgentToolChoice;
10
11
  }
11
12
  export type AIAgentToolChoice = "auto" | "none" | "required" | "router" | Agent;
13
+ export declare const aiAgentToolChoiceSchema: z.ZodUnion<[z.ZodLiteral<"auto">, z.ZodLiteral<"none">, z.ZodLiteral<"required">, z.ZodLiteral<"router">, z.ZodType<Agent<Message, Message>, z.ZodTypeDef, Agent<Message, Message>>]>;
14
+ export declare const aiAgentOptionsSchema: z.ZodObject<{
15
+ model: z.ZodOptional<z.ZodType<ChatModel, z.ZodTypeDef, ChatModel>>;
16
+ instructions: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<PromptBuilder, z.ZodTypeDef, PromptBuilder>]>>;
17
+ outputKey: z.ZodOptional<z.ZodString>;
18
+ toolChoice: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"auto">, z.ZodLiteral<"none">, z.ZodLiteral<"required">, z.ZodLiteral<"router">, z.ZodType<Agent<Message, Message>, z.ZodTypeDef, Agent<Message, Message>>]>>;
19
+ enableHistory: z.ZodOptional<z.ZodBoolean>;
20
+ maxHistoryMessages: z.ZodOptional<z.ZodNumber>;
21
+ includeInputInOutput: z.ZodOptional<z.ZodBoolean>;
22
+ subscribeTopic: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
23
+ publishTopic: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">, z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>]>>;
24
+ name: z.ZodOptional<z.ZodString>;
25
+ description: z.ZodOptional<z.ZodString>;
26
+ tools: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodType<Agent<Message, Message>, z.ZodTypeDef, Agent<Message, Message>>, z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>]>, "many">>;
27
+ disableLogging: z.ZodOptional<z.ZodBoolean>;
28
+ memory: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodAny, z.ZodAny]>>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ tools?: (Agent<Message, Message> | ((...args: unknown[]) => unknown))[] | undefined;
31
+ toolChoice?: "auto" | "none" | "required" | Agent<Message, Message> | "router" | undefined;
32
+ name?: string | undefined;
33
+ description?: string | undefined;
34
+ model?: ChatModel | undefined;
35
+ instructions?: string | PromptBuilder | undefined;
36
+ outputKey?: string | undefined;
37
+ enableHistory?: boolean | undefined;
38
+ maxHistoryMessages?: number | undefined;
39
+ includeInputInOutput?: boolean | undefined;
40
+ subscribeTopic?: string | string[] | undefined;
41
+ publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
42
+ disableLogging?: boolean | undefined;
43
+ memory?: any;
44
+ }, {
45
+ tools?: (Agent<Message, Message> | ((...args: unknown[]) => unknown))[] | undefined;
46
+ toolChoice?: "auto" | "none" | "required" | Agent<Message, Message> | "router" | undefined;
47
+ name?: string | undefined;
48
+ description?: string | undefined;
49
+ model?: ChatModel | undefined;
50
+ instructions?: string | PromptBuilder | undefined;
51
+ outputKey?: string | undefined;
52
+ enableHistory?: boolean | undefined;
53
+ maxHistoryMessages?: number | undefined;
54
+ includeInputInOutput?: boolean | undefined;
55
+ subscribeTopic?: string | string[] | undefined;
56
+ publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
57
+ disableLogging?: boolean | undefined;
58
+ memory?: any;
59
+ }>;
12
60
  export declare class AIAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
13
61
  static from<I extends Message, O extends Message>(options: AIAgentOptions<I, O>): AIAgent<I, O>;
14
62
  constructor(options: AIAgentOptions<I, O>);
@@ -1,12 +1,38 @@
1
+ import { z } from "zod";
2
+ import { ChatModel } from "../models/chat-model.js";
1
3
  import { MESSAGE_KEY, PromptBuilder } from "../prompt/prompt-builder.js";
2
4
  import { AgentMessageTemplate, ToolMessageTemplate } from "../prompt/template.js";
3
5
  import { Agent } from "./agent.js";
4
6
  import { isTransferAgentOutput } from "./types.js";
7
+ export const aiAgentToolChoiceSchema = z.union([
8
+ z.literal("auto"),
9
+ z.literal("none"),
10
+ z.literal("required"),
11
+ z.literal("router"),
12
+ z.instanceof(Agent),
13
+ ], { message: "aiAgentToolChoice must be 'auto', 'none', 'required', 'router', or an Agent" });
14
+ export const aiAgentOptionsSchema = z.object({
15
+ model: z.instanceof(ChatModel).optional(),
16
+ instructions: z.union([z.string(), z.instanceof(PromptBuilder)]).optional(),
17
+ outputKey: z.string().optional(),
18
+ toolChoice: aiAgentToolChoiceSchema.optional(),
19
+ enableHistory: z.boolean().optional(),
20
+ maxHistoryMessages: z.number().optional(),
21
+ includeInputInOutput: z.boolean().optional(),
22
+ subscribeTopic: z.union([z.string(), z.array(z.string())]).optional(),
23
+ publishTopic: z.union([z.string(), z.array(z.string()), z.function()]).optional(),
24
+ name: z.string().optional(),
25
+ description: z.string().optional(),
26
+ tools: z.array(z.union([z.instanceof(Agent), z.function()])).optional(),
27
+ disableLogging: z.boolean().optional(),
28
+ memory: z.union([z.boolean(), z.any(), z.any()]).optional(),
29
+ });
5
30
  export class AIAgent extends Agent {
6
31
  static from(options) {
7
32
  return new AIAgent(options);
8
33
  }
9
34
  constructor(options) {
35
+ aiAgentOptionsSchema.parse(options);
10
36
  super(options);
11
37
  this.model = options.model;
12
38
  this.instructions =
@@ -2,9 +2,10 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
2
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
3
3
  import { StdioClientTransport, getDefaultEnvironment, } from "@modelcontextprotocol/sdk/client/stdio.js";
4
4
  import { UriTemplate } from "@modelcontextprotocol/sdk/shared/uriTemplate.js";
5
+ import { z } from "zod";
5
6
  import { logger } from "../utils/logger.js";
6
7
  import { promptFromMCPPrompt, resourceFromMCPResource, toolFromMCPTool, } from "../utils/mcp-utils.js";
7
- import { createAccessorArray } from "../utils/type-utils.js";
8
+ import { checkArguments, createAccessorArray } from "../utils/type-utils.js";
8
9
  import { Agent } from "./agent.js";
9
10
  const MCP_AGENT_CLIENT_NAME = "MCPAgent";
10
11
  const MCP_AGENT_CLIENT_VERSION = "0.0.1";
@@ -15,11 +16,21 @@ function isSSEServerParameters(options) {
15
16
  function isStdioServerParameters(options) {
16
17
  return "command" in options && typeof options.command === "string";
17
18
  }
19
+ function getMCPServerString(options) {
20
+ if (isSSEServerParameters(options)) {
21
+ return options.url;
22
+ }
23
+ if (isStdioServerParameters(options)) {
24
+ return `${options.command} ${options.args?.join(" ") || ""}`;
25
+ }
26
+ return "unknown";
27
+ }
18
28
  export class MCPAgent extends Agent {
19
29
  static from(options) {
30
+ checkArguments("MCPAgent.from", mcpAgentOptionsSchema, options);
20
31
  if (isSSEServerParameters(options)) {
21
32
  const transport = new SSEClientTransport(new URL(options.url));
22
- return MCPAgent.fromTransport(transport);
33
+ return MCPAgent.fromTransport(transport, options);
23
34
  }
24
35
  if (isStdioServerParameters(options)) {
25
36
  const transport = new StdioClientTransport({
@@ -30,16 +41,16 @@ export class MCPAgent extends Agent {
30
41
  },
31
42
  stderr: "pipe",
32
43
  });
33
- return MCPAgent.fromTransport(transport);
44
+ return MCPAgent.fromTransport(transport, options);
34
45
  }
35
46
  return new MCPAgent(options);
36
47
  }
37
- static async fromTransport(transport) {
48
+ static async fromTransport(transport, options) {
38
49
  const client = new Client({
39
50
  name: MCP_AGENT_CLIENT_NAME,
40
51
  version: MCP_AGENT_CLIENT_VERSION,
41
52
  });
42
- await debug.spinner(client.connect(transport), "Connecting to MCP server");
53
+ await debug.spinner(client.connect(transport), `Connecting to MCP server: ${getMCPServerString(options)}`);
43
54
  const mcpServer = getMCPServerName(client);
44
55
  const { tools: isToolsAvailable, prompts: isPromptsAvailable, resources: isResourcesAvailable, } = client.getServerCapabilities() ?? {};
45
56
  const tools = isToolsAvailable
@@ -134,3 +145,18 @@ function getMCPServerName(client) {
134
145
  const { name, version } = info;
135
146
  return `${name}@${version}`;
136
147
  }
148
+ const mcpAgentOptionsSchema = z.union([
149
+ z.object({
150
+ client: z.instanceof(Client),
151
+ prompts: z.array(z.instanceof(MCPPrompt)).optional(),
152
+ resources: z.array(z.instanceof(MCPResource)).optional(),
153
+ }),
154
+ z.object({
155
+ url: z.string(),
156
+ }),
157
+ z.object({
158
+ command: z.string(),
159
+ args: z.array(z.string()).optional(),
160
+ env: z.record(z.string()).optional(),
161
+ }),
162
+ ]);
@@ -1,6 +1,8 @@
1
- import { orArrayToArray } from "../utils/type-utils.js";
1
+ import { z } from "zod";
2
+ import { checkArguments, orArrayToArray } from "../utils/type-utils.js";
2
3
  export class AgentMemory {
3
4
  constructor(options) {
5
+ checkArguments("AgentMemory", agentMemoryOptionsSchema, options);
4
6
  this.enabled = options.enabled ?? true;
5
7
  this.subscribeTopic = options.subscribeTopic;
6
8
  this.maxMemoriesInChat = options.maxMemoriesInChat;
@@ -32,3 +34,8 @@ export class AgentMemory {
32
34
  this.subscriptions = [];
33
35
  }
34
36
  }
37
+ const agentMemoryOptionsSchema = z.object({
38
+ enabled: z.boolean().optional(),
39
+ subscribeTopic: z.union([z.string(), z.array(z.string())]).optional(),
40
+ maxMemoriesInChat: z.number().optional(),
41
+ });
@@ -1,7 +1,7 @@
1
1
  import EventEmitter from "node:events";
2
2
  import { Agent, type Message } from "../agents/agent.js";
3
3
  import { UserAgent } from "../agents/user-agent.js";
4
- import type { ChatModel } from "../models/chat-model.js";
4
+ import { ChatModel } from "../models/chat-model.js";
5
5
  import type { Context, Runnable } from "./context.js";
6
6
  import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
7
7
  export interface ExecutionEngineOptions {
@@ -1,12 +1,17 @@
1
1
  import EventEmitter from "node:events";
2
2
  import { isNil } from "lodash-es";
3
+ import { z } from "zod";
3
4
  import { Agent } from "../agents/agent.js";
4
5
  import { isTransferAgentOutput, transferAgentOutputKey } from "../agents/types.js";
5
6
  import { UserAgent } from "../agents/user-agent.js";
7
+ import { ChatModel } from "../models/chat-model.js";
6
8
  import { createMessage } from "../prompt/prompt-builder.js";
9
+ import { checkArguments } from "../utils/type-utils.js";
7
10
  import { MessageQueue, } from "./message-queue.js";
8
11
  export class ExecutionEngine extends EventEmitter {
9
12
  constructor(options) {
13
+ if (options)
14
+ checkArguments("ExecutionEngine", executionEngineOptionsSchema, options);
10
15
  super();
11
16
  this.model = options?.model;
12
17
  this.tools = options?.tools ?? [];
@@ -19,6 +24,7 @@ export class ExecutionEngine extends EventEmitter {
19
24
  tools;
20
25
  agents = [];
21
26
  addAgent(...agents) {
27
+ checkArguments("ExecutionEngine.addAgent", executionEngineAddAgentArgsSchema, agents);
22
28
  for (const agent of agents) {
23
29
  this.agents.push(agent);
24
30
  agent.attach(this);
@@ -34,6 +40,11 @@ export class ExecutionEngine extends EventEmitter {
34
40
  * @param from the agent who publish the message, if not provided, it will be treated as a user message
35
41
  */
36
42
  publish(topic, message, from) {
43
+ checkArguments("ExecutionEngine.publish", executionEnginePublishArgsSchema, {
44
+ topic,
45
+ message,
46
+ from,
47
+ });
37
48
  const request = {
38
49
  role: !from || from instanceof UserAgent ? "user" : "agent",
39
50
  source: from?.name,
@@ -42,6 +53,11 @@ export class ExecutionEngine extends EventEmitter {
42
53
  this.messageQueue.publish(topic, request);
43
54
  }
44
55
  call(agent, message, options) {
56
+ checkArguments("ExecutionEngine.call", executionEngineCallArgsSchema, {
57
+ agent,
58
+ message,
59
+ options,
60
+ });
45
61
  if (isNil(message)) {
46
62
  let activeAgent = agent;
47
63
  return UserAgent.from({
@@ -76,9 +92,17 @@ export class ExecutionEngine extends EventEmitter {
76
92
  return { output, agent: activeAgent };
77
93
  }
78
94
  subscribe(topic, listener) {
95
+ checkArguments("ExecutionEngine.subscribe", executionEngineSubscribeArgsSchema, {
96
+ topic,
97
+ listener,
98
+ });
79
99
  return this.messageQueue.subscribe(topic, listener);
80
100
  }
81
101
  unsubscribe(topic, listener) {
102
+ checkArguments("ExecutionEngine.unsubscribe", executionEngineUnsubscribeArgsSchema, {
103
+ topic,
104
+ listener,
105
+ });
82
106
  this.messageQueue.unsubscribe(topic, listener);
83
107
  }
84
108
  async callAgent(agent, input) {
@@ -127,3 +151,27 @@ export class ExecutionEngine extends EventEmitter {
127
151
  process.on("exit", shutdownAndExit);
128
152
  }
129
153
  }
154
+ const executionEngineOptionsSchema = z.object({
155
+ model: z.instanceof(ChatModel).optional(),
156
+ tools: z.array(z.instanceof(Agent)).optional(),
157
+ agents: z.array(z.instanceof(Agent)).optional(),
158
+ });
159
+ const executionEngineAddAgentArgsSchema = z.array(z.instanceof(Agent));
160
+ const executionEnginePublishArgsSchema = z.object({
161
+ topic: z.union([z.string(), z.array(z.string())]),
162
+ message: z.union([z.string(), z.record(z.unknown())]),
163
+ from: z.instanceof(Agent).optional(),
164
+ });
165
+ const executionEngineCallArgsSchema = z.object({
166
+ agent: z.union([z.function(), z.instanceof(Agent)]),
167
+ message: z.union([z.record(z.unknown()), z.string()]).optional(),
168
+ options: z.object({ returnActiveAgent: z.boolean().optional() }).optional(),
169
+ });
170
+ const executionEngineSubscribeArgsSchema = z.object({
171
+ topic: z.string(),
172
+ listener: z.function(z.tuple([z.any()]), z.any()).optional(),
173
+ });
174
+ const executionEngineUnsubscribeArgsSchema = z.object({
175
+ topic: z.string(),
176
+ listener: z.function(z.tuple([z.any()]), z.any()),
177
+ });
@@ -1,4 +1,4 @@
1
- import type { FunctionAgentFn } from "../agents/agent.js";
1
+ import { type FunctionAgentFn } from "../agents/agent.js";
2
2
  import type { Runnable } from "./context.js";
3
3
  export declare function sequential(..._agents: [Runnable, ...Runnable[]]): FunctionAgentFn;
4
4
  export declare function parallel(..._agents: [Runnable, ...Runnable[]]): FunctionAgentFn;
@@ -1,4 +1,8 @@
1
+ import { z } from "zod";
2
+ import { Agent } from "../agents/agent.js";
3
+ import { checkArguments } from "../utils/type-utils.js";
1
4
  export function sequential(..._agents) {
5
+ checkArguments("sequential", agentArraySchema, _agents);
2
6
  let agents = [..._agents];
3
7
  return async (input, context) => {
4
8
  if (!context)
@@ -16,6 +20,7 @@ export function sequential(..._agents) {
16
20
  };
17
21
  }
18
22
  export function parallel(..._agents) {
23
+ checkArguments("parallel", agentArraySchema, _agents);
19
24
  let agents = [..._agents];
20
25
  return async (input, context) => {
21
26
  if (!context)
@@ -26,3 +31,4 @@ export function parallel(..._agents) {
26
31
  return Object.assign({}, ...outputs);
27
32
  };
28
33
  }
34
+ const agentArraySchema = z.array(z.union([z.function(), z.instanceof(Agent)]));
@@ -8,7 +8,10 @@ export * from "./execution-engine/index.js";
8
8
  export * from "./models/chat-model.js";
9
9
  export * from "./models/claude-chat-model.js";
10
10
  export * from "./models/openai-chat-model.js";
11
+ export * from "./models/xai-chat-model.js";
11
12
  export * from "./prompt/prompt-builder.js";
12
13
  export * from "./prompt/template.js";
14
+ export * from "./utils/json-schema.js";
13
15
  export * from "./utils/logger.js";
14
16
  export * from "./utils/run-chat-loop.js";
17
+ export * from "./utils/type-utils.js";
package/lib/esm/index.js CHANGED
@@ -8,7 +8,10 @@ export * from "./execution-engine/index.js";
8
8
  export * from "./models/chat-model.js";
9
9
  export * from "./models/claude-chat-model.js";
10
10
  export * from "./models/openai-chat-model.js";
11
+ export * from "./models/xai-chat-model.js";
11
12
  export * from "./prompt/prompt-builder.js";
12
13
  export * from "./prompt/template.js";
14
+ export * from "./utils/json-schema.js";
13
15
  export * from "./utils/logger.js";
14
16
  export * from "./utils/run-chat-loop.js";
17
+ export * from "./utils/type-utils.js";
@@ -65,6 +65,7 @@ export interface ChatModelOptions {
65
65
  topP?: number;
66
66
  frequencyPenalty?: number;
67
67
  presencePenalty?: number;
68
+ parallelToolCalls?: boolean;
68
69
  }
69
70
  export interface ChatModelOutput extends Message {
70
71
  text?: string;