@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
@@ -6,6 +6,6 @@ export interface ContextUsage {
6
6
  export declare function newEmptyContextUsage(): ContextUsage;
7
7
  export interface ContextLimits {
8
8
  maxTokens?: number;
9
- maxAgentCalls?: number;
9
+ maxAgentInvokes?: number;
10
10
  timeout?: number;
11
11
  }
@@ -0,0 +1,19 @@
1
+ import type { AgentInvokeOptions, AgentResponse, AgentResponseStream, Message } from "../agents/agent.js";
2
+ export interface AIGNEClientOptions {
3
+ url: string;
4
+ }
5
+ export interface AIGNEClientInvokeOptions extends AgentInvokeOptions {
6
+ fetchOptions?: Partial<RequestInit>;
7
+ }
8
+ export declare class AIGNEClient {
9
+ options: AIGNEClientOptions;
10
+ constructor(options: AIGNEClientOptions);
11
+ invoke<I extends Message, O extends Message>(agent: string, input: I, options: AIGNEClientInvokeOptions & {
12
+ streaming: true;
13
+ }): Promise<AgentResponseStream<O>>;
14
+ invoke<I extends Message, O extends Message>(agent: string, input: I, options?: AIGNEClientInvokeOptions & {
15
+ streaming?: false;
16
+ }): Promise<O>;
17
+ invoke<I extends Message, O extends Message>(agent: string, input: I, options?: AIGNEClientInvokeOptions): Promise<AgentResponse<O>>;
18
+ fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
19
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AIGNEClient = void 0;
4
+ const event_stream_js_1 = require("../utils/event-stream.js");
5
+ const type_utils_js_1 = require("../utils/type-utils.js");
6
+ class AIGNEClient {
7
+ options;
8
+ constructor(options) {
9
+ this.options = options;
10
+ }
11
+ async invoke(agent, input, options) {
12
+ const response = await this.fetch(this.options.url, {
13
+ ...options?.fetchOptions,
14
+ method: "POST",
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ ...options?.fetchOptions?.headers,
18
+ },
19
+ body: JSON.stringify({ agent, input, options }),
20
+ });
21
+ if (!options?.streaming) {
22
+ return await response.json();
23
+ }
24
+ const stream = response.body;
25
+ if (!stream)
26
+ throw new Error("Response body is not a stream");
27
+ return stream
28
+ .pipeThrough(new TextDecoderStream())
29
+ .pipeThrough(new event_stream_js_1.EventStreamParser())
30
+ .pipeThrough(new event_stream_js_1.AgentResponseStreamParser());
31
+ }
32
+ async fetch(...args) {
33
+ const result = await globalThis.fetch(...args);
34
+ if (!result.ok) {
35
+ let message;
36
+ try {
37
+ const text = await result.text();
38
+ const json = (0, type_utils_js_1.tryOrThrow)(() => JSON.parse(text));
39
+ message = json?.error?.message || text;
40
+ }
41
+ catch {
42
+ // ignore
43
+ }
44
+ throw new Error(`Failed to fetch url ${args[0]} with status ${result.status}: ${message}`);
45
+ }
46
+ return result;
47
+ }
48
+ }
49
+ exports.AIGNEClient = AIGNEClient;
@@ -2,9 +2,10 @@ export * from "./agents/agent.js";
2
2
  export * from "./agents/ai-agent.js";
3
3
  export * from "./agents/mcp-agent.js";
4
4
  export * from "./agents/memory.js";
5
+ export * from "./agents/team-agent.js";
5
6
  export * from "./agents/types.js";
6
7
  export * from "./agents/user-agent.js";
7
- export * from "./execution-engine/index.js";
8
+ export * from "./aigne/index.js";
8
9
  export * from "./models/chat-model.js";
9
10
  export * from "./prompt/prompt-builder.js";
10
11
  export * from "./prompt/template.js";
package/lib/cjs/index.js CHANGED
@@ -18,9 +18,10 @@ __exportStar(require("./agents/agent.js"), exports);
18
18
  __exportStar(require("./agents/ai-agent.js"), exports);
19
19
  __exportStar(require("./agents/mcp-agent.js"), exports);
20
20
  __exportStar(require("./agents/memory.js"), exports);
21
+ __exportStar(require("./agents/team-agent.js"), exports);
21
22
  __exportStar(require("./agents/types.js"), exports);
22
23
  __exportStar(require("./agents/user-agent.js"), exports);
23
- __exportStar(require("./execution-engine/index.js"), exports);
24
+ __exportStar(require("./aigne/index.js"), exports);
24
25
  __exportStar(require("./models/chat-model.js"), exports);
25
26
  __exportStar(require("./prompt/prompt-builder.js"), exports);
26
27
  __exportStar(require("./prompt/template.js"), exports);
@@ -2,12 +2,12 @@ import { type ZodObject, type ZodType, z } from "zod";
2
2
  export declare function loadAgentFromYamlFile(path: string): Promise<{
3
3
  type: "ai";
4
4
  name: string;
5
- tools?: string[] | undefined;
6
5
  description?: string | undefined;
7
- instructions?: string | undefined;
8
6
  memory?: true | {
9
- subscribeTopic: string[];
7
+ subscribeTopic?: string[] | undefined;
10
8
  } | undefined;
9
+ skills?: string[] | undefined;
10
+ instructions?: string | undefined;
11
11
  inputSchema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
12
12
  [x: string]: any;
13
13
  }, {
@@ -30,7 +30,7 @@ const agentFileSchema = zod_1.z.discriminatedUnion("type", [
30
30
  .string()
31
31
  .nullish()
32
32
  .transform((v) => v ?? undefined),
33
- tools: zod_1.z
33
+ skills: zod_1.z
34
34
  .array(zod_1.z.string())
35
35
  .nullish()
36
36
  .transform((v) => v ?? undefined),
@@ -42,7 +42,10 @@ const agentFileSchema = zod_1.z.discriminatedUnion("type", [
42
42
  .union([
43
43
  zod_1.z.boolean(),
44
44
  zod_1.z.object({
45
- subscribe_topic: zod_1.z.array(zod_1.z.string()),
45
+ subscribe_topic: zod_1.z
46
+ .array(zod_1.z.string())
47
+ .nullish()
48
+ .transform((v) => v ?? undefined),
46
49
  }),
47
50
  ])
48
51
  .nullish()
@@ -67,7 +70,11 @@ const agentFileSchema = zod_1.z.discriminatedUnion("type", [
67
70
  async function loadAgentFromYamlFile(path) {
68
71
  const raw = await (0, type_utils_js_1.tryOrThrow)(() => (0, promises_1.readFile)(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
69
72
  const json = await (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
70
- const agent = (0, type_utils_js_1.tryOrThrow)(() => (0, camelize_js_1.customCamelize)(agentFileSchema.parse({ ...json, type: json.type ?? "ai" }), {
73
+ const agent = (0, type_utils_js_1.tryOrThrow)(() => (0, camelize_js_1.customCamelize)(agentFileSchema.parse({
74
+ ...json,
75
+ type: json.type ?? "ai",
76
+ skills: json.skills ?? json.tools,
77
+ }), {
71
78
  shallowKeys: ["input_schema", "output_schema"],
72
79
  }), (error) => new Error(`Failed to validate agent definition from ${path}: ${error.message}`));
73
80
  return agent;
@@ -7,9 +7,9 @@ export interface LoadOptions {
7
7
  export declare function load(options: LoadOptions): Promise<{
8
8
  model: ChatModel | undefined;
9
9
  agents: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
10
- tools: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
11
- name?: string | null | undefined;
10
+ skills: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
12
11
  description?: string | null | undefined;
12
+ name?: string | null | undefined;
13
13
  chat_model?: {
14
14
  name?: string | null | undefined;
15
15
  temperature?: number | null | undefined;
@@ -61,11 +61,11 @@ declare const aigneFileSchema: z.ZodObject<{
61
61
  presence_penalty?: number | null | undefined;
62
62
  } | null | undefined>;
63
63
  agents: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
64
- tools: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
64
+ skills: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
65
65
  }, "strip", z.ZodTypeAny, {
66
- tools?: string[] | null | undefined;
67
- name?: string | null | undefined;
68
66
  description?: string | null | undefined;
67
+ name?: string | null | undefined;
68
+ skills?: string[] | null | undefined;
69
69
  chat_model?: {
70
70
  name?: string | null | undefined;
71
71
  temperature?: number | null | undefined;
@@ -76,9 +76,9 @@ declare const aigneFileSchema: z.ZodObject<{
76
76
  } | null | undefined;
77
77
  agents?: string[] | null | undefined;
78
78
  }, {
79
- tools?: string[] | null | undefined;
80
- name?: string | null | undefined;
81
79
  description?: string | null | undefined;
80
+ name?: string | null | undefined;
81
+ skills?: string[] | null | undefined;
82
82
  chat_model?: string | {
83
83
  name?: string | null | undefined;
84
84
  temperature?: number | null | undefined;
@@ -90,9 +90,9 @@ declare const aigneFileSchema: z.ZodObject<{
90
90
  agents?: string[] | null | undefined;
91
91
  }>;
92
92
  export declare function loadAIGNEFile(path: string): Promise<{
93
- tools?: string[] | null | undefined;
94
- name?: string | null | undefined;
95
93
  description?: string | null | undefined;
94
+ name?: string | null | undefined;
95
+ skills?: string[] | null | undefined;
96
96
  chat_model?: {
97
97
  name?: string | null | undefined;
98
98
  temperature?: number | null | undefined;
@@ -28,12 +28,12 @@ async function load(options) {
28
28
  const rootDir = (0, node_path_1.dirname)(aigneFilePath);
29
29
  const aigne = await loadAIGNEFile(aigneFilePath);
30
30
  const agents = await Promise.all((aigne.agents ?? []).map((filename) => loadAgent((0, node_path_1.join)(rootDir, filename))));
31
- const tools = await Promise.all((aigne.tools ?? []).map((filename) => loadAgent((0, node_path_1.join)(rootDir, filename))));
31
+ const skills = await Promise.all((aigne.skills ?? []).map((filename) => loadAgent((0, node_path_1.join)(rootDir, filename))));
32
32
  return {
33
33
  ...aigne,
34
34
  model: await loadModel(aigne.chat_model),
35
35
  agents,
36
- tools,
36
+ skills,
37
37
  };
38
38
  }
39
39
  async function loadAgent(path) {
@@ -46,8 +46,8 @@ async function loadAgent(path) {
46
46
  if (agent.type === "ai") {
47
47
  return ai_agent_js_1.AIAgent.from({
48
48
  ...agent,
49
- tools: agent.tools &&
50
- (await Promise.all(agent.tools.map((filename) => loadAgent((0, node_path_1.join)((0, node_path_1.dirname)(path), filename))))),
49
+ skills: agent.skills &&
50
+ (await Promise.all(agent.skills.map((filename) => loadAgent((0, node_path_1.join)((0, node_path_1.dirname)(path), filename))))),
51
51
  });
52
52
  }
53
53
  if (agent.type === "mcp") {
@@ -112,12 +112,12 @@ const aigneFileSchema = zod_1.z.object({
112
112
  .nullish()
113
113
  .transform((v) => (typeof v === "string" ? { name: v } : v)),
114
114
  agents: zod_1.z.array(zod_1.z.string()).nullish(),
115
- tools: zod_1.z.array(zod_1.z.string()).nullish(),
115
+ skills: zod_1.z.array(zod_1.z.string()).nullish(),
116
116
  });
117
117
  async function loadAIGNEFile(path) {
118
118
  const raw = await (0, type_utils_js_1.tryOrThrow)(() => (0, promises_1.readFile)(path, "utf8"), (error) => new Error(`Failed to load aigne.yaml from ${path}: ${error.message}`));
119
119
  const json = await (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse aigne.yaml from ${path}: ${error.message}`));
120
- const agent = (0, type_utils_js_1.tryOrThrow)(() => aigneFileSchema.parse(json), (error) => new Error(`Failed to validate aigne.yaml from ${path}: ${error.message}`));
120
+ const agent = (0, type_utils_js_1.tryOrThrow)(() => aigneFileSchema.parse({ ...json, skills: json.skills ?? json.tools }), (error) => new Error(`Failed to validate aigne.yaml from ${path}: ${error.message}`));
121
121
  return agent;
122
122
  }
123
123
  async function getAIGNEFilePath(path) {
@@ -1,5 +1,5 @@
1
1
  import { Agent, type Message } from "../agents/agent.js";
2
- import type { Context } from "../execution-engine/context.js";
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,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";
@@ -117,10 +117,10 @@ class PromptBuilder {
117
117
  : undefined;
118
118
  }
119
119
  buildTools(options) {
120
- const toolAgents = (options.context?.tools ?? [])
121
- .concat(options.agent?.tools ?? [])
120
+ const toolAgents = (options.context?.skills ?? [])
121
+ .concat(options.agent?.skills ?? [])
122
122
  // TODO: support nested tools?
123
- .flatMap((i) => (i.isCallable ? i.tools.concat(i) : i.tools));
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,4 @@
1
+ export declare class ServerError extends Error {
2
+ status: number;
3
+ constructor(status: number, message: string);
4
+ }
@@ -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,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, json_schema_to_zod_1.jsonSchemaToZod)(tool.inputSchema),
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
  }