@aigne/core 1.11.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +11 -10
  3. package/README.zh.md +7 -6
  4. package/lib/cjs/agents/agent.d.ts +20 -20
  5. package/lib/cjs/agents/agent.js +25 -26
  6. package/lib/cjs/agents/ai-agent.d.ts +17 -18
  7. package/lib/cjs/agents/ai-agent.js +6 -6
  8. package/lib/cjs/agents/mcp-agent.d.ts +10 -4
  9. package/lib/cjs/agents/mcp-agent.js +12 -6
  10. package/lib/cjs/agents/memory.d.ts +1 -1
  11. package/lib/cjs/agents/team-agent.d.ts +28 -0
  12. package/lib/cjs/agents/team-agent.js +93 -0
  13. package/lib/cjs/agents/user-agent.d.ts +9 -10
  14. package/lib/cjs/agents/user-agent.js +10 -13
  15. package/lib/{esm/execution-engine/execution-engine.d.ts → cjs/aigne/aigne.d.ts} +9 -12
  16. package/lib/cjs/{execution-engine/execution-engine.js → aigne/aigne.js} +19 -19
  17. package/lib/cjs/{execution-engine → aigne}/context.d.ts +31 -32
  18. package/lib/cjs/{execution-engine → aigne}/context.js +30 -40
  19. package/lib/cjs/aigne/index.d.ts +4 -0
  20. package/lib/cjs/{execution-engine → aigne}/index.js +2 -2
  21. package/lib/cjs/{execution-engine → aigne}/usage.d.ts +1 -1
  22. package/lib/cjs/client/client.d.ts +19 -0
  23. package/lib/cjs/client/client.js +49 -0
  24. package/lib/cjs/index.d.ts +2 -1
  25. package/lib/cjs/index.js +2 -1
  26. package/lib/cjs/loader/agent-yaml.d.ts +3 -3
  27. package/lib/cjs/loader/agent-yaml.js +10 -3
  28. package/lib/cjs/loader/index.d.ts +9 -9
  29. package/lib/cjs/loader/index.js +6 -6
  30. package/lib/cjs/models/chat-model.d.ts +1 -1
  31. package/lib/cjs/models/claude-chat-model.d.ts +3 -3
  32. package/lib/cjs/models/openai-chat-model.d.ts +3 -3
  33. package/lib/cjs/prompt/prompt-builder.d.ts +1 -1
  34. package/lib/cjs/prompt/prompt-builder.js +3 -3
  35. package/lib/cjs/server/error.d.ts +4 -0
  36. package/lib/cjs/server/error.js +11 -0
  37. package/lib/cjs/server/server.d.ts +54 -0
  38. package/lib/cjs/server/server.js +130 -0
  39. package/lib/cjs/utils/event-stream.d.ts +11 -0
  40. package/lib/cjs/utils/event-stream.js +91 -0
  41. package/lib/cjs/utils/mcp-utils.js +4 -1
  42. package/lib/cjs/utils/stream-utils.d.ts +7 -2
  43. package/lib/cjs/utils/stream-utils.js +43 -34
  44. package/lib/cjs/utils/type-utils.d.ts +4 -2
  45. package/lib/cjs/utils/type-utils.js +10 -2
  46. package/lib/dts/agents/agent.d.ts +20 -20
  47. package/lib/dts/agents/ai-agent.d.ts +17 -18
  48. package/lib/dts/agents/mcp-agent.d.ts +10 -4
  49. package/lib/dts/agents/memory.d.ts +1 -1
  50. package/lib/dts/agents/team-agent.d.ts +28 -0
  51. package/lib/dts/agents/user-agent.d.ts +9 -10
  52. package/lib/dts/{execution-engine/execution-engine.d.ts → aigne/aigne.d.ts} +9 -12
  53. package/lib/dts/{execution-engine → aigne}/context.d.ts +31 -32
  54. package/lib/dts/aigne/index.d.ts +4 -0
  55. package/lib/dts/{execution-engine → aigne}/usage.d.ts +1 -1
  56. package/lib/dts/client/client.d.ts +19 -0
  57. package/lib/dts/index.d.ts +2 -1
  58. package/lib/dts/loader/agent-yaml.d.ts +3 -3
  59. package/lib/dts/loader/index.d.ts +9 -9
  60. package/lib/dts/models/chat-model.d.ts +1 -1
  61. package/lib/dts/models/claude-chat-model.d.ts +3 -3
  62. package/lib/dts/models/openai-chat-model.d.ts +3 -3
  63. package/lib/dts/prompt/prompt-builder.d.ts +1 -1
  64. package/lib/dts/server/error.d.ts +4 -0
  65. package/lib/dts/server/server.d.ts +54 -0
  66. package/lib/dts/utils/event-stream.d.ts +11 -0
  67. package/lib/dts/utils/stream-utils.d.ts +7 -2
  68. package/lib/dts/utils/type-utils.d.ts +4 -2
  69. package/lib/esm/agents/agent.d.ts +20 -20
  70. package/lib/esm/agents/agent.js +25 -26
  71. package/lib/esm/agents/ai-agent.d.ts +17 -18
  72. package/lib/esm/agents/ai-agent.js +6 -6
  73. package/lib/esm/agents/mcp-agent.d.ts +10 -4
  74. package/lib/esm/agents/mcp-agent.js +12 -6
  75. package/lib/esm/agents/memory.d.ts +1 -1
  76. package/lib/esm/agents/team-agent.d.ts +28 -0
  77. package/lib/esm/agents/team-agent.js +89 -0
  78. package/lib/esm/agents/user-agent.d.ts +9 -10
  79. package/lib/esm/agents/user-agent.js +11 -14
  80. package/lib/{cjs/execution-engine/execution-engine.d.ts → esm/aigne/aigne.d.ts} +9 -12
  81. package/lib/esm/{execution-engine/execution-engine.js → aigne/aigne.js} +18 -18
  82. package/lib/esm/{execution-engine → aigne}/context.d.ts +31 -32
  83. package/lib/esm/{execution-engine → aigne}/context.js +28 -38
  84. package/lib/esm/aigne/index.d.ts +4 -0
  85. package/lib/esm/aigne/index.js +4 -0
  86. package/lib/esm/{execution-engine → aigne}/usage.d.ts +1 -1
  87. package/lib/esm/client/client.d.ts +19 -0
  88. package/lib/esm/client/client.js +45 -0
  89. package/lib/esm/index.d.ts +2 -1
  90. package/lib/esm/index.js +2 -1
  91. package/lib/esm/loader/agent-yaml.d.ts +3 -3
  92. package/lib/esm/loader/agent-yaml.js +10 -3
  93. package/lib/esm/loader/index.d.ts +9 -9
  94. package/lib/esm/loader/index.js +6 -6
  95. package/lib/esm/models/chat-model.d.ts +1 -1
  96. package/lib/esm/models/claude-chat-model.d.ts +3 -3
  97. package/lib/esm/models/openai-chat-model.d.ts +3 -3
  98. package/lib/esm/prompt/prompt-builder.d.ts +1 -1
  99. package/lib/esm/prompt/prompt-builder.js +3 -3
  100. package/lib/esm/server/error.d.ts +4 -0
  101. package/lib/esm/server/error.js +7 -0
  102. package/lib/esm/server/server.d.ts +54 -0
  103. package/lib/esm/server/server.js +123 -0
  104. package/lib/esm/utils/event-stream.d.ts +11 -0
  105. package/lib/esm/utils/event-stream.js +85 -0
  106. package/lib/esm/utils/mcp-utils.js +4 -1
  107. package/lib/esm/utils/stream-utils.d.ts +7 -2
  108. package/lib/esm/utils/stream-utils.js +42 -33
  109. package/lib/esm/utils/type-utils.d.ts +4 -2
  110. package/lib/esm/utils/type-utils.js +9 -2
  111. package/package.json +13 -4
  112. package/lib/cjs/execution-engine/index.d.ts +0 -4
  113. package/lib/cjs/execution-engine/utils.d.ts +0 -4
  114. package/lib/cjs/execution-engine/utils.js +0 -34
  115. package/lib/dts/execution-engine/index.d.ts +0 -4
  116. package/lib/dts/execution-engine/utils.d.ts +0 -4
  117. package/lib/esm/execution-engine/index.d.ts +0 -4
  118. package/lib/esm/execution-engine/index.js +0 -4
  119. package/lib/esm/execution-engine/utils.d.ts +0 -4
  120. package/lib/esm/execution-engine/utils.js +0 -30
  121. /package/lib/cjs/{execution-engine → aigne}/message-queue.d.ts +0 -0
  122. /package/lib/cjs/{execution-engine → aigne}/message-queue.js +0 -0
  123. /package/lib/cjs/{execution-engine → aigne}/usage.js +0 -0
  124. /package/lib/dts/{execution-engine → aigne}/message-queue.d.ts +0 -0
  125. /package/lib/esm/{execution-engine → aigne}/message-queue.d.ts +0 -0
  126. /package/lib/esm/{execution-engine → aigne}/message-queue.js +0 -0
  127. /package/lib/esm/{execution-engine → aigne}/usage.js +0 -0
@@ -1,7 +1,7 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
2
  import { z } from "zod";
3
- import type { AgentCallOptions, AgentResponse } from "../agents/agent.js";
4
- import type { Context } from "../execution-engine/context.js";
3
+ import type { AgentInvokeOptions, AgentResponse } from "../agents/agent.js";
4
+ import type { Context } from "../aigne/context.js";
5
5
  import { ChatModel, type ChatModelInput, type ChatModelOptions, type ChatModelOutput } from "./chat-model.js";
6
6
  export interface ClaudeChatModelOptions {
7
7
  apiKey?: string;
@@ -62,7 +62,7 @@ export declare class ClaudeChatModel extends ChatModel {
62
62
  protected _client?: Anthropic;
63
63
  get client(): Anthropic;
64
64
  get modelOptions(): ChatModelOptions | undefined;
65
- process(input: ChatModelInput, _context: Context, options?: AgentCallOptions): Promise<AgentResponse<ChatModelOutput>>;
65
+ process(input: ChatModelInput, _context: Context, options?: AgentInvokeOptions): Promise<AgentResponse<ChatModelOutput>>;
66
66
  private extractResultFromClaudeStream;
67
67
  private requestStructuredOutput;
68
68
  }
@@ -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 { AgentCallOptions, AgentResponse } from "../agents/agent.js";
5
- import type { Context } from "../execution-engine/context.js";
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?: AgentCallOptions): Promise<AgentResponse<ChatModelOutput>>;
86
+ process(input: ChatModelInput, _context: Context, options?: AgentInvokeOptions): Promise<AgentResponse<ChatModelOutput>>;
87
87
  private getParallelToolCalls;
88
88
  private getRunMessages;
89
89
  private getRunResponseFormat;
@@ -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 "../execution-engine/context.js";
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";
@@ -112,10 +112,10 @@ export class PromptBuilder {
112
112
  : undefined;
113
113
  }
114
114
  buildTools(options) {
115
- const toolAgents = (options.context?.tools ?? [])
116
- .concat(options.agent?.tools ?? [])
115
+ const toolAgents = (options.context?.skills ?? [])
116
+ .concat(options.agent?.skills ?? [])
117
117
  // TODO: support nested tools?
118
- .flatMap((i) => (i.isCallable ? i.tools.concat(i) : i.tools));
118
+ .flatMap((i) => (i.isInvokable ? i.skills.concat(i) : i.skills));
119
119
  const tools = toolAgents.map((i) => ({
120
120
  type: "function",
121
121
  function: {
@@ -0,0 +1,4 @@
1
+ export declare class ServerError extends Error {
2
+ status: number;
3
+ constructor(status: number, message: string);
4
+ }
@@ -0,0 +1,7 @@
1
+ export class ServerError extends Error {
2
+ status;
3
+ constructor(status, message) {
4
+ super(message);
5
+ this.status = status;
6
+ }
7
+ }
@@ -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,123 @@
1
+ import { IncomingMessage, ServerResponse } from "node:http";
2
+ import contentType from "content-type";
3
+ import getRawBody from "raw-body";
4
+ import { z } from "zod";
5
+ import { AgentResponseStreamSSE } from "../utils/event-stream.js";
6
+ import { readableStreamToAsyncIterator } from "../utils/stream-utils.js";
7
+ import { checkArguments, isRecord, tryOrThrow } from "../utils/type-utils.js";
8
+ import { ServerError } from "./error.js";
9
+ const DEFAULT_MAXIMUM_BODY_SIZE = "4mb";
10
+ export const invokePayloadSchema = z.object({
11
+ agent: z.string(),
12
+ input: z.record(z.string(), z.unknown()),
13
+ options: z
14
+ .object({
15
+ streaming: z.boolean().nullish(),
16
+ })
17
+ .nullish(),
18
+ });
19
+ export class AIGNEServer {
20
+ engine;
21
+ options;
22
+ constructor(engine, options) {
23
+ this.engine = engine;
24
+ this.options = options;
25
+ }
26
+ async invoke(request, response) {
27
+ const result = await this._invoke(request);
28
+ if (response instanceof ServerResponse) {
29
+ await this._writeResponse(result, response);
30
+ return;
31
+ }
32
+ return result;
33
+ }
34
+ async _invoke(request) {
35
+ const { engine } = this;
36
+ try {
37
+ const payload = await this._prepareInput(request);
38
+ const { agent: agentName, input, options, } = tryOrThrow(() => checkArguments(`Invoke agent ${payload.agent}`, invokePayloadSchema, payload), (error) => new ServerError(400, error.message));
39
+ const agent = engine.agents[agentName];
40
+ if (!agent)
41
+ throw new ServerError(404, `Agent ${agentName} not found`);
42
+ if (!options?.streaming) {
43
+ const result = await engine.invoke(agent, input);
44
+ return new Response(JSON.stringify(result), {
45
+ headers: { "Content-Type": "application/json" },
46
+ });
47
+ }
48
+ const stream = await engine.invoke(agent, input, { streaming: true });
49
+ return new Response(new AgentResponseStreamSSE(stream), {
50
+ headers: {
51
+ "Content-Type": "text/event-stream",
52
+ "Cache-Control": "no-cache",
53
+ "X-Accel-Buffering": "no",
54
+ },
55
+ });
56
+ }
57
+ catch (error) {
58
+ return new Response(JSON.stringify({ error: { message: error.message } }), {
59
+ status: error instanceof ServerError ? error.status : 500,
60
+ headers: { "Content-Type": "application/json" },
61
+ });
62
+ }
63
+ }
64
+ async _prepareInput(request) {
65
+ const contentTypeError = new ServerError(415, "Unsupported Media Type: Content-Type must be application/json");
66
+ if (request instanceof IncomingMessage) {
67
+ // Support for express with json() middleware
68
+ if ("body" in request && typeof request.body === "object") {
69
+ if (!isRecord(request.body))
70
+ throw contentTypeError;
71
+ return request.body;
72
+ }
73
+ // Support vanilla nodejs http server
74
+ const maximumBodySize = this.options?.maximumBodySize || DEFAULT_MAXIMUM_BODY_SIZE;
75
+ const ct = request.headers["content-type"];
76
+ if (!ct || !ct.includes("application/json"))
77
+ throw contentTypeError;
78
+ const parsedCt = contentType.parse(ct);
79
+ const raw = await getRawBody(request, {
80
+ limit: maximumBodySize,
81
+ encoding: parsedCt.parameters.charset ?? "utf-8",
82
+ });
83
+ return tryOrThrow(() => JSON.parse(raw.toString()), (error) => new ServerError(400, `Parse request body to json error: ${error.message}`));
84
+ }
85
+ if (request instanceof Request) {
86
+ if (!request.headers.get("content-type")?.includes("application/json")) {
87
+ throw contentTypeError;
88
+ }
89
+ return await request.json();
90
+ }
91
+ if (!isRecord(request))
92
+ throw contentTypeError;
93
+ return request;
94
+ }
95
+ async _writeResponse(response, res) {
96
+ try {
97
+ res.writeHead(response.status, response.headers.toJSON());
98
+ res.flushHeaders();
99
+ if (!response.body)
100
+ throw new Error("Response body is empty");
101
+ for await (const chunk of readableStreamToAsyncIterator(response.body)) {
102
+ res.write(chunk);
103
+ // Support for express with compression middleware
104
+ if ("flush" in res && typeof res.flush === "function") {
105
+ res.flush();
106
+ }
107
+ }
108
+ }
109
+ catch (error) {
110
+ if (!res.headersSent) {
111
+ res.writeHead(error instanceof ServerError ? error.status : 500, {
112
+ "Content-Type": "application/json",
113
+ });
114
+ }
115
+ if (res.writable) {
116
+ res.write(JSON.stringify({ error: { message: error.message } }));
117
+ }
118
+ }
119
+ finally {
120
+ res.end();
121
+ }
122
+ }
123
+ }
@@ -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,85 @@
1
+ import { createParser } from "eventsource-parser";
2
+ import { produce } from "immer";
3
+ import { tryOrThrow } from "./type-utils.js";
4
+ export class EventStreamParser extends TransformStream {
5
+ constructor() {
6
+ let parser;
7
+ super({
8
+ start(controller) {
9
+ parser = createParser({
10
+ onEvent: (event) => {
11
+ const json = tryOrThrow(() => JSON.parse(event.data), (e) => {
12
+ controller.enqueue(new Error(`Parse response chunk json error: ${e.message} ${event.data}`));
13
+ });
14
+ if (json) {
15
+ if (event.event === "error") {
16
+ controller.enqueue(new Error(json.message));
17
+ }
18
+ else {
19
+ controller.enqueue(json);
20
+ }
21
+ }
22
+ },
23
+ });
24
+ },
25
+ transform(chunk) {
26
+ parser?.feed(chunk);
27
+ },
28
+ });
29
+ }
30
+ }
31
+ export class AgentResponseStreamParser extends TransformStream {
32
+ json = {};
33
+ constructor() {
34
+ super({
35
+ transform: (chunk, controller) => {
36
+ if (chunk instanceof Error) {
37
+ controller.error(chunk);
38
+ controller.terminate();
39
+ return;
40
+ }
41
+ this.json = produce(this.json, (draft) => {
42
+ if (chunk.delta.json)
43
+ Object.assign(draft, chunk.delta.json);
44
+ if (chunk.delta.text) {
45
+ for (const [key, text] of Object.entries(chunk.delta.text)) {
46
+ const original = draft[key];
47
+ const t = (original || "") + (text || "");
48
+ if (t)
49
+ Object.assign(draft, { [key]: t });
50
+ }
51
+ }
52
+ });
53
+ controller.enqueue({
54
+ ...chunk,
55
+ delta: {
56
+ ...chunk.delta,
57
+ json: this.json,
58
+ },
59
+ });
60
+ },
61
+ });
62
+ }
63
+ }
64
+ export class AgentResponseStreamSSE extends ReadableStream {
65
+ constructor(stream) {
66
+ let reader;
67
+ super({
68
+ async pull(controller) {
69
+ reader ??= stream.getReader();
70
+ try {
71
+ const { value, done } = await reader.read();
72
+ if (done) {
73
+ controller.close();
74
+ return;
75
+ }
76
+ controller.enqueue(`data: ${JSON.stringify(value)}\n\n`);
77
+ }
78
+ catch (error) {
79
+ controller.enqueue(`event: error\ndata: ${JSON.stringify({ message: error.message })}\n\n`);
80
+ controller.close();
81
+ }
82
+ },
83
+ });
84
+ }
85
+ }
@@ -3,12 +3,15 @@ import { UriTemplate } from "@modelcontextprotocol/sdk/shared/uriTemplate.js";
3
3
  import { CallToolResultSchema, GetPromptResultSchema, ReadResourceResultSchema, } from "@modelcontextprotocol/sdk/types.js";
4
4
  import { z } from "zod";
5
5
  import { MCPPrompt, MCPResource, MCPTool } from "../agents/mcp-agent.js";
6
+ import { isEmpty } from "./type-utils.js";
6
7
  export function toolFromMCPTool(tool, options) {
7
8
  return new MCPTool({
8
9
  ...options,
9
10
  name: tool.name,
10
11
  description: tool.description,
11
- inputSchema: jsonSchemaToZod(tool.inputSchema),
12
+ inputSchema: isEmpty(tool.inputSchema.properties)
13
+ ? z.object({})
14
+ : jsonSchemaToZod(tool.inputSchema),
12
15
  outputSchema: CallToolResultSchema,
13
16
  });
14
17
  }
@@ -11,7 +11,12 @@ export declare function onAgentResponseStreamEnd<T extends Message>(stream: Agen
11
11
  }): ReadableStream<any>;
12
12
  export declare function isAsyncGenerator<T extends AsyncGenerator>(value: AsyncGenerator | unknown): value is T;
13
13
  export declare function arrayToAgentProcessAsyncGenerator<T extends Message>(chunks: (AgentResponseChunk<T> | Error)[], result?: Partial<T>): AgentProcessAsyncGenerator<T>;
14
- export declare function arrayToAgentResponseStream<T>(chunks: (AgentResponseChunk<T> | Error)[]): AgentResponseStream<T>;
15
- export declare function readableStreamToArray<T>(stream: ReadableStream<T>): Promise<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[]>;
16
21
  export declare function readableStreamToAsyncIterator<T>(stream: ReadableStream<T>): AsyncIterable<T>;
17
22
  export declare function stringToAgentResponseStream(str: string, key?: "text" | typeof MESSAGE_KEY | string): AgentResponseStream<Message>;
@@ -3,7 +3,7 @@ import { isEmptyChunk, } from "../agents/agent.js";
3
3
  import { omitBy } from "./type-utils.js";
4
4
  export function objectToAgentResponseStream(json) {
5
5
  return new ReadableStream({
6
- start(controller) {
6
+ pull(controller) {
7
7
  controller.enqueue({ delta: { json } });
8
8
  controller.close();
9
9
  },
@@ -49,22 +49,20 @@ export async function agentResponseStreamToObject(stream) {
49
49
  }
50
50
  export function asyncGeneratorToReadableStream(generator) {
51
51
  return new ReadableStream({
52
- async start(controller) {
52
+ async pull(controller) {
53
53
  try {
54
- for (;;) {
55
- const chunk = await generator.next();
56
- if (chunk.value) {
57
- if (chunk.done) {
58
- controller.enqueue({ delta: { json: chunk.value } });
59
- }
60
- else {
61
- controller.enqueue(chunk.value);
62
- }
54
+ const chunk = await generator.next();
55
+ if (chunk.value) {
56
+ if (chunk.done) {
57
+ controller.enqueue({ delta: { json: chunk.value } });
58
+ }
59
+ else {
60
+ controller.enqueue(chunk.value);
63
61
  }
64
- if (chunk.done)
65
- break;
66
62
  }
67
- controller.close();
63
+ if (chunk.done) {
64
+ controller.close();
65
+ }
68
66
  }
69
67
  catch (error) {
70
68
  controller.error(error);
@@ -73,15 +71,18 @@ export function asyncGeneratorToReadableStream(generator) {
73
71
  });
74
72
  }
75
73
  export function onAgentResponseStreamEnd(stream, callback, options) {
74
+ const json = {};
75
+ const reader = stream.getReader();
76
76
  return new ReadableStream({
77
- async start(controller) {
77
+ async pull(controller) {
78
78
  try {
79
- const json = {};
80
- for await (const value of readableStreamToAsyncIterator(stream)) {
79
+ const { value, done } = await reader.read();
80
+ if (!done) {
81
81
  const chunk = options?.processChunk ? options.processChunk(value) : value;
82
82
  if (!isEmptyChunk(chunk))
83
83
  controller.enqueue(chunk);
84
84
  mergeAgentResponseChunk(json, value);
85
+ return;
85
86
  }
86
87
  const result = await callback(json);
87
88
  if (result && !equal(result, json)) {
@@ -90,13 +91,11 @@ export function onAgentResponseStreamEnd(stream, callback, options) {
90
91
  chunk = options.processChunk(chunk);
91
92
  controller.enqueue(chunk);
92
93
  }
94
+ controller.close();
93
95
  }
94
96
  catch (error) {
95
97
  controller.error(options?.errorCallback?.(error) ?? error);
96
98
  }
97
- finally {
98
- controller.close();
99
- }
100
99
  },
101
100
  });
102
101
  }
@@ -112,24 +111,34 @@ export async function* arrayToAgentProcessAsyncGenerator(chunks, result) {
112
111
  if (result !== undefined)
113
112
  return result;
114
113
  }
115
- export function arrayToAgentResponseStream(chunks) {
114
+ export function arrayToReadableStream(chunks) {
115
+ const list = [...chunks];
116
116
  return new ReadableStream({
117
- start(controller) {
118
- for (const chunk of chunks) {
119
- if (chunk instanceof Error) {
120
- controller.error(chunk);
121
- return;
122
- }
123
- controller.enqueue(chunk);
117
+ pull(controller) {
118
+ const item = list.shift();
119
+ if (!item) {
120
+ controller.close();
121
+ return;
124
122
  }
125
- controller.close();
123
+ if (item instanceof Error) {
124
+ controller.error(item);
125
+ return;
126
+ }
127
+ controller.enqueue(item);
126
128
  },
127
129
  });
128
130
  }
129
- export async function readableStreamToArray(stream) {
131
+ export async function readableStreamToArray(stream, options) {
130
132
  const result = [];
131
- for await (const value of readableStreamToAsyncIterator(stream)) {
132
- result.push(value);
133
+ try {
134
+ for await (const value of readableStreamToAsyncIterator(stream)) {
135
+ result.push(value);
136
+ }
137
+ }
138
+ catch (error) {
139
+ if (!options?.catchError)
140
+ throw error;
141
+ result.push(error);
133
142
  }
134
143
  return result;
135
144
  }
@@ -145,5 +154,5 @@ export async function* readableStreamToAsyncIterator(stream) {
145
154
  export function stringToAgentResponseStream(str, key = "text") {
146
155
  const segmenter = new Intl.Segmenter(undefined, { granularity: "word" });
147
156
  const segments = segmenter.segment(str);
148
- return arrayToAgentResponseStream(Array.from(segments).map((segment) => ({ delta: { text: { [key]: segment.segment } } })));
157
+ return arrayToReadableStream(Array.from(segments).map((segment) => ({ delta: { text: { [key]: segment.segment } } })));
149
158
  }
@@ -1,8 +1,9 @@
1
1
  import { type ZodType } from "zod";
2
2
  export type PromiseOrValue<T> = T | Promise<T>;
3
- export type Nullish<T> = T | null | undefined;
3
+ export type Nullish<T> = T | null | undefined | void;
4
4
  export type OmitPropertiesFromArrayFirstElement<T extends unknown[], K extends string | number | symbol> = T extends [infer U, ...infer Rest] ? [Omit<U, K>, ...Rest] : never;
5
5
  export declare function isNil(value: unknown): value is null | undefined;
6
+ export declare function isRecord<T>(value: unknown): value is Record<string, T>;
6
7
  export declare function isEmpty(obj: unknown): boolean;
7
8
  export declare function isNonNullable<T>(value: T): value is NonNullable<T>;
8
9
  export declare function isNotEmpty<T>(arr: T[]): arr is [T, ...T[]];
@@ -12,5 +13,6 @@ export declare function orArrayToArray<T>(value?: T | T[]): T[];
12
13
  export declare function createAccessorArray<T>(array: T[], accessor: (array: T[], name: string) => T | undefined): T[] & {
13
14
  [key: string]: T;
14
15
  };
15
- export declare function checkArguments<T>(prefix: string, schema: ZodType<T>, args: T): T;
16
+ export declare function checkArguments<T>(prefix: string, schema: ZodType<T>, args: T | unknown): T;
16
17
  export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error: string | Error | ((error: Error) => Error)): P;
18
+ export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error?: Nullish<string | Error | ((error: Error) => Nullish<Error>)>): P | undefined;
@@ -2,6 +2,9 @@ import { z } from "zod";
2
2
  export function isNil(value) {
3
3
  return value === null || value === undefined;
4
4
  }
5
+ export function isRecord(value) {
6
+ return !!value && typeof value === "object" && !Array.isArray(value);
7
+ }
5
8
  export function isEmpty(obj) {
6
9
  if (isNil(obj))
7
10
  return true;
@@ -101,12 +104,16 @@ export function tryOrThrow(fn, error) {
101
104
  const result = fn();
102
105
  if (result instanceof Promise) {
103
106
  return result.catch((e) => {
104
- throw createError(e);
107
+ const error = createError(e);
108
+ if (error)
109
+ throw error;
105
110
  });
106
111
  }
107
112
  return result;
108
113
  }
109
114
  catch (e) {
110
- throw createError(e);
115
+ const error = createError(e);
116
+ if (error)
117
+ throw error;
111
118
  }
112
119
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "AIGNE core library for building AI-powered applications",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -44,8 +44,8 @@
44
44
  "agents/*": [
45
45
  "./lib/dts/agents/*"
46
46
  ],
47
- "execution-engine/*": [
48
- "./lib/dts/execution-engine/*"
47
+ "aigne/*": [
48
+ "./lib/dts/aigne/*"
49
49
  ],
50
50
  "loader/*": [
51
51
  "./lib/dts/loader/*"
@@ -63,15 +63,20 @@
63
63
  },
64
64
  "dependencies": {
65
65
  "@aigne/json-schema-to-zod": "^1.3.3",
66
- "@modelcontextprotocol/sdk": "^1.9.0",
66
+ "@modelcontextprotocol/sdk": "^1.10.2",
67
67
  "@types/debug": "^4.1.12",
68
68
  "camelize-ts": "^3.0.0",
69
+ "content-type": "^1.0.5",
69
70
  "debug": "^4.4.0",
71
+ "eventsource-parser": "^3.0.1",
70
72
  "fast-deep-equal": "^3.1.3",
73
+ "immer": "^10.1.1",
71
74
  "inquirer": "^12.5.2",
72
75
  "mustache": "^4.2.0",
73
76
  "nanoid": "^5.1.5",
74
77
  "p-retry": "^6.2.1",
78
+ "raw-body": "^3.0.0",
79
+ "ufo": "^1.6.1",
75
80
  "uuid": "^11.1.0",
76
81
  "yaml": "^2.7.1",
77
82
  "zod": "^3.24.2",
@@ -86,11 +91,15 @@
86
91
  "@anthropic-ai/sdk": "^0.39.0",
87
92
  "@google/generative-ai": "^0.24.0",
88
93
  "@types/bun": "^1.2.9",
94
+ "@types/compression": "^1.7.5",
95
+ "@types/content-type": "^1.1.8",
89
96
  "@types/express": "^5.0.1",
90
97
  "@types/mustache": "^4.2.5",
91
98
  "@types/node": "^22.14.1",
99
+ "compression": "^1.8.0",
92
100
  "detect-port": "^2.1.0",
93
101
  "express": "^5.1.0",
102
+ "hono": "^4.7.7",
94
103
  "npm-run-all": "^4.1.5",
95
104
  "openai": "^4.94.0",
96
105
  "rimraf": "^6.0.1",
@@ -1,4 +0,0 @@
1
- export * from "./context.js";
2
- export * from "./execution-engine.js";
3
- export * from "./message-queue.js";
4
- export * from "./utils.js";
@@ -1,4 +0,0 @@
1
- import { type FunctionAgentFn } from "../agents/agent.js";
2
- import type { Runnable } from "./context.js";
3
- export declare function sequential(...agents: [Runnable, ...Runnable[]]): FunctionAgentFn;
4
- export declare function parallel(...agents: [Runnable, ...Runnable[]]): FunctionAgentFn;