@aigne/core 1.12.0 → 1.14.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 (197) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +13 -26
  3. package/README.zh.md +24 -37
  4. package/lib/cjs/agents/agent.d.ts +522 -15
  5. package/lib/cjs/agents/agent.js +357 -36
  6. package/lib/cjs/agents/ai-agent.d.ts +210 -52
  7. package/lib/cjs/agents/ai-agent.js +182 -24
  8. package/lib/cjs/agents/mcp-agent.d.ts +112 -0
  9. package/lib/cjs/agents/mcp-agent.js +79 -1
  10. package/lib/cjs/agents/team-agent.d.ts +99 -0
  11. package/lib/cjs/agents/team-agent.js +94 -0
  12. package/lib/cjs/agents/user-agent.d.ts +6 -4
  13. package/lib/cjs/agents/user-agent.js +16 -5
  14. package/lib/cjs/aigne/aigne.d.ts +263 -16
  15. package/lib/cjs/aigne/aigne.js +130 -20
  16. package/lib/cjs/aigne/context.d.ts +24 -8
  17. package/lib/cjs/aigne/context.js +8 -22
  18. package/lib/cjs/aigne/message-queue.d.ts +26 -4
  19. package/lib/cjs/aigne/message-queue.js +42 -7
  20. package/lib/cjs/aigne/usage.d.ts +9 -0
  21. package/lib/cjs/aigne/usage.js +3 -0
  22. package/lib/cjs/client/client.d.ts +81 -3
  23. package/lib/cjs/client/client.js +38 -0
  24. package/lib/cjs/client/index.d.ts +1 -0
  25. package/lib/cjs/client/index.js +17 -0
  26. package/lib/cjs/index.d.ts +0 -1
  27. package/lib/cjs/index.js +0 -1
  28. package/lib/cjs/loader/agent-js.d.ts +1 -1
  29. package/lib/cjs/loader/agent-js.js +2 -2
  30. package/lib/cjs/loader/agent-yaml.d.ts +3 -2
  31. package/lib/cjs/loader/agent-yaml.js +2 -1
  32. package/lib/cjs/loader/index.d.ts +4 -4
  33. package/lib/cjs/loader/index.js +2 -0
  34. package/lib/cjs/memory/default-memory.d.ts +16 -0
  35. package/lib/cjs/memory/default-memory.js +70 -0
  36. package/lib/cjs/memory/index.d.ts +3 -0
  37. package/lib/cjs/memory/index.js +19 -0
  38. package/lib/cjs/memory/memory.d.ts +89 -0
  39. package/lib/cjs/memory/memory.js +132 -0
  40. package/lib/cjs/memory/recorder.d.ts +86 -0
  41. package/lib/cjs/memory/recorder.js +50 -0
  42. package/lib/cjs/memory/retriever.d.ts +99 -0
  43. package/lib/cjs/memory/retriever.js +51 -0
  44. package/lib/cjs/models/bedrock-chat-model.d.ts +79 -0
  45. package/lib/cjs/models/bedrock-chat-model.js +303 -0
  46. package/lib/cjs/models/chat-model.d.ts +279 -1
  47. package/lib/cjs/models/chat-model.js +62 -0
  48. package/lib/cjs/models/claude-chat-model.d.ts +49 -3
  49. package/lib/cjs/models/claude-chat-model.js +34 -2
  50. package/lib/cjs/models/deepseek-chat-model.d.ts +16 -0
  51. package/lib/cjs/models/deepseek-chat-model.js +16 -0
  52. package/lib/cjs/models/gemini-chat-model.d.ts +15 -0
  53. package/lib/cjs/models/gemini-chat-model.js +15 -0
  54. package/lib/cjs/models/ollama-chat-model.d.ts +16 -0
  55. package/lib/cjs/models/ollama-chat-model.js +16 -0
  56. package/lib/cjs/models/open-router-chat-model.d.ts +16 -0
  57. package/lib/cjs/models/open-router-chat-model.js +16 -0
  58. package/lib/cjs/models/openai-chat-model.d.ts +70 -3
  59. package/lib/cjs/models/openai-chat-model.js +147 -102
  60. package/lib/cjs/models/xai-chat-model.d.ts +16 -0
  61. package/lib/cjs/models/xai-chat-model.js +16 -0
  62. package/lib/cjs/prompt/prompt-builder.d.ts +4 -4
  63. package/lib/cjs/prompt/prompt-builder.js +21 -20
  64. package/lib/cjs/prompt/prompts/memory-message-template.d.ts +1 -0
  65. package/lib/cjs/prompt/prompts/memory-message-template.js +10 -0
  66. package/lib/cjs/prompt/template.js +5 -1
  67. package/lib/cjs/server/error.d.ts +11 -0
  68. package/lib/cjs/server/error.js +11 -0
  69. package/lib/cjs/server/index.d.ts +2 -0
  70. package/lib/cjs/server/index.js +18 -0
  71. package/lib/cjs/server/server.d.ts +89 -8
  72. package/lib/cjs/server/server.js +58 -0
  73. package/lib/cjs/utils/fs.d.ts +2 -0
  74. package/lib/cjs/utils/fs.js +25 -0
  75. package/lib/cjs/utils/prompts.d.ts +1 -0
  76. package/lib/cjs/utils/prompts.js +11 -2
  77. package/lib/cjs/utils/type-utils.d.ts +2 -0
  78. package/lib/cjs/utils/type-utils.js +26 -0
  79. package/lib/dts/agents/agent.d.ts +522 -15
  80. package/lib/dts/agents/ai-agent.d.ts +210 -52
  81. package/lib/dts/agents/mcp-agent.d.ts +112 -0
  82. package/lib/dts/agents/team-agent.d.ts +99 -0
  83. package/lib/dts/agents/user-agent.d.ts +6 -4
  84. package/lib/dts/aigne/aigne.d.ts +263 -16
  85. package/lib/dts/aigne/context.d.ts +24 -8
  86. package/lib/dts/aigne/message-queue.d.ts +26 -4
  87. package/lib/dts/aigne/usage.d.ts +9 -0
  88. package/lib/dts/client/client.d.ts +81 -3
  89. package/lib/dts/client/index.d.ts +1 -0
  90. package/lib/dts/index.d.ts +0 -1
  91. package/lib/dts/loader/agent-js.d.ts +1 -1
  92. package/lib/dts/loader/agent-yaml.d.ts +3 -2
  93. package/lib/dts/loader/index.d.ts +4 -4
  94. package/lib/dts/memory/default-memory.d.ts +16 -0
  95. package/lib/dts/memory/index.d.ts +3 -0
  96. package/lib/dts/memory/memory.d.ts +89 -0
  97. package/lib/dts/memory/recorder.d.ts +86 -0
  98. package/lib/dts/memory/retriever.d.ts +99 -0
  99. package/lib/dts/models/bedrock-chat-model.d.ts +79 -0
  100. package/lib/dts/models/chat-model.d.ts +279 -1
  101. package/lib/dts/models/claude-chat-model.d.ts +49 -3
  102. package/lib/dts/models/deepseek-chat-model.d.ts +16 -0
  103. package/lib/dts/models/gemini-chat-model.d.ts +15 -0
  104. package/lib/dts/models/ollama-chat-model.d.ts +16 -0
  105. package/lib/dts/models/open-router-chat-model.d.ts +16 -0
  106. package/lib/dts/models/openai-chat-model.d.ts +70 -3
  107. package/lib/dts/models/xai-chat-model.d.ts +16 -0
  108. package/lib/dts/prompt/prompt-builder.d.ts +4 -4
  109. package/lib/dts/prompt/prompts/memory-message-template.d.ts +1 -0
  110. package/lib/dts/server/error.d.ts +11 -0
  111. package/lib/dts/server/index.d.ts +2 -0
  112. package/lib/dts/server/server.d.ts +89 -8
  113. package/lib/dts/utils/fs.d.ts +2 -0
  114. package/lib/dts/utils/prompts.d.ts +1 -0
  115. package/lib/dts/utils/type-utils.d.ts +2 -0
  116. package/lib/esm/agents/agent.d.ts +522 -15
  117. package/lib/esm/agents/agent.js +351 -35
  118. package/lib/esm/agents/ai-agent.d.ts +210 -52
  119. package/lib/esm/agents/ai-agent.js +183 -25
  120. package/lib/esm/agents/mcp-agent.d.ts +112 -0
  121. package/lib/esm/agents/mcp-agent.js +79 -1
  122. package/lib/esm/agents/team-agent.d.ts +99 -0
  123. package/lib/esm/agents/team-agent.js +94 -0
  124. package/lib/esm/agents/user-agent.d.ts +6 -4
  125. package/lib/esm/agents/user-agent.js +17 -6
  126. package/lib/esm/aigne/aigne.d.ts +263 -16
  127. package/lib/esm/aigne/aigne.js +132 -22
  128. package/lib/esm/aigne/context.d.ts +24 -8
  129. package/lib/esm/aigne/context.js +9 -22
  130. package/lib/esm/aigne/message-queue.d.ts +26 -4
  131. package/lib/esm/aigne/message-queue.js +42 -8
  132. package/lib/esm/aigne/usage.d.ts +9 -0
  133. package/lib/esm/aigne/usage.js +3 -0
  134. package/lib/esm/client/client.d.ts +81 -3
  135. package/lib/esm/client/client.js +38 -0
  136. package/lib/esm/client/index.d.ts +1 -0
  137. package/lib/esm/client/index.js +1 -0
  138. package/lib/esm/index.d.ts +0 -1
  139. package/lib/esm/index.js +0 -1
  140. package/lib/esm/loader/agent-js.d.ts +1 -1
  141. package/lib/esm/loader/agent-js.js +2 -2
  142. package/lib/esm/loader/agent-yaml.d.ts +3 -2
  143. package/lib/esm/loader/agent-yaml.js +2 -1
  144. package/lib/esm/loader/index.d.ts +4 -4
  145. package/lib/esm/loader/index.js +2 -0
  146. package/lib/esm/memory/default-memory.d.ts +16 -0
  147. package/lib/esm/memory/default-memory.js +63 -0
  148. package/lib/esm/memory/index.d.ts +3 -0
  149. package/lib/esm/memory/index.js +3 -0
  150. package/lib/esm/memory/memory.d.ts +89 -0
  151. package/lib/esm/memory/memory.js +127 -0
  152. package/lib/esm/memory/recorder.d.ts +86 -0
  153. package/lib/esm/memory/recorder.js +46 -0
  154. package/lib/esm/memory/retriever.d.ts +99 -0
  155. package/lib/esm/memory/retriever.js +47 -0
  156. package/lib/esm/models/bedrock-chat-model.d.ts +79 -0
  157. package/lib/esm/models/bedrock-chat-model.js +298 -0
  158. package/lib/esm/models/chat-model.d.ts +279 -1
  159. package/lib/esm/models/chat-model.js +62 -0
  160. package/lib/esm/models/claude-chat-model.d.ts +49 -3
  161. package/lib/esm/models/claude-chat-model.js +35 -3
  162. package/lib/esm/models/deepseek-chat-model.d.ts +16 -0
  163. package/lib/esm/models/deepseek-chat-model.js +16 -0
  164. package/lib/esm/models/gemini-chat-model.d.ts +15 -0
  165. package/lib/esm/models/gemini-chat-model.js +15 -0
  166. package/lib/esm/models/ollama-chat-model.d.ts +16 -0
  167. package/lib/esm/models/ollama-chat-model.js +16 -0
  168. package/lib/esm/models/open-router-chat-model.d.ts +16 -0
  169. package/lib/esm/models/open-router-chat-model.js +16 -0
  170. package/lib/esm/models/openai-chat-model.d.ts +70 -3
  171. package/lib/esm/models/openai-chat-model.js +147 -102
  172. package/lib/esm/models/xai-chat-model.d.ts +16 -0
  173. package/lib/esm/models/xai-chat-model.js +16 -0
  174. package/lib/esm/prompt/prompt-builder.d.ts +4 -4
  175. package/lib/esm/prompt/prompt-builder.js +22 -21
  176. package/lib/esm/prompt/prompts/memory-message-template.d.ts +1 -0
  177. package/lib/esm/prompt/prompts/memory-message-template.js +7 -0
  178. package/lib/esm/prompt/template.js +5 -1
  179. package/lib/esm/server/error.d.ts +11 -0
  180. package/lib/esm/server/error.js +11 -0
  181. package/lib/esm/server/index.d.ts +2 -0
  182. package/lib/esm/server/index.js +2 -0
  183. package/lib/esm/server/server.d.ts +89 -8
  184. package/lib/esm/server/server.js +58 -0
  185. package/lib/esm/utils/fs.d.ts +2 -0
  186. package/lib/esm/utils/fs.js +21 -0
  187. package/lib/esm/utils/prompts.d.ts +1 -0
  188. package/lib/esm/utils/prompts.js +10 -2
  189. package/lib/esm/utils/type-utils.d.ts +2 -0
  190. package/lib/esm/utils/type-utils.js +24 -0
  191. package/package.json +21 -11
  192. package/lib/cjs/agents/memory.d.ts +0 -26
  193. package/lib/cjs/agents/memory.js +0 -45
  194. package/lib/dts/agents/memory.d.ts +0 -26
  195. package/lib/esm/agents/memory.d.ts +0 -26
  196. package/lib/esm/agents/memory.js +0 -41
  197. /package/{LICENSE → LICENSE.md} +0 -0
@@ -12,6 +12,9 @@ const OPENAI_CHAT_MODEL_CAPABILITIES = {
12
12
  "o4-mini": { supportsParallelToolCalls: false, supportsTemperature: false },
13
13
  "o3-mini": { supportsParallelToolCalls: false, supportsTemperature: false },
14
14
  };
15
+ /**
16
+ * @hidden
17
+ */
15
18
  export const openAIChatModelOptionsSchema = z.object({
16
19
  apiKey: z.string().optional(),
17
20
  baseURL: z.string().optional(),
@@ -27,6 +30,25 @@ export const openAIChatModelOptionsSchema = z.object({
27
30
  })
28
31
  .optional(),
29
32
  });
33
+ /**
34
+ * Implementation of the ChatModel interface for OpenAI's API
35
+ *
36
+ * This model provides access to OpenAI's capabilities including:
37
+ * - Text generation
38
+ * - Tool use with parallel tool calls
39
+ * - JSON structured output
40
+ * - Image understanding
41
+ *
42
+ * Default model: 'gpt-4o-mini'
43
+ *
44
+ * @example
45
+ * Here's how to create and use an OpenAI chat model:
46
+ * {@includeCode ../../test/models/openai-chat-model.test.ts#example-openai-chat-model}
47
+ *
48
+ * @example
49
+ * Here's an example with streaming response:
50
+ * {@includeCode ../../test/models/openai-chat-model.test.ts#example-openai-chat-model-streaming}
51
+ */
30
52
  export class OpenAIChatModel extends ChatModel {
31
53
  options;
32
54
  constructor(options) {
@@ -37,6 +59,9 @@ export class OpenAIChatModel extends ChatModel {
37
59
  const preset = options?.model ? OPENAI_CHAT_MODEL_CAPABILITIES[options.model] : undefined;
38
60
  Object.assign(this, preset);
39
61
  }
62
+ /**
63
+ * @hidden
64
+ */
40
65
  _client;
41
66
  apiKeyEnvName = "OPENAI_API_KEY";
42
67
  apiKeyDefault;
@@ -45,6 +70,7 @@ export class OpenAIChatModel extends ChatModel {
45
70
  supportsToolsUseWithJsonSchema = true;
46
71
  supportsParallelToolCalls = true;
47
72
  supportsToolsEmptyParameters = true;
73
+ supportsToolStreaming = true;
48
74
  supportsTemperature = true;
49
75
  get client() {
50
76
  const apiKey = this.options?.apiKey || process.env[this.apiKeyEnvName] || this.apiKeyDefault;
@@ -59,7 +85,15 @@ export class OpenAIChatModel extends ChatModel {
59
85
  get modelOptions() {
60
86
  return this.options?.modelOptions;
61
87
  }
62
- async process(input, _context, options) {
88
+ /**
89
+ * Process the input and generate a response
90
+ * @param input The input to process
91
+ * @returns The generated response
92
+ */
93
+ process(input) {
94
+ return this._process(input);
95
+ }
96
+ async _process(input) {
63
97
  const messages = await this.getRunMessages(input);
64
98
  const body = {
65
99
  model: this.options?.model || CHAT_MODEL_OPENAI_DEFAULT_MODEL,
@@ -85,10 +119,10 @@ export class OpenAIChatModel extends ChatModel {
85
119
  parallel_tool_calls: this.getParallelToolCalls(input),
86
120
  response_format: responseFormat,
87
121
  });
88
- if (options?.streaming && input.responseFormat?.type !== "json_schema") {
89
- return await extractResultFromStream(stream, false, true);
122
+ if (input.responseFormat?.type !== "json_schema") {
123
+ return await this.extractResultFromStream(stream, false, true);
90
124
  }
91
- const result = await extractResultFromStream(stream, jsonMode);
125
+ const result = await this.extractResultFromStream(stream, jsonMode);
92
126
  if (!this.supportsToolsUseWithJsonSchema &&
93
127
  !result.toolCalls?.length &&
94
128
  input.responseFormat?.type === "json_schema" &&
@@ -154,15 +188,117 @@ export class OpenAIChatModel extends ChatModel {
154
188
  ...body,
155
189
  response_format: resolvedResponseFormat,
156
190
  });
157
- return extractResultFromStream(res, jsonMode);
191
+ return this.extractResultFromStream(res, jsonMode);
192
+ }
193
+ async extractResultFromStream(stream, jsonMode, streaming) {
194
+ const result = new ReadableStream({
195
+ start: async (controller) => {
196
+ try {
197
+ let text = "";
198
+ let refusal = "";
199
+ const toolCalls = [];
200
+ let model;
201
+ for await (const chunk of stream) {
202
+ const choice = chunk.choices?.[0];
203
+ if (!model) {
204
+ model = chunk.model;
205
+ controller.enqueue({
206
+ delta: {
207
+ json: {
208
+ model,
209
+ },
210
+ },
211
+ });
212
+ }
213
+ if (choice?.delta.tool_calls?.length) {
214
+ for (const call of choice.delta.tool_calls) {
215
+ if (this.supportsToolStreaming && call.index !== undefined) {
216
+ handleToolCallDelta(toolCalls, call);
217
+ }
218
+ else {
219
+ handleCompleteToolCall(toolCalls, call);
220
+ }
221
+ }
222
+ }
223
+ if (choice?.delta.content) {
224
+ text += choice.delta.content;
225
+ if (!jsonMode) {
226
+ controller.enqueue({
227
+ delta: {
228
+ text: {
229
+ text: choice.delta.content,
230
+ },
231
+ },
232
+ });
233
+ }
234
+ }
235
+ if (choice?.delta.refusal) {
236
+ refusal += choice.delta.refusal;
237
+ if (!jsonMode) {
238
+ controller.enqueue({
239
+ delta: {
240
+ text: { text: choice.delta.refusal },
241
+ },
242
+ });
243
+ }
244
+ }
245
+ if (chunk.usage) {
246
+ controller.enqueue({
247
+ delta: {
248
+ json: {
249
+ usage: {
250
+ inputTokens: chunk.usage.prompt_tokens,
251
+ outputTokens: chunk.usage.completion_tokens,
252
+ },
253
+ },
254
+ },
255
+ });
256
+ }
257
+ }
258
+ text = text || refusal;
259
+ if (jsonMode && text) {
260
+ controller.enqueue({
261
+ delta: {
262
+ json: {
263
+ json: parseJSON(text),
264
+ },
265
+ },
266
+ });
267
+ }
268
+ if (toolCalls.length) {
269
+ controller.enqueue({
270
+ delta: {
271
+ json: {
272
+ toolCalls: toolCalls.map(({ args, ...c }) => ({
273
+ ...c,
274
+ function: { ...c.function, arguments: parseJSON(args) },
275
+ })),
276
+ },
277
+ },
278
+ });
279
+ }
280
+ controller.close();
281
+ }
282
+ catch (error) {
283
+ controller.error(error);
284
+ }
285
+ },
286
+ });
287
+ return streaming ? result : await agentResponseStreamToObject(result);
158
288
  }
159
289
  }
290
+ /**
291
+ * @hidden
292
+ */
160
293
  export const ROLE_MAP = {
161
294
  system: "system",
162
295
  user: "user",
163
296
  agent: "assistant",
164
297
  tool: "tool",
165
298
  };
299
+ /**
300
+ * @hidden
301
+ */
166
302
  export async function contentsFromInputMessages(messages) {
167
303
  return messages.map((i) => ({
168
304
  role: ROLE_MAP[i.role],
@@ -192,6 +328,9 @@ export async function contentsFromInputMessages(messages) {
192
328
  name: i.name,
193
329
  }));
194
330
  }
331
+ /**
332
+ * @hidden
333
+ */
195
334
  export function toolsFromInputTools(tools, options) {
196
335
  return tools?.length
197
336
  ? tools.map((i) => {
@@ -210,6 +349,9 @@ export function toolsFromInputTools(tools, options) {
210
349
  })
211
350
  : undefined;
212
351
  }
352
+ /**
353
+ * @hidden
354
+ */
213
355
  export function jsonSchemaToOpenAIJsonSchema(schema) {
214
356
  if (schema?.type === "object") {
215
357
  const { required, properties } = schema;
@@ -235,103 +377,6 @@ export function jsonSchemaToOpenAIJsonSchema(schema) {
235
377
  }
236
378
  return schema;
237
379
  }
238
- async function extractResultFromStream(stream, jsonMode, streaming) {
239
- const result = new ReadableStream({
240
- async start(controller) {
241
- try {
242
- let text = "";
243
- let refusal = "";
244
- const toolCalls = [];
245
- let model;
246
- for await (const chunk of stream) {
247
- const choice = chunk.choices?.[0];
248
- if (!model) {
249
- model = chunk.model;
250
- controller.enqueue({
251
- delta: {
252
- json: {
253
- model,
254
- },
255
- },
256
- });
257
- }
258
- if (choice?.delta.tool_calls?.length) {
259
- for (const call of choice.delta.tool_calls) {
260
- // Gemini not support tool call delta
261
- if (call.index !== undefined) {
262
- handleToolCallDelta(toolCalls, call);
263
- }
264
- else {
265
- handleCompleteToolCall(toolCalls, call);
266
- }
267
- }
268
- }
269
- if (choice?.delta.content) {
270
- text += choice.delta.content;
271
- if (!jsonMode) {
272
- controller.enqueue({
273
- delta: {
274
- text: {
275
- text: choice.delta.content,
276
- },
277
- },
278
- });
279
- }
280
- }
281
- if (choice?.delta.refusal) {
282
- refusal += choice.delta.refusal;
283
- if (!jsonMode) {
284
- controller.enqueue({
285
- delta: {
286
- text: { text: choice.delta.refusal },
287
- },
288
- });
289
- }
290
- }
291
- if (chunk.usage) {
292
- controller.enqueue({
293
- delta: {
294
- json: {
295
- usage: {
296
- inputTokens: chunk.usage.prompt_tokens,
297
- outputTokens: chunk.usage.completion_tokens,
298
- },
299
- },
300
- },
301
- });
302
- }
303
- }
304
- text = text || refusal;
305
- if (jsonMode && text) {
306
- controller.enqueue({
307
- delta: {
308
- json: {
309
- json: parseJSON(text),
310
- },
311
- },
312
- });
313
- }
314
- if (toolCalls.length) {
315
- controller.enqueue({
316
- delta: {
317
- json: {
318
- toolCalls: toolCalls.map(({ args, ...c }) => ({
319
- ...c,
320
- function: { ...c.function, arguments: parseJSON(args) },
321
- })),
322
- },
323
- },
324
- });
325
- }
326
- controller.close();
327
- }
328
- catch (error) {
329
- controller.error(error);
330
- }
331
- },
332
- });
333
- return streaming ? result : await agentResponseStreamToObject(result);
334
- }
335
380
  function handleToolCallDelta(toolCalls, call) {
336
381
  toolCalls[call.index] ??= {
337
382
  id: call.id || nanoid(),
@@ -1,4 +1,20 @@
1
1
  import { OpenAIChatModel, type OpenAIChatModelOptions } from "./openai-chat-model.js";
2
+ /**
3
+ * Implementation of the ChatModel interface for X.AI's API (Grok)
4
+ *
5
+ * This model uses OpenAI-compatible API format to interact with X.AI models,
6
+ * providing access to models like Grok.
7
+ *
8
+ * Default model: 'grok-2-latest'
9
+ *
10
+ * @example
11
+ * Here's how to create and use an X.AI chat model:
12
+ * {@includeCode ../../test/models/xai-chat-model.test.ts#example-xai-chat-model}
13
+ *
14
+ * @example
15
+ * Here's an example with streaming response:
16
+ * {@includeCode ../../test/models/xai-chat-model.test.ts#example-xai-chat-model-streaming}
17
+ */
2
18
  export declare class XAIChatModel extends OpenAIChatModel {
3
19
  constructor(options?: OpenAIChatModelOptions);
4
20
  protected apiKeyEnvName: string;
@@ -1,6 +1,22 @@
1
1
  import { OpenAIChatModel } from "./openai-chat-model.js";
2
2
  const XAI_DEFAULT_CHAT_MODEL = "grok-2-latest";
3
3
  const XAI_BASE_URL = "https://api.x.ai/v1";
4
+ /**
5
+ * Implementation of the ChatModel interface for X.AI's API (Grok)
6
+ *
7
+ * This model uses OpenAI-compatible API format to interact with X.AI models,
8
+ * providing access to models like Grok.
9
+ *
10
+ * Default model: 'grok-2-latest'
11
+ *
12
+ * @example
13
+ * Here's how to create and use an X.AI chat model:
14
+ * {@includeCode ../../test/models/xai-chat-model.test.ts#example-xai-chat-model}
15
+ *
16
+ * @example
17
+ * Here's an example with streaming response:
18
+ * {@includeCode ../../test/models/xai-chat-model.test.ts#example-xai-chat-model-streaming}
19
+ */
4
20
  export class XAIChatModel extends OpenAIChatModel {
5
21
  constructor(options) {
6
22
  super({
@@ -1,20 +1,19 @@
1
1
  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
- import type { AgentMemory } from "../agents/memory.js";
5
4
  import type { Context } from "../aigne/context.js";
5
+ import type { MemoryAgent } from "../memory/memory.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";
9
- export declare const DEFAULT_MAX_HISTORY_MESSAGES = 10;
10
9
  export declare function createMessage<I extends Message>(message: string | I): I;
11
10
  export declare function getMessage(input: Message): string | undefined;
12
11
  export interface PromptBuilderOptions {
13
12
  instructions?: string | ChatMessagesTemplate;
14
13
  }
15
14
  export interface PromptBuilderBuildOptions {
16
- memory?: AgentMemory;
17
- context?: Context;
15
+ memory?: MemoryAgent | MemoryAgent[];
16
+ context: Context;
18
17
  agent?: AIAgent;
19
18
  input?: Message;
20
19
  model?: ChatModel;
@@ -37,6 +36,7 @@ export declare class PromptBuilder {
37
36
  toolAgents?: Agent[];
38
37
  }>;
39
38
  private buildMessages;
39
+ private convertMemoriesToMessages;
40
40
  private buildResponseFormat;
41
41
  private buildTools;
42
42
  }
@@ -1,11 +1,12 @@
1
1
  import { readFile } from "node:fs/promises";
2
+ import { stringify } from "yaml";
2
3
  import { ZodObject } from "zod";
3
4
  import { Agent } from "../agents/agent.js";
4
5
  import { outputSchemaToResponseFormatSchema } from "../utils/json-schema.js";
5
- import { isNil } from "../utils/type-utils.js";
6
- import { AgentMessageTemplate, ChatMessagesTemplate, SystemMessageTemplate, UserMessageTemplate, } from "./template.js";
6
+ import { isNil, orArrayToArray, unique } from "../utils/type-utils.js";
7
+ import { MEMORY_MESSAGE_TEMPLATE } from "./prompts/memory-message-template.js";
8
+ import { AgentMessageTemplate, ChatMessagesTemplate, PromptTemplate, SystemMessageTemplate, UserMessageTemplate, } from "./template.js";
7
9
  export const MESSAGE_KEY = "$message";
8
- export const DEFAULT_MAX_HISTORY_MESSAGES = 10;
9
10
  export function createMessage(message) {
10
11
  return typeof message === "string"
11
12
  ? { [MESSAGE_KEY]: message }
@@ -67,26 +68,20 @@ export class PromptBuilder {
67
68
  instructions;
68
69
  async build(options) {
69
70
  return {
70
- messages: this.buildMessages(options),
71
+ messages: await this.buildMessages(options),
71
72
  responseFormat: this.buildResponseFormat(options),
72
73
  ...this.buildTools(options),
73
74
  };
74
75
  }
75
- buildMessages(options) {
76
+ async buildMessages(options) {
76
77
  const { input } = options;
77
78
  const messages = (typeof this.instructions === "string"
78
79
  ? ChatMessagesTemplate.from([SystemMessageTemplate.from(this.instructions)])
79
80
  : this.instructions)?.format(options.input) ?? [];
80
- const memory = options.memory ?? options.agent?.memory;
81
- if (memory?.enabled) {
82
- const k = memory.maxMemoriesInChat ?? DEFAULT_MAX_HISTORY_MESSAGES;
83
- const histories = memory.memories.slice(-k);
84
- if (histories?.length)
85
- messages.push(...histories.map((i) => ({
86
- role: i.role,
87
- content: convertMessageToContent(i.content),
88
- name: i.source,
89
- })));
81
+ for (const memory of orArrayToArray(options.memory ?? options.agent?.memories)) {
82
+ const memories = (await memory.retrieve({ search: input && getMessage(input) }, options.context))?.memories;
83
+ if (memories?.length)
84
+ messages.push(...this.convertMemoriesToMessages(memories, options));
90
85
  }
91
86
  const content = input && getMessage(input);
92
87
  // add user input if it's not the same as the last message
@@ -95,6 +90,15 @@ export class PromptBuilder {
95
90
  }
96
91
  return messages;
97
92
  }
93
+ convertMemoriesToMessages(memories, options) {
94
+ const str = stringify(memories.map((i) => i.content));
95
+ return [
96
+ {
97
+ role: "system",
98
+ content: PromptTemplate.from(options.agent?.memoryPromptTemplate || MEMORY_MESSAGE_TEMPLATE).format({ memories: str }),
99
+ },
100
+ ];
101
+ }
98
102
  buildResponseFormat(options) {
99
103
  const outputSchema = options.outputSchema || options.agent?.outputSchema;
100
104
  if (!outputSchema)
@@ -112,10 +116,11 @@ export class PromptBuilder {
112
116
  : undefined;
113
117
  }
114
118
  buildTools(options) {
115
- const toolAgents = (options.context?.skills ?? [])
119
+ const toolAgents = unique((options.context?.skills ?? [])
116
120
  .concat(options.agent?.skills ?? [])
121
+ .concat(options.agent?.memoryAgentsAsTools ? options.agent.memories : [])
117
122
  // TODO: support nested tools?
118
- .flatMap((i) => (i.isInvokable ? i.skills.concat(i) : i.skills));
123
+ .flatMap((i) => (i.isInvokable ? i.skills.concat(i) : i.skills)), (i) => i.name);
119
124
  const tools = toolAgents.map((i) => ({
120
125
  type: "function",
121
126
  function: {
@@ -169,7 +174,3 @@ function isFromPath(value) {
169
174
  function isEmptyObjectType(schema) {
170
175
  return schema instanceof ZodObject && Object.keys(schema.shape).length === 0;
171
176
  }
172
- function convertMessageToContent(i) {
173
- const str = i[MESSAGE_KEY];
174
- return !isNil(str) ? (typeof str === "string" ? str : JSON.stringify(str)) : JSON.stringify(i);
175
- }
@@ -0,0 +1 @@
1
+ export declare const MEMORY_MESSAGE_TEMPLATE = "Here are some useful memories to consider:\n\n<memories>\n{{memories}}\n</memories>\n";
@@ -0,0 +1,7 @@
1
+ export const MEMORY_MESSAGE_TEMPLATE = `\
2
+ Here are some useful memories to consider:
3
+
4
+ <memories>
5
+ {{memories}}
6
+ </memories>
7
+ `;
@@ -1,5 +1,7 @@
1
+ import { inspect } from "node:util";
1
2
  import Mustache from "mustache";
2
3
  import { z } from "zod";
4
+ import { tryOrThrow } from "../utils/type-utils.js";
3
5
  export class PromptTemplate {
4
6
  template;
5
7
  static from(template) {
@@ -76,7 +78,9 @@ export class ToolMessageTemplate extends ChatMessageTemplate {
76
78
  return new ToolMessageTemplate(content, toolCallId, name);
77
79
  }
78
80
  constructor(content, toolCallId, name) {
79
- super("tool", typeof content === "string" ? content : JSON.stringify(content), name);
81
+ super("tool", typeof content === "string"
82
+ ? content
83
+ : tryOrThrow(() => JSON.stringify(content), `Failed to stringify tool content. toolCallId: ${toolCallId}, content: ${inspect(content)}`), name);
80
84
  this.toolCallId = toolCallId;
81
85
  }
82
86
  format(variables) {
@@ -1,4 +1,15 @@
1
+ /**
2
+ * Custom error class for AIGNEServer HTTP-related errors.
3
+ * Extends the standard Error class with an HTTP status code property.
4
+ * This allows error responses to include appropriate HTTP status codes.
5
+ */
1
6
  export declare class ServerError extends Error {
2
7
  status: number;
8
+ /**
9
+ * Creates a new ServerError instance.
10
+ *
11
+ * @param status - The HTTP status code for this error (e.g., 400, 404, 500)
12
+ * @param message - The error message describing what went wrong
13
+ */
3
14
  constructor(status: number, message: string);
4
15
  }
@@ -1,5 +1,16 @@
1
+ /**
2
+ * Custom error class for AIGNEServer HTTP-related errors.
3
+ * Extends the standard Error class with an HTTP status code property.
4
+ * This allows error responses to include appropriate HTTP status codes.
5
+ */
1
6
  export class ServerError extends Error {
2
7
  status;
8
+ /**
9
+ * Creates a new ServerError instance.
10
+ *
11
+ * @param status - The HTTP status code for this error (e.g., 400, 404, 500)
12
+ * @param message - The error message describing what went wrong
13
+ */
3
14
  constructor(status, message) {
4
15
  super(message);
5
16
  this.status = status;
@@ -0,0 +1,2 @@
1
+ export * from "./error.js";
2
+ export * from "./server.js";
@@ -0,0 +1,2 @@
1
+ export * from "./error.js";
2
+ export * from "./server.js";