@aigne/core 1.5.1-2 → 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.
- package/CHANGELOG.md +28 -0
- package/lib/cjs/agents/agent.d.ts +5 -2
- package/lib/cjs/agents/agent.js +42 -24
- package/lib/cjs/agents/ai-agent.d.ts +8 -8
- package/lib/cjs/agents/ai-agent.js +5 -2
- package/lib/cjs/agents/mcp-agent.d.ts +11 -0
- package/lib/cjs/agents/mcp-agent.js +37 -23
- package/lib/cjs/agents/user-agent.d.ts +9 -9
- package/lib/cjs/agents/user-agent.js +26 -16
- package/lib/cjs/execution-engine/context.d.ts +84 -46
- package/lib/cjs/execution-engine/context.js +136 -98
- package/lib/cjs/execution-engine/execution-engine.d.ts +20 -47
- package/lib/cjs/execution-engine/execution-engine.js +20 -41
- package/lib/cjs/execution-engine/message-queue.d.ts +3 -3
- package/lib/cjs/execution-engine/message-queue.js +32 -2
- package/lib/cjs/execution-engine/usage.d.ts +11 -0
- package/lib/cjs/execution-engine/usage.js +10 -0
- package/lib/{esm/loader/function-agent.d.ts → cjs/loader/agent-js.d.ts} +1 -5
- package/lib/cjs/loader/{function-agent.js → agent-js.js} +2 -2
- package/lib/cjs/loader/{ai-agent.d.ts → agent-yaml.d.ts} +7 -4
- package/lib/cjs/loader/agent-yaml.js +58 -0
- package/lib/cjs/loader/index.d.ts +14 -4
- package/lib/cjs/loader/index.js +57 -22
- package/lib/cjs/models/chat-model.d.ts +3 -2
- package/lib/cjs/models/chat-model.js +6 -5
- package/lib/cjs/models/claude-chat-model.js +10 -7
- package/lib/cjs/models/openai-chat-model.js +5 -2
- package/lib/cjs/prompt/prompt-builder.d.ts +1 -1
- package/lib/cjs/prompt/prompt-builder.js +3 -1
- package/lib/cjs/utils/json-schema.js +2 -2
- package/lib/cjs/utils/logger.d.ts +3 -15
- package/lib/cjs/utils/logger.js +3 -77
- package/lib/cjs/utils/mcp-utils.js +1 -5
- package/lib/cjs/utils/model-utils.js +2 -2
- package/lib/cjs/utils/type-utils.d.ts +1 -0
- package/lib/cjs/utils/typed-event-emtter.d.ts +10 -0
- package/lib/cjs/utils/typed-event-emtter.js +2 -0
- package/lib/dts/agents/agent.d.ts +5 -2
- package/lib/dts/agents/ai-agent.d.ts +8 -8
- package/lib/dts/agents/mcp-agent.d.ts +11 -0
- package/lib/dts/agents/user-agent.d.ts +9 -9
- package/lib/dts/execution-engine/context.d.ts +84 -46
- package/lib/dts/execution-engine/execution-engine.d.ts +20 -47
- package/lib/dts/execution-engine/message-queue.d.ts +3 -3
- package/lib/dts/execution-engine/usage.d.ts +11 -0
- package/lib/dts/loader/{function-agent.d.ts → agent-js.d.ts} +1 -5
- package/lib/dts/loader/{ai-agent.d.ts → agent-yaml.d.ts} +7 -4
- package/lib/dts/loader/index.d.ts +14 -4
- package/lib/dts/models/chat-model.d.ts +3 -2
- package/lib/dts/prompt/prompt-builder.d.ts +1 -1
- package/lib/dts/utils/logger.d.ts +3 -15
- package/lib/dts/utils/type-utils.d.ts +1 -0
- package/lib/dts/utils/typed-event-emtter.d.ts +10 -0
- package/lib/esm/agents/agent.d.ts +5 -2
- package/lib/esm/agents/agent.js +42 -24
- package/lib/esm/agents/ai-agent.d.ts +8 -8
- package/lib/esm/agents/ai-agent.js +5 -2
- package/lib/esm/agents/mcp-agent.d.ts +11 -0
- package/lib/esm/agents/mcp-agent.js +38 -24
- package/lib/esm/agents/user-agent.d.ts +9 -9
- package/lib/esm/agents/user-agent.js +26 -16
- package/lib/esm/execution-engine/context.d.ts +84 -46
- package/lib/esm/execution-engine/context.js +135 -98
- package/lib/esm/execution-engine/execution-engine.d.ts +20 -47
- package/lib/esm/execution-engine/execution-engine.js +21 -39
- package/lib/esm/execution-engine/message-queue.d.ts +3 -3
- package/lib/esm/execution-engine/message-queue.js +33 -3
- package/lib/esm/execution-engine/usage.d.ts +11 -0
- package/lib/esm/execution-engine/usage.js +7 -0
- package/lib/{cjs/loader/function-agent.d.ts → esm/loader/agent-js.d.ts} +1 -5
- package/lib/esm/loader/{function-agent.js → agent-js.js} +2 -2
- package/lib/esm/loader/{ai-agent.d.ts → agent-yaml.d.ts} +7 -4
- package/lib/esm/loader/agent-yaml.js +55 -0
- package/lib/esm/loader/index.d.ts +14 -4
- package/lib/esm/loader/index.js +56 -21
- package/lib/esm/models/chat-model.d.ts +3 -2
- package/lib/esm/models/chat-model.js +6 -5
- package/lib/esm/models/claude-chat-model.js +10 -7
- package/lib/esm/models/openai-chat-model.js +5 -2
- package/lib/esm/prompt/prompt-builder.d.ts +1 -1
- package/lib/esm/prompt/prompt-builder.js +3 -1
- package/lib/esm/utils/json-schema.js +2 -2
- package/lib/esm/utils/logger.d.ts +3 -15
- package/lib/esm/utils/logger.js +3 -77
- package/lib/esm/utils/mcp-utils.js +1 -5
- package/lib/esm/utils/model-utils.js +2 -2
- package/lib/esm/utils/type-utils.d.ts +1 -0
- package/lib/esm/utils/typed-event-emtter.d.ts +10 -0
- package/lib/esm/utils/typed-event-emtter.js +1 -0
- package/package.json +10 -10
- package/lib/cjs/loader/ai-agent.js +0 -40
- package/lib/cjs/utils/run-chat-loop.d.ts +0 -11
- package/lib/cjs/utils/run-chat-loop.js +0 -82
- package/lib/dts/utils/run-chat-loop.d.ts +0 -11
- package/lib/esm/loader/ai-agent.js +0 -37
- package/lib/esm/utils/run-chat-loop.d.ts +0 -11
- package/lib/esm/utils/run-chat-loop.js +0 -76
package/CHANGELOG.md
CHANGED
|
@@ -22,6 +22,34 @@
|
|
|
22
22
|
* rename @aigne/core-next to @aigne/core ([3a81009](https://github.com/AIGNE-io/aigne-framework/commit/3a8100962c81813217b687ae28e8de604419c622))
|
|
23
23
|
* use text resource from MCP correctly ([8b9eba8](https://github.com/AIGNE-io/aigne-framework/commit/8b9eba83352ec096a2a5d4f410d4c4bde7420bce))
|
|
24
24
|
|
|
25
|
+
## [1.7.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.6.0...core-v1.7.0) (2025-04-15)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
* add TerminalTracer for better UX in terminal ([#56](https://github.com/AIGNE-io/aigne-framework/issues/56)) ([9875a5d](https://github.com/AIGNE-io/aigne-framework/commit/9875a5d46abb55073340ffae841fed6bd6b83ff4))
|
|
31
|
+
* **cli:** support run agents from remote URL ([#60](https://github.com/AIGNE-io/aigne-framework/issues/60)) ([5f49920](https://github.com/AIGNE-io/aigne-framework/commit/5f4992089d36f9e780ba55a912a1d35508cad28e))
|
|
32
|
+
* **core:** support oauth for McpAgent with example ([#55](https://github.com/AIGNE-io/aigne-framework/issues/55)) ([9420f3a](https://github.com/AIGNE-io/aigne-framework/commit/9420f3a56cf18986cd45f173044e660be76daab4))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Bug Fixes
|
|
36
|
+
|
|
37
|
+
* remove usage of new Node.js exists API for compatibility ([#57](https://github.com/AIGNE-io/aigne-framework/issues/57)) ([c10cc08](https://github.com/AIGNE-io/aigne-framework/commit/c10cc086d8ecd0744f38cdb1367d4c8816b723b3))
|
|
38
|
+
|
|
39
|
+
## [1.6.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.5.0...core-v1.6.0) (2025-04-08)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Features
|
|
43
|
+
|
|
44
|
+
* add `serve` command for @aigne/cli ([#54](https://github.com/AIGNE-io/aigne-framework/issues/54)) ([1cca843](https://github.com/AIGNE-io/aigne-framework/commit/1cca843f1760abe832b6651108fa858130f47355))
|
|
45
|
+
* add agent library support ([#51](https://github.com/AIGNE-io/aigne-framework/issues/51)) ([1f0d34d](https://github.com/AIGNE-io/aigne-framework/commit/1f0d34ddda3154283a4bc958ddb9b68b4ac106b0))
|
|
46
|
+
* support token/call/time limits for ExecutionEngine ([#44](https://github.com/AIGNE-io/aigne-framework/issues/44)) ([5a2ca0a](https://github.com/AIGNE-io/aigne-framework/commit/5a2ca0a033267dd4765f574b53dca71e932e53d4))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### Bug Fixes
|
|
50
|
+
|
|
51
|
+
* support reconnect to the MCP server automatically ([#50](https://github.com/AIGNE-io/aigne-framework/issues/50)) ([898d83f](https://github.com/AIGNE-io/aigne-framework/commit/898d83f75fc655142b93c70a1afeda376a2e92b4))
|
|
52
|
+
|
|
25
53
|
## [1.5.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.4.0...core-v1.5.0) (2025-03-27)
|
|
26
54
|
|
|
27
55
|
|
|
@@ -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
|
-
|
|
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
|
|
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> {
|
package/lib/cjs/agents/agent.js
CHANGED
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.FunctionAgent = exports.Agent = void 0;
|
|
37
|
+
const node_util_1 = require("node:util");
|
|
37
38
|
const zod_1 = require("zod");
|
|
38
39
|
const prompt_builder_js_1 = require("../prompt/prompt-builder.js");
|
|
39
40
|
const logger_js_1 = require("../utils/logger.js");
|
|
@@ -55,7 +56,7 @@ class Agent {
|
|
|
55
56
|
this.publishTopic = options.publishTopic;
|
|
56
57
|
if (options.tools?.length)
|
|
57
58
|
this.tools.push(...options.tools.map(functionToAgent));
|
|
58
|
-
this.
|
|
59
|
+
this.disableEvents = options.disableEvents;
|
|
59
60
|
if (options.memory) {
|
|
60
61
|
this.memory =
|
|
61
62
|
options.memory instanceof memory_js_1.AgentMemory
|
|
@@ -92,7 +93,7 @@ class Agent {
|
|
|
92
93
|
subscribeTopic;
|
|
93
94
|
publishTopic;
|
|
94
95
|
tools = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((t) => t.name === name));
|
|
95
|
-
|
|
96
|
+
disableEvents;
|
|
96
97
|
/**
|
|
97
98
|
* Attach agent to context:
|
|
98
99
|
* - subscribe to topic and call process method when message received
|
|
@@ -107,7 +108,7 @@ class Agent {
|
|
|
107
108
|
await context.call(this, message);
|
|
108
109
|
}
|
|
109
110
|
catch (error) {
|
|
110
|
-
context.emit("
|
|
111
|
+
context.emit("agentFailed", { agent: this, error });
|
|
111
112
|
}
|
|
112
113
|
});
|
|
113
114
|
}
|
|
@@ -131,31 +132,45 @@ class Agent {
|
|
|
131
132
|
}
|
|
132
133
|
async call(input, context) {
|
|
133
134
|
const ctx = context ?? (await this.newDefaultContext());
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
135
|
+
const message = typeof input === "string" ? (0, prompt_builder_js_1.createMessage)(input) : input;
|
|
136
|
+
logger_js_1.logger.core("Call agent %s started with input: %O", this.name, input);
|
|
137
|
+
if (!this.disableEvents)
|
|
138
|
+
ctx.emit("agentStarted", { agent: this, input: message });
|
|
139
|
+
try {
|
|
140
|
+
const parsedInput = this.inputSchema.parse(message);
|
|
141
|
+
this.preprocess(parsedInput, ctx);
|
|
142
|
+
this.checkContextStatus(ctx);
|
|
143
|
+
const output = await this.process(parsedInput, ctx)
|
|
144
|
+
.then((output) => {
|
|
145
|
+
const parsedOutput = this.outputSchema.parse(output);
|
|
146
|
+
return this.includeInputInOutput ? { ...parsedInput, ...parsedOutput } : parsedOutput;
|
|
147
|
+
})
|
|
148
|
+
.then((output) => {
|
|
149
|
+
this.postprocess(parsedInput, output, ctx);
|
|
150
|
+
return output;
|
|
151
|
+
});
|
|
152
|
+
logger_js_1.logger.core("Call agent %s succeed with output: %O", this.name, input);
|
|
153
|
+
if (!this.disableEvents)
|
|
154
|
+
ctx.emit("agentSucceed", { agent: this, output });
|
|
146
155
|
return output;
|
|
147
|
-
}
|
|
148
|
-
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
logger_js_1.logger.core("Call agent %s failed with error: %O", this.name, error);
|
|
159
|
+
if (!this.disableEvents)
|
|
160
|
+
ctx.emit("agentFailed", { agent: this, error });
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
checkUsageAgentCalls(context) {
|
|
165
|
+
const { limits, usage } = context;
|
|
166
|
+
if (limits?.maxAgentCalls && usage.agentCalls >= limits.maxAgentCalls) {
|
|
167
|
+
throw new Error(`Exceeded max agent calls ${usage.agentCalls}/${limits.maxAgentCalls}`);
|
|
168
|
+
}
|
|
169
|
+
usage.agentCalls++;
|
|
149
170
|
}
|
|
150
171
|
preprocess(_, context) {
|
|
151
172
|
this.checkContextStatus(context);
|
|
152
|
-
|
|
153
|
-
const { limits, usage } = context;
|
|
154
|
-
if (limits?.maxAgentCalls && usage.agentCalls >= limits.maxAgentCalls) {
|
|
155
|
-
throw new Error(`Exceeded max agent calls ${usage.agentCalls}/${limits.maxAgentCalls}`);
|
|
156
|
-
}
|
|
157
|
-
usage.agentCalls++;
|
|
158
|
-
}
|
|
173
|
+
this.checkUsageAgentCalls(context);
|
|
159
174
|
}
|
|
160
175
|
postprocess(input, output, context) {
|
|
161
176
|
this.checkContextStatus(context);
|
|
@@ -169,6 +184,9 @@ class Agent {
|
|
|
169
184
|
async shutdown() {
|
|
170
185
|
this.memory?.detach();
|
|
171
186
|
}
|
|
187
|
+
[node_util_1.inspect.custom]() {
|
|
188
|
+
return this.name;
|
|
189
|
+
}
|
|
172
190
|
}
|
|
173
191
|
exports.Agent = Agent;
|
|
174
192
|
function checkAgentInputOutputSchema(schema) {
|
|
@@ -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>;
|
|
@@ -62,7 +62,10 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
62
62
|
const toolsMap = new Map(toolAgents?.map((i) => [i.name, i]));
|
|
63
63
|
const toolCallMessages = [];
|
|
64
64
|
for (;;) {
|
|
65
|
-
const { text, json, toolCalls } = await
|
|
65
|
+
const { text, json, toolCalls } = await context.call(model, {
|
|
66
|
+
...modelInput,
|
|
67
|
+
messages: messages.concat(toolCallMessages),
|
|
68
|
+
});
|
|
66
69
|
if (toolCalls?.length) {
|
|
67
70
|
const executedToolCalls = [];
|
|
68
71
|
// Execute tools
|
|
@@ -71,7 +74,7 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
71
74
|
if (!tool)
|
|
72
75
|
throw new Error(`Tool not found: ${call.function.name}`);
|
|
73
76
|
// NOTE: should pass both arguments (model generated) and input (user provided) to the tool
|
|
74
|
-
const output = await
|
|
77
|
+
const output = await context.call(tool, { ...call.function.arguments, ...input }, { disableTransfer: true });
|
|
75
78
|
// NOTE: Return transfer output immediately
|
|
76
79
|
if ((0, types_js_1.isTransferAgentOutput)(output)) {
|
|
77
80
|
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
|
}
|
|
@@ -17,7 +17,6 @@ const agent_js_1 = require("./agent.js");
|
|
|
17
17
|
const MCP_AGENT_CLIENT_NAME = "MCPAgent";
|
|
18
18
|
const MCP_AGENT_CLIENT_VERSION = "0.0.1";
|
|
19
19
|
const DEFAULT_MAX_RECONNECTS = 10;
|
|
20
|
-
const debug = logger_js_1.logger.base.extend("mcp");
|
|
21
20
|
function isSSEServerParameters(options) {
|
|
22
21
|
return "url" in options && typeof options.url === "string";
|
|
23
22
|
}
|
|
@@ -37,7 +36,7 @@ class MCPAgent extends agent_js_1.Agent {
|
|
|
37
36
|
static from(options) {
|
|
38
37
|
(0, type_utils_js_1.checkArguments)("MCPAgent.from", mcpAgentOptionsSchema, options);
|
|
39
38
|
if (isSSEServerParameters(options)) {
|
|
40
|
-
const transport = () => new sse_js_1.SSEClientTransport(new URL(options.url));
|
|
39
|
+
const transport = () => new sse_js_1.SSEClientTransport(new URL(options.url), options.opts);
|
|
41
40
|
return MCPAgent.fromTransport(transport, options);
|
|
42
41
|
}
|
|
43
42
|
if (isStdioServerParameters(options)) {
|
|
@@ -59,29 +58,36 @@ class MCPAgent extends agent_js_1.Agent {
|
|
|
59
58
|
version: MCP_AGENT_CLIENT_VERSION,
|
|
60
59
|
}, undefined, isSSEServerParameters(options) ? { transportCreator, ...options } : undefined);
|
|
61
60
|
const transport = transportCreator();
|
|
62
|
-
|
|
61
|
+
logger_js_1.logger.mcp(`Connecting to MCP server: ${getMCPServerString(options)}`);
|
|
62
|
+
await client.connect(transport);
|
|
63
63
|
const mcpServer = getMCPServerName(client);
|
|
64
64
|
const { tools: isToolsAvailable, prompts: isPromptsAvailable, resources: isResourcesAvailable, } = client.getServerCapabilities() ?? {};
|
|
65
|
+
logger_js_1.logger.mcp(`Listing tools from ${mcpServer}`);
|
|
65
66
|
const tools = isToolsAvailable
|
|
66
|
-
? await
|
|
67
|
-
.
|
|
68
|
-
|
|
67
|
+
? await client.listTools().then(({ tools }) => {
|
|
68
|
+
logger_js_1.logger.mcp(`Listing tools from ${mcpServer} completed %O`, tools?.map((i) => i.name));
|
|
69
|
+
return tools.map((tool) => (0, mcp_utils_js_1.toolFromMCPTool)(tool, { client }));
|
|
70
|
+
})
|
|
69
71
|
: undefined;
|
|
72
|
+
logger_js_1.logger.mcp(`Listing prompts from ${mcpServer}`);
|
|
70
73
|
const prompts = isPromptsAvailable
|
|
71
|
-
? await
|
|
72
|
-
.
|
|
73
|
-
|
|
74
|
+
? await client.listPrompts().then(({ prompts }) => {
|
|
75
|
+
logger_js_1.logger.mcp(`Listing prompts from ${mcpServer} completed %O`, prompts?.map((i) => i.name));
|
|
76
|
+
return prompts.map((prompt) => (0, mcp_utils_js_1.promptFromMCPPrompt)(prompt, { client }));
|
|
77
|
+
})
|
|
74
78
|
: undefined;
|
|
79
|
+
logger_js_1.logger.mcp(`Listing resources from ${mcpServer}`);
|
|
80
|
+
// TODO: should conditionally call listResourceTemplates based on the server capabilities
|
|
81
|
+
// but the capability is not correct in the current SDK version
|
|
75
82
|
const resources = isResourcesAvailable
|
|
76
|
-
? await
|
|
77
|
-
.spinner(
|
|
78
|
-
// TODO: should conditionally call listResourceTemplates based on the server capabilities
|
|
79
|
-
// but the capability is not correct in the current SDK version
|
|
80
|
-
Promise.all([
|
|
83
|
+
? await Promise.all([
|
|
81
84
|
client.listResources().catch(() => ({ resources: [] })),
|
|
82
85
|
client.listResourceTemplates().catch(() => ({ resourceTemplates: [] })),
|
|
83
|
-
])
|
|
84
|
-
|
|
86
|
+
]).then(([{ resources }, { resourceTemplates }]) => {
|
|
87
|
+
const result = [...resources, ...resourceTemplates].map((resource) => (0, mcp_utils_js_1.resourceFromMCPResource)(resource, { client }));
|
|
88
|
+
logger_js_1.logger.mcp(`Listing resources from ${mcpServer} completed %O`, result.map((i) => i.name));
|
|
89
|
+
return result;
|
|
90
|
+
})
|
|
85
91
|
: undefined;
|
|
86
92
|
return new MCPAgent({
|
|
87
93
|
name: client.getServerVersion()?.name,
|
|
@@ -138,18 +144,22 @@ class ClientWithReconnect extends index_js_1.Client {
|
|
|
138
144
|
}, {
|
|
139
145
|
retries: this.reconnectOptions?.maxReconnects ?? DEFAULT_MAX_RECONNECTS,
|
|
140
146
|
shouldRetry: this.shouldReconnect,
|
|
141
|
-
onFailedAttempt: (error) =>
|
|
147
|
+
onFailedAttempt: (error) => logger_js_1.logger.mcp("Reconnect attempt failed: %O", error),
|
|
142
148
|
});
|
|
143
149
|
}
|
|
144
150
|
async request(request, resultSchema, options) {
|
|
151
|
+
const mergedOptions = {
|
|
152
|
+
...(options ?? {}),
|
|
153
|
+
timeout: options?.timeout ?? this.reconnectOptions?.timeout ?? 10000,
|
|
154
|
+
};
|
|
145
155
|
try {
|
|
146
|
-
return await super.request(request, resultSchema,
|
|
156
|
+
return await super.request(request, resultSchema, mergedOptions);
|
|
147
157
|
}
|
|
148
158
|
catch (error) {
|
|
149
159
|
if (this.shouldReconnect(error)) {
|
|
150
|
-
|
|
160
|
+
logger_js_1.logger.mcp("Error occurred, reconnecting to MCP server: %O", error);
|
|
151
161
|
await this.reconnect();
|
|
152
|
-
return await super.request(request, resultSchema,
|
|
162
|
+
return await super.request(request, resultSchema, mergedOptions);
|
|
153
163
|
}
|
|
154
164
|
throw error;
|
|
155
165
|
}
|
|
@@ -168,14 +178,14 @@ class MCPBase extends agent_js_1.Agent {
|
|
|
168
178
|
exports.MCPBase = MCPBase;
|
|
169
179
|
class MCPTool extends MCPBase {
|
|
170
180
|
async process(input) {
|
|
171
|
-
const result = await
|
|
181
|
+
const result = await this.client.callTool({ name: this.name, arguments: input });
|
|
172
182
|
return result;
|
|
173
183
|
}
|
|
174
184
|
}
|
|
175
185
|
exports.MCPTool = MCPTool;
|
|
176
186
|
class MCPPrompt extends MCPBase {
|
|
177
187
|
async process(input) {
|
|
178
|
-
const result = await
|
|
188
|
+
const result = await this.client.getPrompt({ name: this.name, arguments: input });
|
|
179
189
|
return result;
|
|
180
190
|
}
|
|
181
191
|
}
|
|
@@ -188,7 +198,7 @@ class MCPResource extends MCPBase {
|
|
|
188
198
|
uri;
|
|
189
199
|
async process(input) {
|
|
190
200
|
const uri = new uriTemplate_js_1.UriTemplate(this.uri).expand(input);
|
|
191
|
-
const result = await
|
|
201
|
+
const result = await this.client.readResource({ uri });
|
|
192
202
|
return result;
|
|
193
203
|
}
|
|
194
204
|
}
|
|
@@ -208,6 +218,10 @@ const mcpAgentOptionsSchema = zod_1.z.union([
|
|
|
208
218
|
}),
|
|
209
219
|
zod_1.z.object({
|
|
210
220
|
url: zod_1.z.string(),
|
|
221
|
+
opts: zod_1.z.object({}).optional(),
|
|
222
|
+
timeout: zod_1.z.number().optional(),
|
|
223
|
+
maxReconnects: zod_1.z.number().optional(),
|
|
224
|
+
shouldReconnect: zod_1.z.function().args(zod_1.z.instanceof(Error)).returns(zod_1.z.boolean()).optional(),
|
|
211
225
|
}),
|
|
212
226
|
zod_1.z.object({
|
|
213
227
|
command: zod_1.z.string(),
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { ReadableStream } from "node:stream/web";
|
|
2
|
-
import type
|
|
3
|
-
import type { MessagePayload
|
|
2
|
+
import { type Context, type Runnable } from "../execution-engine/context.js";
|
|
3
|
+
import type { MessagePayload } from "../execution-engine/message-queue.js";
|
|
4
4
|
import { type PromiseOrValue } from "../utils/type-utils.js";
|
|
5
5
|
import { Agent, type AgentOptions, type Message } from "./agent.js";
|
|
6
6
|
export interface UserAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
|
|
7
7
|
context: Context;
|
|
8
8
|
process?: (input: I, context: Context) => PromiseOrValue<O>;
|
|
9
|
+
activeAgent?: Runnable;
|
|
9
10
|
}
|
|
10
11
|
export declare class UserAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
|
|
11
12
|
static from<I extends Message, O extends Message>(options: UserAgentOptions<I, O>): UserAgent<I, O>;
|
|
12
13
|
constructor(options: UserAgentOptions<I, O>);
|
|
13
|
-
|
|
14
|
-
private get ctx();
|
|
14
|
+
context: Context;
|
|
15
15
|
private _process?;
|
|
16
|
+
private activeAgent?;
|
|
16
17
|
call(input: string | I, context?: Context): Promise<O>;
|
|
17
18
|
process(input: I, context: Context): Promise<O>;
|
|
18
|
-
publish
|
|
19
|
-
subscribe
|
|
20
|
-
|
|
21
|
-
subscribe(topic: string, listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
|
|
22
|
-
unsubscribe(topic: string, listener: MessageQueueListener): void;
|
|
19
|
+
publish: Context["publish"];
|
|
20
|
+
subscribe: Context["subscribe"];
|
|
21
|
+
unsubscribe: Context["unsubscribe"];
|
|
23
22
|
get stream(): ReadableStream<MessagePayload & {
|
|
24
23
|
topic: string;
|
|
25
24
|
}>;
|
|
25
|
+
protected checkUsageAgentCalls(_context: Context): void;
|
|
26
26
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.UserAgent = void 0;
|
|
4
4
|
const web_1 = require("node:stream/web");
|
|
5
|
+
const context_js_1 = require("../execution-engine/context.js");
|
|
5
6
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
6
7
|
const agent_js_1 = require("./agent.js");
|
|
7
8
|
class UserAgent extends agent_js_1.Agent {
|
|
@@ -9,40 +10,46 @@ class UserAgent extends agent_js_1.Agent {
|
|
|
9
10
|
return new UserAgent(options);
|
|
10
11
|
}
|
|
11
12
|
constructor(options) {
|
|
12
|
-
super({ ...options,
|
|
13
|
+
super({ ...options, disableEvents: true });
|
|
13
14
|
this._process = options.process;
|
|
14
15
|
this.context = options.context;
|
|
16
|
+
this.activeAgent = options.activeAgent;
|
|
15
17
|
}
|
|
16
18
|
context;
|
|
17
|
-
get ctx() {
|
|
18
|
-
if (!this.context)
|
|
19
|
-
throw new Error("UserAgent must have a context");
|
|
20
|
-
return this.context;
|
|
21
|
-
}
|
|
22
19
|
_process;
|
|
20
|
+
activeAgent;
|
|
23
21
|
call(input, context) {
|
|
22
|
+
if (!context)
|
|
23
|
+
this.context = this.context.newContext({ reset: true });
|
|
24
24
|
return super.call(input, context ?? this.context);
|
|
25
25
|
}
|
|
26
26
|
async process(input, context) {
|
|
27
27
|
if (this._process) {
|
|
28
28
|
return this._process(input, context);
|
|
29
29
|
}
|
|
30
|
+
if (this.activeAgent) {
|
|
31
|
+
const [output, agent] = await context.call(this.activeAgent, input, {
|
|
32
|
+
returnActiveAgent: true,
|
|
33
|
+
});
|
|
34
|
+
this.activeAgent = agent;
|
|
35
|
+
return output;
|
|
36
|
+
}
|
|
30
37
|
const publicTopic = typeof this.publishTopic === "function" ? await this.publishTopic(input) : this.publishTopic;
|
|
31
38
|
if (publicTopic?.length) {
|
|
32
|
-
context.publish(publicTopic, input, this);
|
|
39
|
+
context.publish(publicTopic, (0, context_js_1.createPublishMessage)(input, this));
|
|
33
40
|
return {};
|
|
34
41
|
}
|
|
35
42
|
throw new Error("UserAgent must have a process function or a publishTopic");
|
|
36
43
|
}
|
|
37
|
-
publish(
|
|
38
|
-
return this.
|
|
39
|
-
}
|
|
40
|
-
subscribe(
|
|
41
|
-
return this.
|
|
42
|
-
}
|
|
43
|
-
unsubscribe(
|
|
44
|
-
this.
|
|
45
|
-
}
|
|
44
|
+
publish = ((...args) => {
|
|
45
|
+
return this.context.publish(...args);
|
|
46
|
+
});
|
|
47
|
+
subscribe = ((...args) => {
|
|
48
|
+
return this.context.subscribe(...args);
|
|
49
|
+
});
|
|
50
|
+
unsubscribe = ((...args) => {
|
|
51
|
+
this.context.unsubscribe(...args);
|
|
52
|
+
});
|
|
46
53
|
get stream() {
|
|
47
54
|
let subscriptions = [];
|
|
48
55
|
return new web_1.ReadableStream({
|
|
@@ -59,5 +66,8 @@ class UserAgent extends agent_js_1.Agent {
|
|
|
59
66
|
},
|
|
60
67
|
});
|
|
61
68
|
}
|
|
69
|
+
checkUsageAgentCalls(_context) {
|
|
70
|
+
// ignore calls usage check for UserAgent
|
|
71
|
+
}
|
|
62
72
|
}
|
|
63
73
|
exports.UserAgent = UserAgent;
|