@aigne/core 1.1.0-beta.6 → 1.3.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 (105) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/lib/cjs/agents/agent.d.ts +37 -33
  3. package/lib/cjs/agents/agent.js +68 -28
  4. package/lib/cjs/agents/ai-agent.d.ts +8 -12
  5. package/lib/cjs/agents/ai-agent.js +17 -35
  6. package/lib/cjs/agents/mcp-agent.d.ts +25 -9
  7. package/lib/cjs/agents/mcp-agent.js +61 -14
  8. package/lib/cjs/agents/memory.d.ts +26 -0
  9. package/lib/cjs/agents/memory.js +38 -0
  10. package/lib/cjs/agents/types.d.ts +4 -3
  11. package/lib/cjs/agents/types.js +11 -1
  12. package/lib/cjs/agents/user-agent.d.ts +24 -0
  13. package/lib/cjs/agents/user-agent.js +62 -0
  14. package/lib/cjs/execution-engine/context.d.ts +35 -5
  15. package/lib/cjs/execution-engine/execution-engine.d.ts +64 -0
  16. package/lib/cjs/execution-engine/execution-engine.js +136 -0
  17. package/lib/cjs/execution-engine/index.d.ts +4 -46
  18. package/lib/cjs/execution-engine/index.js +17 -193
  19. package/lib/cjs/execution-engine/message-queue.d.ts +17 -2
  20. package/lib/cjs/execution-engine/message-queue.js +37 -1
  21. package/lib/cjs/execution-engine/utils.d.ts +4 -0
  22. package/lib/cjs/execution-engine/utils.js +32 -0
  23. package/lib/cjs/index.d.ts +14 -12
  24. package/lib/cjs/index.js +14 -12
  25. package/lib/{dts/models/chat.d.ts → cjs/models/chat-model.d.ts} +15 -12
  26. package/lib/cjs/models/{chat.js → chat-model.js} +5 -5
  27. package/lib/cjs/models/claude-chat-model.d.ts +17 -0
  28. package/lib/cjs/models/claude-chat-model.js +199 -0
  29. package/lib/cjs/models/{chat-openai.d.ts → openai-chat-model.d.ts} +2 -2
  30. package/lib/cjs/models/{chat-openai.js → openai-chat-model.js} +8 -8
  31. package/lib/cjs/prompt/prompt-builder.d.ts +14 -14
  32. package/lib/cjs/prompt/prompt-builder.js +62 -67
  33. package/lib/cjs/prompt/template.d.ts +9 -21
  34. package/lib/cjs/prompt/template.js +3 -5
  35. package/lib/cjs/utils/json-schema.d.ts +3 -0
  36. package/lib/cjs/utils/json-schema.js +23 -0
  37. package/lib/cjs/utils/mcp-utils.d.ts +3 -2
  38. package/lib/cjs/utils/mcp-utils.js +29 -17
  39. package/lib/cjs/utils/run-chat-loop.d.ts +5 -4
  40. package/lib/cjs/utils/run-chat-loop.js +25 -4
  41. package/lib/cjs/utils/type-utils.d.ts +3 -0
  42. package/lib/cjs/utils/type-utils.js +8 -8
  43. package/lib/dts/agents/agent.d.ts +37 -33
  44. package/lib/dts/agents/ai-agent.d.ts +8 -12
  45. package/lib/dts/agents/mcp-agent.d.ts +25 -9
  46. package/lib/dts/agents/memory.d.ts +26 -0
  47. package/lib/dts/agents/types.d.ts +4 -3
  48. package/lib/dts/agents/user-agent.d.ts +24 -0
  49. package/lib/dts/execution-engine/context.d.ts +35 -5
  50. package/lib/dts/execution-engine/execution-engine.d.ts +64 -0
  51. package/lib/dts/execution-engine/index.d.ts +4 -46
  52. package/lib/dts/execution-engine/message-queue.d.ts +17 -2
  53. package/lib/dts/execution-engine/utils.d.ts +4 -0
  54. package/lib/dts/index.d.ts +14 -12
  55. package/lib/{esm/models/chat.d.ts → dts/models/chat-model.d.ts} +15 -12
  56. package/lib/dts/models/claude-chat-model.d.ts +17 -0
  57. package/lib/dts/models/{chat-openai.d.ts → openai-chat-model.d.ts} +2 -2
  58. package/lib/dts/prompt/prompt-builder.d.ts +14 -14
  59. package/lib/dts/prompt/template.d.ts +9 -21
  60. package/lib/dts/utils/json-schema.d.ts +3 -0
  61. package/lib/dts/utils/mcp-utils.d.ts +3 -2
  62. package/lib/dts/utils/run-chat-loop.d.ts +5 -4
  63. package/lib/dts/utils/type-utils.d.ts +3 -0
  64. package/lib/esm/agents/agent.d.ts +37 -33
  65. package/lib/esm/agents/agent.js +67 -24
  66. package/lib/esm/agents/ai-agent.d.ts +8 -12
  67. package/lib/esm/agents/ai-agent.js +13 -31
  68. package/lib/esm/agents/mcp-agent.d.ts +25 -9
  69. package/lib/esm/agents/mcp-agent.js +54 -8
  70. package/lib/esm/agents/memory.d.ts +26 -0
  71. package/lib/esm/agents/memory.js +34 -0
  72. package/lib/esm/agents/types.d.ts +4 -3
  73. package/lib/esm/agents/types.js +10 -1
  74. package/lib/esm/agents/user-agent.d.ts +24 -0
  75. package/lib/esm/agents/user-agent.js +58 -0
  76. package/lib/esm/execution-engine/context.d.ts +35 -5
  77. package/lib/esm/execution-engine/execution-engine.d.ts +64 -0
  78. package/lib/esm/execution-engine/execution-engine.js +129 -0
  79. package/lib/esm/execution-engine/index.d.ts +4 -46
  80. package/lib/esm/execution-engine/index.js +4 -188
  81. package/lib/esm/execution-engine/message-queue.d.ts +17 -2
  82. package/lib/esm/execution-engine/message-queue.js +37 -1
  83. package/lib/esm/execution-engine/utils.d.ts +4 -0
  84. package/lib/esm/execution-engine/utils.js +28 -0
  85. package/lib/esm/index.d.ts +14 -12
  86. package/lib/esm/index.js +14 -12
  87. package/lib/{cjs/models/chat.d.ts → esm/models/chat-model.d.ts} +15 -12
  88. package/lib/esm/models/{chat.js → chat-model.js} +4 -4
  89. package/lib/esm/models/claude-chat-model.d.ts +17 -0
  90. package/lib/esm/models/claude-chat-model.js +192 -0
  91. package/lib/esm/models/{chat-openai.d.ts → openai-chat-model.d.ts} +2 -2
  92. package/lib/esm/models/{chat-openai.js → openai-chat-model.js} +5 -5
  93. package/lib/esm/prompt/prompt-builder.d.ts +14 -14
  94. package/lib/esm/prompt/prompt-builder.js +56 -58
  95. package/lib/esm/prompt/template.d.ts +9 -21
  96. package/lib/esm/prompt/template.js +3 -5
  97. package/lib/esm/utils/json-schema.d.ts +3 -0
  98. package/lib/esm/utils/json-schema.js +20 -0
  99. package/lib/esm/utils/mcp-utils.d.ts +3 -2
  100. package/lib/esm/utils/mcp-utils.js +26 -15
  101. package/lib/esm/utils/run-chat-loop.d.ts +5 -4
  102. package/lib/esm/utils/run-chat-loop.js +25 -4
  103. package/lib/esm/utils/type-utils.d.ts +3 -0
  104. package/lib/esm/utils/type-utils.js +4 -2
  105. package/package.json +31 -30
package/CHANGELOG.md CHANGED
@@ -1,3 +1,80 @@
1
+ ## [1.3.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.2.0...core-v1.3.0) (2025-03-24)
2
+
3
+
4
+ ### Features
5
+
6
+ * add Agent FunctionAgent AIAgent MCPAgent and ExecutionEngine ([4d2a5a1](https://github.com/AIGNE-io/aigne-framework/commit/4d2a5a1b3366b8f935f50a0937c2da6e49073348))
7
+ * add OrchestratorAgent in agent library ([25a5e9e](https://github.com/AIGNE-io/aigne-framework/commit/25a5e9e6c60d747c8bf484ac884b31dc02c14757))
8
+ * add sequential and parallel helper function ([a295697](https://github.com/AIGNE-io/aigne-framework/commit/a295697b5694754e02954fc5c7f382a3b219a3ab))
9
+ * add support for MCP resources ([1ded2fb](https://github.com/AIGNE-io/aigne-framework/commit/1ded2fbf222fa8984e75df0852ff384524f73b04))
10
+ * **core:** add ChatModelClaude to use models of anthropic ([#30](https://github.com/AIGNE-io/aigne-framework/issues/30)) ([0a62a64](https://github.com/AIGNE-io/aigne-framework/commit/0a62a6499e3da723a4646e67952051708ce7de6a))
11
+ * **core:** add support for subscribing topics for agent memory ([#28](https://github.com/AIGNE-io/aigne-framework/issues/28)) ([eeecc67](https://github.com/AIGNE-io/aigne-framework/commit/eeecc67049a60ebcc4cdba0fbcd987b3d81f4af6))
12
+ * **prompt-builder:** support chat history in PromptBuilder ([6ca05f2](https://github.com/AIGNE-io/aigne-framework/commit/6ca05f28eddb683a4f1e228865f8bbf8a8e190f1))
13
+ * support run puppeteer example chat loop in terminal ([85ce7f8](https://github.com/AIGNE-io/aigne-framework/commit/85ce7f8de8b443c86e50815dd7bcab99f869c4ce))
14
+ * use PromptBuilder instead of string instructions ([e4cb2cb](https://github.com/AIGNE-io/aigne-framework/commit/e4cb2cb6baf4f9bcef390567a4a174e9246c29a3))
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **AIAgent:** should pass both arguments (model generated) and input (user input) to tool ([c49d64e](https://github.com/AIGNE-io/aigne-framework/commit/c49d64ee35f7efd83b0f82f43205bb1c40f999e8))
20
+ * **core:** enforce stricter input/output type checks ([#26](https://github.com/AIGNE-io/aigne-framework/issues/26)) ([ef8cf53](https://github.com/AIGNE-io/aigne-framework/commit/ef8cf53586aff08a809909c56ab2a20f215fa129))
21
+ * **MCP:** catch list resource error treat as empty list ([1885fab](https://github.com/AIGNE-io/aigne-framework/commit/1885fab3585e0dd1467b127e5b47cd0b98282bab))
22
+ * rename @aigne/core-next to @aigne/core ([3a81009](https://github.com/AIGNE-io/aigne-framework/commit/3a8100962c81813217b687ae28e8de604419c622))
23
+ * use text resource from MCP correctly ([8b9eba8](https://github.com/AIGNE-io/aigne-framework/commit/8b9eba83352ec096a2a5d4f410d4c4bde7420bce))
24
+
25
+ ## [1.2.0](https://github.com/AIGNE-io/aigne-framework/compare/core-next-v1.1.0...core-next-v1.2.0) (2025-03-18)
26
+
27
+ - chore: release v1.2.0
28
+
29
+ ## 1.1.0-beta.17 (2025-3-18)
30
+
31
+ - chore: add support for esm module
32
+
33
+
34
+ ## 1.1.0-beta.16 (2025-3-18)
35
+
36
+ - chore: add puppeteer in linux need docker_container
37
+
38
+ ## 1.1.0-beta.15 (2025-3-18)
39
+
40
+ - chore: make coverage report as text to terminal
41
+ - chore: update contributing docs
42
+
43
+ ## 1.1.0-beta.14 (2025-3-18)
44
+
45
+ - chore(example): add code-execution example
46
+
47
+ ## 1.1.0-beta.13 (2025-3-18)
48
+
49
+ - feat: add OrchestratorAgent in agent library
50
+
51
+ ## 1.1.0-beta.12 (2025-3-14)
52
+
53
+ - chore(example): add concurrency reflection handoff workflow examples
54
+
55
+ ## 1.1.0-beta.11 (2025-3-14)
56
+
57
+ - feat(core): add sequential and parallel helper function
58
+ - chore(examples): add workflow-sequential example
59
+
60
+ ## 1.1.0-beta.10 (2025-3-13)
61
+
62
+ - chore: ensure required environment variables have values
63
+
64
+ ## 1.1.0-beta.9 (2025-3-13)
65
+
66
+ - fix(MCP): catch list resource error treat as empty list
67
+
68
+ ## 1.1.0-beta.8 (2025-3-13)
69
+
70
+ - fix(AIAgent): should pass both arguments (model generated) and input (user input) to tool
71
+ - chore(examples): add workflow-router example
72
+ - chore(examples): rename examples puppeteer-mcp-server and sqlite-mcp-server to mcp-server-puppeteer and mcp-server-sqlite
73
+
74
+ ## 1.1.0-beta.7 (2025-3-13)
75
+
76
+ - chore: rename @aigne/core to @aigne/core
77
+
1
78
  ## 1.1.0-beta.6 (2025-3-13)
2
79
 
3
80
  - chore(examples): default enable mcp debug message for examples
@@ -1,57 +1,61 @@
1
- import EventEmitter from "node:events";
2
- import { type ZodObject, type ZodType } from "zod";
3
- import type { Context } from "../execution-engine/context";
4
- import { type TransferAgentOutput } from "./types";
5
- export type AgentInput = Record<string, unknown>;
6
- export type AgentOutput = Record<string, unknown> & Partial<TransferAgentOutput>;
1
+ import { type ZodType } from "zod";
2
+ import type { Context } from "../execution-engine/context.js";
3
+ import { type Nullish, type PromiseOrValue } from "../utils/type-utils.js";
4
+ import { AgentMemory, type AgentMemoryOptions } from "./memory.js";
5
+ import { type TransferAgentOutput } from "./types.js";
6
+ export type Message = Record<string, unknown>;
7
7
  export type SubscribeTopic = string | string[];
8
- export type PublishTopic<O extends AgentOutput = AgentOutput> = string | string[] | ((output: O) => string | string[] | Promise<string | string[]>);
9
- export interface AgentOptions<I extends AgentInput = AgentInput, O extends AgentOutput = AgentOutput> {
8
+ export type PublishTopic<O extends Message> = string | string[] | ((output: O) => PromiseOrValue<Nullish<string | string[]>>);
9
+ export interface AgentOptions<I extends Message = Message, O extends Message = Message> {
10
10
  subscribeTopic?: SubscribeTopic;
11
11
  publishTopic?: PublishTopic<O>;
12
12
  name?: string;
13
13
  description?: string;
14
- inputSchema?: ZodObject<{
15
- [key in keyof I]: ZodType;
16
- }>;
17
- outputSchema?: ZodObject<{
18
- [key in keyof O]: ZodType;
19
- }>;
14
+ inputSchema?: ZodType<I>;
15
+ outputSchema?: ZodType<O>;
20
16
  includeInputInOutput?: boolean;
21
17
  tools?: (Agent | FunctionAgentFn)[];
22
18
  disableLogging?: boolean;
19
+ memory?: AgentMemory | AgentMemoryOptions | true;
23
20
  }
24
- export declare class Agent<I extends AgentInput = AgentInput, O extends AgentOutput = AgentOutput> extends EventEmitter {
25
- static from<I extends AgentInput = AgentInput, O extends AgentOutput = AgentOutput>(options: AgentOptions<I, O>): Agent<I, O>;
26
- constructor(options: AgentOptions<I, O>);
21
+ export declare abstract class Agent<I extends Message = Message, O extends Message = Message> {
22
+ constructor({ inputSchema, outputSchema, ...options }: AgentOptions<I, O>);
23
+ readonly memory?: AgentMemory;
27
24
  readonly name: string;
25
+ /**
26
+ * Default topic this agent will subscribe to
27
+ */
28
+ get topic(): string;
28
29
  readonly description?: string;
29
- readonly inputSchema: ZodObject<{
30
- [key in keyof I]: ZodType;
31
- }>;
32
- readonly outputSchema: ZodObject<{
33
- [key in keyof O]: ZodType;
34
- }>;
30
+ readonly inputSchema: ZodType<I>;
31
+ readonly outputSchema: ZodType<O>;
35
32
  readonly includeInputInOutput?: boolean;
36
33
  readonly subscribeTopic?: SubscribeTopic;
37
- readonly publishTopic?: PublishTopic<AgentOutput>;
38
- readonly tools: Agent<AgentInput, AgentOutput>[] & {
39
- [key: string]: Agent<AgentInput, AgentOutput>;
34
+ readonly publishTopic?: PublishTopic<Message>;
35
+ readonly tools: Agent<Message, Message>[] & {
36
+ [key: string]: Agent<Message, Message>;
40
37
  };
41
38
  private disableLogging?;
42
- addTool<I extends AgentInput, O extends AgentOutput>(tool: Agent<I, O> | FunctionAgentFn<I, O>): void;
39
+ /**
40
+ * Attach agent to context:
41
+ * - subscribe to topic and call process method when message received
42
+ * - subscribe to memory topic if memory is enabled
43
+ * @param context Context to attach
44
+ */
45
+ attach(context: Context): void;
46
+ addTool<I extends Message, O extends Message>(tool: Agent<I, O> | FunctionAgentFn<I, O>): void;
43
47
  get isCallable(): boolean;
44
48
  call(input: I | string, context?: Context): Promise<O>;
45
- process?(input: I, context?: Context): Promise<O>;
49
+ abstract process(input: I, context?: Context): Promise<O | TransferAgentOutput>;
46
50
  shutdown(): Promise<void>;
47
51
  }
48
- export interface FunctionAgentOptions<I extends AgentInput = AgentInput, O extends AgentOutput = AgentOutput> extends AgentOptions<I, O> {
52
+ export interface FunctionAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
49
53
  fn?: FunctionAgentFn<I, O>;
50
54
  }
51
- export declare class FunctionAgent<I extends AgentInput = AgentInput, O extends AgentOutput = AgentOutput> extends Agent<I, O> {
52
- static from<I extends AgentInput, O extends AgentOutput>(options: FunctionAgentOptions<I, O> | FunctionAgentFn<I, O>): FunctionAgent<I, O>;
55
+ export declare class FunctionAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
56
+ static from<I extends Message, O extends Message>(options: FunctionAgentOptions<I, O> | FunctionAgentFn<I, O>): FunctionAgent<I, O>;
53
57
  constructor(options: FunctionAgentOptions<I, O>);
54
58
  fn: FunctionAgentFn<I, O>;
55
- process(input: I, context?: Context): Promise<O>;
59
+ process(input: I, context?: Context): Promise<TransferAgentOutput | O>;
56
60
  }
57
- export type FunctionAgentFn<I extends AgentInput = AgentInput, O extends AgentOutput = AgentOutput> = (input: I, context?: Context) => O | Promise<O> | Agent | Promise<Agent>;
61
+ export type FunctionAgentFn<I extends Message = Message, O extends Message = Message> = (input: I, context?: Context) => O | Promise<O> | Agent | Promise<Agent>;
@@ -1,43 +1,72 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.FunctionAgent = exports.Agent = void 0;
7
- const node_events_1 = __importDefault(require("node:events"));
8
4
  const zod_1 = require("zod");
9
- const prompt_builder_1 = require("../prompt/prompt-builder");
10
- const logger_1 = require("../utils/logger");
11
- const type_utils_1 = require("../utils/type-utils");
12
- const types_1 = require("./types");
13
- class Agent extends node_events_1.default {
14
- static from(options) {
15
- return new Agent(options);
16
- }
17
- constructor(options) {
18
- super();
5
+ const prompt_builder_js_1 = require("../prompt/prompt-builder.js");
6
+ const logger_js_1 = require("../utils/logger.js");
7
+ const type_utils_js_1 = require("../utils/type-utils.js");
8
+ const memory_js_1 = require("./memory.js");
9
+ const types_js_1 = require("./types.js");
10
+ class Agent {
11
+ constructor({ inputSchema, outputSchema, ...options }) {
19
12
  this.name = options.name || this.constructor.name;
20
13
  this.description = options.description;
21
- this.inputSchema =
22
- options.inputSchema || zod_1.z.object({});
23
- this.outputSchema =
24
- options.outputSchema || zod_1.z.object({});
14
+ if ((inputSchema && !(inputSchema instanceof zod_1.ZodObject)) ||
15
+ (outputSchema && !(outputSchema instanceof zod_1.ZodObject))) {
16
+ throw new Error("inputSchema must be a Zod object");
17
+ }
18
+ this.inputSchema = (inputSchema || zod_1.z.object({})).passthrough();
19
+ this.outputSchema = (outputSchema || zod_1.z.object({})).passthrough();
25
20
  this.includeInputInOutput = options.includeInputInOutput;
26
21
  this.subscribeTopic = options.subscribeTopic;
27
22
  this.publishTopic = options.publishTopic;
28
23
  if (options.tools?.length)
29
24
  this.tools.push(...options.tools.map(functionToAgent));
30
25
  this.disableLogging = options.disableLogging;
26
+ if (options.memory) {
27
+ this.memory =
28
+ options.memory instanceof memory_js_1.AgentMemory
29
+ ? options.memory
30
+ : typeof options.memory === "boolean"
31
+ ? new memory_js_1.AgentMemory({ enabled: options.memory })
32
+ : new memory_js_1.AgentMemory(options.memory);
33
+ }
31
34
  }
35
+ memory;
32
36
  name;
37
+ /**
38
+ * Default topic this agent will subscribe to
39
+ */
40
+ get topic() {
41
+ return `$agent_${this.name}`;
42
+ }
33
43
  description;
34
44
  inputSchema;
35
45
  outputSchema;
36
46
  includeInputInOutput;
37
47
  subscribeTopic;
38
48
  publishTopic;
39
- tools = (0, type_utils_1.createAccessorArray)([], (arr, name) => arr.find((t) => t.name === name));
49
+ tools = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((t) => t.name === name));
40
50
  disableLogging;
51
+ /**
52
+ * Attach agent to context:
53
+ * - subscribe to topic and call process method when message received
54
+ * - subscribe to memory topic if memory is enabled
55
+ * @param context Context to attach
56
+ */
57
+ attach(context) {
58
+ this.memory?.attach(context);
59
+ for (const topic of (0, type_utils_js_1.orArrayToArray)(this.subscribeTopic).concat(this.topic)) {
60
+ context.subscribe(topic, async ({ message }) => {
61
+ try {
62
+ await context.call(this, message);
63
+ }
64
+ catch (error) {
65
+ context.emit("error", error);
66
+ }
67
+ });
68
+ }
69
+ }
41
70
  addTool(tool) {
42
71
  this.tools.push(typeof tool === "function" ? functionToAgent(tool) : tool);
43
72
  }
@@ -45,17 +74,28 @@ class Agent extends node_events_1.default {
45
74
  return !!this.process;
46
75
  }
47
76
  async call(input, context) {
48
- if (!this.process)
49
- throw new Error("Agent must implement process method");
50
- const _input = typeof input === "string" ? (0, prompt_builder_1.userInput)(input) : input;
51
- const parsedInput = this.inputSchema.passthrough().parse(_input);
52
- const result = this.process(parsedInput, context).then((output) => {
53
- const parsedOutput = this.outputSchema.passthrough().parse(output);
77
+ const _input = typeof input === "string" ? (0, prompt_builder_js_1.createMessage)(input) : input;
78
+ const parsedInput = this.inputSchema.parse(_input);
79
+ logger_js_1.logger.debug("Call agent %s start with input: %O", this.name, input);
80
+ const result = this.process(parsedInput, context)
81
+ .then((output) => {
82
+ const parsedOutput = this.outputSchema.parse(output);
54
83
  return this.includeInputInOutput ? { ...parsedInput, ...parsedOutput } : parsedOutput;
84
+ })
85
+ .then((output) => {
86
+ this.memory?.addMemory({ role: "user", content: _input });
87
+ this.memory?.addMemory({
88
+ role: "agent",
89
+ content: (0, types_js_1.replaceTransferAgentToName)(output),
90
+ source: this.name,
91
+ });
92
+ return output;
55
93
  });
56
- return logger_1.logger.debug.spinner(result, `Call agent ${this.name}`, (output) => logger_1.logger.debug("input: %O\noutput: %O", input, output), { disabled: this.disableLogging });
94
+ return logger_js_1.logger.debug.spinner(result, `Call agent ${this.name}`, (output) => logger_js_1.logger.debug("Call agent %s succeed with output: %O", this.name, (0, types_js_1.replaceTransferAgentToName)(output)), { disabled: this.disableLogging });
95
+ }
96
+ async shutdown() {
97
+ this.memory?.detach();
57
98
  }
58
- async shutdown() { }
59
99
  }
60
100
  exports.Agent = Agent;
61
101
  class FunctionAgent extends Agent {
@@ -70,7 +110,7 @@ class FunctionAgent extends Agent {
70
110
  async process(input, context) {
71
111
  const result = await this.fn(input, context);
72
112
  if (result instanceof Agent) {
73
- return (0, types_1.transferToAgentOutput)(result);
113
+ return (0, types_js_1.transferToAgentOutput)(result);
74
114
  }
75
115
  return result;
76
116
  }
@@ -1,24 +1,20 @@
1
- import type { Context } from "../execution-engine/context";
2
- import type { ChatModel } from "../models/chat";
3
- import { PromptBuilder } from "../prompt/prompt-builder";
4
- import { Agent, type AgentInput, type AgentOptions, type AgentOutput } from "./agent";
5
- export interface AIAgentOptions<I extends AgentInput = AgentInput, O extends AgentOutput = AgentOutput> extends AgentOptions<I, O> {
1
+ import type { Context } from "../execution-engine/context.js";
2
+ import type { ChatModel } from "../models/chat-model.js";
3
+ import { PromptBuilder } from "../prompt/prompt-builder.js";
4
+ import { Agent, type AgentOptions, type Message } from "./agent.js";
5
+ export interface AIAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
6
6
  model?: ChatModel;
7
7
  instructions?: string | PromptBuilder;
8
8
  outputKey?: string;
9
9
  toolChoice?: AIAgentToolChoice;
10
- enableHistory?: boolean;
11
- maxHistoryMessages?: number;
12
10
  }
13
11
  export type AIAgentToolChoice = "auto" | "none" | "required" | "router" | Agent;
14
- export declare class AIAgent<I extends AgentInput = AgentInput, O extends AgentOutput = AgentOutput> extends Agent<I, O> {
15
- static from<I extends AgentInput, O extends AgentOutput>(options: AIAgentOptions<I, O>): AIAgent<I, O>;
12
+ export declare class AIAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
13
+ static from<I extends Message, O extends Message>(options: AIAgentOptions<I, O>): AIAgent<I, O>;
16
14
  constructor(options: AIAgentOptions<I, O>);
17
15
  model?: ChatModel;
18
16
  instructions: PromptBuilder;
19
17
  outputKey?: string;
20
18
  toolChoice?: AIAgentToolChoice;
21
- enableHistory?: boolean;
22
- maxHistoryMessages: number;
23
- process(input: I, context?: Context): Promise<O>;
19
+ process(input: I, context?: Context): Promise<import("./types.js").TransferAgentOutput | O>;
24
20
  }
@@ -1,13 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AIAgent = void 0;
4
- const prompt_builder_1 = require("../prompt/prompt-builder");
5
- const template_1 = require("../prompt/template");
6
- const agent_1 = require("./agent");
7
- const types_1 = require("./types");
8
- const DEFAULT_OUTPUT_KEY = "text";
9
- const DEFAULT_MAX_HISTORY_MESSAGES = 10;
10
- class AIAgent extends agent_1.Agent {
4
+ const prompt_builder_js_1 = require("../prompt/prompt-builder.js");
5
+ const template_js_1 = require("../prompt/template.js");
6
+ const agent_js_1 = require("./agent.js");
7
+ const types_js_1 = require("./types.js");
8
+ class AIAgent extends agent_js_1.Agent {
11
9
  static from(options) {
12
10
  return new AIAgent(options);
13
11
  }
@@ -16,27 +14,22 @@ class AIAgent extends agent_1.Agent {
16
14
  this.model = options.model;
17
15
  this.instructions =
18
16
  typeof options.instructions === "string"
19
- ? prompt_builder_1.PromptBuilder.from(options.instructions)
20
- : (options.instructions ?? new prompt_builder_1.PromptBuilder());
17
+ ? prompt_builder_js_1.PromptBuilder.from(options.instructions)
18
+ : (options.instructions ?? new prompt_builder_js_1.PromptBuilder());
21
19
  this.outputKey = options.outputKey;
22
20
  this.toolChoice = options.toolChoice;
23
- this.enableHistory = options.enableHistory;
24
- this.maxHistoryMessages = options.maxHistoryMessages ?? DEFAULT_MAX_HISTORY_MESSAGES;
25
21
  }
26
22
  model;
27
23
  instructions;
28
24
  outputKey;
29
25
  toolChoice;
30
- enableHistory;
31
- maxHistoryMessages;
32
26
  async process(input, context) {
27
+ if (!context)
28
+ throw new Error("Context is required to run AIAgent");
33
29
  const model = context?.model ?? this.model;
34
30
  if (!model)
35
31
  throw new Error("model is required to run AIAgent");
36
- let transferOutput;
37
32
  const { toolAgents, messages, ...modelInput } = await this.instructions.build({
38
- enableHistory: this.enableHistory,
39
- maxHistoryMessages: this.maxHistoryMessages,
40
33
  agent: this,
41
34
  input,
42
35
  model,
@@ -53,18 +46,17 @@ class AIAgent extends agent_1.Agent {
53
46
  const tool = toolsMap.get(call.function.name);
54
47
  if (!tool)
55
48
  throw new Error(`Tool not found: ${call.function.name}`);
56
- const output = await tool.call(call.function.arguments, context);
57
- // Save the TransferAgentOutput for later
58
- if ((0, types_1.isTransferAgentOutput)(output)) {
59
- transferOutput = output;
60
- }
61
- else {
62
- executedToolCalls.push({ call, output });
49
+ // NOTE: should pass both arguments (model generated) and input (user provided) to the tool
50
+ const output = await tool.call({ ...call.function.arguments, ...input }, context);
51
+ // NOTE: Return transfer output immediately
52
+ if ((0, types_js_1.isTransferAgentOutput)(output)) {
53
+ return output;
63
54
  }
55
+ executedToolCalls.push({ call, output });
64
56
  }
65
57
  // Continue LLM function calling loop if any tools were executed
66
58
  if (executedToolCalls.length) {
67
- toolCallMessages.push(template_1.AgentMessageTemplate.from(executedToolCalls.map(({ call }) => call)).format(), ...executedToolCalls.map(({ call, output }) => template_1.ToolMessageTemplate.from(output, call.id).format()));
59
+ toolCallMessages.push(template_js_1.AgentMessageTemplate.from(undefined, executedToolCalls.map(({ call }) => call)).format(), ...executedToolCalls.map(({ call, output }) => template_js_1.ToolMessageTemplate.from(output, call.id).format()));
68
60
  // Return the output of the first tool if the toolChoice is "router"
69
61
  if (this.toolChoice === "router") {
70
62
  const output = executedToolCalls[0]?.output;
@@ -77,23 +69,13 @@ class AIAgent extends agent_1.Agent {
77
69
  }
78
70
  }
79
71
  const result = {};
80
- if (json) {
81
- this.instructions.addHistory(template_1.AgentMessageTemplate.from(JSON.stringify(json)).format());
82
- }
83
- else if (text) {
84
- this.instructions.addHistory(template_1.AgentMessageTemplate.from(text).format());
85
- }
86
72
  if (modelInput.responseFormat?.type === "json_schema") {
87
73
  Object.assign(result, json);
88
74
  }
89
75
  else {
90
- const outputKey = this.outputKey || DEFAULT_OUTPUT_KEY;
76
+ const outputKey = this.outputKey || prompt_builder_js_1.MESSAGE_KEY;
91
77
  Object.assign(result, { [outputKey]: text });
92
78
  }
93
- // Return the TransferAgentOutput if it exists
94
- if (transferOutput) {
95
- result[types_1.transferAgentOutputKey] = transferOutput[types_1.transferAgentOutputKey];
96
- }
97
79
  return result;
98
80
  }
99
81
  }
@@ -1,10 +1,12 @@
1
1
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
2
  import { type StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js";
3
- import type { CallToolResult, GetPromptResult } from "@modelcontextprotocol/sdk/types";
4
- import { Agent, type AgentInput, type AgentOptions, type AgentOutput } from "./agent";
3
+ import type { CallToolResult, GetPromptResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
4
+ import type { Context } from "../execution-engine/context.js";
5
+ import { Agent, type AgentOptions, type Message } from "./agent.js";
5
6
  export interface MCPAgentOptions extends AgentOptions {
6
7
  client: Client;
7
8
  prompts?: MCPPrompt[];
9
+ resources?: MCPResource[];
8
10
  }
9
11
  export type MCPServerOptions = SSEServerParameters | StdioServerParameters;
10
12
  export type SSEServerParameters = {
@@ -19,21 +21,35 @@ export declare class MCPAgent extends Agent {
19
21
  readonly prompts: MCPPrompt[] & {
20
22
  [key: string]: MCPPrompt;
21
23
  };
24
+ readonly resources: MCPResource[] & {
25
+ [key: string]: MCPResource;
26
+ };
27
+ get isCallable(): boolean;
28
+ process(_input: Message, _context?: Context): Promise<Message>;
22
29
  shutdown(): Promise<void>;
23
30
  }
24
- export interface MCPToolBaseOptions<I extends AgentInput, O extends AgentOutput> extends AgentOptions<I, O> {
31
+ export interface MCPToolBaseOptions<I extends Message, O extends Message> extends AgentOptions<I, O> {
25
32
  client: Client;
26
33
  }
27
- export declare abstract class MCPBase<I extends AgentInput, O extends AgentOutput> extends Agent<I, O> {
34
+ export declare abstract class MCPBase<I extends Message, O extends Message> extends Agent<I, O> {
28
35
  constructor(options: MCPToolBaseOptions<I, O>);
29
36
  protected client: Client;
30
37
  protected get mcpServer(): string | undefined;
31
38
  }
32
- export declare class MCPTool extends MCPBase<AgentInput, CallToolResult> {
33
- process(input: AgentInput): Promise<CallToolResult>;
39
+ export declare class MCPTool extends MCPBase<Message, CallToolResult> {
40
+ process(input: Message): Promise<CallToolResult>;
34
41
  }
35
- export declare class MCPPrompt extends MCPBase<{
42
+ export interface MCPPromptInput extends Message {
36
43
  [key: string]: string;
37
- }, GetPromptResult> {
38
- process(input: AgentInput): Promise<GetPromptResult>;
44
+ }
45
+ export declare class MCPPrompt extends MCPBase<MCPPromptInput, GetPromptResult> {
46
+ process(input: MCPPromptInput): Promise<GetPromptResult>;
47
+ }
48
+ export interface MCPResourceOptions extends MCPToolBaseOptions<MCPPromptInput, ReadResourceResult> {
49
+ uri: string;
50
+ }
51
+ export declare class MCPResource extends MCPBase<MCPPromptInput, ReadResourceResult> {
52
+ constructor(options: MCPResourceOptions);
53
+ uri: string;
54
+ process(input: MCPPromptInput): Promise<ReadResourceResult>;
39
55
  }
@@ -1,30 +1,38 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MCPPrompt = exports.MCPTool = exports.MCPBase = exports.MCPAgent = void 0;
3
+ exports.MCPResource = exports.MCPPrompt = exports.MCPTool = exports.MCPBase = exports.MCPAgent = void 0;
4
4
  const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
5
5
  const sse_js_1 = require("@modelcontextprotocol/sdk/client/sse.js");
6
6
  const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
7
- const logger_1 = require("../utils/logger");
8
- const mcp_utils_1 = require("../utils/mcp-utils");
9
- const type_utils_1 = require("../utils/type-utils");
10
- const agent_1 = require("./agent");
7
+ const uriTemplate_js_1 = require("@modelcontextprotocol/sdk/shared/uriTemplate.js");
8
+ const logger_js_1 = require("../utils/logger.js");
9
+ const mcp_utils_js_1 = require("../utils/mcp-utils.js");
10
+ const type_utils_js_1 = require("../utils/type-utils.js");
11
+ const agent_js_1 = require("./agent.js");
11
12
  const MCP_AGENT_CLIENT_NAME = "MCPAgent";
12
13
  const MCP_AGENT_CLIENT_VERSION = "0.0.1";
13
- const debug = logger_1.logger.base.extend("mcp");
14
+ const debug = logger_js_1.logger.base.extend("mcp");
14
15
  function isSSEServerParameters(options) {
15
16
  return "url" in options && typeof options.url === "string";
16
17
  }
17
18
  function isStdioServerParameters(options) {
18
19
  return "command" in options && typeof options.command === "string";
19
20
  }
20
- class MCPAgent extends agent_1.Agent {
21
+ class MCPAgent extends agent_js_1.Agent {
21
22
  static from(options) {
22
23
  if (isSSEServerParameters(options)) {
23
24
  const transport = new sse_js_1.SSEClientTransport(new URL(options.url));
24
25
  return MCPAgent.fromTransport(transport);
25
26
  }
26
27
  if (isStdioServerParameters(options)) {
27
- const transport = new stdio_js_1.StdioClientTransport({ ...options, stderr: "pipe" });
28
+ const transport = new stdio_js_1.StdioClientTransport({
29
+ ...options,
30
+ env: {
31
+ ...(0, stdio_js_1.getDefaultEnvironment)(),
32
+ ...options.env,
33
+ },
34
+ stderr: "pipe",
35
+ });
28
36
  return MCPAgent.fromTransport(transport);
29
37
  }
30
38
  return new MCPAgent(options);
@@ -36,34 +44,60 @@ class MCPAgent extends agent_1.Agent {
36
44
  });
37
45
  await debug.spinner(client.connect(transport), "Connecting to MCP server");
38
46
  const mcpServer = getMCPServerName(client);
39
- const { tools: isToolsAvailable, prompts: isPromptsAvailable } = client.getServerCapabilities() ?? {};
47
+ const { tools: isToolsAvailable, prompts: isPromptsAvailable, resources: isResourcesAvailable, } = client.getServerCapabilities() ?? {};
40
48
  const tools = isToolsAvailable
41
49
  ? await debug
42
50
  .spinner(client.listTools(), `Listing tools from ${mcpServer}`, ({ tools }) => debug("%O", tools))
43
- .then(({ tools }) => tools.map((tool) => (0, mcp_utils_1.toolFromMCPTool)(client, tool)))
51
+ .then(({ tools }) => tools.map((tool) => (0, mcp_utils_js_1.toolFromMCPTool)(client, tool)))
44
52
  : undefined;
45
53
  const prompts = isPromptsAvailable
46
54
  ? await debug
47
55
  .spinner(client.listPrompts(), `Listing prompts from ${mcpServer}`, ({ prompts }) => debug("%O", prompts))
48
- .then(({ prompts }) => prompts.map((prompt) => (0, mcp_utils_1.promptFromMCPPrompt)(client, prompt)))
56
+ .then(({ prompts }) => prompts.map((prompt) => (0, mcp_utils_js_1.promptFromMCPPrompt)(client, prompt)))
49
57
  : undefined;
50
- return new MCPAgent({ client, tools, prompts });
58
+ const resources = isResourcesAvailable
59
+ ? await debug
60
+ .spinner(
61
+ // TODO: should conditionally call listResourceTemplates based on the server capabilities
62
+ // but the capability is not correct in the current SDK version
63
+ Promise.all([
64
+ client.listResources().catch(() => ({ resources: [] })),
65
+ client.listResourceTemplates().catch(() => ({ resourceTemplates: [] })),
66
+ ]), `Listing resources from ${mcpServer}`, ([{ resources }, { resourceTemplates }]) => debug("%O\n%O", resources, resourceTemplates))
67
+ .then(([{ resources }, { resourceTemplates }]) => [...resources, ...resourceTemplates].map((resource) => (0, mcp_utils_js_1.resourceFromMCPResource)(client, resource)))
68
+ : undefined;
69
+ return new MCPAgent({
70
+ name: client.getServerVersion()?.name,
71
+ client,
72
+ tools,
73
+ prompts,
74
+ resources,
75
+ });
51
76
  }
52
77
  constructor(options) {
53
78
  super(options);
54
79
  this.client = options.client;
55
80
  if (options.prompts?.length)
56
81
  this.prompts.push(...options.prompts);
82
+ if (options.resources?.length)
83
+ this.resources.push(...options.resources);
57
84
  }
58
85
  client;
59
- prompts = (0, type_utils_1.createAccessorArray)([], (arr, name) => arr.find((i) => i.name === name));
86
+ prompts = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((i) => i.name === name));
87
+ resources = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((i) => i.name === name));
88
+ get isCallable() {
89
+ return false;
90
+ }
91
+ async process(_input, _context) {
92
+ throw new Error("Method not implemented.");
93
+ }
60
94
  async shutdown() {
61
95
  super.shutdown();
62
96
  await this.client.close();
63
97
  }
64
98
  }
65
99
  exports.MCPAgent = MCPAgent;
66
- class MCPBase extends agent_1.Agent {
100
+ class MCPBase extends agent_js_1.Agent {
67
101
  constructor(options) {
68
102
  super(options);
69
103
  this.client = options.client;
@@ -88,6 +122,19 @@ class MCPPrompt extends MCPBase {
88
122
  }
89
123
  }
90
124
  exports.MCPPrompt = MCPPrompt;
125
+ class MCPResource extends MCPBase {
126
+ constructor(options) {
127
+ super(options);
128
+ this.uri = options.uri;
129
+ }
130
+ uri;
131
+ async process(input) {
132
+ const uri = new uriTemplate_js_1.UriTemplate(this.uri).expand(input);
133
+ const result = await debug.spinner(this.client.readResource({ uri }), `Read resource ${this.name} from ${this.mcpServer}`, (output) => debug("input: %O\noutput: %O", input, output));
134
+ return result;
135
+ }
136
+ }
137
+ exports.MCPResource = MCPResource;
91
138
  function getMCPServerName(client) {
92
139
  const info = client.getServerVersion();
93
140
  if (!info)