@aigne/core 1.10.0 → 1.12.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/LICENSE +93 -0
- package/README.md +90 -0
- package/README.zh.md +90 -0
- package/lib/cjs/agents/agent.d.ts +21 -20
- package/lib/cjs/agents/agent.js +29 -26
- package/lib/cjs/agents/ai-agent.d.ts +9 -8
- package/lib/cjs/agents/ai-agent.js +20 -14
- package/lib/cjs/agents/mcp-agent.d.ts +10 -4
- package/lib/cjs/agents/mcp-agent.js +12 -6
- package/lib/cjs/agents/memory.d.ts +1 -1
- package/lib/cjs/agents/team-agent.d.ts +28 -0
- package/lib/cjs/agents/team-agent.js +93 -0
- package/lib/cjs/agents/user-agent.d.ts +9 -10
- package/lib/cjs/agents/user-agent.js +10 -13
- package/lib/{esm/execution-engine/execution-engine.d.ts → cjs/aigne/aigne.d.ts} +9 -12
- package/lib/cjs/{execution-engine/execution-engine.js → aigne/aigne.js} +19 -19
- package/lib/cjs/{execution-engine → aigne}/context.d.ts +31 -32
- package/lib/cjs/{execution-engine → aigne}/context.js +30 -40
- package/lib/cjs/aigne/index.d.ts +4 -0
- package/lib/cjs/{execution-engine → aigne}/index.js +2 -2
- package/lib/cjs/{execution-engine → aigne}/usage.d.ts +1 -1
- package/lib/cjs/client/client.d.ts +19 -0
- package/lib/cjs/client/client.js +49 -0
- package/lib/cjs/index.d.ts +2 -1
- package/lib/cjs/index.js +2 -1
- package/lib/cjs/loader/agent-js.d.ts +2 -2
- package/lib/cjs/loader/agent-js.js +4 -5
- package/lib/cjs/loader/agent-yaml.d.ts +8 -5
- package/lib/cjs/loader/agent-yaml.js +21 -2
- package/lib/cjs/loader/index.d.ts +5 -5
- package/lib/cjs/loader/index.js +8 -19
- package/lib/cjs/models/chat-model.d.ts +1 -1
- package/lib/cjs/models/claude-chat-model.d.ts +3 -1
- package/lib/cjs/models/claude-chat-model.js +75 -60
- package/lib/cjs/models/openai-chat-model.d.ts +3 -3
- package/lib/cjs/models/openai-chat-model.js +1 -3
- package/lib/cjs/prompt/prompt-builder.d.ts +1 -1
- package/lib/cjs/prompt/prompt-builder.js +3 -3
- package/lib/cjs/server/error.d.ts +4 -0
- package/lib/cjs/server/error.js +11 -0
- package/lib/cjs/server/server.d.ts +54 -0
- package/lib/cjs/server/server.js +130 -0
- package/lib/cjs/utils/camelize.d.ts +13 -0
- package/lib/cjs/utils/camelize.js +16 -0
- package/lib/cjs/utils/event-stream.d.ts +11 -0
- package/lib/cjs/utils/event-stream.js +91 -0
- package/lib/cjs/utils/mcp-utils.js +4 -1
- package/lib/cjs/utils/stream-utils.d.ts +10 -3
- package/lib/cjs/utils/stream-utils.js +51 -36
- package/lib/cjs/utils/type-utils.d.ts +4 -2
- package/lib/cjs/utils/type-utils.js +10 -2
- package/lib/dts/agents/agent.d.ts +21 -20
- package/lib/dts/agents/ai-agent.d.ts +9 -8
- package/lib/dts/agents/mcp-agent.d.ts +10 -4
- package/lib/dts/agents/memory.d.ts +1 -1
- package/lib/dts/agents/team-agent.d.ts +28 -0
- package/lib/dts/agents/user-agent.d.ts +9 -10
- package/lib/dts/{execution-engine/execution-engine.d.ts → aigne/aigne.d.ts} +9 -12
- package/lib/dts/{execution-engine → aigne}/context.d.ts +31 -32
- package/lib/dts/aigne/index.d.ts +4 -0
- package/lib/dts/{execution-engine → aigne}/usage.d.ts +1 -1
- package/lib/dts/client/client.d.ts +19 -0
- package/lib/dts/index.d.ts +2 -1
- package/lib/dts/loader/agent-js.d.ts +2 -2
- package/lib/dts/loader/agent-yaml.d.ts +8 -5
- package/lib/dts/loader/index.d.ts +5 -5
- package/lib/dts/models/chat-model.d.ts +1 -1
- package/lib/dts/models/claude-chat-model.d.ts +3 -1
- package/lib/dts/models/openai-chat-model.d.ts +3 -3
- package/lib/dts/prompt/prompt-builder.d.ts +1 -1
- package/lib/dts/server/error.d.ts +4 -0
- package/lib/dts/server/server.d.ts +54 -0
- package/lib/dts/utils/camelize.d.ts +13 -0
- package/lib/dts/utils/event-stream.d.ts +11 -0
- package/lib/dts/utils/stream-utils.d.ts +10 -3
- package/lib/dts/utils/type-utils.d.ts +4 -2
- package/lib/esm/agents/agent.d.ts +21 -20
- package/lib/esm/agents/agent.js +29 -27
- package/lib/esm/agents/ai-agent.d.ts +9 -8
- package/lib/esm/agents/ai-agent.js +20 -14
- package/lib/esm/agents/mcp-agent.d.ts +10 -4
- package/lib/esm/agents/mcp-agent.js +12 -6
- package/lib/esm/agents/memory.d.ts +1 -1
- package/lib/esm/agents/team-agent.d.ts +28 -0
- package/lib/esm/agents/team-agent.js +89 -0
- package/lib/esm/agents/user-agent.d.ts +9 -10
- package/lib/esm/agents/user-agent.js +11 -14
- package/lib/{cjs/execution-engine/execution-engine.d.ts → esm/aigne/aigne.d.ts} +9 -12
- package/lib/esm/{execution-engine/execution-engine.js → aigne/aigne.js} +18 -18
- package/lib/esm/{execution-engine → aigne}/context.d.ts +31 -32
- package/lib/esm/{execution-engine → aigne}/context.js +28 -38
- package/lib/esm/aigne/index.d.ts +4 -0
- package/lib/esm/aigne/index.js +4 -0
- package/lib/esm/{execution-engine → aigne}/usage.d.ts +1 -1
- package/lib/esm/client/client.d.ts +19 -0
- package/lib/esm/client/client.js +45 -0
- package/lib/esm/index.d.ts +2 -1
- package/lib/esm/index.js +2 -1
- package/lib/esm/loader/agent-js.d.ts +2 -2
- package/lib/esm/loader/agent-js.js +4 -5
- package/lib/esm/loader/agent-yaml.d.ts +8 -5
- package/lib/esm/loader/agent-yaml.js +21 -2
- package/lib/esm/loader/index.d.ts +5 -5
- package/lib/esm/loader/index.js +8 -19
- package/lib/esm/models/chat-model.d.ts +1 -1
- package/lib/esm/models/claude-chat-model.d.ts +3 -1
- package/lib/esm/models/claude-chat-model.js +75 -60
- package/lib/esm/models/openai-chat-model.d.ts +3 -3
- package/lib/esm/models/openai-chat-model.js +1 -3
- package/lib/esm/prompt/prompt-builder.d.ts +1 -1
- package/lib/esm/prompt/prompt-builder.js +3 -3
- package/lib/esm/server/error.d.ts +4 -0
- package/lib/esm/server/error.js +7 -0
- package/lib/esm/server/server.d.ts +54 -0
- package/lib/esm/server/server.js +123 -0
- package/lib/esm/utils/camelize.d.ts +13 -0
- package/lib/esm/utils/camelize.js +10 -0
- package/lib/esm/utils/event-stream.d.ts +11 -0
- package/lib/esm/utils/event-stream.js +85 -0
- package/lib/esm/utils/mcp-utils.js +4 -1
- package/lib/esm/utils/stream-utils.d.ts +10 -3
- package/lib/esm/utils/stream-utils.js +49 -35
- package/lib/esm/utils/type-utils.d.ts +4 -2
- package/lib/esm/utils/type-utils.js +9 -2
- package/package.json +15 -5
- package/lib/cjs/execution-engine/index.d.ts +0 -4
- package/lib/cjs/execution-engine/utils.d.ts +0 -4
- package/lib/cjs/execution-engine/utils.js +0 -34
- package/lib/dts/execution-engine/index.d.ts +0 -4
- package/lib/dts/execution-engine/utils.d.ts +0 -4
- package/lib/esm/execution-engine/index.d.ts +0 -4
- package/lib/esm/execution-engine/index.js +0 -4
- package/lib/esm/execution-engine/utils.d.ts +0 -4
- package/lib/esm/execution-engine/utils.js +0 -30
- /package/lib/cjs/{execution-engine → aigne}/message-queue.d.ts +0 -0
- /package/lib/cjs/{execution-engine → aigne}/message-queue.js +0 -0
- /package/lib/cjs/{execution-engine → aigne}/usage.js +0 -0
- /package/lib/dts/{execution-engine → aigne}/message-queue.d.ts +0 -0
- /package/lib/esm/{execution-engine → aigne}/message-queue.d.ts +0 -0
- /package/lib/esm/{execution-engine → aigne}/message-queue.js +0 -0
- /package/lib/esm/{execution-engine → aigne}/usage.js +0 -0
|
@@ -28,7 +28,7 @@ exports.aiAgentOptionsSchema = zod_1.z.object({
|
|
|
28
28
|
publishTopic: zod_1.z.union([zod_1.z.string(), zod_1.z.array(zod_1.z.string()), zod_1.z.function()]).optional(),
|
|
29
29
|
name: zod_1.z.string().optional(),
|
|
30
30
|
description: zod_1.z.string().optional(),
|
|
31
|
-
|
|
31
|
+
skills: zod_1.z.array(zod_1.z.union([zod_1.z.instanceof(agent_js_1.Agent), zod_1.z.function()])).optional(),
|
|
32
32
|
disableLogging: zod_1.z.boolean().optional(),
|
|
33
33
|
memory: zod_1.z.union([zod_1.z.boolean(), zod_1.z.any(), zod_1.z.any()]).optional(),
|
|
34
34
|
});
|
|
@@ -52,21 +52,25 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
52
52
|
outputKey;
|
|
53
53
|
toolChoice;
|
|
54
54
|
async *process(input, context) {
|
|
55
|
-
const model =
|
|
55
|
+
const model = this.model ?? context.model;
|
|
56
56
|
if (!model)
|
|
57
57
|
throw new Error("model is required to run AIAgent");
|
|
58
|
-
const { toolAgents,
|
|
58
|
+
const { toolAgents, ...modelInput } = await this.instructions.build({
|
|
59
59
|
agent: this,
|
|
60
60
|
input,
|
|
61
61
|
model,
|
|
62
62
|
context,
|
|
63
63
|
});
|
|
64
64
|
const toolsMap = new Map(toolAgents?.map((i) => [i.name, i]));
|
|
65
|
+
if (this.toolChoice === "router") {
|
|
66
|
+
yield* this.processRouter(input, model, modelInput, context, toolsMap);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
65
69
|
const toolCallMessages = [];
|
|
66
70
|
const outputKey = this.outputKey || prompt_builder_js_1.MESSAGE_KEY;
|
|
67
71
|
for (;;) {
|
|
68
72
|
const modelOutput = {};
|
|
69
|
-
const stream = await context.
|
|
73
|
+
const stream = await context.invoke(model, { ...modelInput, messages: modelInput.messages.concat(toolCallMessages) }, { streaming: true });
|
|
70
74
|
for await (const value of (0, stream_utils_js_1.readableStreamToAsyncIterator)(stream)) {
|
|
71
75
|
if (value.delta.text?.text) {
|
|
72
76
|
yield { delta: { text: { [outputKey]: value.delta.text.text } } };
|
|
@@ -84,7 +88,7 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
84
88
|
if (!tool)
|
|
85
89
|
throw new Error(`Tool not found: ${call.function.name}`);
|
|
86
90
|
// NOTE: should pass both arguments (model generated) and input (user provided) to the tool
|
|
87
|
-
const output = await context.
|
|
91
|
+
const output = await context.invoke(tool, { ...call.function.arguments, ...input }, { disableTransfer: true });
|
|
88
92
|
// NOTE: Return transfer output immediately
|
|
89
93
|
if ((0, types_js_1.isTransferAgentOutput)(output)) {
|
|
90
94
|
return output;
|
|
@@ -94,15 +98,6 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
94
98
|
// Continue LLM function calling loop if any tools were executed
|
|
95
99
|
if (executedToolCalls.length) {
|
|
96
100
|
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()));
|
|
97
|
-
// Return the output of the first tool if the toolChoice is "router"
|
|
98
|
-
if (this.toolChoice === "router") {
|
|
99
|
-
const output = executedToolCalls[0]?.output;
|
|
100
|
-
const { supportsParallelToolCalls } = model.getModelCapabilities();
|
|
101
|
-
if (!output || (supportsParallelToolCalls && executedToolCalls.length !== 1)) {
|
|
102
|
-
throw new Error("Router toolChoice requires exactly one tool to be executed");
|
|
103
|
-
}
|
|
104
|
-
return output;
|
|
105
|
-
}
|
|
106
101
|
continue;
|
|
107
102
|
}
|
|
108
103
|
}
|
|
@@ -119,5 +114,16 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
119
114
|
return;
|
|
120
115
|
}
|
|
121
116
|
}
|
|
117
|
+
async *processRouter(input, model, modelInput, context, toolsMap) {
|
|
118
|
+
const { toolCalls: [call] = [], } = await context.invoke(model, modelInput);
|
|
119
|
+
if (!call) {
|
|
120
|
+
throw new Error("Router toolChoice requires exactly one tool to be executed");
|
|
121
|
+
}
|
|
122
|
+
const tool = toolsMap.get(call.function.name);
|
|
123
|
+
if (!tool)
|
|
124
|
+
throw new Error(`Tool not found: ${call.function.name}`);
|
|
125
|
+
const stream = await context.invoke(tool, { ...call.function.arguments, ...input }, { streaming: true });
|
|
126
|
+
yield* (0, stream_utils_js_1.readableStreamToAsyncIterator)(stream);
|
|
127
|
+
}
|
|
122
128
|
}
|
|
123
129
|
exports.AIAgent = AIAgent;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Client, type ClientOptions } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
2
|
import { type SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
3
3
|
import { type StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
4
|
+
import { type StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
4
5
|
import type { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
5
6
|
import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
6
7
|
import type { CallToolResult, GetPromptResult, Implementation, ReadResourceResult, Request } from "@modelcontextprotocol/sdk/types.js";
|
|
7
8
|
import { type ZodType, z } from "zod";
|
|
8
|
-
import type { Context } from "../
|
|
9
|
+
import type { Context } from "../aigne/context.js";
|
|
9
10
|
import { type PromiseOrValue } from "../utils/type-utils.js";
|
|
10
11
|
import { Agent, type AgentOptions, type Message } from "./agent.js";
|
|
11
12
|
export interface MCPAgentOptions extends AgentOptions {
|
|
@@ -17,9 +18,14 @@ export type MCPServerOptions = SSEServerParameters | StdioServerParameters;
|
|
|
17
18
|
export type SSEServerParameters = {
|
|
18
19
|
url: string;
|
|
19
20
|
/**
|
|
20
|
-
*
|
|
21
|
+
* Whether to use the StreamableHTTPClientTransport instead of the SSEClientTransport.
|
|
22
|
+
* @default "sse"
|
|
21
23
|
*/
|
|
22
|
-
|
|
24
|
+
transport?: "sse" | "streamableHttp";
|
|
25
|
+
/**
|
|
26
|
+
* Additional options to pass to the SSEClientTransport or StreamableHTTPClientTransport.
|
|
27
|
+
*/
|
|
28
|
+
opts?: SSEClientTransportOptions | StreamableHTTPClientTransportOptions;
|
|
23
29
|
/**
|
|
24
30
|
* The timeout for requests to the server, in milliseconds.
|
|
25
31
|
* @default 60000
|
|
@@ -48,7 +54,7 @@ export declare class MCPAgent extends Agent {
|
|
|
48
54
|
readonly resources: MCPResource[] & {
|
|
49
55
|
[key: string]: MCPResource;
|
|
50
56
|
};
|
|
51
|
-
get
|
|
57
|
+
get isInvokable(): boolean;
|
|
52
58
|
process(_input: Message, _context?: Context): Promise<Message>;
|
|
53
59
|
shutdown(): Promise<void>;
|
|
54
60
|
}
|
|
@@ -7,6 +7,7 @@ exports.MCPResource = exports.MCPPrompt = exports.MCPTool = exports.MCPBase = ex
|
|
|
7
7
|
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
8
8
|
const sse_js_1 = require("@modelcontextprotocol/sdk/client/sse.js");
|
|
9
9
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
|
|
10
|
+
const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
10
11
|
const uriTemplate_js_1 = require("@modelcontextprotocol/sdk/shared/uriTemplate.js");
|
|
11
12
|
const p_retry_1 = __importDefault(require("p-retry"));
|
|
12
13
|
const zod_1 = require("zod");
|
|
@@ -14,8 +15,8 @@ const logger_js_1 = require("../utils/logger.js");
|
|
|
14
15
|
const mcp_utils_js_1 = require("../utils/mcp-utils.js");
|
|
15
16
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
16
17
|
const agent_js_1 = require("./agent.js");
|
|
17
|
-
const MCP_AGENT_CLIENT_NAME = "MCPAgent";
|
|
18
|
-
const MCP_AGENT_CLIENT_VERSION = "
|
|
18
|
+
const MCP_AGENT_CLIENT_NAME = "AIGNE/MCPAgent";
|
|
19
|
+
const MCP_AGENT_CLIENT_VERSION = "1.10.0"; // This should match the version in package.json
|
|
19
20
|
const DEFAULT_MAX_RECONNECTS = 10;
|
|
20
21
|
const DEFAULT_TIMEOUT = () => zod_1.z.coerce
|
|
21
22
|
.number()
|
|
@@ -41,7 +42,12 @@ class MCPAgent extends agent_js_1.Agent {
|
|
|
41
42
|
static from(options) {
|
|
42
43
|
(0, type_utils_js_1.checkArguments)("MCPAgent.from", mcpAgentOptionsSchema, options);
|
|
43
44
|
if (isSSEServerParameters(options)) {
|
|
44
|
-
const transport = () =>
|
|
45
|
+
const transport = () => {
|
|
46
|
+
if (options.transport === "streamableHttp") {
|
|
47
|
+
return new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(options.url), options.opts);
|
|
48
|
+
}
|
|
49
|
+
return new sse_js_1.SSEClientTransport(new URL(options.url), options.opts);
|
|
50
|
+
};
|
|
45
51
|
return MCPAgent.fromTransport(transport, options);
|
|
46
52
|
}
|
|
47
53
|
if (isStdioServerParameters(options)) {
|
|
@@ -68,7 +74,7 @@ class MCPAgent extends agent_js_1.Agent {
|
|
|
68
74
|
const mcpServer = getMCPServerName(client);
|
|
69
75
|
const { tools: isToolsAvailable, prompts: isPromptsAvailable, resources: isResourcesAvailable, } = client.getServerCapabilities() ?? {};
|
|
70
76
|
logger_js_1.logger.mcp(`Listing tools from ${mcpServer}`);
|
|
71
|
-
const
|
|
77
|
+
const skills = isToolsAvailable
|
|
72
78
|
? await client.listTools().then(({ tools }) => {
|
|
73
79
|
logger_js_1.logger.mcp(`Listing tools from ${mcpServer} completed %O`, tools?.map((i) => i.name));
|
|
74
80
|
return tools.map((tool) => (0, mcp_utils_js_1.toolFromMCPTool)(tool, { client }));
|
|
@@ -97,7 +103,7 @@ class MCPAgent extends agent_js_1.Agent {
|
|
|
97
103
|
return new MCPAgent({
|
|
98
104
|
name: client.getServerVersion()?.name,
|
|
99
105
|
client,
|
|
100
|
-
|
|
106
|
+
skills,
|
|
101
107
|
prompts,
|
|
102
108
|
resources,
|
|
103
109
|
});
|
|
@@ -113,7 +119,7 @@ class MCPAgent extends agent_js_1.Agent {
|
|
|
113
119
|
client;
|
|
114
120
|
prompts = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((i) => i.name === name));
|
|
115
121
|
resources = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((i) => i.name === name));
|
|
116
|
-
get
|
|
122
|
+
get isInvokable() {
|
|
117
123
|
return false;
|
|
118
124
|
}
|
|
119
125
|
async process(_input, _context) {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Context } from "../aigne/context.js";
|
|
2
|
+
import { type PromiseOrValue } from "../utils/type-utils.js";
|
|
3
|
+
import { Agent, type AgentOptions, type AgentProcessResult, type Message } from "./agent.js";
|
|
4
|
+
export declare enum ProcessMode {
|
|
5
|
+
/**
|
|
6
|
+
* Process the agents one by one, passing the output of each agent to the next.
|
|
7
|
+
*/
|
|
8
|
+
sequential = "sequential",
|
|
9
|
+
/**
|
|
10
|
+
* Process all agents in parallel, merging the output of all agents.
|
|
11
|
+
*/
|
|
12
|
+
parallel = "parallel"
|
|
13
|
+
}
|
|
14
|
+
export interface TeamAgentOptions<I extends Message, O extends Message> extends AgentOptions<I, O> {
|
|
15
|
+
/**
|
|
16
|
+
* The method to process the agents in the team.
|
|
17
|
+
* @default {ProcessMode.sequential}
|
|
18
|
+
*/
|
|
19
|
+
mode?: ProcessMode;
|
|
20
|
+
}
|
|
21
|
+
export declare class TeamAgent<I extends Message, O extends Message> extends Agent<I, O> {
|
|
22
|
+
static from<I extends Message, O extends Message>(options: TeamAgentOptions<I, O>): TeamAgent<I, O>;
|
|
23
|
+
constructor(options: TeamAgentOptions<I, O>);
|
|
24
|
+
mode: ProcessMode;
|
|
25
|
+
process(input: I, context: Context): PromiseOrValue<AgentProcessResult<O>>;
|
|
26
|
+
_processSequential(input: I, context: Context): PromiseOrValue<AgentProcessResult<O>>;
|
|
27
|
+
_processParallel(input: I, context: Context): PromiseOrValue<AgentProcessResult<O>>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TeamAgent = exports.ProcessMode = void 0;
|
|
4
|
+
const stream_utils_js_1 = require("../utils/stream-utils.js");
|
|
5
|
+
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
6
|
+
const agent_js_1 = require("./agent.js");
|
|
7
|
+
var ProcessMode;
|
|
8
|
+
(function (ProcessMode) {
|
|
9
|
+
/**
|
|
10
|
+
* Process the agents one by one, passing the output of each agent to the next.
|
|
11
|
+
*/
|
|
12
|
+
ProcessMode["sequential"] = "sequential";
|
|
13
|
+
/**
|
|
14
|
+
* Process all agents in parallel, merging the output of all agents.
|
|
15
|
+
*/
|
|
16
|
+
ProcessMode["parallel"] = "parallel";
|
|
17
|
+
})(ProcessMode || (exports.ProcessMode = ProcessMode = {}));
|
|
18
|
+
class TeamAgent extends agent_js_1.Agent {
|
|
19
|
+
static from(options) {
|
|
20
|
+
return new TeamAgent(options);
|
|
21
|
+
}
|
|
22
|
+
constructor(options) {
|
|
23
|
+
super(options);
|
|
24
|
+
this.mode = options.mode ?? ProcessMode.sequential;
|
|
25
|
+
}
|
|
26
|
+
mode;
|
|
27
|
+
process(input, context) {
|
|
28
|
+
switch (this.mode) {
|
|
29
|
+
case ProcessMode.sequential:
|
|
30
|
+
return this._processSequential(input, context);
|
|
31
|
+
case ProcessMode.parallel:
|
|
32
|
+
return this._processParallel(input, context);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async *_processSequential(input, context) {
|
|
36
|
+
const output = {};
|
|
37
|
+
// Clone the agents to run, so that we can update the agents list during the loop
|
|
38
|
+
const agents = [...this.skills];
|
|
39
|
+
const newAgents = [];
|
|
40
|
+
for (const agent of agents) {
|
|
41
|
+
const [o, transferToAgent] = await context.invoke(agent, { ...input, ...output }, { returnActiveAgent: true, streaming: true });
|
|
42
|
+
for await (const chunk of (0, stream_utils_js_1.readableStreamToAsyncIterator)(o)) {
|
|
43
|
+
yield chunk;
|
|
44
|
+
(0, stream_utils_js_1.mergeAgentResponseChunk)(output, chunk);
|
|
45
|
+
}
|
|
46
|
+
newAgents.push(await transferToAgent);
|
|
47
|
+
}
|
|
48
|
+
this.skills.splice(0);
|
|
49
|
+
this.skills.push(...newAgents);
|
|
50
|
+
}
|
|
51
|
+
async *_processParallel(input, context) {
|
|
52
|
+
const result = await Promise.all(this.skills.map((agent) => context.invoke(agent, input, { returnActiveAgent: true, streaming: true })));
|
|
53
|
+
const streams = result.map((i) => i[0]);
|
|
54
|
+
const read = async (index, reader) => {
|
|
55
|
+
const promise = reader.read();
|
|
56
|
+
return promise.then((result) => ({ ...result, reader, index }));
|
|
57
|
+
};
|
|
58
|
+
const tasks = new Map(streams.map((stream, index) => [index, read(index, stream.getReader())]));
|
|
59
|
+
// NOTE: Flag to check if the output key is used by agent at the index,
|
|
60
|
+
const outputKeyUsed = new Map();
|
|
61
|
+
while (tasks.size) {
|
|
62
|
+
const { value, done, reader, index } = await Promise.race(tasks.values());
|
|
63
|
+
tasks.delete(index);
|
|
64
|
+
if (!done) {
|
|
65
|
+
tasks.set(index, read(index, reader));
|
|
66
|
+
}
|
|
67
|
+
if (value) {
|
|
68
|
+
let { delta: { text, ...delta }, } = value;
|
|
69
|
+
if (text) {
|
|
70
|
+
for (const key of Object.keys(text)) {
|
|
71
|
+
// the output key is unused, add to map to lock it
|
|
72
|
+
if (!outputKeyUsed.has(key)) {
|
|
73
|
+
outputKeyUsed.set(key, index);
|
|
74
|
+
}
|
|
75
|
+
// the output key is used by the agent at the index, abandon it
|
|
76
|
+
else if (outputKeyUsed.get(key) !== index) {
|
|
77
|
+
delete text[key];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if ((0, type_utils_js_1.isEmpty)(text)) {
|
|
81
|
+
text = undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (!(0, type_utils_js_1.isEmpty)(delta.json) || !(0, type_utils_js_1.isEmpty)(text))
|
|
85
|
+
yield { delta: { ...delta, text } };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const agents = await Promise.all(result.map((i) => i[1]));
|
|
89
|
+
this.skills.splice(0);
|
|
90
|
+
this.skills.push(...agents);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.TeamAgent = TeamAgent;
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import { ReadableStream } from "node:stream/web";
|
|
2
|
-
import { type Context
|
|
3
|
-
import type { MessagePayload } from "../
|
|
4
|
-
import { type
|
|
5
|
-
import { Agent, type AgentOptions, type AgentProcessAsyncGenerator, type Message } from "./agent.js";
|
|
2
|
+
import { type Context } from "../aigne/context.js";
|
|
3
|
+
import type { MessagePayload } from "../aigne/message-queue.js";
|
|
4
|
+
import { type Agent, type AgentOptions, type AgentProcessResult, FunctionAgent, type FunctionAgentFn, type Message } from "./agent.js";
|
|
6
5
|
export interface UserAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
|
|
7
6
|
context: Context;
|
|
8
|
-
process?:
|
|
9
|
-
activeAgent?:
|
|
7
|
+
process?: FunctionAgentFn<I, O>;
|
|
8
|
+
activeAgent?: Agent;
|
|
10
9
|
}
|
|
11
|
-
export declare class UserAgent<I extends Message = Message, O extends Message = Message> extends
|
|
10
|
+
export declare class UserAgent<I extends Message = Message, O extends Message = Message> extends FunctionAgent<I, O> {
|
|
12
11
|
static from<I extends Message, O extends Message>(options: UserAgentOptions<I, O>): UserAgent<I, O>;
|
|
13
12
|
constructor(options: UserAgentOptions<I, O>);
|
|
14
13
|
context: Context;
|
|
15
14
|
private _process?;
|
|
16
15
|
private activeAgent?;
|
|
17
|
-
|
|
18
|
-
process(input: I, context: Context):
|
|
16
|
+
invoke: Agent<I, O>["invoke"];
|
|
17
|
+
process(input: I, context: Context): Promise<AgentProcessResult<O>>;
|
|
19
18
|
publish: Context["publish"];
|
|
20
19
|
subscribe: Context["subscribe"];
|
|
21
20
|
unsubscribe: Context["unsubscribe"];
|
|
22
21
|
get stream(): ReadableStream<MessagePayload & {
|
|
23
22
|
topic: string;
|
|
24
23
|
}>;
|
|
25
|
-
protected
|
|
24
|
+
protected checkAgentInvokesUsage(_context: Context): void;
|
|
26
25
|
}
|
|
@@ -2,11 +2,10 @@
|
|
|
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("../
|
|
6
|
-
const stream_utils_js_1 = require("../utils/stream-utils.js");
|
|
5
|
+
const context_js_1 = require("../aigne/context.js");
|
|
7
6
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
8
7
|
const agent_js_1 = require("./agent.js");
|
|
9
|
-
class UserAgent extends agent_js_1.
|
|
8
|
+
class UserAgent extends agent_js_1.FunctionAgent {
|
|
10
9
|
static from(options) {
|
|
11
10
|
return new UserAgent(options);
|
|
12
11
|
}
|
|
@@ -19,31 +18,29 @@ class UserAgent extends agent_js_1.Agent {
|
|
|
19
18
|
context;
|
|
20
19
|
_process;
|
|
21
20
|
activeAgent;
|
|
22
|
-
|
|
21
|
+
invoke = ((input, context, options) => {
|
|
23
22
|
if (!context)
|
|
24
23
|
this.context = this.context.newContext({ reset: true });
|
|
25
|
-
return super.
|
|
24
|
+
return super.invoke(input, context ?? this.context, options);
|
|
26
25
|
});
|
|
27
|
-
async
|
|
26
|
+
async process(input, context) {
|
|
28
27
|
if (this._process) {
|
|
29
|
-
|
|
30
|
-
return;
|
|
28
|
+
return this._process(input, context);
|
|
31
29
|
}
|
|
32
30
|
if (this.activeAgent) {
|
|
33
|
-
const [output, agent] = await context.
|
|
31
|
+
const [output, agent] = await context.invoke(this.activeAgent, input, {
|
|
34
32
|
returnActiveAgent: true,
|
|
35
33
|
streaming: true,
|
|
36
34
|
});
|
|
37
35
|
agent.then((agent) => {
|
|
38
36
|
this.activeAgent = agent;
|
|
39
37
|
});
|
|
40
|
-
|
|
41
|
-
return;
|
|
38
|
+
return output;
|
|
42
39
|
}
|
|
43
40
|
const publicTopic = typeof this.publishTopic === "function" ? await this.publishTopic(input) : this.publishTopic;
|
|
44
41
|
if (publicTopic?.length) {
|
|
45
42
|
context.publish(publicTopic, (0, context_js_1.createPublishMessage)(input, this));
|
|
46
|
-
return;
|
|
43
|
+
return {};
|
|
47
44
|
}
|
|
48
45
|
throw new Error("UserAgent must have a process function or a publishTopic");
|
|
49
46
|
}
|
|
@@ -72,7 +69,7 @@ class UserAgent extends agent_js_1.Agent {
|
|
|
72
69
|
},
|
|
73
70
|
});
|
|
74
71
|
}
|
|
75
|
-
|
|
72
|
+
checkAgentInvokesUsage(_context) {
|
|
76
73
|
// ignore calls usage check for UserAgent
|
|
77
74
|
}
|
|
78
75
|
}
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
import { Agent } from "../agents/agent.js";
|
|
2
2
|
import { ChatModel } from "../models/chat-model.js";
|
|
3
|
-
import { type Context
|
|
3
|
+
import { AIGNEContext, type Context } from "./context.js";
|
|
4
4
|
import { MessageQueue } from "./message-queue.js";
|
|
5
5
|
import type { ContextLimits } from "./usage.js";
|
|
6
|
-
export interface
|
|
6
|
+
export interface AIGNEOptions {
|
|
7
7
|
name?: string;
|
|
8
8
|
description?: string;
|
|
9
9
|
model?: ChatModel;
|
|
10
|
-
|
|
10
|
+
skills?: Agent[];
|
|
11
11
|
agents?: Agent[];
|
|
12
12
|
limits?: ContextLimits;
|
|
13
13
|
}
|
|
14
|
-
export
|
|
15
|
-
returnActiveAgent?: boolean;
|
|
16
|
-
}
|
|
17
|
-
export declare class ExecutionEngine {
|
|
14
|
+
export declare class AIGNE {
|
|
18
15
|
static load({ path, ...options }: {
|
|
19
16
|
path: string;
|
|
20
|
-
} &
|
|
21
|
-
constructor(options?:
|
|
17
|
+
} & AIGNEOptions): Promise<AIGNE>;
|
|
18
|
+
constructor(options?: AIGNEOptions);
|
|
22
19
|
name?: string;
|
|
23
20
|
description?: string;
|
|
24
21
|
readonly messageQueue: MessageQueue;
|
|
25
22
|
model?: ChatModel;
|
|
26
|
-
readonly
|
|
23
|
+
readonly skills: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[] & {
|
|
27
24
|
[key: string]: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>;
|
|
28
25
|
};
|
|
29
26
|
readonly agents: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[] & {
|
|
@@ -31,9 +28,9 @@ export declare class ExecutionEngine {
|
|
|
31
28
|
};
|
|
32
29
|
limits?: ContextLimits;
|
|
33
30
|
addAgent(...agents: Agent[]): void;
|
|
34
|
-
newContext():
|
|
31
|
+
newContext(): AIGNEContext;
|
|
35
32
|
publish: Context["publish"];
|
|
36
|
-
|
|
33
|
+
invoke: Context["invoke"];
|
|
37
34
|
subscribe: Context["subscribe"];
|
|
38
35
|
unsubscribe: Context["unsubscribe"];
|
|
39
36
|
shutdown(): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.AIGNE = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const agent_js_1 = require("../agents/agent.js");
|
|
6
6
|
const index_js_1 = require("../loader/index.js");
|
|
@@ -8,27 +8,27 @@ const chat_model_js_1 = require("../models/chat-model.js");
|
|
|
8
8
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
9
9
|
const context_js_1 = require("./context.js");
|
|
10
10
|
const message_queue_js_1 = require("./message-queue.js");
|
|
11
|
-
class
|
|
11
|
+
class AIGNE {
|
|
12
12
|
static async load({ path, ...options }) {
|
|
13
|
-
const { model, agents,
|
|
14
|
-
return new
|
|
13
|
+
const { model, agents, skills, ...aigne } = await (0, index_js_1.load)({ path });
|
|
14
|
+
return new AIGNE({
|
|
15
15
|
...options,
|
|
16
16
|
model: options.model || model,
|
|
17
17
|
name: options.name || aigne.name || undefined,
|
|
18
18
|
description: options.description || aigne.description || undefined,
|
|
19
19
|
agents: agents.concat(options.agents ?? []),
|
|
20
|
-
|
|
20
|
+
skills: skills.concat(options.skills ?? []),
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
constructor(options) {
|
|
24
24
|
if (options)
|
|
25
|
-
(0, type_utils_js_1.checkArguments)("
|
|
25
|
+
(0, type_utils_js_1.checkArguments)("AIGNE", aigneOptionsSchema, options);
|
|
26
26
|
this.name = options?.name;
|
|
27
27
|
this.description = options?.description;
|
|
28
28
|
this.model = options?.model;
|
|
29
29
|
this.limits = options?.limits;
|
|
30
|
-
if (options?.
|
|
31
|
-
this.
|
|
30
|
+
if (options?.skills?.length)
|
|
31
|
+
this.skills.push(...options.skills);
|
|
32
32
|
if (options?.agents?.length)
|
|
33
33
|
this.addAgent(...options.agents);
|
|
34
34
|
this.initProcessExitHandler();
|
|
@@ -37,24 +37,24 @@ class ExecutionEngine {
|
|
|
37
37
|
description;
|
|
38
38
|
messageQueue = new message_queue_js_1.MessageQueue();
|
|
39
39
|
model;
|
|
40
|
-
|
|
40
|
+
skills = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((i) => i.name === name));
|
|
41
41
|
agents = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((i) => i.name === name));
|
|
42
42
|
limits;
|
|
43
43
|
addAgent(...agents) {
|
|
44
|
-
(0, type_utils_js_1.checkArguments)("
|
|
44
|
+
(0, type_utils_js_1.checkArguments)("AIGNE.addAgent", aigneAddAgentArgsSchema, agents);
|
|
45
45
|
for (const agent of agents) {
|
|
46
46
|
this.agents.push(agent);
|
|
47
47
|
agent.attach(this);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
newContext() {
|
|
51
|
-
return new context_js_1.
|
|
51
|
+
return new context_js_1.AIGNEContext(this);
|
|
52
52
|
}
|
|
53
53
|
publish = ((...args) => {
|
|
54
|
-
return new context_js_1.
|
|
54
|
+
return new context_js_1.AIGNEContext(this).publish(...args);
|
|
55
55
|
});
|
|
56
|
-
|
|
57
|
-
return new context_js_1.
|
|
56
|
+
invoke = ((...args) => {
|
|
57
|
+
return new context_js_1.AIGNEContext(this).invoke(...args);
|
|
58
58
|
});
|
|
59
59
|
subscribe = ((...args) => {
|
|
60
60
|
return this.messageQueue.subscribe(...args);
|
|
@@ -63,7 +63,7 @@ class ExecutionEngine {
|
|
|
63
63
|
this.messageQueue.unsubscribe(...args);
|
|
64
64
|
});
|
|
65
65
|
async shutdown() {
|
|
66
|
-
for (const tool of this.
|
|
66
|
+
for (const tool of this.skills) {
|
|
67
67
|
await tool.shutdown();
|
|
68
68
|
}
|
|
69
69
|
for (const agent of this.agents) {
|
|
@@ -76,10 +76,10 @@ class ExecutionEngine {
|
|
|
76
76
|
process.on("exit", shutdownAndExit);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
exports.
|
|
80
|
-
const
|
|
79
|
+
exports.AIGNE = AIGNE;
|
|
80
|
+
const aigneOptionsSchema = zod_1.z.object({
|
|
81
81
|
model: zod_1.z.instanceof(chat_model_js_1.ChatModel).optional(),
|
|
82
|
-
|
|
82
|
+
skills: zod_1.z.array(zod_1.z.instanceof(agent_js_1.Agent)).optional(),
|
|
83
83
|
agents: zod_1.z.array(zod_1.z.instanceof(agent_js_1.Agent)).optional(),
|
|
84
84
|
});
|
|
85
|
-
const
|
|
85
|
+
const aigneAddAgentArgsSchema = zod_1.z.array(zod_1.z.instanceof(agent_js_1.Agent));
|