@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Agent, type Message } from "../agents/agent.js";
|
|
2
|
-
import type { Context } from "../
|
|
2
|
+
import type { Context } from "../aigne/context.js";
|
|
3
3
|
export declare abstract class ChatModel extends Agent<ChatModelInput, ChatModelOutput> {
|
|
4
4
|
constructor();
|
|
5
5
|
protected supportsParallelToolCalls: boolean;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Anthropic from "@anthropic-ai/sdk";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import type { AgentInvokeOptions, AgentResponse } from "../agents/agent.js";
|
|
4
|
+
import type { Context } from "../aigne/context.js";
|
|
3
5
|
import { ChatModel, type ChatModelInput, type ChatModelOptions, type ChatModelOutput } from "./chat-model.js";
|
|
4
6
|
export interface ClaudeChatModelOptions {
|
|
5
7
|
apiKey?: string;
|
|
@@ -60,7 +62,7 @@ export declare class ClaudeChatModel extends ChatModel {
|
|
|
60
62
|
protected _client?: Anthropic;
|
|
61
63
|
get client(): Anthropic;
|
|
62
64
|
get modelOptions(): ChatModelOptions | undefined;
|
|
63
|
-
process(input: ChatModelInput): Promise<ChatModelOutput
|
|
65
|
+
process(input: ChatModelInput, _context: Context, options?: AgentInvokeOptions): Promise<AgentResponse<ChatModelOutput>>;
|
|
64
66
|
private extractResultFromClaudeStream;
|
|
65
67
|
private requestStructuredOutput;
|
|
66
68
|
}
|
|
@@ -7,8 +7,8 @@ exports.ClaudeChatModel = exports.claudeChatModelOptionsSchema = void 0;
|
|
|
7
7
|
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
8
|
const zod_1 = require("zod");
|
|
9
9
|
const json_schema_js_1 = require("../utils/json-schema.js");
|
|
10
|
-
const logger_js_1 = require("../utils/logger.js");
|
|
11
10
|
const model_utils_js_1 = require("../utils/model-utils.js");
|
|
11
|
+
const stream_utils_js_1 = require("../utils/stream-utils.js");
|
|
12
12
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
13
13
|
const chat_model_js_1 = require("./chat-model.js");
|
|
14
14
|
const CHAT_MODEL_CLAUDE_DEFAULT_MODEL = "claude-3-7-sonnet-latest";
|
|
@@ -45,7 +45,7 @@ class ClaudeChatModel extends chat_model_js_1.ChatModel {
|
|
|
45
45
|
get modelOptions() {
|
|
46
46
|
return this.options?.modelOptions;
|
|
47
47
|
}
|
|
48
|
-
async process(input) {
|
|
48
|
+
async process(input, _context, options) {
|
|
49
49
|
const model = this.options?.model || CHAT_MODEL_CLAUDE_DEFAULT_MODEL;
|
|
50
50
|
const disableParallelToolUse = input.modelOptions?.parallelToolCalls === false ||
|
|
51
51
|
this.modelOptions?.parallelToolCalls === false;
|
|
@@ -62,6 +62,9 @@ class ClaudeChatModel extends chat_model_js_1.ChatModel {
|
|
|
62
62
|
...body,
|
|
63
63
|
stream: true,
|
|
64
64
|
});
|
|
65
|
+
if (options?.streaming && input.responseFormat?.type !== "json_schema") {
|
|
66
|
+
return this.extractResultFromClaudeStream(stream, true);
|
|
67
|
+
}
|
|
65
68
|
const result = await this.extractResultFromClaudeStream(stream);
|
|
66
69
|
// Claude doesn't support json_schema response and tool calls in the same request,
|
|
67
70
|
// so we need to make a separate request for json_schema response when the tool calls is empty
|
|
@@ -75,67 +78,79 @@ class ClaudeChatModel extends chat_model_js_1.ChatModel {
|
|
|
75
78
|
}
|
|
76
79
|
return result;
|
|
77
80
|
}
|
|
78
|
-
async extractResultFromClaudeStream(stream) {
|
|
81
|
+
async extractResultFromClaudeStream(stream, streaming) {
|
|
79
82
|
const logs = [];
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
83
|
+
const result = new ReadableStream({
|
|
84
|
+
async start(controller) {
|
|
85
|
+
try {
|
|
86
|
+
const toolCalls = [];
|
|
87
|
+
let usage;
|
|
88
|
+
let model;
|
|
89
|
+
for await (const chunk of stream) {
|
|
90
|
+
if (chunk.type === "message_start") {
|
|
91
|
+
if (!model) {
|
|
92
|
+
model = chunk.message.model;
|
|
93
|
+
controller.enqueue({ delta: { json: { model } } });
|
|
94
|
+
}
|
|
95
|
+
const { input_tokens, output_tokens } = chunk.message.usage;
|
|
96
|
+
usage = {
|
|
97
|
+
inputTokens: input_tokens,
|
|
98
|
+
outputTokens: output_tokens,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (chunk.type === "message_delta" && usage) {
|
|
102
|
+
usage.outputTokens = chunk.usage.output_tokens;
|
|
103
|
+
}
|
|
104
|
+
logs.push(JSON.stringify(chunk));
|
|
105
|
+
// handle streaming text
|
|
106
|
+
if (chunk.type === "content_block_delta" && chunk.delta.type === "text_delta") {
|
|
107
|
+
controller.enqueue({ delta: { text: { text: chunk.delta.text } } });
|
|
108
|
+
}
|
|
109
|
+
if (chunk.type === "content_block_start" && chunk.content_block.type === "tool_use") {
|
|
110
|
+
toolCalls[chunk.index] = {
|
|
111
|
+
type: "function",
|
|
112
|
+
id: chunk.content_block.id,
|
|
113
|
+
function: {
|
|
114
|
+
name: chunk.content_block.name,
|
|
115
|
+
arguments: {},
|
|
116
|
+
},
|
|
117
|
+
args: "",
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (chunk.type === "content_block_delta" && chunk.delta.type === "input_json_delta") {
|
|
121
|
+
const call = toolCalls[chunk.index];
|
|
122
|
+
if (!call)
|
|
123
|
+
throw new Error("Tool call not found");
|
|
124
|
+
call.args += chunk.delta.partial_json;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
controller.enqueue({ delta: { json: { usage } } });
|
|
128
|
+
if (toolCalls.length) {
|
|
129
|
+
controller.enqueue({
|
|
130
|
+
delta: {
|
|
131
|
+
json: {
|
|
132
|
+
toolCalls: toolCalls
|
|
133
|
+
.map(({ args, ...c }) => ({
|
|
134
|
+
...c,
|
|
135
|
+
function: {
|
|
136
|
+
...c.function,
|
|
137
|
+
// NOTE: claude may return a blank string for empty object (the tool's input schema is a empty object)
|
|
138
|
+
arguments: args.trim() ? (0, json_schema_js_1.parseJSON)(args) : {},
|
|
139
|
+
},
|
|
140
|
+
}))
|
|
141
|
+
.filter(type_utils_js_1.isNonNullable),
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
controller.close();
|
|
101
147
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
type: "function",
|
|
105
|
-
id: chunk.content_block.id,
|
|
106
|
-
function: {
|
|
107
|
-
name: chunk.content_block.name,
|
|
108
|
-
arguments: {},
|
|
109
|
-
},
|
|
110
|
-
args: "",
|
|
111
|
-
};
|
|
148
|
+
catch (error) {
|
|
149
|
+
controller.error(error);
|
|
112
150
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
throw new Error("Tool call not found");
|
|
117
|
-
call.args += chunk.delta.partial_json;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
const result = { usage, model, text };
|
|
121
|
-
if (toolCalls.length) {
|
|
122
|
-
result.toolCalls = toolCalls
|
|
123
|
-
.map(({ args, ...c }) => ({
|
|
124
|
-
...c,
|
|
125
|
-
function: {
|
|
126
|
-
...c.function,
|
|
127
|
-
// NOTE: claude may return a blank string for empty object (the tool's input schema is a empty object)
|
|
128
|
-
arguments: args.trim() ? (0, json_schema_js_1.parseJSON)(args) : {},
|
|
129
|
-
},
|
|
130
|
-
}))
|
|
131
|
-
.filter(type_utils_js_1.isNonNullable);
|
|
132
|
-
}
|
|
133
|
-
return result;
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
logger_js_1.logger.core("Failed to process Claude stream", { error, logs });
|
|
137
|
-
throw error;
|
|
138
|
-
}
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
return streaming ? result : await (0, stream_utils_js_1.agentResponseStreamToObject)(result);
|
|
139
154
|
}
|
|
140
155
|
async requestStructuredOutput(body, responseFormat) {
|
|
141
156
|
if (responseFormat?.type !== "json_schema") {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
2
|
import type { ChatCompletionMessageParam, ChatCompletionTool } from "openai/resources";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
import type {
|
|
5
|
-
import type { Context } from "../
|
|
4
|
+
import type { AgentInvokeOptions, AgentResponse } from "../agents/agent.js";
|
|
5
|
+
import type { Context } from "../aigne/context.js";
|
|
6
6
|
import { ChatModel, type ChatModelInput, type ChatModelInputMessage, type ChatModelInputTool, type ChatModelOptions, type ChatModelOutput, type Role } from "./chat-model.js";
|
|
7
7
|
export interface OpenAIChatModelCapabilities {
|
|
8
8
|
supportsNativeStructuredOutputs: boolean;
|
|
@@ -83,7 +83,7 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
83
83
|
protected supportsTemperature: boolean;
|
|
84
84
|
get client(): OpenAI;
|
|
85
85
|
get modelOptions(): ChatModelOptions | undefined;
|
|
86
|
-
process(input: ChatModelInput, _context: Context, options?:
|
|
86
|
+
process(input: ChatModelInput, _context: Context, options?: AgentInvokeOptions): Promise<AgentResponse<ChatModelOutput>>;
|
|
87
87
|
private getParallelToolCalls;
|
|
88
88
|
private getRunMessages;
|
|
89
89
|
private getRunResponseFormat;
|
|
@@ -333,13 +333,11 @@ async function extractResultFromStream(stream, jsonMode, streaming) {
|
|
|
333
333
|
},
|
|
334
334
|
});
|
|
335
335
|
}
|
|
336
|
+
controller.close();
|
|
336
337
|
}
|
|
337
338
|
catch (error) {
|
|
338
339
|
controller.error(error);
|
|
339
340
|
}
|
|
340
|
-
finally {
|
|
341
|
-
controller.close();
|
|
342
|
-
}
|
|
343
341
|
},
|
|
344
342
|
});
|
|
345
343
|
return streaming ? result : await (0, stream_utils_js_1.agentResponseStreamToObject)(result);
|
|
@@ -2,7 +2,7 @@ import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
|
|
|
2
2
|
import { Agent, type Message } from "../agents/agent.js";
|
|
3
3
|
import type { AIAgent } from "../agents/ai-agent.js";
|
|
4
4
|
import type { AgentMemory } from "../agents/memory.js";
|
|
5
|
-
import type { Context } from "../
|
|
5
|
+
import type { Context } from "../aigne/context.js";
|
|
6
6
|
import type { ChatModel, ChatModelInput } from "../models/chat-model.js";
|
|
7
7
|
import { ChatMessagesTemplate } from "./template.js";
|
|
8
8
|
export declare const MESSAGE_KEY = "$message";
|
|
@@ -117,10 +117,10 @@ class PromptBuilder {
|
|
|
117
117
|
: undefined;
|
|
118
118
|
}
|
|
119
119
|
buildTools(options) {
|
|
120
|
-
const toolAgents = (options.context?.
|
|
121
|
-
.concat(options.agent?.
|
|
120
|
+
const toolAgents = (options.context?.skills ?? [])
|
|
121
|
+
.concat(options.agent?.skills ?? [])
|
|
122
122
|
// TODO: support nested tools?
|
|
123
|
-
.flatMap((i) => (i.
|
|
123
|
+
.flatMap((i) => (i.isInvokable ? i.skills.concat(i) : i.skills));
|
|
124
124
|
const tools = toolAgents.map((i) => ({
|
|
125
125
|
type: "function",
|
|
126
126
|
function: {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServerError = void 0;
|
|
4
|
+
class ServerError extends Error {
|
|
5
|
+
status;
|
|
6
|
+
constructor(status, message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.status = status;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.ServerError = ServerError;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { AIGNE } from "../aigne/aigne.js";
|
|
4
|
+
export declare const invokePayloadSchema: z.ZodObject<{
|
|
5
|
+
agent: z.ZodString;
|
|
6
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
7
|
+
options: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
8
|
+
streaming: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
streaming?: boolean | null | undefined;
|
|
11
|
+
}, {
|
|
12
|
+
streaming?: boolean | null | undefined;
|
|
13
|
+
}>>>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
agent: string;
|
|
16
|
+
input: Record<string, unknown>;
|
|
17
|
+
options?: {
|
|
18
|
+
streaming?: boolean | null | undefined;
|
|
19
|
+
} | null | undefined;
|
|
20
|
+
}, {
|
|
21
|
+
agent: string;
|
|
22
|
+
input: Record<string, unknown>;
|
|
23
|
+
options?: {
|
|
24
|
+
streaming?: boolean | null | undefined;
|
|
25
|
+
} | null | undefined;
|
|
26
|
+
}>;
|
|
27
|
+
export interface AIGNEServerOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Maximum body size for the request.
|
|
30
|
+
* Only used when the request is a Node.js IncomingMessage and no `body` property is present.
|
|
31
|
+
* @default "4mb"
|
|
32
|
+
*/
|
|
33
|
+
maximumBodySize?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare class AIGNEServer {
|
|
36
|
+
engine: AIGNE;
|
|
37
|
+
options?: AIGNEServerOptions | undefined;
|
|
38
|
+
constructor(engine: AIGNE, options?: AIGNEServerOptions | undefined);
|
|
39
|
+
/**
|
|
40
|
+
* Invoke the agent with the given input.
|
|
41
|
+
* @param request - The request object, which can be a parsed JSON object, a Fetch API Request object, or a Node.js IncomingMessage object.
|
|
42
|
+
* @returns The web standard response, you can return it directly in supported frameworks like hono.
|
|
43
|
+
*/
|
|
44
|
+
invoke(request: Record<string, unknown> | Request | IncomingMessage): Promise<Response>;
|
|
45
|
+
/**
|
|
46
|
+
* Invoke the agent with the given input, and write the SSE response to the Node.js ServerResponse.
|
|
47
|
+
* @param request - The request object, which can be a parsed JSON object, a Fetch API Request object, or a Node.js IncomingMessage object.
|
|
48
|
+
* @param response - The Node.js ServerResponse object to write the SSE response to.
|
|
49
|
+
*/
|
|
50
|
+
invoke(request: Record<string, unknown> | Request | IncomingMessage, response: ServerResponse): Promise<void>;
|
|
51
|
+
_invoke(request: Record<string, unknown> | Request | IncomingMessage): Promise<Response>;
|
|
52
|
+
_prepareInput(request: Record<string, unknown> | Request | IncomingMessage): Promise<Record<string, unknown>>;
|
|
53
|
+
_writeResponse(response: Response, res: ServerResponse): Promise<void>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AIGNEServer = exports.invokePayloadSchema = void 0;
|
|
7
|
+
const node_http_1 = require("node:http");
|
|
8
|
+
const content_type_1 = __importDefault(require("content-type"));
|
|
9
|
+
const raw_body_1 = __importDefault(require("raw-body"));
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
const event_stream_js_1 = require("../utils/event-stream.js");
|
|
12
|
+
const stream_utils_js_1 = require("../utils/stream-utils.js");
|
|
13
|
+
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
14
|
+
const error_js_1 = require("./error.js");
|
|
15
|
+
const DEFAULT_MAXIMUM_BODY_SIZE = "4mb";
|
|
16
|
+
exports.invokePayloadSchema = zod_1.z.object({
|
|
17
|
+
agent: zod_1.z.string(),
|
|
18
|
+
input: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
|
|
19
|
+
options: zod_1.z
|
|
20
|
+
.object({
|
|
21
|
+
streaming: zod_1.z.boolean().nullish(),
|
|
22
|
+
})
|
|
23
|
+
.nullish(),
|
|
24
|
+
});
|
|
25
|
+
class AIGNEServer {
|
|
26
|
+
engine;
|
|
27
|
+
options;
|
|
28
|
+
constructor(engine, options) {
|
|
29
|
+
this.engine = engine;
|
|
30
|
+
this.options = options;
|
|
31
|
+
}
|
|
32
|
+
async invoke(request, response) {
|
|
33
|
+
const result = await this._invoke(request);
|
|
34
|
+
if (response instanceof node_http_1.ServerResponse) {
|
|
35
|
+
await this._writeResponse(result, response);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
async _invoke(request) {
|
|
41
|
+
const { engine } = this;
|
|
42
|
+
try {
|
|
43
|
+
const payload = await this._prepareInput(request);
|
|
44
|
+
const { agent: agentName, input, options, } = (0, type_utils_js_1.tryOrThrow)(() => (0, type_utils_js_1.checkArguments)(`Invoke agent ${payload.agent}`, exports.invokePayloadSchema, payload), (error) => new error_js_1.ServerError(400, error.message));
|
|
45
|
+
const agent = engine.agents[agentName];
|
|
46
|
+
if (!agent)
|
|
47
|
+
throw new error_js_1.ServerError(404, `Agent ${agentName} not found`);
|
|
48
|
+
if (!options?.streaming) {
|
|
49
|
+
const result = await engine.invoke(agent, input);
|
|
50
|
+
return new Response(JSON.stringify(result), {
|
|
51
|
+
headers: { "Content-Type": "application/json" },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const stream = await engine.invoke(agent, input, { streaming: true });
|
|
55
|
+
return new Response(new event_stream_js_1.AgentResponseStreamSSE(stream), {
|
|
56
|
+
headers: {
|
|
57
|
+
"Content-Type": "text/event-stream",
|
|
58
|
+
"Cache-Control": "no-cache",
|
|
59
|
+
"X-Accel-Buffering": "no",
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
return new Response(JSON.stringify({ error: { message: error.message } }), {
|
|
65
|
+
status: error instanceof error_js_1.ServerError ? error.status : 500,
|
|
66
|
+
headers: { "Content-Type": "application/json" },
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async _prepareInput(request) {
|
|
71
|
+
const contentTypeError = new error_js_1.ServerError(415, "Unsupported Media Type: Content-Type must be application/json");
|
|
72
|
+
if (request instanceof node_http_1.IncomingMessage) {
|
|
73
|
+
// Support for express with json() middleware
|
|
74
|
+
if ("body" in request && typeof request.body === "object") {
|
|
75
|
+
if (!(0, type_utils_js_1.isRecord)(request.body))
|
|
76
|
+
throw contentTypeError;
|
|
77
|
+
return request.body;
|
|
78
|
+
}
|
|
79
|
+
// Support vanilla nodejs http server
|
|
80
|
+
const maximumBodySize = this.options?.maximumBodySize || DEFAULT_MAXIMUM_BODY_SIZE;
|
|
81
|
+
const ct = request.headers["content-type"];
|
|
82
|
+
if (!ct || !ct.includes("application/json"))
|
|
83
|
+
throw contentTypeError;
|
|
84
|
+
const parsedCt = content_type_1.default.parse(ct);
|
|
85
|
+
const raw = await (0, raw_body_1.default)(request, {
|
|
86
|
+
limit: maximumBodySize,
|
|
87
|
+
encoding: parsedCt.parameters.charset ?? "utf-8",
|
|
88
|
+
});
|
|
89
|
+
return (0, type_utils_js_1.tryOrThrow)(() => JSON.parse(raw.toString()), (error) => new error_js_1.ServerError(400, `Parse request body to json error: ${error.message}`));
|
|
90
|
+
}
|
|
91
|
+
if (request instanceof Request) {
|
|
92
|
+
if (!request.headers.get("content-type")?.includes("application/json")) {
|
|
93
|
+
throw contentTypeError;
|
|
94
|
+
}
|
|
95
|
+
return await request.json();
|
|
96
|
+
}
|
|
97
|
+
if (!(0, type_utils_js_1.isRecord)(request))
|
|
98
|
+
throw contentTypeError;
|
|
99
|
+
return request;
|
|
100
|
+
}
|
|
101
|
+
async _writeResponse(response, res) {
|
|
102
|
+
try {
|
|
103
|
+
res.writeHead(response.status, response.headers.toJSON());
|
|
104
|
+
res.flushHeaders();
|
|
105
|
+
if (!response.body)
|
|
106
|
+
throw new Error("Response body is empty");
|
|
107
|
+
for await (const chunk of (0, stream_utils_js_1.readableStreamToAsyncIterator)(response.body)) {
|
|
108
|
+
res.write(chunk);
|
|
109
|
+
// Support for express with compression middleware
|
|
110
|
+
if ("flush" in res && typeof res.flush === "function") {
|
|
111
|
+
res.flush();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
if (!res.headersSent) {
|
|
117
|
+
res.writeHead(error instanceof error_js_1.ServerError ? error.status : 500, {
|
|
118
|
+
"Content-Type": "application/json",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (res.writable) {
|
|
122
|
+
res.write(JSON.stringify({ error: { message: error.message } }));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
res.end();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.AIGNEServer = AIGNEServer;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function customCamelize<T extends Record<string, unknown>, K extends KeyofUnion<T> = never>(obj: T, { shallowKeys }?: {
|
|
2
|
+
shallowKeys?: K[];
|
|
3
|
+
}): CustomCamelize<T, K>;
|
|
4
|
+
type KeyofUnion<U> = U extends Record<string, unknown> ? keyof U : never;
|
|
5
|
+
type CamelCase<S extends string> = S extends `${infer P1}_${infer P2}${infer P3}` ? `${P1}${Uppercase<P2>}${CamelCase<P3>}` : S;
|
|
6
|
+
declare const _unique: unique symbol;
|
|
7
|
+
type _never = typeof _unique;
|
|
8
|
+
type ExtractTypeFromUnion<T, U> = Extract<T, U> extends never ? _never : Extract<T, U> extends Array<infer E> ? Array<E> : U;
|
|
9
|
+
type ExtractTypeWithConstFromUnion<T, U> = Exclude<T, Exclude<T, U>>;
|
|
10
|
+
export type CustomCamelize<T, ShallowKeys extends KeyofUnion<T> | undefined = undefined> = ExtractTypeFromUnion<T, never> extends never ? never : ExtractTypeFromUnion<T, Date> extends Date ? ExtractTypeWithConstFromUnion<T, Date> | CustomCamelize<Exclude<T, Date>> : ExtractTypeFromUnion<T, RegExp> extends RegExp ? ExtractTypeWithConstFromUnion<T, RegExp> | CustomCamelize<Exclude<T, RegExp>> : ExtractTypeFromUnion<T, Array<unknown>> extends Array<infer U> ? Array<CustomCamelize<U>> | CustomCamelize<Exclude<T, Array<U>>> : ExtractTypeFromUnion<T, Function> extends Function ? ExtractTypeWithConstFromUnion<T, Function> | CustomCamelize<Exclude<T, Function>> : ExtractTypeFromUnion<T, object> extends object ? {
|
|
11
|
+
[K in keyof T as Uncapitalize<CamelCase<string & K>>]: K extends Exclude<ShallowKeys, undefined> ? T[K] : CustomCamelize<T[K]>;
|
|
12
|
+
} : T;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.customCamelize = customCamelize;
|
|
7
|
+
const camelize_ts_1 = __importDefault(require("camelize-ts"));
|
|
8
|
+
function customCamelize(obj, { shallowKeys = [] } = {}) {
|
|
9
|
+
const shallow = Object.fromEntries(shallowKeys?.filter((key) => key in obj).map((key) => [key, obj[key]]) ?? []);
|
|
10
|
+
const deep = Object.fromEntries(Object.entries(obj).filter(([key]) => !shallowKeys?.includes(key)));
|
|
11
|
+
return {
|
|
12
|
+
...(0, camelize_ts_1.default)(shallow, true),
|
|
13
|
+
...(0, camelize_ts_1.default)(deep),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const _unique = Symbol();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentResponseChunk, AgentResponseStream, Message } from "../agents/agent.js";
|
|
2
|
+
export declare class EventStreamParser<T> extends TransformStream<string, T | Error> {
|
|
3
|
+
constructor();
|
|
4
|
+
}
|
|
5
|
+
export declare class AgentResponseStreamParser<O extends Message> extends TransformStream<AgentResponseChunk<O> | Error, AgentResponseChunk<O>> {
|
|
6
|
+
private json;
|
|
7
|
+
constructor();
|
|
8
|
+
}
|
|
9
|
+
export declare class AgentResponseStreamSSE<O extends Message> extends ReadableStream<string> {
|
|
10
|
+
constructor(stream: AgentResponseStream<O>);
|
|
11
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentResponseStreamSSE = exports.AgentResponseStreamParser = exports.EventStreamParser = void 0;
|
|
4
|
+
const eventsource_parser_1 = require("eventsource-parser");
|
|
5
|
+
const immer_1 = require("immer");
|
|
6
|
+
const type_utils_js_1 = require("./type-utils.js");
|
|
7
|
+
class EventStreamParser extends TransformStream {
|
|
8
|
+
constructor() {
|
|
9
|
+
let parser;
|
|
10
|
+
super({
|
|
11
|
+
start(controller) {
|
|
12
|
+
parser = (0, eventsource_parser_1.createParser)({
|
|
13
|
+
onEvent: (event) => {
|
|
14
|
+
const json = (0, type_utils_js_1.tryOrThrow)(() => JSON.parse(event.data), (e) => {
|
|
15
|
+
controller.enqueue(new Error(`Parse response chunk json error: ${e.message} ${event.data}`));
|
|
16
|
+
});
|
|
17
|
+
if (json) {
|
|
18
|
+
if (event.event === "error") {
|
|
19
|
+
controller.enqueue(new Error(json.message));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
controller.enqueue(json);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
transform(chunk) {
|
|
29
|
+
parser?.feed(chunk);
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.EventStreamParser = EventStreamParser;
|
|
35
|
+
class AgentResponseStreamParser extends TransformStream {
|
|
36
|
+
json = {};
|
|
37
|
+
constructor() {
|
|
38
|
+
super({
|
|
39
|
+
transform: (chunk, controller) => {
|
|
40
|
+
if (chunk instanceof Error) {
|
|
41
|
+
controller.error(chunk);
|
|
42
|
+
controller.terminate();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.json = (0, immer_1.produce)(this.json, (draft) => {
|
|
46
|
+
if (chunk.delta.json)
|
|
47
|
+
Object.assign(draft, chunk.delta.json);
|
|
48
|
+
if (chunk.delta.text) {
|
|
49
|
+
for (const [key, text] of Object.entries(chunk.delta.text)) {
|
|
50
|
+
const original = draft[key];
|
|
51
|
+
const t = (original || "") + (text || "");
|
|
52
|
+
if (t)
|
|
53
|
+
Object.assign(draft, { [key]: t });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
controller.enqueue({
|
|
58
|
+
...chunk,
|
|
59
|
+
delta: {
|
|
60
|
+
...chunk.delta,
|
|
61
|
+
json: this.json,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.AgentResponseStreamParser = AgentResponseStreamParser;
|
|
69
|
+
class AgentResponseStreamSSE extends ReadableStream {
|
|
70
|
+
constructor(stream) {
|
|
71
|
+
let reader;
|
|
72
|
+
super({
|
|
73
|
+
async pull(controller) {
|
|
74
|
+
reader ??= stream.getReader();
|
|
75
|
+
try {
|
|
76
|
+
const { value, done } = await reader.read();
|
|
77
|
+
if (done) {
|
|
78
|
+
controller.close();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
controller.enqueue(`data: ${JSON.stringify(value)}\n\n`);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
controller.enqueue(`event: error\ndata: ${JSON.stringify({ message: error.message })}\n\n`);
|
|
85
|
+
controller.close();
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.AgentResponseStreamSSE = AgentResponseStreamSSE;
|
|
@@ -8,12 +8,15 @@ const uriTemplate_js_1 = require("@modelcontextprotocol/sdk/shared/uriTemplate.j
|
|
|
8
8
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
9
9
|
const zod_1 = require("zod");
|
|
10
10
|
const mcp_agent_js_1 = require("../agents/mcp-agent.js");
|
|
11
|
+
const type_utils_js_1 = require("./type-utils.js");
|
|
11
12
|
function toolFromMCPTool(tool, options) {
|
|
12
13
|
return new mcp_agent_js_1.MCPTool({
|
|
13
14
|
...options,
|
|
14
15
|
name: tool.name,
|
|
15
16
|
description: tool.description,
|
|
16
|
-
inputSchema: (0,
|
|
17
|
+
inputSchema: (0, type_utils_js_1.isEmpty)(tool.inputSchema.properties)
|
|
18
|
+
? zod_1.z.object({})
|
|
19
|
+
: (0, json_schema_to_zod_1.jsonSchemaToZod)(tool.inputSchema),
|
|
17
20
|
outputSchema: types_js_1.CallToolResultSchema,
|
|
18
21
|
});
|
|
19
22
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AgentProcessAsyncGenerator, type AgentResponseChunk, type AgentResponseStream, type Message } from "../agents/agent.js";
|
|
2
|
+
import type { MESSAGE_KEY } from "../prompt/prompt-builder.js";
|
|
2
3
|
import { type PromiseOrValue } from "./type-utils.js";
|
|
3
4
|
export declare function objectToAgentResponseStream<T extends Message>(json: T): AgentResponseStream<T>;
|
|
4
5
|
export declare function mergeAgentResponseChunk<T extends Message>(output: T, chunk: AgentResponseChunk<T>): T;
|
|
@@ -10,6 +11,12 @@ export declare function onAgentResponseStreamEnd<T extends Message>(stream: Agen
|
|
|
10
11
|
}): ReadableStream<any>;
|
|
11
12
|
export declare function isAsyncGenerator<T extends AsyncGenerator>(value: AsyncGenerator | unknown): value is T;
|
|
12
13
|
export declare function arrayToAgentProcessAsyncGenerator<T extends Message>(chunks: (AgentResponseChunk<T> | Error)[], result?: Partial<T>): AgentProcessAsyncGenerator<T>;
|
|
13
|
-
export declare function
|
|
14
|
-
export declare function readableStreamToArray<T>(stream: ReadableStream<T
|
|
14
|
+
export declare function arrayToReadableStream<T>(chunks: (T | Error)[]): ReadableStream<T>;
|
|
15
|
+
export declare function readableStreamToArray<T>(stream: ReadableStream<T>, options: {
|
|
16
|
+
catchError: true;
|
|
17
|
+
}): Promise<(T | Error)[]>;
|
|
18
|
+
export declare function readableStreamToArray<T>(stream: ReadableStream<T>, options?: {
|
|
19
|
+
catchError?: false;
|
|
20
|
+
}): Promise<T[]>;
|
|
15
21
|
export declare function readableStreamToAsyncIterator<T>(stream: ReadableStream<T>): AsyncIterable<T>;
|
|
22
|
+
export declare function stringToAgentResponseStream(str: string, key?: "text" | typeof MESSAGE_KEY | string): AgentResponseStream<Message>;
|