@aigne/core 1.6.0 → 1.7.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 (82) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/lib/cjs/agents/agent.d.ts +5 -2
  3. package/lib/cjs/agents/agent.js +42 -24
  4. package/lib/cjs/agents/ai-agent.d.ts +8 -8
  5. package/lib/cjs/agents/ai-agent.js +5 -2
  6. package/lib/cjs/agents/mcp-agent.d.ts +11 -0
  7. package/lib/cjs/agents/mcp-agent.js +37 -23
  8. package/lib/cjs/agents/user-agent.d.ts +9 -9
  9. package/lib/cjs/agents/user-agent.js +26 -16
  10. package/lib/cjs/execution-engine/context.d.ts +84 -46
  11. package/lib/cjs/execution-engine/context.js +136 -98
  12. package/lib/cjs/execution-engine/execution-engine.d.ts +16 -47
  13. package/lib/cjs/execution-engine/execution-engine.js +13 -40
  14. package/lib/cjs/execution-engine/message-queue.d.ts +3 -3
  15. package/lib/cjs/execution-engine/message-queue.js +32 -2
  16. package/lib/cjs/execution-engine/usage.d.ts +11 -0
  17. package/lib/cjs/execution-engine/usage.js +10 -0
  18. package/lib/cjs/loader/index.js +1 -1
  19. package/lib/cjs/models/chat-model.d.ts +3 -2
  20. package/lib/cjs/models/chat-model.js +6 -5
  21. package/lib/cjs/models/claude-chat-model.js +10 -7
  22. package/lib/cjs/models/openai-chat-model.js +5 -2
  23. package/lib/cjs/prompt/prompt-builder.d.ts +1 -1
  24. package/lib/cjs/prompt/prompt-builder.js +3 -1
  25. package/lib/cjs/utils/json-schema.js +2 -2
  26. package/lib/cjs/utils/logger.d.ts +3 -15
  27. package/lib/cjs/utils/logger.js +3 -77
  28. package/lib/cjs/utils/mcp-utils.js +1 -5
  29. package/lib/cjs/utils/model-utils.js +2 -2
  30. package/lib/cjs/utils/type-utils.d.ts +1 -0
  31. package/lib/cjs/utils/typed-event-emtter.d.ts +10 -0
  32. package/lib/cjs/utils/typed-event-emtter.js +2 -0
  33. package/lib/dts/agents/agent.d.ts +5 -2
  34. package/lib/dts/agents/ai-agent.d.ts +8 -8
  35. package/lib/dts/agents/mcp-agent.d.ts +11 -0
  36. package/lib/dts/agents/user-agent.d.ts +9 -9
  37. package/lib/dts/execution-engine/context.d.ts +84 -46
  38. package/lib/dts/execution-engine/execution-engine.d.ts +16 -47
  39. package/lib/dts/execution-engine/message-queue.d.ts +3 -3
  40. package/lib/dts/execution-engine/usage.d.ts +11 -0
  41. package/lib/dts/models/chat-model.d.ts +3 -2
  42. package/lib/dts/prompt/prompt-builder.d.ts +1 -1
  43. package/lib/dts/utils/logger.d.ts +3 -15
  44. package/lib/dts/utils/type-utils.d.ts +1 -0
  45. package/lib/dts/utils/typed-event-emtter.d.ts +10 -0
  46. package/lib/esm/agents/agent.d.ts +5 -2
  47. package/lib/esm/agents/agent.js +42 -24
  48. package/lib/esm/agents/ai-agent.d.ts +8 -8
  49. package/lib/esm/agents/ai-agent.js +5 -2
  50. package/lib/esm/agents/mcp-agent.d.ts +11 -0
  51. package/lib/esm/agents/mcp-agent.js +38 -24
  52. package/lib/esm/agents/user-agent.d.ts +9 -9
  53. package/lib/esm/agents/user-agent.js +26 -16
  54. package/lib/esm/execution-engine/context.d.ts +84 -46
  55. package/lib/esm/execution-engine/context.js +135 -98
  56. package/lib/esm/execution-engine/execution-engine.d.ts +16 -47
  57. package/lib/esm/execution-engine/execution-engine.js +14 -38
  58. package/lib/esm/execution-engine/message-queue.d.ts +3 -3
  59. package/lib/esm/execution-engine/message-queue.js +33 -3
  60. package/lib/esm/execution-engine/usage.d.ts +11 -0
  61. package/lib/esm/execution-engine/usage.js +7 -0
  62. package/lib/esm/loader/index.js +2 -2
  63. package/lib/esm/models/chat-model.d.ts +3 -2
  64. package/lib/esm/models/chat-model.js +6 -5
  65. package/lib/esm/models/claude-chat-model.js +10 -7
  66. package/lib/esm/models/openai-chat-model.js +5 -2
  67. package/lib/esm/prompt/prompt-builder.d.ts +1 -1
  68. package/lib/esm/prompt/prompt-builder.js +3 -1
  69. package/lib/esm/utils/json-schema.js +2 -2
  70. package/lib/esm/utils/logger.d.ts +3 -15
  71. package/lib/esm/utils/logger.js +3 -77
  72. package/lib/esm/utils/mcp-utils.js +1 -5
  73. package/lib/esm/utils/model-utils.js +2 -2
  74. package/lib/esm/utils/type-utils.d.ts +1 -0
  75. package/lib/esm/utils/typed-event-emtter.d.ts +10 -0
  76. package/lib/esm/utils/typed-event-emtter.js +1 -0
  77. package/package.json +7 -8
  78. package/lib/cjs/utils/run-chat-loop.d.ts +0 -11
  79. package/lib/cjs/utils/run-chat-loop.js +0 -82
  80. package/lib/dts/utils/run-chat-loop.d.ts +0 -11
  81. package/lib/esm/utils/run-chat-loop.d.ts +0 -11
  82. package/lib/esm/utils/run-chat-loop.js +0 -76
@@ -2,19 +2,36 @@ import EventEmitter from "node:events";
2
2
  import { Agent, type FunctionAgentFn, type Message } from "../agents/agent.js";
3
3
  import { UserAgent } from "../agents/user-agent.js";
4
4
  import type { ChatModel } from "../models/chat-model.js";
5
+ import { type OmitPropertiesFromArrayFirstElement } from "../utils/type-utils.js";
6
+ import type { Args, Listener, TypedEventEmitter } from "../utils/typed-event-emtter.js";
5
7
  import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
8
+ import { type ContextLimits, type ContextUsage } from "./usage.js";
6
9
  export type Runnable<I extends Message = Message, O extends Message = Message> = Agent<I, O> | FunctionAgentFn;
7
- export interface ContextUsage {
8
- promptTokens: number;
9
- completionTokens: number;
10
- agentCalls: number;
10
+ export interface AgentEvent {
11
+ parentContextId?: string;
12
+ contextId: string;
13
+ timestamp: number;
14
+ agent: Agent;
11
15
  }
12
- export interface ContextLimits {
13
- maxTokens?: number;
14
- maxAgentCalls?: number;
15
- timeout?: number;
16
+ export interface ContextEventMap {
17
+ agentStarted: [AgentEvent & {
18
+ input: Message;
19
+ }];
20
+ agentSucceed: [AgentEvent & {
21
+ output: Message;
22
+ }];
23
+ agentFailed: [AgentEvent & {
24
+ error: Error;
25
+ }];
16
26
  }
17
- export interface Context extends EventEmitter {
27
+ export type ContextEmitEventMap = {
28
+ [K in keyof ContextEventMap]: OmitPropertiesFromArrayFirstElement<ContextEventMap[K], "contextId" | "parentContextId" | "timestamp">;
29
+ };
30
+ export interface CallOptions {
31
+ returnActiveAgent?: boolean;
32
+ disableTransfer?: boolean;
33
+ }
34
+ export interface Context extends TypedEventEmitter<ContextEventMap, ContextEmitEventMap> {
18
35
  model?: ChatModel;
19
36
  tools?: Agent[];
20
37
  usage: ContextUsage;
@@ -26,13 +43,6 @@ export interface Context extends EventEmitter {
26
43
  * @returns User agent
27
44
  */
28
45
  call<I extends Message, O extends Message>(agent: Runnable<I, O>): UserAgent<I, O>;
29
- /**
30
- * Call an agent with a message
31
- * @param agent Agent to call
32
- * @param message Message to pass to the agent
33
- * @returns the output of the agent
34
- */
35
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string): Promise<O>;
36
46
  /**
37
47
  * Call an agent with a message and return the output and the active agent
38
48
  * @param agent Agent to call
@@ -40,54 +50,82 @@ export interface Context extends EventEmitter {
40
50
  * @param options.returnActiveAgent return the active agent
41
51
  * @returns the output of the agent and the final active agent
42
52
  */
43
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options: {
53
+ call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options: CallOptions & {
44
54
  returnActiveAgent: true;
45
55
  }): Promise<[O, Runnable]>;
46
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options?: {
47
- returnActiveAgent?: boolean;
48
- }): UserAgent<I, O> | Promise<O | [O, Runnable]>;
56
+ /**
57
+ * Call an agent with a message
58
+ * @param agent Agent to call
59
+ * @param message Message to pass to the agent
60
+ * @returns the output of the agent
61
+ */
62
+ call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options?: CallOptions): Promise<O>;
63
+ call<I extends Message, O extends Message>(agent: Runnable<I, O>, message?: I | string, options?: CallOptions): UserAgent<I, O> | Promise<O | [O, Runnable]>;
49
64
  /**
50
65
  * Publish a message to a topic, the engine will call the listeners of the topic
51
66
  * @param topic topic name, or an array of topic names
52
- * @param message message to publish
53
- * @param from the agent who publish the message, if not provided, it will be treated as a user message
67
+ * @param payload message to publish
54
68
  */
55
- publish(topic: string | string[], message: Message | string, from?: Agent): void;
69
+ publish(topic: string | string[], payload: Omit<MessagePayload, "context">): void;
56
70
  subscribe(topic: string, listener?: undefined): Promise<MessagePayload>;
57
71
  subscribe(topic: string, listener: MessageQueueListener): Unsubscribe;
58
72
  subscribe(topic: string, listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
73
+ subscribe(topic: string, listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
59
74
  unsubscribe(topic: string, listener: MessageQueueListener): void;
75
+ /**
76
+ * Create a child context with the same configuration as the parent context.
77
+ * If `reset` is true, the child context will have a new state (such as: usage).
78
+ *
79
+ * @param options
80
+ * @param options.reset create a new context with initial state (such as: usage)
81
+ * @returns new context
82
+ */
83
+ newContext(options?: {
84
+ reset?: boolean;
85
+ }): Context;
86
+ }
87
+ export declare function createPublishMessage(message: string | Message, from?: Agent): Omit<MessagePayload, "context">;
88
+ export declare class ExecutionContext implements Context {
89
+ constructor(parent?: ConstructorParameters<typeof ExecutionContextInternal>[0]);
90
+ parentId?: string;
91
+ id: string;
92
+ readonly internal: ExecutionContextInternal;
93
+ get model(): ChatModel | undefined;
94
+ get tools(): Agent<Message, Message>[] | undefined;
95
+ get limits(): ContextLimits | undefined;
96
+ get status(): "normal" | "timeout";
97
+ get usage(): ContextUsage;
98
+ newContext({ reset }?: {
99
+ reset?: boolean;
100
+ }): ExecutionContext;
101
+ call: Context["call"];
102
+ publish: Context["publish"];
103
+ subscribe: Context["subscribe"];
104
+ unsubscribe: Context["unsubscribe"];
105
+ emit<K extends keyof ContextEmitEventMap>(eventName: K, ...args: Args<K, ContextEmitEventMap>): boolean;
106
+ on<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
107
+ once<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
108
+ off<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
60
109
  }
61
- export declare class ExecutionContext extends EventEmitter implements Context {
62
- private readonly engine?;
63
- constructor(engine?: {
64
- model?: ChatModel;
65
- tools?: Agent[];
66
- limits?: ContextLimits;
110
+ declare class ExecutionContextInternal {
111
+ private readonly parent?;
112
+ constructor(parent?: (Pick<Context, "model" | "tools" | "limits"> & {
67
113
  messageQueue?: MessageQueue;
68
- emit?: EventEmitter["emit"];
69
- } | undefined);
70
- private messageQueue;
114
+ }) | undefined);
115
+ readonly messageQueue: MessageQueue;
116
+ readonly events: EventEmitter<ContextEventMap>;
71
117
  get model(): ChatModel | undefined;
72
118
  get tools(): Agent<Message, Message>[] | undefined;
119
+ get limits(): ContextLimits | undefined;
73
120
  usage: ContextUsage;
74
- limits?: ContextLimits | undefined;
75
121
  private abortController;
76
122
  private timer?;
77
123
  private initTimeout;
78
124
  get status(): "normal" | "timeout";
79
- call<I extends Message, O extends Message>(agent: Runnable<I, O>): UserAgent<I, O>;
80
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string): Promise<O>;
81
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options: {
82
- returnActiveAgent: true;
83
- }): Promise<[O, Runnable]>;
84
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message?: I | string, options?: {
85
- returnActiveAgent?: boolean;
86
- }): UserAgent<I, O> | Promise<O | [O, Runnable]>;
87
- publish(topic: string | string[], message: Message | string, from?: Agent): void;
88
- subscribe(topic: string, listener?: undefined): Promise<MessagePayload>;
89
- subscribe(topic: string, listener: MessageQueueListener): Unsubscribe;
90
- unsubscribe(topic: string, listener: MessageQueueListener): void;
91
- emit(eventName: string | symbol, ...args: unknown[]): boolean;
125
+ call<I extends Message, O extends Message>(agent: Runnable<I, O>, input: I, context: Context, options?: CallOptions): Promise<{
126
+ agent: Runnable;
127
+ output: O;
128
+ }>;
92
129
  private callAgent;
93
130
  }
131
+ export {};
@@ -1,9 +1,8 @@
1
- import EventEmitter from "node:events";
2
- import { Agent, type Message } from "../agents/agent.js";
3
- import type { UserAgent } from "../agents/user-agent.js";
1
+ import { Agent } from "../agents/agent.js";
4
2
  import { ChatModel } from "../models/chat-model.js";
5
- import { type ContextLimits, ExecutionContext, type Runnable } from "./context.js";
6
- import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
3
+ import { type Context, ExecutionContext } from "./context.js";
4
+ import { MessageQueue } from "./message-queue.js";
5
+ import type { ContextLimits } from "./usage.js";
7
6
  export interface ExecutionEngineOptions {
8
7
  name?: string;
9
8
  description?: string;
@@ -12,7 +11,10 @@ export interface ExecutionEngineOptions {
12
11
  agents?: Agent[];
13
12
  limits?: ContextLimits;
14
13
  }
15
- export declare class ExecutionEngine extends EventEmitter {
14
+ export interface ExecutionEngineRunOptions {
15
+ returnActiveAgent?: boolean;
16
+ }
17
+ export declare class ExecutionEngine {
16
18
  static load({ path, ...options }: {
17
19
  path: string;
18
20
  } & ExecutionEngineOptions): Promise<ExecutionEngine>;
@@ -21,52 +23,19 @@ export declare class ExecutionEngine extends EventEmitter {
21
23
  description?: string;
22
24
  readonly messageQueue: MessageQueue;
23
25
  model?: ChatModel;
24
- readonly tools: Agent<Message, Message>[] & {
25
- [key: string]: Agent<Message, Message>;
26
+ readonly tools: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[] & {
27
+ [key: string]: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>;
26
28
  };
27
- readonly agents: Agent<Message, Message>[] & {
28
- [key: string]: Agent<Message, Message>;
29
+ readonly agents: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[] & {
30
+ [key: string]: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>;
29
31
  };
30
32
  limits?: ContextLimits;
31
33
  addAgent(...agents: Agent[]): void;
32
34
  newContext(): ExecutionContext;
33
- /**
34
- * Publish a message to a topic, the engine will call the listeners of the topic
35
- * @param topic topic name, or an array of topic names
36
- * @param message message to publish
37
- * @param from the agent who publish the message, if not provided, it will be treated as a user message
38
- */
39
- publish(topic: string | string[], message: Message | string, from?: Agent): void;
40
- /**
41
- * Create a user agent to consistently call an agent
42
- * @param agent Agent to call
43
- * @returns User agent
44
- */
45
- call<I extends Message, O extends Message>(agent: Runnable<I, O>): UserAgent<I, O>;
46
- /**
47
- * Call an agent with a message
48
- * @param agent Agent to call
49
- * @param message Message to pass to the agent
50
- * @returns the output of the agent
51
- */
52
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string): Promise<O>;
53
- /**
54
- * Call an agent with a message and return the output and the active agent
55
- * @param agent Agent to call
56
- * @param message Message to pass to the agent
57
- * @param options.returnActiveAgent return the active agent
58
- * @returns the output of the agent and the final active agent
59
- */
60
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options: {
61
- returnActiveAgent: true;
62
- }): Promise<[O, Runnable]>;
63
- call<I extends Message, O extends Message>(agent: Runnable<I, O>, message?: I | string, options?: {
64
- returnActiveAgent?: boolean;
65
- }): UserAgent<I, O> | Promise<O | [O, Runnable]>;
66
- subscribe(topic: string, listener?: undefined): Promise<MessagePayload>;
67
- subscribe(topic: string, listener: MessageQueueListener): Unsubscribe;
68
- subscribe(topic: string, listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
69
- unsubscribe(topic: string, listener: MessageQueueListener): void;
35
+ publish: Context["publish"];
36
+ call: Context["call"];
37
+ subscribe: Context["subscribe"];
38
+ unsubscribe: Context["unsubscribe"];
70
39
  shutdown(): Promise<void>;
71
40
  private initProcessExitHandler;
72
41
  }
@@ -1,3 +1,4 @@
1
+ import { EventEmitter } from "node:events";
1
2
  import type { Message } from "../agents/agent.js";
2
3
  import type { Context } from "./context.js";
3
4
  export declare const UserInputTopic = "UserInputTopic";
@@ -9,11 +10,10 @@ export interface MessagePayload {
9
10
  context: Context;
10
11
  }
11
12
  export type MessageQueueListener = (message: MessagePayload) => void;
12
- export type MessageRequest = MessagePayload;
13
13
  export type Unsubscribe = () => void;
14
14
  export declare class MessageQueue {
15
- private events;
16
- publish(topic: string | string[], message: MessageRequest): void;
15
+ events: EventEmitter<[never]>;
16
+ publish(topic: string | string[], payload: MessagePayload): void;
17
17
  error(error: Error): void;
18
18
  subscribe(topic: string, listener?: undefined): Promise<MessagePayload>;
19
19
  subscribe(topic: string, listener: MessageQueueListener): Unsubscribe;
@@ -0,0 +1,11 @@
1
+ export interface ContextUsage {
2
+ inputTokens: number;
3
+ outputTokens: number;
4
+ agentCalls: number;
5
+ }
6
+ export declare function newEmptyContextUsage(): ContextUsage;
7
+ export interface ContextLimits {
8
+ maxTokens?: number;
9
+ maxAgentCalls?: number;
10
+ timeout?: number;
11
+ }
@@ -75,6 +75,7 @@ export interface ChatModelOutput extends Message {
75
75
  json?: object;
76
76
  toolCalls?: ChatModelOutputToolCall[];
77
77
  usage?: ChatModelOutputUsage;
78
+ model?: string;
78
79
  }
79
80
  export interface ChatModelOutputToolCall {
80
81
  id: string;
@@ -85,6 +86,6 @@ export interface ChatModelOutputToolCall {
85
86
  };
86
87
  }
87
88
  export interface ChatModelOutputUsage {
88
- promptTokens: number;
89
- completionTokens: number;
89
+ inputTokens: number;
90
+ outputTokens: number;
90
91
  }
@@ -7,7 +7,7 @@ import type { ChatModel, ChatModelInput } from "../models/chat-model.js";
7
7
  import { ChatMessagesTemplate } from "./template.js";
8
8
  export declare const MESSAGE_KEY = "$message";
9
9
  export declare const DEFAULT_MAX_HISTORY_MESSAGES = 10;
10
- export declare function createMessage(message: string | object): Message;
10
+ export declare function createMessage<I extends Message>(message: string | I): I;
11
11
  export declare function getMessage(input: Message): string | undefined;
12
12
  export interface PromptBuilderOptions {
13
13
  instructions?: string | ChatMessagesTemplate;
@@ -1,20 +1,8 @@
1
- import debug, { type Debugger } from "debug";
2
- import type { Ora } from "ora";
3
- interface DebugWithSpinner extends Debugger {
4
- spinner<T>(promise: Promise<T>, message?: string, callback?: (result: T) => void, options?: {
5
- disabled?: boolean;
6
- }): Promise<T>;
7
- extend: (namespace: string) => DebugWithSpinner;
8
- }
9
- declare function spinner<T>(promise: Promise<T>, message?: string, callback?: (result: T) => void): Promise<T>;
1
+ import debug from "debug";
10
2
  export declare const logger: debug.Debug & {
11
3
  debug: debug.Debug;
12
4
  default: debug.Debug;
13
5
  } & {
14
- globalSpinner: Ora | undefined;
15
- base: DebugWithSpinner;
16
- debug: DebugWithSpinner;
17
- spinner: typeof spinner;
18
- setSpinner: (spinner: Ora) => void;
6
+ core: debug.Debugger;
7
+ mcp: debug.Debugger;
19
8
  };
20
- export {};
@@ -1,6 +1,7 @@
1
1
  import { type ZodType } from "zod";
2
2
  export type PromiseOrValue<T> = T | Promise<T>;
3
3
  export type Nullish<T> = T | null | undefined;
4
+ export type OmitPropertiesFromArrayFirstElement<T extends unknown[], K extends string | number | symbol> = T extends [infer U, ...infer Rest] ? [Omit<U, K>, ...Rest] : never;
4
5
  export declare function isNil(value: unknown): value is null | undefined;
5
6
  export declare function isEmpty(obj: unknown): boolean;
6
7
  export declare function isNonNullable<T>(value: T): value is NonNullable<T>;
@@ -0,0 +1,10 @@
1
+ type EventMap<T> = Record<keyof T, unknown[]>;
2
+ export type Args<K, T> = K extends keyof T ? T[K] : never;
3
+ export type Listener<K, T> = K extends keyof T ? T[K] extends unknown[] ? (...args: T[K]) => void : never : never;
4
+ export interface TypedEventEmitter<T extends EventMap<T>, E extends EventMap<E> = T> {
5
+ emit<K extends keyof E>(eventName: K, ...args: Args<K, E>): boolean;
6
+ on<K extends keyof T>(eventName: K, listener: Listener<K, T>): this;
7
+ once<K extends keyof T>(eventName: K, listener: Listener<K, T>): this;
8
+ off<K extends keyof T>(eventName: K, listener: Listener<K, T>): this;
9
+ }
10
+ export {};
@@ -1,3 +1,4 @@
1
+ import { inspect } from "node:util";
1
2
  import { type ZodType } from "zod";
2
3
  import type { Context } from "../execution-engine/context.js";
3
4
  import { type Nullish, type PromiseOrValue } from "../utils/type-utils.js";
@@ -15,7 +16,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
15
16
  outputSchema?: AgentInputOutputSchema<O>;
16
17
  includeInputInOutput?: boolean;
17
18
  tools?: (Agent | FunctionAgentFn)[];
18
- disableLogging?: boolean;
19
+ disableEvents?: boolean;
19
20
  memory?: AgentMemory | AgentMemoryOptions | true;
20
21
  }
21
22
  export declare abstract class Agent<I extends Message = Message, O extends Message = Message> {
@@ -37,7 +38,7 @@ export declare abstract class Agent<I extends Message = Message, O extends Messa
37
38
  readonly tools: Agent<Message, Message>[] & {
38
39
  [key: string]: Agent<Message, Message>;
39
40
  };
40
- private disableLogging?;
41
+ private disableEvents?;
41
42
  /**
42
43
  * Attach agent to context:
43
44
  * - subscribe to topic and call process method when message received
@@ -50,10 +51,12 @@ export declare abstract class Agent<I extends Message = Message, O extends Messa
50
51
  private checkContextStatus;
51
52
  private newDefaultContext;
52
53
  call(input: I | string, context?: Context): Promise<O>;
54
+ protected checkUsageAgentCalls(context: Context): void;
53
55
  protected preprocess(_: I, context: Context): void;
54
56
  protected postprocess(input: I, output: O, context: Context): void;
55
57
  abstract process(input: I, context: Context): Promise<O | TransferAgentOutput>;
56
58
  shutdown(): Promise<void>;
59
+ [inspect.custom](): string;
57
60
  }
58
61
  export type AgentInputOutputSchema<I extends Message = Message> = ZodType<I> | ((agent: Agent) => ZodType<I>);
59
62
  export interface FunctionAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
@@ -1,3 +1,4 @@
1
+ import { inspect } from "node:util";
1
2
  import { ZodObject, z } from "zod";
2
3
  import { createMessage } from "../prompt/prompt-builder.js";
3
4
  import { logger } from "../utils/logger.js";
@@ -19,7 +20,7 @@ export class Agent {
19
20
  this.publishTopic = options.publishTopic;
20
21
  if (options.tools?.length)
21
22
  this.tools.push(...options.tools.map(functionToAgent));
22
- this.disableLogging = options.disableLogging;
23
+ this.disableEvents = options.disableEvents;
23
24
  if (options.memory) {
24
25
  this.memory =
25
26
  options.memory instanceof AgentMemory
@@ -56,7 +57,7 @@ export class Agent {
56
57
  subscribeTopic;
57
58
  publishTopic;
58
59
  tools = createAccessorArray([], (arr, name) => arr.find((t) => t.name === name));
59
- disableLogging;
60
+ disableEvents;
60
61
  /**
61
62
  * Attach agent to context:
62
63
  * - subscribe to topic and call process method when message received
@@ -71,7 +72,7 @@ export class Agent {
71
72
  await context.call(this, message);
72
73
  }
73
74
  catch (error) {
74
- context.emit("error", error);
75
+ context.emit("agentFailed", { agent: this, error });
75
76
  }
76
77
  });
77
78
  }
@@ -95,31 +96,45 @@ export class Agent {
95
96
  }
96
97
  async call(input, context) {
97
98
  const ctx = context ?? (await this.newDefaultContext());
98
- const _input = typeof input === "string" ? createMessage(input) : input;
99
- const parsedInput = this.inputSchema.parse(_input);
100
- logger.debug("Call agent %s start with input: %O", this.name, input);
101
- this.preprocess(parsedInput, ctx);
102
- this.checkContextStatus(ctx);
103
- const result = this.process(parsedInput, ctx)
104
- .then((output) => {
105
- const parsedOutput = this.outputSchema.parse(output);
106
- return this.includeInputInOutput ? { ...parsedInput, ...parsedOutput } : parsedOutput;
107
- })
108
- .then((output) => {
109
- this.postprocess(parsedInput, output, ctx);
99
+ const message = typeof input === "string" ? createMessage(input) : input;
100
+ logger.core("Call agent %s started with input: %O", this.name, input);
101
+ if (!this.disableEvents)
102
+ ctx.emit("agentStarted", { agent: this, input: message });
103
+ try {
104
+ const parsedInput = this.inputSchema.parse(message);
105
+ this.preprocess(parsedInput, ctx);
106
+ this.checkContextStatus(ctx);
107
+ const output = await this.process(parsedInput, ctx)
108
+ .then((output) => {
109
+ const parsedOutput = this.outputSchema.parse(output);
110
+ return this.includeInputInOutput ? { ...parsedInput, ...parsedOutput } : parsedOutput;
111
+ })
112
+ .then((output) => {
113
+ this.postprocess(parsedInput, output, ctx);
114
+ return output;
115
+ });
116
+ logger.core("Call agent %s succeed with output: %O", this.name, input);
117
+ if (!this.disableEvents)
118
+ ctx.emit("agentSucceed", { agent: this, output });
110
119
  return output;
111
- });
112
- return logger.debug.spinner(result, `Call agent ${this.name}`, (output) => logger.debug("Call agent %s succeed with output: %O", this.name, replaceTransferAgentToName(output)), { disabled: this.disableLogging });
120
+ }
121
+ catch (error) {
122
+ logger.core("Call agent %s failed with error: %O", this.name, error);
123
+ if (!this.disableEvents)
124
+ ctx.emit("agentFailed", { agent: this, error });
125
+ throw error;
126
+ }
127
+ }
128
+ checkUsageAgentCalls(context) {
129
+ const { limits, usage } = context;
130
+ if (limits?.maxAgentCalls && usage.agentCalls >= limits.maxAgentCalls) {
131
+ throw new Error(`Exceeded max agent calls ${usage.agentCalls}/${limits.maxAgentCalls}`);
132
+ }
133
+ usage.agentCalls++;
113
134
  }
114
135
  preprocess(_, context) {
115
136
  this.checkContextStatus(context);
116
- if (context) {
117
- const { limits, usage } = context;
118
- if (limits?.maxAgentCalls && usage.agentCalls >= limits.maxAgentCalls) {
119
- throw new Error(`Exceeded max agent calls ${usage.agentCalls}/${limits.maxAgentCalls}`);
120
- }
121
- usage.agentCalls++;
122
- }
137
+ this.checkUsageAgentCalls(context);
123
138
  }
124
139
  postprocess(input, output, context) {
125
140
  this.checkContextStatus(context);
@@ -133,6 +148,9 @@ export class Agent {
133
148
  async shutdown() {
134
149
  this.memory?.detach();
135
150
  }
151
+ [inspect.custom]() {
152
+ return this.name;
153
+ }
136
154
  }
137
155
  function checkAgentInputOutputSchema(schema) {
138
156
  if (!(schema instanceof ZodObject) && typeof schema !== "function") {
@@ -28,6 +28,10 @@ export declare const aiAgentOptionsSchema: z.ZodObject<{
28
28
  memory: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodAny, z.ZodAny]>>;
29
29
  }, "strip", z.ZodTypeAny, {
30
30
  description?: string | undefined;
31
+ memory?: any;
32
+ includeInputInOutput?: boolean | undefined;
33
+ subscribeTopic?: string | string[] | undefined;
34
+ publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
31
35
  tools?: (Agent<Message, Message> | ((...args: unknown[]) => unknown))[] | undefined;
32
36
  toolChoice?: Agent<Message, Message> | "auto" | "none" | "required" | "router" | undefined;
33
37
  name?: string | undefined;
@@ -36,13 +40,13 @@ export declare const aiAgentOptionsSchema: z.ZodObject<{
36
40
  outputKey?: string | undefined;
37
41
  enableHistory?: boolean | undefined;
38
42
  maxHistoryMessages?: number | undefined;
39
- includeInputInOutput?: boolean | undefined;
40
- subscribeTopic?: string | string[] | undefined;
41
- publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
42
43
  disableLogging?: boolean | undefined;
43
- memory?: any;
44
44
  }, {
45
45
  description?: string | undefined;
46
+ memory?: any;
47
+ includeInputInOutput?: boolean | undefined;
48
+ subscribeTopic?: string | string[] | undefined;
49
+ publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
46
50
  tools?: (Agent<Message, Message> | ((...args: unknown[]) => unknown))[] | undefined;
47
51
  toolChoice?: Agent<Message, Message> | "auto" | "none" | "required" | "router" | undefined;
48
52
  name?: string | undefined;
@@ -51,11 +55,7 @@ export declare const aiAgentOptionsSchema: z.ZodObject<{
51
55
  outputKey?: string | undefined;
52
56
  enableHistory?: boolean | undefined;
53
57
  maxHistoryMessages?: number | undefined;
54
- includeInputInOutput?: boolean | undefined;
55
- subscribeTopic?: string | string[] | undefined;
56
- publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
57
58
  disableLogging?: boolean | undefined;
58
- memory?: any;
59
59
  }>;
60
60
  export declare class AIAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
61
61
  static from<I extends Message, O extends Message>(options: AIAgentOptions<I, O>): AIAgent<I, O>;
@@ -59,7 +59,10 @@ export class AIAgent extends Agent {
59
59
  const toolsMap = new Map(toolAgents?.map((i) => [i.name, i]));
60
60
  const toolCallMessages = [];
61
61
  for (;;) {
62
- const { text, json, toolCalls } = await model.call({ ...modelInput, messages: messages.concat(toolCallMessages) }, context);
62
+ const { text, json, toolCalls } = await context.call(model, {
63
+ ...modelInput,
64
+ messages: messages.concat(toolCallMessages),
65
+ });
63
66
  if (toolCalls?.length) {
64
67
  const executedToolCalls = [];
65
68
  // Execute tools
@@ -68,7 +71,7 @@ export class AIAgent extends Agent {
68
71
  if (!tool)
69
72
  throw new Error(`Tool not found: ${call.function.name}`);
70
73
  // NOTE: should pass both arguments (model generated) and input (user provided) to the tool
71
- const output = await tool.call({ ...call.function.arguments, ...input }, context);
74
+ const output = await context.call(tool, { ...call.function.arguments, ...input }, { disableTransfer: true });
72
75
  // NOTE: Return transfer output immediately
73
76
  if (isTransferAgentOutput(output)) {
74
77
  return output;
@@ -1,4 +1,5 @@
1
1
  import { Client, type ClientOptions } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { type SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.js";
2
3
  import { type StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js";
3
4
  import type { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
4
5
  import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
@@ -15,6 +16,15 @@ export interface MCPAgentOptions extends AgentOptions {
15
16
  export type MCPServerOptions = SSEServerParameters | StdioServerParameters;
16
17
  export type SSEServerParameters = {
17
18
  url: string;
19
+ /**
20
+ * Additional options to pass to the SSEClientTransport.
21
+ */
22
+ opts?: SSEClientTransportOptions;
23
+ /**
24
+ * The timeout for requests to the server, in milliseconds.
25
+ * @default 10000
26
+ */
27
+ timeout?: number;
18
28
  /**
19
29
  * Whether to automatically reconnect to the server if the connection is lost.
20
30
  * @default 10 set to 0 to disable automatic reconnection
@@ -44,6 +54,7 @@ export declare class MCPAgent extends Agent {
44
54
  }
45
55
  export interface ClientWithReconnectOptions {
46
56
  transportCreator?: () => PromiseOrValue<Transport>;
57
+ timeout?: number;
47
58
  maxReconnects?: number;
48
59
  shouldReconnect?: (error: Error) => boolean;
49
60
  }