@aigne/core 1.1.0-beta.6 → 1.3.1

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 (105) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/lib/cjs/agents/agent.d.ts +37 -33
  3. package/lib/cjs/agents/agent.js +68 -28
  4. package/lib/cjs/agents/ai-agent.d.ts +8 -12
  5. package/lib/cjs/agents/ai-agent.js +17 -35
  6. package/lib/cjs/agents/mcp-agent.d.ts +25 -9
  7. package/lib/cjs/agents/mcp-agent.js +61 -14
  8. package/lib/cjs/agents/memory.d.ts +26 -0
  9. package/lib/cjs/agents/memory.js +38 -0
  10. package/lib/cjs/agents/types.d.ts +4 -3
  11. package/lib/cjs/agents/types.js +11 -1
  12. package/lib/cjs/agents/user-agent.d.ts +24 -0
  13. package/lib/cjs/agents/user-agent.js +62 -0
  14. package/lib/cjs/execution-engine/context.d.ts +35 -5
  15. package/lib/cjs/execution-engine/execution-engine.d.ts +64 -0
  16. package/lib/cjs/execution-engine/execution-engine.js +136 -0
  17. package/lib/cjs/execution-engine/index.d.ts +4 -46
  18. package/lib/cjs/execution-engine/index.js +17 -193
  19. package/lib/cjs/execution-engine/message-queue.d.ts +17 -2
  20. package/lib/cjs/execution-engine/message-queue.js +37 -1
  21. package/lib/cjs/execution-engine/utils.d.ts +4 -0
  22. package/lib/cjs/execution-engine/utils.js +32 -0
  23. package/lib/cjs/index.d.ts +14 -12
  24. package/lib/cjs/index.js +14 -12
  25. package/lib/{dts/models/chat.d.ts → cjs/models/chat-model.d.ts} +15 -12
  26. package/lib/cjs/models/{chat.js → chat-model.js} +5 -5
  27. package/lib/cjs/models/claude-chat-model.d.ts +17 -0
  28. package/lib/cjs/models/claude-chat-model.js +210 -0
  29. package/lib/cjs/models/{chat-openai.d.ts → openai-chat-model.d.ts} +2 -2
  30. package/lib/cjs/models/{chat-openai.js → openai-chat-model.js} +11 -10
  31. package/lib/cjs/prompt/prompt-builder.d.ts +14 -14
  32. package/lib/cjs/prompt/prompt-builder.js +62 -67
  33. package/lib/cjs/prompt/template.d.ts +9 -21
  34. package/lib/cjs/prompt/template.js +3 -5
  35. package/lib/cjs/utils/json-schema.d.ts +4 -0
  36. package/lib/cjs/utils/json-schema.js +34 -0
  37. package/lib/cjs/utils/mcp-utils.d.ts +3 -2
  38. package/lib/cjs/utils/mcp-utils.js +29 -17
  39. package/lib/cjs/utils/run-chat-loop.d.ts +5 -4
  40. package/lib/cjs/utils/run-chat-loop.js +25 -4
  41. package/lib/cjs/utils/type-utils.d.ts +3 -0
  42. package/lib/cjs/utils/type-utils.js +8 -8
  43. package/lib/dts/agents/agent.d.ts +37 -33
  44. package/lib/dts/agents/ai-agent.d.ts +8 -12
  45. package/lib/dts/agents/mcp-agent.d.ts +25 -9
  46. package/lib/dts/agents/memory.d.ts +26 -0
  47. package/lib/dts/agents/types.d.ts +4 -3
  48. package/lib/dts/agents/user-agent.d.ts +24 -0
  49. package/lib/dts/execution-engine/context.d.ts +35 -5
  50. package/lib/dts/execution-engine/execution-engine.d.ts +64 -0
  51. package/lib/dts/execution-engine/index.d.ts +4 -46
  52. package/lib/dts/execution-engine/message-queue.d.ts +17 -2
  53. package/lib/dts/execution-engine/utils.d.ts +4 -0
  54. package/lib/dts/index.d.ts +14 -12
  55. package/lib/{esm/models/chat.d.ts → dts/models/chat-model.d.ts} +15 -12
  56. package/lib/dts/models/claude-chat-model.d.ts +17 -0
  57. package/lib/dts/models/{chat-openai.d.ts → openai-chat-model.d.ts} +2 -2
  58. package/lib/dts/prompt/prompt-builder.d.ts +14 -14
  59. package/lib/dts/prompt/template.d.ts +9 -21
  60. package/lib/dts/utils/json-schema.d.ts +4 -0
  61. package/lib/dts/utils/mcp-utils.d.ts +3 -2
  62. package/lib/dts/utils/run-chat-loop.d.ts +5 -4
  63. package/lib/dts/utils/type-utils.d.ts +3 -0
  64. package/lib/esm/agents/agent.d.ts +37 -33
  65. package/lib/esm/agents/agent.js +67 -24
  66. package/lib/esm/agents/ai-agent.d.ts +8 -12
  67. package/lib/esm/agents/ai-agent.js +13 -31
  68. package/lib/esm/agents/mcp-agent.d.ts +25 -9
  69. package/lib/esm/agents/mcp-agent.js +54 -8
  70. package/lib/esm/agents/memory.d.ts +26 -0
  71. package/lib/esm/agents/memory.js +34 -0
  72. package/lib/esm/agents/types.d.ts +4 -3
  73. package/lib/esm/agents/types.js +10 -1
  74. package/lib/esm/agents/user-agent.d.ts +24 -0
  75. package/lib/esm/agents/user-agent.js +58 -0
  76. package/lib/esm/execution-engine/context.d.ts +35 -5
  77. package/lib/esm/execution-engine/execution-engine.d.ts +64 -0
  78. package/lib/esm/execution-engine/execution-engine.js +129 -0
  79. package/lib/esm/execution-engine/index.d.ts +4 -46
  80. package/lib/esm/execution-engine/index.js +4 -188
  81. package/lib/esm/execution-engine/message-queue.d.ts +17 -2
  82. package/lib/esm/execution-engine/message-queue.js +37 -1
  83. package/lib/esm/execution-engine/utils.d.ts +4 -0
  84. package/lib/esm/execution-engine/utils.js +28 -0
  85. package/lib/esm/index.d.ts +14 -12
  86. package/lib/esm/index.js +14 -12
  87. package/lib/{cjs/models/chat.d.ts → esm/models/chat-model.d.ts} +15 -12
  88. package/lib/esm/models/{chat.js → chat-model.js} +4 -4
  89. package/lib/esm/models/claude-chat-model.d.ts +17 -0
  90. package/lib/esm/models/claude-chat-model.js +203 -0
  91. package/lib/esm/models/{chat-openai.d.ts → openai-chat-model.d.ts} +2 -2
  92. package/lib/esm/models/{chat-openai.js → openai-chat-model.js} +8 -7
  93. package/lib/esm/prompt/prompt-builder.d.ts +14 -14
  94. package/lib/esm/prompt/prompt-builder.js +56 -58
  95. package/lib/esm/prompt/template.d.ts +9 -21
  96. package/lib/esm/prompt/template.js +3 -5
  97. package/lib/esm/utils/json-schema.d.ts +4 -0
  98. package/lib/esm/utils/json-schema.js +30 -0
  99. package/lib/esm/utils/mcp-utils.d.ts +3 -2
  100. package/lib/esm/utils/mcp-utils.js +26 -15
  101. package/lib/esm/utils/run-chat-loop.d.ts +5 -4
  102. package/lib/esm/utils/run-chat-loop.js +25 -4
  103. package/lib/esm/utils/type-utils.d.ts +3 -0
  104. package/lib/esm/utils/type-utils.js +4 -2
  105. package/package.json +31 -30
@@ -0,0 +1,210 @@
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.ClaudeChatModel = void 0;
7
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
8
+ const lodash_es_1 = require("lodash-es");
9
+ const json_schema_js_1 = require("../utils/json-schema.js");
10
+ const type_utils_js_1 = require("../utils/type-utils.js");
11
+ const chat_model_js_1 = require("./chat-model.js");
12
+ const CHAT_MODEL_CLAUDE_DEFAULT_MODEL = "claude-3-7-sonnet-latest";
13
+ class ClaudeChatModel extends chat_model_js_1.ChatModel {
14
+ config;
15
+ constructor(config) {
16
+ super();
17
+ this.config = config;
18
+ }
19
+ _client;
20
+ get client() {
21
+ if (!this.config?.apiKey)
22
+ throw new Error("Api Key is required for ClaudeChatModel");
23
+ this._client ??= new sdk_1.default({ apiKey: this.config.apiKey });
24
+ return this._client;
25
+ }
26
+ async process(input) {
27
+ const model = this.config?.model || CHAT_MODEL_CLAUDE_DEFAULT_MODEL;
28
+ const body = {
29
+ model,
30
+ temperature: input.modelOptions?.temperature,
31
+ top_p: input.modelOptions?.topP,
32
+ // TODO: make dynamic based on model https://docs.anthropic.com/en/docs/about-claude/models/all-models
33
+ max_tokens: /claude-3-[5|7]/.test(model) ? 8192 : 4096,
34
+ ...convertMessages(input),
35
+ ...convertTools(input),
36
+ };
37
+ const stream = this.client.messages.stream({
38
+ ...body,
39
+ stream: true,
40
+ });
41
+ const result = await this.extractResultFromClaudeStream(stream);
42
+ // Claude doesn't support json_schema response and tool calls in the same request,
43
+ // so we need to make a separate request for json_schema response when the tool calls is empty
44
+ if (!result.toolCalls?.length && input.responseFormat?.type === "json_schema") {
45
+ return this.requestStructuredOutput(body, input.responseFormat);
46
+ }
47
+ return result;
48
+ }
49
+ async extractResultFromClaudeStream(stream) {
50
+ let text = "";
51
+ const toolCalls = [];
52
+ for await (const chunk of stream) {
53
+ // handle streaming text
54
+ if (chunk.type === "content_block_delta" && chunk.delta.type === "text_delta") {
55
+ text += chunk.delta.text;
56
+ }
57
+ if (chunk.type === "content_block_start" && chunk.content_block.type === "tool_use") {
58
+ toolCalls[chunk.index] = {
59
+ type: "function",
60
+ id: chunk.content_block.id,
61
+ function: {
62
+ name: chunk.content_block.name,
63
+ arguments: {},
64
+ },
65
+ args: "",
66
+ };
67
+ }
68
+ if (chunk.type === "content_block_delta" && chunk.delta.type === "input_json_delta") {
69
+ const call = toolCalls[chunk.index];
70
+ if (!call)
71
+ throw new Error("Tool call not found");
72
+ call.args += chunk.delta.partial_json;
73
+ }
74
+ }
75
+ const result = { text };
76
+ if (toolCalls.length) {
77
+ result.toolCalls = toolCalls
78
+ .map(({ args, ...c }) => ({
79
+ ...c,
80
+ function: { ...c.function, arguments: (0, json_schema_js_1.parseJSON)(args) },
81
+ }))
82
+ .filter(type_utils_js_1.isNonNullable);
83
+ }
84
+ return result;
85
+ }
86
+ async requestStructuredOutput(body, responseFormat) {
87
+ if (responseFormat?.type !== "json_schema") {
88
+ throw new Error("Expected json_schema response format");
89
+ }
90
+ const result = await this.client.messages.create({
91
+ ...body,
92
+ tools: [
93
+ {
94
+ name: "generate_json",
95
+ description: "Generate a json result by given context",
96
+ input_schema: responseFormat.jsonSchema.schema,
97
+ },
98
+ ],
99
+ tool_choice: {
100
+ type: "tool",
101
+ name: "generate_json",
102
+ disable_parallel_tool_use: true,
103
+ },
104
+ stream: false,
105
+ });
106
+ const jsonTool = result.content.find((i) => i.type === "tool_use" && i.name === "generate_json");
107
+ if (!jsonTool)
108
+ throw new Error("Json tool not found");
109
+ return {
110
+ json: jsonTool.input,
111
+ };
112
+ }
113
+ }
114
+ exports.ClaudeChatModel = ClaudeChatModel;
115
+ function convertMessages({ messages, responseFormat }) {
116
+ const systemMessages = [];
117
+ const msgs = [];
118
+ for (const msg of messages) {
119
+ if (msg.role === "system") {
120
+ if (typeof msg.content !== "string")
121
+ throw new Error("System message must have content");
122
+ systemMessages.push(msg.content);
123
+ }
124
+ else if (msg.role === "tool") {
125
+ if (!msg.toolCallId)
126
+ throw new Error("Tool message must have toolCallId");
127
+ if (typeof msg.content !== "string")
128
+ throw new Error("Tool message must have string content");
129
+ msgs.push({
130
+ role: "user",
131
+ content: [{ type: "tool_result", tool_use_id: msg.toolCallId, content: msg.content }],
132
+ });
133
+ }
134
+ else if (msg.role === "user") {
135
+ if (!msg.content)
136
+ throw new Error("User message must have content");
137
+ msgs.push({ role: "user", content: convertContent(msg.content) });
138
+ }
139
+ else if (msg.role === "agent") {
140
+ if (msg.toolCalls?.length) {
141
+ msgs.push({
142
+ role: "assistant",
143
+ content: msg.toolCalls.map((i) => ({
144
+ type: "tool_use",
145
+ id: i.id,
146
+ name: i.function.name,
147
+ input: i.function.arguments,
148
+ })),
149
+ });
150
+ }
151
+ else if (msg.content) {
152
+ msgs.push({ role: "assistant", content: convertContent(msg.content) });
153
+ }
154
+ else {
155
+ throw new Error("Agent message must have content or toolCalls");
156
+ }
157
+ }
158
+ }
159
+ if (responseFormat?.type === "json_schema") {
160
+ systemMessages.push(`You should provide a json response with schema: ${JSON.stringify(responseFormat.jsonSchema.schema)}`);
161
+ }
162
+ const system = systemMessages.join("\n").trim() || undefined;
163
+ // Claude requires at least one message, so we add a system message if there are no messages
164
+ if (msgs.length === 0) {
165
+ if (!system)
166
+ throw new Error("No messages provided");
167
+ return { messages: [{ role: "user", content: system }] };
168
+ }
169
+ return { messages: msgs, system };
170
+ }
171
+ function convertContent(content) {
172
+ if (typeof content === "string")
173
+ return content;
174
+ if (Array.isArray(content)) {
175
+ return content.map((item) => item.type === "image_url"
176
+ ? { type: "image", source: { type: "url", url: item.url } }
177
+ : { type: "text", text: item.text });
178
+ }
179
+ throw new Error("Invalid chat message content");
180
+ }
181
+ function convertTools({ tools, toolChoice, }) {
182
+ let choice;
183
+ if (typeof toolChoice === "object" && "type" in toolChoice && toolChoice.type === "function") {
184
+ choice = {
185
+ type: "tool",
186
+ name: toolChoice.function.name,
187
+ };
188
+ }
189
+ else if (toolChoice === "required") {
190
+ choice = { type: "any" };
191
+ }
192
+ else if (toolChoice === "auto") {
193
+ choice = { type: "auto" };
194
+ }
195
+ else if (toolChoice === "none") {
196
+ choice = { type: "none" };
197
+ }
198
+ return {
199
+ tools: tools?.length
200
+ ? tools.map((i) => ({
201
+ name: i.function.name,
202
+ description: i.function.description,
203
+ input_schema: (0, lodash_es_1.isEmpty)(i.function.parameters)
204
+ ? { type: "object" }
205
+ : i.function.parameters,
206
+ }))
207
+ : undefined,
208
+ tool_choice: choice,
209
+ };
210
+ }
@@ -1,5 +1,5 @@
1
- import { ChatModel, type ChatModelInput, type ChatModelOutput } from "./chat";
2
- export declare class ChatModelOpenAI extends ChatModel {
1
+ import { ChatModel, type ChatModelInput, type ChatModelOutput } from "./chat-model.js";
2
+ export declare class OpenAIChatModel extends ChatModel {
3
3
  config?: {
4
4
  apiKey?: string;
5
5
  model?: string;
@@ -3,13 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ChatModelOpenAI = void 0;
6
+ exports.OpenAIChatModel = void 0;
7
7
  const nanoid_1 = require("nanoid");
8
8
  const openai_1 = __importDefault(require("openai"));
9
- const type_utils_1 = require("../utils/type-utils");
10
- const chat_1 = require("./chat");
9
+ const json_schema_js_1 = require("../utils/json-schema.js");
10
+ const type_utils_js_1 = require("../utils/type-utils.js");
11
+ const chat_model_js_1 = require("./chat-model.js");
11
12
  const CHAT_MODEL_OPENAI_DEFAULT_MODEL = "gpt-4o-mini";
12
- class ChatModelOpenAI extends chat_1.ChatModel {
13
+ class OpenAIChatModel extends chat_model_js_1.ChatModel {
13
14
  config;
14
15
  constructor(config) {
15
16
  super();
@@ -18,7 +19,7 @@ class ChatModelOpenAI extends chat_1.ChatModel {
18
19
  _client;
19
20
  get client() {
20
21
  if (!this.config?.apiKey)
21
- throw new Error("Api Key is required for ChatModelOpenAI");
22
+ throw new Error("Api Key is required for OpenAIChatModel");
22
23
  this._client ??= new openai_1.default({ apiKey: this.config.apiKey });
23
24
  return this._client;
24
25
  }
@@ -68,8 +69,8 @@ class ChatModelOpenAI extends chat_1.ChatModel {
68
69
  text += choice.delta.content;
69
70
  }
70
71
  const result = {};
71
- if (input.responseFormat?.type === "json_schema") {
72
- result.json = JSON.parse(text);
72
+ if (input.responseFormat?.type === "json_schema" && text) {
73
+ result.json = (0, json_schema_js_1.parseJSON)(text);
73
74
  }
74
75
  else {
75
76
  result.text = text;
@@ -77,13 +78,13 @@ class ChatModelOpenAI extends chat_1.ChatModel {
77
78
  if (toolCalls.length) {
78
79
  result.toolCalls = toolCalls.map(({ args, ...c }) => ({
79
80
  ...c,
80
- function: { ...c.function, arguments: JSON.parse(args) },
81
+ function: { ...c.function, arguments: (0, json_schema_js_1.parseJSON)(args) },
81
82
  }));
82
83
  }
83
84
  return result;
84
85
  }
85
86
  }
86
- exports.ChatModelOpenAI = ChatModelOpenAI;
87
+ exports.OpenAIChatModel = OpenAIChatModel;
87
88
  const ROLE_MAP = {
88
89
  system: "system",
89
90
  user: "user",
@@ -107,7 +108,7 @@ async function contentsFromInputMessages(messages) {
107
108
  };
108
109
  }
109
110
  })
110
- .filter(type_utils_1.isNonNullable),
111
+ .filter(type_utils_js_1.isNonNullable),
111
112
  tool_calls: i.toolCalls?.map((i) => ({
112
113
  ...i,
113
114
  function: {
@@ -1,22 +1,24 @@
1
- import type { GetPromptResult } from "@modelcontextprotocol/sdk/types";
2
- import { Agent, type AgentInput } from "../agents/agent";
3
- import type { AIAgent } from "../agents/ai-agent";
4
- import type { Context } from "../execution-engine/context";
5
- import type { ChatModel, ChatModelInput, ChatModelInputMessage } from "../models/chat";
6
- import { ChatMessagesTemplate } from "./template";
7
- export declare const USER_INPUT_MESSAGE_KEY = "$user_input_message";
8
- export declare function userInput(message: string | object): AgentInput;
9
- export declare function addMessagesToInput(input: AgentInput, messages: ChatModelInputMessage[]): AgentInput;
1
+ import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
+ import { Agent, type AgentOptions, type Message } from "../agents/agent.js";
3
+ import type { AIAgent } from "../agents/ai-agent.js";
4
+ import type { AgentMemory } from "../agents/memory.js";
5
+ import type { Context } from "../execution-engine/context.js";
6
+ import type { ChatModel, ChatModelInput } from "../models/chat-model.js";
7
+ import { ChatMessagesTemplate } from "./template.js";
8
+ export declare const MESSAGE_KEY = "$message";
9
+ export declare const DEFAULT_MAX_HISTORY_MESSAGES = 10;
10
+ export declare function createMessage(message: string | object): Message;
11
+ export declare function getMessage(input: Message): string | undefined;
10
12
  export interface PromptBuilderOptions {
11
13
  instructions?: string | ChatMessagesTemplate;
12
14
  }
13
15
  export interface PromptBuilderBuildOptions {
14
- enableHistory?: boolean;
15
- maxHistoryMessages?: number;
16
+ memory?: AgentMemory;
16
17
  context?: Context;
17
18
  agent?: AIAgent;
18
- input?: AgentInput;
19
+ input?: Message;
19
20
  model?: ChatModel;
21
+ outputSchema?: AgentOptions["outputSchema"];
20
22
  }
21
23
  export declare class PromptBuilder {
22
24
  static from(instructions: string): PromptBuilder;
@@ -31,8 +33,6 @@ export declare class PromptBuilder {
31
33
  private static fromMCPPromptResult;
32
34
  constructor(options?: PromptBuilderOptions);
33
35
  instructions?: string | ChatMessagesTemplate;
34
- histories: ChatModelInputMessage[];
35
- addHistory(...messages: ChatModelInputMessage[]): void;
36
36
  build(options: PromptBuilderBuildOptions): Promise<ChatModelInput & {
37
37
  toolAgents?: Agent[];
38
38
  }>;
@@ -1,39 +1,26 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PromptBuilder = exports.USER_INPUT_MESSAGE_KEY = void 0;
7
- exports.userInput = userInput;
8
- exports.addMessagesToInput = addMessagesToInput;
3
+ exports.PromptBuilder = exports.DEFAULT_MAX_HISTORY_MESSAGES = exports.MESSAGE_KEY = void 0;
4
+ exports.createMessage = createMessage;
5
+ exports.getMessage = getMessage;
9
6
  const promises_1 = require("node:fs/promises");
10
- const lodash_1 = require("lodash");
7
+ const lodash_es_1 = require("lodash-es");
11
8
  const zod_1 = require("zod");
12
- const zod_to_json_schema_1 = __importDefault(require("zod-to-json-schema"));
13
- const agent_1 = require("../agents/agent");
14
- const template_1 = require("./template");
15
- exports.USER_INPUT_MESSAGE_KEY = "$user_input_message";
16
- function userInput(message) {
17
- return { [exports.USER_INPUT_MESSAGE_KEY]: message };
9
+ const agent_js_1 = require("../agents/agent.js");
10
+ const json_schema_js_1 = require("../utils/json-schema.js");
11
+ const template_js_1 = require("./template.js");
12
+ exports.MESSAGE_KEY = "$message";
13
+ exports.DEFAULT_MAX_HISTORY_MESSAGES = 10;
14
+ function createMessage(message) {
15
+ return { [exports.MESSAGE_KEY]: message };
18
16
  }
19
- function addMessagesToInput(input, messages) {
20
- const originalUserInputMessages = input[exports.USER_INPUT_MESSAGE_KEY];
21
- const newMessages = [];
22
- if (typeof originalUserInputMessages === "string") {
23
- newMessages.push({ role: "user", content: originalUserInputMessages });
24
- }
25
- else {
26
- const messages = (0, template_1.parseChatMessages)(originalUserInputMessages);
27
- if (messages)
28
- newMessages.push(...messages);
29
- else
30
- newMessages.push({
31
- role: "user",
32
- content: JSON.stringify(originalUserInputMessages),
33
- });
34
- }
35
- newMessages.push(...messages);
36
- return { ...input, [exports.USER_INPUT_MESSAGE_KEY]: newMessages };
17
+ function getMessage(input) {
18
+ const userInputMessage = input[exports.MESSAGE_KEY];
19
+ if (typeof userInputMessage === "string")
20
+ return userInputMessage;
21
+ if (!(0, lodash_es_1.isNil)(userInputMessage))
22
+ return JSON.stringify(userInputMessage);
23
+ return undefined;
37
24
  }
38
25
  class PromptBuilder {
39
26
  static from(instructions) {
@@ -51,13 +38,28 @@ class PromptBuilder {
51
38
  }
52
39
  static fromMCPPromptResult(result) {
53
40
  return new PromptBuilder({
54
- instructions: template_1.ChatMessagesTemplate.from(result.messages.map((i) => {
55
- if (i.content.type !== "text")
41
+ instructions: template_js_1.ChatMessagesTemplate.from(result.messages.map((i) => {
42
+ let content;
43
+ if (i.content.type === "text")
44
+ content = i.content.text;
45
+ else if (i.content.type === "resource") {
46
+ const { resource } = i.content;
47
+ if (typeof resource.text === "string") {
48
+ content = resource.text;
49
+ }
50
+ else if (typeof resource.blob === "string") {
51
+ content = [{ type: "image_url", url: resource.blob }];
52
+ }
53
+ }
54
+ else if (i.content.type === "image") {
55
+ content = [{ type: "image_url", url: i.content.data }];
56
+ }
57
+ if (!content)
56
58
  throw new Error(`Unsupported content type ${i.content.type}`);
57
59
  if (i.role === "user")
58
- return template_1.UserMessageTemplate.from(i.content.text);
60
+ return template_js_1.UserMessageTemplate.from(content);
59
61
  if (i.role === "assistant")
60
- return template_1.AgentMessageTemplate.from(i.content.text);
62
+ return template_js_1.AgentMessageTemplate.from(content);
61
63
  throw new Error(`Unsupported role ${i.role}`);
62
64
  })),
63
65
  });
@@ -66,10 +68,6 @@ class PromptBuilder {
66
68
  this.instructions = options?.instructions;
67
69
  }
68
70
  instructions;
69
- histories = [];
70
- addHistory(...messages) {
71
- this.histories.push(...messages);
72
- }
73
71
  async build(options) {
74
72
  return {
75
73
  messages: this.buildMessages(options),
@@ -80,37 +78,28 @@ class PromptBuilder {
80
78
  buildMessages(options) {
81
79
  const { input } = options;
82
80
  const messages = (typeof this.instructions === "string"
83
- ? template_1.ChatMessagesTemplate.from([template_1.SystemMessageTemplate.from(this.instructions)])
81
+ ? template_js_1.ChatMessagesTemplate.from([template_js_1.SystemMessageTemplate.from(this.instructions)])
84
82
  : this.instructions)?.format(options.input) ?? [];
85
- if (options.enableHistory) {
86
- messages.push(...(options.maxHistoryMessages
87
- ? this.histories.slice(-options.maxHistoryMessages)
88
- : this.histories));
89
- }
90
- const userMessages = [];
91
- const userInputMessage = input?.[exports.USER_INPUT_MESSAGE_KEY];
92
- // Parse messages from the user input with the key $user_input_message
93
- if (!(0, lodash_1.isNil)(userInputMessage)) {
94
- if (typeof userInputMessage === "string") {
95
- userMessages.push(template_1.UserMessageTemplate.from(userInputMessage).format());
96
- }
97
- else {
98
- const messages = (0, template_1.parseChatMessages)(userInputMessage);
99
- if (messages)
100
- userMessages.push(...messages.map((i) => i.format()));
101
- else
102
- userMessages.push(template_1.UserMessageTemplate.from(JSON.stringify(userInputMessage)).format());
103
- }
83
+ const memory = options.memory ?? options.agent?.memory;
84
+ if (memory?.enabled) {
85
+ const k = memory.maxMemoriesInChat ?? exports.DEFAULT_MAX_HISTORY_MESSAGES;
86
+ const histories = memory.memories.slice(-k);
87
+ if (histories?.length)
88
+ messages.push(...histories.map((i) => ({
89
+ role: i.role,
90
+ content: convertMessageToContent(i.content),
91
+ name: i.source,
92
+ })));
104
93
  }
105
- if (userMessages.length) {
106
- if (options.enableHistory)
107
- this.addHistory(...userMessages);
108
- messages.push(...userMessages);
94
+ const content = input && getMessage(input);
95
+ // add user input if it's not the same as the last message
96
+ if (content && messages.at(-1)?.content !== content) {
97
+ messages.push({ role: "user", content });
109
98
  }
110
99
  return messages;
111
100
  }
112
101
  buildResponseFormat(options) {
113
- const outputSchema = options.agent?.outputSchema;
102
+ const outputSchema = options.outputSchema || options.agent?.outputSchema;
114
103
  if (!outputSchema)
115
104
  return undefined;
116
105
  const isJsonOutput = !isEmptyObjectType(outputSchema);
@@ -119,7 +108,7 @@ class PromptBuilder {
119
108
  type: "json_schema",
120
109
  jsonSchema: {
121
110
  name: "output",
122
- schema: (0, zod_to_json_schema_1.default)(outputSchema),
111
+ schema: (0, json_schema_js_1.outputSchemaToResponseFormatSchema)(outputSchema),
123
112
  strict: true,
124
113
  },
125
114
  }
@@ -135,14 +124,16 @@ class PromptBuilder {
135
124
  function: {
136
125
  name: i.name,
137
126
  description: i.description,
138
- parameters: !isEmptyObjectType(i.inputSchema) ? (0, zod_to_json_schema_1.default)(i.inputSchema) : {},
127
+ parameters: !isEmptyObjectType(i.inputSchema)
128
+ ? (0, json_schema_js_1.outputSchemaToResponseFormatSchema)(i.inputSchema)
129
+ : {},
139
130
  },
140
131
  }));
141
132
  let toolChoice;
142
133
  // use manual choice if configured in the agent
143
134
  const manualChoice = options.agent?.toolChoice;
144
135
  if (manualChoice) {
145
- if (manualChoice instanceof agent_1.Agent) {
136
+ if (manualChoice instanceof agent_js_1.Agent) {
146
137
  toolChoice = {
147
138
  type: "function",
148
139
  function: {
@@ -179,3 +170,7 @@ function isFromPath(value) {
179
170
  function isEmptyObjectType(schema) {
180
171
  return schema instanceof zod_1.ZodObject && Object.keys(schema.shape).length === 0;
181
172
  }
173
+ function convertMessageToContent(i) {
174
+ const str = i[exports.MESSAGE_KEY];
175
+ return !(0, lodash_es_1.isNil)(str) ? (typeof str === "string" ? str : JSON.stringify(str)) : JSON.stringify(i);
176
+ }
@@ -1,4 +1,4 @@
1
- import type { ChatModelInputMessage, ChatModelOutputToolCall } from "../models/chat";
1
+ import type { ChatModelInputMessage, ChatModelInputMessageContent, ChatModelOutputToolCall } from "../models/chat-model.js";
2
2
  export declare class PromptTemplate {
3
3
  template: string;
4
4
  static from(template: string): PromptTemplate;
@@ -16,22 +16,16 @@ export declare class SystemMessageTemplate extends ChatMessageTemplate {
16
16
  static from(content: string, name?: string): SystemMessageTemplate;
17
17
  }
18
18
  export declare class UserMessageTemplate extends ChatMessageTemplate {
19
- static from(template: NonNullable<ChatModelInputMessage["content"]>, name?: string): UserMessageTemplate;
19
+ static from(template: ChatModelInputMessageContent, name?: string): UserMessageTemplate;
20
20
  }
21
21
  export declare class AgentMessageTemplate extends ChatMessageTemplate {
22
22
  toolCalls?: ChatModelOutputToolCall[] | undefined;
23
- static from(template: string | ChatModelOutputToolCall[], name?: string): AgentMessageTemplate;
24
- constructor(content?: string, toolCalls?: ChatModelOutputToolCall[] | undefined, name?: string);
23
+ static from(template?: ChatModelInputMessage["content"], toolCalls?: ChatModelOutputToolCall[], name?: string): AgentMessageTemplate;
24
+ constructor(content?: ChatModelInputMessage["content"], toolCalls?: ChatModelOutputToolCall[] | undefined, name?: string);
25
25
  format(variables?: Record<string, unknown>): {
26
26
  toolCalls: ChatModelOutputToolCall[] | undefined;
27
- role: import("../models/chat").Role;
28
- content?: string | ({
29
- type: "text";
30
- text: string;
31
- } | {
32
- type: "image_url";
33
- url: string;
34
- })[];
27
+ role: import("../models/chat-model.js").Role;
28
+ content?: ChatModelInputMessageContent;
35
29
  toolCallId?: string;
36
30
  name?: string;
37
31
  };
@@ -42,20 +36,14 @@ export declare class ToolMessageTemplate extends ChatMessageTemplate {
42
36
  constructor(content: object | string, toolCallId: string, name?: string);
43
37
  format(variables?: Record<string, unknown>): {
44
38
  toolCallId: string;
45
- role: import("../models/chat").Role;
46
- content?: string | ({
47
- type: "text";
48
- text: string;
49
- } | {
50
- type: "image_url";
51
- url: string;
52
- })[];
39
+ role: import("../models/chat-model.js").Role;
40
+ content?: ChatModelInputMessageContent;
53
41
  toolCalls?: {
54
42
  id: string;
55
43
  type: "function";
56
44
  function: {
57
45
  name: string;
58
- arguments: import("..").AgentInput;
46
+ arguments: import("../index.js").Message;
59
47
  };
60
48
  }[];
61
49
  name?: string;
@@ -67,10 +67,8 @@ class UserMessageTemplate extends ChatMessageTemplate {
67
67
  exports.UserMessageTemplate = UserMessageTemplate;
68
68
  class AgentMessageTemplate extends ChatMessageTemplate {
69
69
  toolCalls;
70
- static from(template, name) {
71
- return typeof template === "string"
72
- ? new AgentMessageTemplate(template, undefined, name)
73
- : new AgentMessageTemplate(undefined, template, name);
70
+ static from(template, toolCalls, name) {
71
+ return new AgentMessageTemplate(template, toolCalls, name);
74
72
  }
75
73
  constructor(content, toolCalls, name) {
76
74
  super("agent", content, name);
@@ -164,7 +162,7 @@ function parseChatMessages(messages) {
164
162
  case "user":
165
163
  return UserMessageTemplate.from(message.content, message.name);
166
164
  case "agent":
167
- return new AgentMessageTemplate(message.content, message.toolCalls, message.name);
165
+ return AgentMessageTemplate.from(message.content, message.toolCalls, message.name);
168
166
  case "tool":
169
167
  return ToolMessageTemplate.from(message.content, message.toolCallId, message.name);
170
168
  }
@@ -0,0 +1,4 @@
1
+ import type { ZodType } from "zod";
2
+ import type { Message } from "../agents/agent.js";
3
+ export declare function outputSchemaToResponseFormatSchema(agentOutput: ZodType<Message>): Record<string, unknown>;
4
+ export declare function parseJSON(json: string): any;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.outputSchemaToResponseFormatSchema = outputSchemaToResponseFormatSchema;
4
+ exports.parseJSON = parseJSON;
5
+ const lodash_es_1 = require("lodash-es");
6
+ const zod_to_json_schema_1 = require("zod-to-json-schema");
7
+ const logger_js_1 = require("./logger.js");
8
+ function outputSchemaToResponseFormatSchema(agentOutput) {
9
+ return setAdditionPropertiesDeep((0, zod_to_json_schema_1.zodToJsonSchema)(agentOutput), false);
10
+ }
11
+ function setAdditionPropertiesDeep(schema, additionalProperties) {
12
+ if (Array.isArray(schema)) {
13
+ return schema.map((s) => setAdditionPropertiesDeep(s, additionalProperties));
14
+ }
15
+ if ((0, lodash_es_1.isObject)(schema)) {
16
+ return Object.entries(schema).reduce((acc, [key, value]) => {
17
+ acc[key] = setAdditionPropertiesDeep(value, additionalProperties);
18
+ if (acc.type === "object") {
19
+ acc.additionalProperties = additionalProperties;
20
+ }
21
+ return acc;
22
+ }, {});
23
+ }
24
+ return schema;
25
+ }
26
+ function parseJSON(json) {
27
+ try {
28
+ return JSON.parse(json);
29
+ }
30
+ catch (error) {
31
+ logger_js_1.logger.debug("Failed to parse JSON", { json, error });
32
+ throw new Error(`Failed to parse JSON ${error.message}`);
33
+ }
34
+ }
@@ -1,5 +1,6 @@
1
1
  import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import type { ListPromptsResult, ListToolsResult } from "@modelcontextprotocol/sdk/types";
3
- import { MCPPrompt, MCPTool } from "../agents/mcp-agent";
2
+ import { type ListPromptsResult, type ListResourceTemplatesResult, type ListResourcesResult, type ListToolsResult } from "@modelcontextprotocol/sdk/types.js";
3
+ import { MCPPrompt, MCPResource, MCPTool } from "../agents/mcp-agent.js";
4
4
  export declare function toolFromMCPTool(client: Client, tool: ListToolsResult["tools"][number]): MCPTool;
5
5
  export declare function promptFromMCPPrompt(client: Client, prompt: ListPromptsResult["prompts"][number]): MCPPrompt;
6
+ export declare function resourceFromMCPResource(client: Client, resource: ListResourcesResult["resources"][number] | ListResourceTemplatesResult["resourceTemplates"][number]): MCPResource;