@aigne/core 1.17.0 → 1.18.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 (102) hide show
  1. package/CHANGELOG.md +33 -19
  2. package/lib/cjs/agents/agent.d.ts +27 -11
  3. package/lib/cjs/agents/agent.js +36 -12
  4. package/lib/cjs/agents/ai-agent.d.ts +1 -3
  5. package/lib/cjs/agents/ai-agent.js +2 -11
  6. package/lib/cjs/agents/mcp-agent.d.ts +1 -1
  7. package/lib/cjs/agents/mcp-agent.js +5 -11
  8. package/lib/cjs/agents/user-agent.d.ts +0 -1
  9. package/lib/cjs/agents/user-agent.js +1 -2
  10. package/lib/cjs/aigne/context.d.ts +2 -3
  11. package/lib/cjs/aigne/context.js +3 -5
  12. package/lib/cjs/aigne/message-queue.d.ts +6 -2
  13. package/lib/cjs/aigne/message-queue.js +2 -2
  14. package/lib/cjs/index.d.ts +1 -0
  15. package/lib/cjs/index.js +1 -0
  16. package/lib/cjs/loader/agent-js.d.ts +1 -1
  17. package/lib/cjs/loader/agent-yaml.d.ts +2 -1
  18. package/lib/cjs/loader/agent-yaml.js +3 -2
  19. package/lib/cjs/loader/index.d.ts +5 -1
  20. package/lib/cjs/loader/index.js +25 -16
  21. package/lib/cjs/memory/retriever.d.ts +2 -2
  22. package/lib/cjs/prompt/prompt-builder.d.ts +2 -6
  23. package/lib/cjs/prompt/prompt-builder.js +10 -6
  24. package/lib/cjs/prompt/template.js +1 -3
  25. package/lib/cjs/utils/logger.js +3 -3
  26. package/lib/cjs/utils/nodejs.d.ts +8 -0
  27. package/lib/cjs/utils/nodejs.js +24 -0
  28. package/lib/dts/agents/agent.d.ts +27 -11
  29. package/lib/dts/agents/ai-agent.d.ts +1 -3
  30. package/lib/dts/agents/mcp-agent.d.ts +1 -1
  31. package/lib/dts/agents/user-agent.d.ts +0 -1
  32. package/lib/dts/aigne/context.d.ts +2 -3
  33. package/lib/dts/aigne/message-queue.d.ts +6 -2
  34. package/lib/dts/index.d.ts +1 -0
  35. package/lib/dts/loader/agent-js.d.ts +1 -1
  36. package/lib/dts/loader/agent-yaml.d.ts +2 -1
  37. package/lib/dts/loader/index.d.ts +5 -1
  38. package/lib/dts/memory/retriever.d.ts +2 -2
  39. package/lib/dts/prompt/prompt-builder.d.ts +2 -6
  40. package/lib/dts/utils/nodejs.d.ts +8 -0
  41. package/lib/esm/agents/agent.d.ts +27 -11
  42. package/lib/esm/agents/agent.js +37 -13
  43. package/lib/esm/agents/ai-agent.d.ts +1 -3
  44. package/lib/esm/agents/ai-agent.js +2 -11
  45. package/lib/esm/agents/mcp-agent.d.ts +1 -1
  46. package/lib/esm/agents/mcp-agent.js +5 -11
  47. package/lib/esm/agents/user-agent.d.ts +0 -1
  48. package/lib/esm/agents/user-agent.js +0 -1
  49. package/lib/esm/aigne/context.d.ts +2 -3
  50. package/lib/esm/aigne/context.js +3 -2
  51. package/lib/esm/aigne/message-queue.d.ts +6 -2
  52. package/lib/esm/aigne/message-queue.js +2 -2
  53. package/lib/esm/index.d.ts +1 -0
  54. package/lib/esm/index.js +1 -0
  55. package/lib/esm/loader/agent-js.d.ts +1 -1
  56. package/lib/esm/loader/agent-yaml.d.ts +2 -1
  57. package/lib/esm/loader/agent-yaml.js +3 -2
  58. package/lib/esm/loader/index.d.ts +5 -1
  59. package/lib/esm/loader/index.js +25 -16
  60. package/lib/esm/memory/retriever.d.ts +2 -2
  61. package/lib/esm/prompt/prompt-builder.d.ts +2 -6
  62. package/lib/esm/prompt/prompt-builder.js +11 -7
  63. package/lib/esm/prompt/template.js +1 -3
  64. package/lib/esm/utils/logger.js +3 -3
  65. package/lib/esm/utils/nodejs.d.ts +8 -0
  66. package/lib/esm/utils/nodejs.js +21 -0
  67. package/package.json +4 -6
  68. package/lib/cjs/memory/default-memory/default-memory-storage/index.d.ts +0 -30
  69. package/lib/cjs/memory/default-memory/default-memory-storage/index.js +0 -69
  70. package/lib/cjs/memory/default-memory/default-memory-storage/migrate.d.ts +0 -7
  71. package/lib/cjs/memory/default-memory/default-memory-storage/migrate.js +0 -53
  72. package/lib/cjs/memory/default-memory/default-memory-storage/migrations/20250523165801-init.d.ts +0 -7
  73. package/lib/cjs/memory/default-memory/default-memory-storage/migrations/20250523165801-init.js +0 -33
  74. package/lib/cjs/memory/default-memory/default-memory-storage/models/memory.d.ts +0 -10
  75. package/lib/cjs/memory/default-memory/default-memory-storage/models/memory.js +0 -32
  76. package/lib/cjs/memory/default-memory/index.d.ts +0 -10
  77. package/lib/cjs/memory/default-memory/index.js +0 -61
  78. package/lib/cjs/memory/default-memory/storage.d.ts +0 -13
  79. package/lib/cjs/memory/default-memory/storage.js +0 -6
  80. package/lib/cjs/utils/fs.d.ts +0 -2
  81. package/lib/cjs/utils/fs.js +0 -25
  82. package/lib/dts/memory/default-memory/default-memory-storage/index.d.ts +0 -30
  83. package/lib/dts/memory/default-memory/default-memory-storage/migrate.d.ts +0 -7
  84. package/lib/dts/memory/default-memory/default-memory-storage/migrations/20250523165801-init.d.ts +0 -7
  85. package/lib/dts/memory/default-memory/default-memory-storage/models/memory.d.ts +0 -10
  86. package/lib/dts/memory/default-memory/index.d.ts +0 -10
  87. package/lib/dts/memory/default-memory/storage.d.ts +0 -13
  88. package/lib/dts/utils/fs.d.ts +0 -2
  89. package/lib/esm/memory/default-memory/default-memory-storage/index.d.ts +0 -30
  90. package/lib/esm/memory/default-memory/default-memory-storage/index.js +0 -64
  91. package/lib/esm/memory/default-memory/default-memory-storage/migrate.d.ts +0 -7
  92. package/lib/esm/memory/default-memory/default-memory-storage/migrate.js +0 -16
  93. package/lib/esm/memory/default-memory/default-memory-storage/migrations/20250523165801-init.d.ts +0 -7
  94. package/lib/esm/memory/default-memory/default-memory-storage/migrations/20250523165801-init.js +0 -28
  95. package/lib/esm/memory/default-memory/default-memory-storage/models/memory.d.ts +0 -10
  96. package/lib/esm/memory/default-memory/default-memory-storage/models/memory.js +0 -29
  97. package/lib/esm/memory/default-memory/index.d.ts +0 -10
  98. package/lib/esm/memory/default-memory/index.js +0 -54
  99. package/lib/esm/memory/default-memory/storage.d.ts +0 -13
  100. package/lib/esm/memory/default-memory/storage.js +0 -2
  101. package/lib/esm/utils/fs.d.ts +0 -2
  102. package/lib/esm/utils/fs.js +0 -21
@@ -1,7 +1,7 @@
1
- import { inspect } from "node:util";
2
1
  import { ZodObject, z } from "zod";
3
- import { createMessage } from "../prompt/prompt-builder.js";
2
+ import { createMessage, getMessage } from "../prompt/prompt-builder.js";
4
3
  import { logger } from "../utils/logger.js";
4
+ import { nodejs } from "../utils/nodejs.js";
5
5
  import { agentResponseStreamToObject, asyncGeneratorToReadableStream, isAsyncGenerator, objectToAgentResponseStream, onAgentResponseStreamEnd, } from "../utils/stream-utils.js";
6
6
  import { checkArguments, createAccessorArray, isEmpty, orArrayToArray, } from "../utils/type-utils.js";
7
7
  import { replaceTransferAgentToName, transferToAgentOutput, } from "./types.js";
@@ -19,6 +19,7 @@ export const agentOptionsSchema = z.object({
19
19
  skills: z.array(z.union([z.custom(), z.custom()])).optional(),
20
20
  disableEvents: z.boolean().optional(),
21
21
  memory: z.union([z.custom(), z.array(z.custom())]).optional(),
22
+ maxRetrieveMemoryCount: z.number().optional(),
22
23
  hooks: z
23
24
  .object({
24
25
  onStart: z.custom().optional(),
@@ -75,6 +76,7 @@ export class Agent {
75
76
  else if (options.memory) {
76
77
  this.memories.push(options.memory);
77
78
  }
79
+ this.maxRetrieveMemoryCount = options.maxRetrieveMemoryCount;
78
80
  this.hooks = options.hooks ?? {};
79
81
  this.guideRails = options.guideRails;
80
82
  }
@@ -82,6 +84,10 @@ export class Agent {
82
84
  * List of memories this agent can use
83
85
  */
84
86
  memories = [];
87
+ /**
88
+ * Maximum number of memory items to retrieve
89
+ */
90
+ maxRetrieveMemoryCount;
85
91
  /**
86
92
  * Lifecycle hooks for agent processing.
87
93
  *
@@ -262,11 +268,33 @@ export class Agent {
262
268
  async newDefaultContext() {
263
269
  return import("../aigne/context.js").then((m) => new m.AIGNEContext());
264
270
  }
271
+ async retrieveMemories(input, options) {
272
+ const memories = [];
273
+ for (const memory of this.memories) {
274
+ const ms = (await memory.retrieve({
275
+ ...input,
276
+ search: typeof input === "string" ? input : input && getMessage(input),
277
+ limit: input.limit ?? this.maxRetrieveMemoryCount,
278
+ }, options.context)).memories;
279
+ memories.push(...ms);
280
+ }
281
+ return memories;
282
+ }
283
+ async recordMemories(input, options) {
284
+ for (const memory of this.memories) {
285
+ if (memory.autoUpdate) {
286
+ await memory.record(input, options.context);
287
+ }
288
+ }
289
+ }
265
290
  async invoke(input, options = {}) {
266
291
  const opts = {
267
292
  ...options,
268
293
  context: options.context ?? (await this.newDefaultContext()),
269
294
  };
295
+ if (options.userContext) {
296
+ Object.assign(opts.context.userContext, options.userContext);
297
+ }
270
298
  const message = typeof input === "string" ? createMessage(input) : input;
271
299
  logger.debug("Invoke agent %s started with input: %O", this.name, input);
272
300
  if (!this.disableEvents)
@@ -440,16 +468,12 @@ export class Agent {
440
468
  async postprocess(input, output, options) {
441
469
  this.checkContextStatus(options);
442
470
  this.publishToTopics(output, options);
443
- for (const memory of this.memories) {
444
- if (memory.autoUpdate) {
445
- await memory.record({
446
- content: [
447
- { role: "user", content: input },
448
- { role: "agent", content: replaceTransferAgentToName(output), source: this.name },
449
- ],
450
- }, options.context);
451
- }
452
- }
471
+ await this.recordMemories({
472
+ content: [
473
+ { role: "user", content: input },
474
+ { role: "agent", content: replaceTransferAgentToName(output), source: this.name },
475
+ ],
476
+ }, options);
453
477
  }
454
478
  async publishToTopics(output, options) {
455
479
  const publishTopics = typeof this.publishTopic === "function" ? await this.publishTopic(output) : this.publishTopic;
@@ -491,7 +515,7 @@ export class Agent {
491
515
  *
492
516
  * @returns Agent name
493
517
  */
494
- [inspect.custom]() {
518
+ [nodejs.customInspect]() {
495
519
  return this.name;
496
520
  }
497
521
  /**
@@ -1,5 +1,4 @@
1
1
  import { type ZodObject, type ZodType, z } from "zod";
2
- import { type DefaultMemoryOptions } from "../memory/default-memory/index.js";
3
2
  import { PromptBuilder } from "../prompt/prompt-builder.js";
4
3
  import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessAsyncGenerator, type Message } from "./agent.js";
5
4
  import { ChatModel, type ChatModelInput } from "./chat-model.js";
@@ -13,7 +12,7 @@ import type { GuideRailAgentOutput } from "./guide-rail-agent.js";
13
12
  * @template I The input message type the agent accepts
14
13
  * @template O The output message type the agent returns
15
14
  */
16
- export interface AIAgentOptions<I extends Message = Message, O extends Message = Message> extends Omit<AgentOptions<I, O>, "memory"> {
15
+ export interface AIAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
17
16
  /**
18
17
  * The language model to use for this agent
19
18
  *
@@ -65,7 +64,6 @@ export interface AIAgentOptions<I extends Message = Message, O extends Message =
65
64
  * The template receives a {{memories}} variable containing serialized memory content.
66
65
  */
67
66
  memoryPromptTemplate?: string;
68
- memory?: AgentOptions<I, O>["memory"] | DefaultMemoryOptions | true;
69
67
  }
70
68
  /**
71
69
  * Tool choice options for AI agents
@@ -1,6 +1,4 @@
1
1
  import { z } from "zod";
2
- import { DefaultMemory } from "../memory/default-memory/index.js";
3
- import { MemoryAgent } from "../memory/memory.js";
4
2
  import { MESSAGE_KEY, PromptBuilder } from "../prompt/prompt-builder.js";
5
3
  import { AgentMessageTemplate, ToolMessageTemplate } from "../prompt/template.js";
6
4
  import { checkArguments, isEmpty } from "../utils/type-utils.js";
@@ -98,14 +96,7 @@ export class AIAgent extends Agent {
98
96
  * @param options Configuration options for the AI agent
99
97
  */
100
98
  constructor(options) {
101
- super({
102
- ...options,
103
- memory: !options.memory
104
- ? undefined
105
- : Array.isArray(options.memory) || options.memory instanceof MemoryAgent
106
- ? options.memory
107
- : new DefaultMemory(options.memory === true ? {} : options.memory),
108
- });
99
+ super(options);
109
100
  checkArguments("AIAgent", aiAgentOptionsSchema, options);
110
101
  this.model = options.model;
111
102
  this.instructions =
@@ -190,10 +181,10 @@ export class AIAgent extends Agent {
190
181
  if (!model)
191
182
  throw new Error("model is required to run AIAgent");
192
183
  const { toolAgents, ...modelInput } = await this.instructions.build({
184
+ ...options,
193
185
  agent: this,
194
186
  input,
195
187
  model,
196
- context: options.context,
197
188
  });
198
189
  const toolsMap = new Map(toolAgents?.map((i) => [i.name, i]));
199
190
  if (this.toolChoice === "router") {
@@ -1,6 +1,6 @@
1
1
  import { Client, type ClientOptions } from "@modelcontextprotocol/sdk/client/index.js";
2
2
  import { type SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.js";
3
- import { type StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js";
3
+ import type { StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js";
4
4
  import { type StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
5
  import type { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
6
6
  import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
@@ -1,12 +1,13 @@
1
+ import { createStdioClientTransport } from "@aigne/platform-helpers/mcp/stdio-client-transport.js";
1
2
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
3
  import { SSEClientTransport, } from "@modelcontextprotocol/sdk/client/sse.js";
3
- import { StdioClientTransport, getDefaultEnvironment, } from "@modelcontextprotocol/sdk/client/stdio.js";
4
4
  import { StreamableHTTPClientTransport, } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
5
  import { UriTemplate } from "@modelcontextprotocol/sdk/shared/uriTemplate.js";
6
6
  import pRetry from "p-retry";
7
7
  import { z } from "zod";
8
8
  import { logger } from "../utils/logger.js";
9
9
  import { promptFromMCPPrompt, resourceFromMCPResource, toolFromMCPTool, } from "../utils/mcp-utils.js";
10
+ import { nodejs } from "../utils/nodejs.js";
10
11
  import { checkArguments, createAccessorArray } from "../utils/type-utils.js";
11
12
  import { Agent } from "./agent.js";
12
13
  const MCP_AGENT_CLIENT_NAME = "AIGNE/MCPAgent";
@@ -16,7 +17,7 @@ const DEFAULT_TIMEOUT = () => z.coerce
16
17
  .number()
17
18
  .int()
18
19
  .min(0)
19
- .safeParse(process.env.MCP_TIMEOUT || process.env.TIMEOUT).data || 60e3;
20
+ .safeParse(nodejs.env.MCP_TIMEOUT || nodejs.env.TIMEOUT).data || 60e3;
20
21
  function isSSEServerParameters(options) {
21
22
  return "url" in options && typeof options.url === "string";
22
23
  }
@@ -60,14 +61,7 @@ export class MCPAgent extends Agent {
60
61
  return MCPAgent.fromTransport(transport, options);
61
62
  }
62
63
  if (isStdioServerParameters(options)) {
63
- const transport = () => new StdioClientTransport({
64
- ...options,
65
- env: {
66
- ...getDefaultEnvironment(),
67
- ...options.env,
68
- },
69
- stderr: "pipe",
70
- });
64
+ const transport = async () => createStdioClientTransport(options);
71
65
  return MCPAgent.fromTransport(transport, options);
72
66
  }
73
67
  return new MCPAgent(options);
@@ -77,7 +71,7 @@ export class MCPAgent extends Agent {
77
71
  name: MCP_AGENT_CLIENT_NAME,
78
72
  version: MCP_AGENT_CLIENT_VERSION,
79
73
  }, undefined, isSSEServerParameters(options) ? { transportCreator, ...options } : undefined);
80
- const transport = transportCreator();
74
+ const transport = await transportCreator();
81
75
  logger.debug(`Connecting to MCP server: ${getMCPServerString(options)}`);
82
76
  await client.connect(transport);
83
77
  const mcpServer = getMCPServerName(client);
@@ -1,4 +1,3 @@
1
- import { ReadableStream } from "node:stream/web";
2
1
  import type { Context } from "../aigne/context.js";
3
2
  import { type MessagePayload } from "../aigne/message-queue.js";
4
3
  import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type FunctionAgentFn, type Message } from "./agent.js";
@@ -1,4 +1,3 @@
1
- import { ReadableStream } from "node:stream/web";
2
1
  import { toMessagePayload } from "../aigne/message-queue.js";
3
2
  import { orArrayToArray } from "../utils/type-utils.js";
4
3
  import { Agent, } from "./agent.js";
@@ -1,4 +1,4 @@
1
- import EventEmitter from "node:events";
1
+ import { Emitter } from "strict-event-emitter";
2
2
  import { Agent, type AgentInvokeOptions, type AgentProcessAsyncGenerator, type AgentResponse, type AgentResponseStream, type Message } from "../agents/agent.js";
3
3
  import type { ChatModel } from "../agents/chat-model.js";
4
4
  import { UserAgent } from "../agents/user-agent.js";
@@ -42,7 +42,6 @@ export interface InvokeOptions<U extends UserContext = UserContext> extends Part
42
42
  returnActiveAgent?: boolean;
43
43
  disableTransfer?: boolean;
44
44
  sourceAgent?: Agent;
45
- userContext?: U;
46
45
  }
47
46
  /**
48
47
  * @hidden
@@ -150,7 +149,7 @@ declare class AIGNEContextShared {
150
149
  messageQueue?: MessageQueue;
151
150
  }) | undefined, overrides?: Partial<Context>);
152
151
  readonly messageQueue: MessageQueue;
153
- readonly events: EventEmitter<ContextEventMap>;
152
+ readonly events: Emitter<any>;
154
153
  get model(): ChatModel | undefined;
155
154
  get skills(): Agent<Message, Message>[] | undefined;
156
155
  get limits(): ContextLimits | undefined;
@@ -1,4 +1,4 @@
1
- import EventEmitter from "node:events";
1
+ import { Emitter } from "strict-event-emitter";
2
2
  import { v7 } from "uuid";
3
3
  import { z } from "zod";
4
4
  import { Agent, } from "../agents/agent.js";
@@ -143,7 +143,8 @@ class AIGNEContextShared {
143
143
  this.userContext = overrides?.userContext ?? {};
144
144
  }
145
145
  messageQueue;
146
- events = new EventEmitter();
146
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
147
+ events = new Emitter();
147
148
  get model() {
148
149
  return this.parent?.model;
149
150
  }
@@ -1,4 +1,4 @@
1
- import { EventEmitter } from "node:events";
1
+ import { Emitter, type EventMap } from "strict-event-emitter";
2
2
  import type { Message } from "../agents/agent.js";
3
3
  import type { Context } from "./context.js";
4
4
  /**
@@ -30,11 +30,14 @@ export type MessageQueueListener = (message: MessagePayload) => void;
30
30
  * @hidden
31
31
  */
32
32
  export type Unsubscribe = () => void;
33
+ interface MessageQueueEventMap extends EventMap {
34
+ [key: string]: any[];
35
+ }
33
36
  /**
34
37
  * @hidden
35
38
  */
36
39
  export declare class MessageQueue {
37
- events: EventEmitter<[never]>;
40
+ events: Emitter<MessageQueueEventMap>;
38
41
  publish(topic: string | string[], payload: MessagePayload): void;
39
42
  error(error: Error): void;
40
43
  subscribe(topic: string | string[], listener?: undefined): Promise<MessagePayload>;
@@ -42,3 +45,4 @@ export declare class MessageQueue {
42
45
  subscribe(topic: string | string[], listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
43
46
  unsubscribe(topic: string | string[], listener: MessageQueueListener): void;
44
47
  }
48
+ export {};
@@ -1,4 +1,4 @@
1
- import { EventEmitter } from "node:events";
1
+ import { Emitter } from "strict-event-emitter";
2
2
  import { z } from "zod";
3
3
  import { createMessage } from "../prompt/prompt-builder.js";
4
4
  import { checkArguments, isNil, orArrayToArray } from "../utils/type-utils.js";
@@ -36,7 +36,7 @@ export function toMessagePayload(payload, options) {
36
36
  * @hidden
37
37
  */
38
38
  export class MessageQueue {
39
- events = new EventEmitter();
39
+ events = new Emitter();
40
40
  publish(topic, payload) {
41
41
  checkArguments("MessageQueue.publish", publishArgsSchema, {
42
42
  topic,
@@ -7,5 +7,6 @@ export * from "./agents/team-agent.js";
7
7
  export * from "./agents/types.js";
8
8
  export * from "./agents/user-agent.js";
9
9
  export * from "./aigne/index.js";
10
+ export * from "./memory/index.js";
10
11
  export * from "./prompt/prompt-builder.js";
11
12
  export * from "./prompt/template.js";
package/lib/esm/index.js CHANGED
@@ -7,5 +7,6 @@ export * from "./agents/team-agent.js";
7
7
  export * from "./agents/types.js";
8
8
  export * from "./agents/user-agent.js";
9
9
  export * from "./aigne/index.js";
10
+ export * from "./memory/index.js";
10
11
  export * from "./prompt/prompt-builder.js";
11
12
  export * from "./prompt/template.js";
@@ -1,8 +1,8 @@
1
1
  import { type ZodObject, type ZodType, z } from "zod";
2
2
  import type { Message } from "../agents/agent.js";
3
3
  export declare function loadAgentFromJsFile(path: string): Promise<{
4
- name: string;
5
4
  process: (args_0: Message) => Message;
5
+ name: string;
6
6
  description?: string | undefined;
7
7
  inputSchema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
8
8
  [x: string]: any;
@@ -5,10 +5,11 @@ export declare function loadAgentFromYamlFile(path: string): Promise<{
5
5
  name: string;
6
6
  description?: string | undefined;
7
7
  skills?: string[] | undefined;
8
+ instructions?: string | undefined;
8
9
  memory?: true | {
10
+ provider: string;
9
11
  subscribeTopic?: string[] | undefined;
10
12
  } | undefined;
11
- instructions?: string | undefined;
12
13
  inputSchema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
13
14
  [x: string]: any;
14
15
  }, {
@@ -1,9 +1,9 @@
1
- import { readFile } from "node:fs/promises";
2
1
  import { jsonSchemaToZod } from "@aigne/json-schema-to-zod";
3
2
  import { parse } from "yaml";
4
3
  import { z } from "zod";
5
4
  import { AIAgentToolChoice } from "../agents/ai-agent.js";
6
5
  import { customCamelize } from "../utils/camelize.js";
6
+ import { nodejs } from "../utils/nodejs.js";
7
7
  import { tryOrThrow } from "../utils/type-utils.js";
8
8
  import { inputOutputSchema } from "./schema.js";
9
9
  const agentFileSchema = z.discriminatedUnion("type", [
@@ -40,6 +40,7 @@ const agentFileSchema = z.discriminatedUnion("type", [
40
40
  .union([
41
41
  z.boolean(),
42
42
  z.object({
43
+ provider: z.string(),
43
44
  subscribe_topic: z
44
45
  .array(z.string())
45
46
  .nullish()
@@ -66,7 +67,7 @@ const agentFileSchema = z.discriminatedUnion("type", [
66
67
  }),
67
68
  ]);
68
69
  export async function loadAgentFromYamlFile(path) {
69
- const raw = await tryOrThrow(() => readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
70
+ const raw = await tryOrThrow(() => nodejs.fs.readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
70
71
  const json = await tryOrThrow(() => parse(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
71
72
  const agent = tryOrThrow(() => customCamelize(agentFileSchema.parse({
72
73
  ...json,
@@ -2,6 +2,7 @@ import type { Camelize } from "camelize-ts";
2
2
  import { z } from "zod";
3
3
  import { type Agent } from "../agents/agent.js";
4
4
  import type { ChatModel, ChatModelOptions } from "../agents/chat-model.js";
5
+ import type { MemoryAgent, MemoryAgentOptions } from "../memory/memory.js";
5
6
  export interface LoadOptions {
6
7
  models: {
7
8
  new (parameters: {
@@ -9,6 +10,9 @@ export interface LoadOptions {
9
10
  modelOptions?: ChatModelOptions;
10
11
  }): ChatModel;
11
12
  }[];
13
+ memories?: {
14
+ new (parameters?: MemoryAgentOptions): MemoryAgent;
15
+ }[];
12
16
  path: string;
13
17
  }
14
18
  export declare function load(options: LoadOptions): Promise<{
@@ -26,7 +30,7 @@ export declare function load(options: LoadOptions): Promise<{
26
30
  presence_penalty?: number | null | undefined;
27
31
  } | null | undefined;
28
32
  }>;
29
- export declare function loadAgent(path: string): Promise<Agent>;
33
+ export declare function loadAgent(path: string, options?: LoadOptions): Promise<Agent>;
30
34
  export declare function loadModel(models: LoadOptions["models"], model?: Camelize<z.infer<typeof aigneFileSchema>["chat_model"]>, modelOptions?: ChatModelOptions): Promise<ChatModel | undefined>;
31
35
  declare const aigneFileSchema: z.ZodObject<{
32
36
  name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -1,21 +1,19 @@
1
- import { readFile, stat } from "node:fs/promises";
2
- import { dirname, extname, join } from "node:path";
3
1
  import { parse } from "yaml";
4
2
  import { z } from "zod";
5
3
  import { FunctionAgent } from "../agents/agent.js";
6
4
  import { AIAgent } from "../agents/ai-agent.js";
7
5
  import { MCPAgent } from "../agents/mcp-agent.js";
6
+ import { nodejs } from "../utils/nodejs.js";
8
7
  import { tryOrThrow } from "../utils/type-utils.js";
9
8
  import { loadAgentFromJsFile } from "./agent-js.js";
10
9
  import { loadAgentFromYamlFile } from "./agent-yaml.js";
11
10
  const AIGNE_FILE_NAME = ["aigne.yaml", "aigne.yml"];
12
11
  export async function load(options) {
13
- const { path } = options;
14
- const aigneFilePath = await getAIGNEFilePath(path);
15
- const rootDir = dirname(aigneFilePath);
12
+ const aigneFilePath = await getAIGNEFilePath(options.path);
13
+ const rootDir = nodejs.path.dirname(aigneFilePath);
16
14
  const aigne = await loadAIGNEFile(aigneFilePath);
17
- const agents = await Promise.all((aigne.agents ?? []).map((filename) => loadAgent(join(rootDir, filename))));
18
- const skills = await Promise.all((aigne.skills ?? []).map((filename) => loadAgent(join(rootDir, filename))));
15
+ const agents = await Promise.all((aigne.agents ?? []).map((filename) => loadAgent(nodejs.path.join(rootDir, filename))));
16
+ const skills = await Promise.all((aigne.skills ?? []).map((filename) => loadAgent(nodejs.path.join(rootDir, filename))));
19
17
  return {
20
18
  ...aigne,
21
19
  model: await loadModel(options.models, aigne.chat_model),
@@ -23,18 +21,21 @@ export async function load(options) {
23
21
  skills,
24
22
  };
25
23
  }
26
- export async function loadAgent(path) {
27
- if (extname(path) === ".js") {
24
+ export async function loadAgent(path, options) {
25
+ if (nodejs.path.extname(path) === ".js") {
28
26
  const agent = await loadAgentFromJsFile(path);
29
27
  return FunctionAgent.from(agent);
30
28
  }
31
- if (extname(path) === ".yaml" || extname(path) === ".yml") {
29
+ if (nodejs.path.extname(path) === ".yaml" || nodejs.path.extname(path) === ".yml") {
32
30
  const agent = await loadAgentFromYamlFile(path);
33
31
  if (agent.type === "ai") {
34
32
  return AIAgent.from({
35
33
  ...agent,
34
+ memory: !options?.memories?.length || !agent.memory
35
+ ? undefined
36
+ : await loadMemory(options.memories, typeof agent.memory === "object" ? agent.memory.provider : undefined, typeof agent.memory === "object" ? agent.memory : {}),
36
37
  skills: agent.skills &&
37
- (await Promise.all(agent.skills.map((filename) => loadAgent(join(dirname(path), filename))))),
38
+ (await Promise.all(agent.skills.map((filename) => loadAgent(nodejs.path.join(nodejs.path.dirname(path), filename))))),
38
39
  });
39
40
  }
40
41
  if (agent.type === "mcp") {
@@ -54,7 +55,15 @@ export async function loadAgent(path) {
54
55
  }
55
56
  throw new Error(`Unsupported agent file type: ${path}`);
56
57
  }
57
- const { MODEL_PROVIDER, MODEL_NAME } = process.env;
58
+ async function loadMemory(memories, provider, options) {
59
+ const M = !provider
60
+ ? memories[0]
61
+ : memories.find((i) => i.name.toLowerCase().includes(provider.toLowerCase()));
62
+ if (!M)
63
+ throw new Error(`Unsupported memory: ${provider}`);
64
+ return new M(options);
65
+ }
66
+ const { MODEL_PROVIDER, MODEL_NAME } = nodejs.env;
58
67
  const DEFAULT_MODEL_PROVIDER = "openai";
59
68
  export async function loadModel(models, model, modelOptions) {
60
69
  const params = {
@@ -92,17 +101,17 @@ const aigneFileSchema = z.object({
92
101
  skills: z.array(z.string()).nullish(),
93
102
  });
94
103
  export async function loadAIGNEFile(path) {
95
- const raw = await tryOrThrow(() => readFile(path, "utf8"), (error) => new Error(`Failed to load aigne.yaml from ${path}: ${error.message}`));
104
+ const raw = await tryOrThrow(() => nodejs.fs.readFile(path, "utf8"), (error) => new Error(`Failed to load aigne.yaml from ${path}: ${error.message}`));
96
105
  const json = await tryOrThrow(() => parse(raw), (error) => new Error(`Failed to parse aigne.yaml from ${path}: ${error.message}`));
97
106
  const agent = tryOrThrow(() => aigneFileSchema.parse({ ...json, skills: json.skills ?? json.tools }), (error) => new Error(`Failed to validate aigne.yaml from ${path}: ${error.message}`));
98
107
  return agent;
99
108
  }
100
109
  async function getAIGNEFilePath(path) {
101
- const s = await stat(path);
110
+ const s = await nodejs.fs.stat(path);
102
111
  if (s.isDirectory()) {
103
112
  for (const file of AIGNE_FILE_NAME) {
104
- const filePath = join(path, file);
105
- if ((await stat(filePath)).isFile())
113
+ const filePath = nodejs.path.join(path, file);
114
+ if ((await nodejs.fs.stat(filePath)).isFile())
106
115
  return filePath;
107
116
  }
108
117
  }
@@ -39,11 +39,11 @@ export declare const memoryRetrieverInputSchema: z.ZodObject<{
39
39
  limit: z.ZodOptional<z.ZodNumber>;
40
40
  search: z.ZodOptional<z.ZodString>;
41
41
  }, "strip", z.ZodTypeAny, {
42
- search?: string | undefined;
43
42
  limit?: number | undefined;
44
- }, {
45
43
  search?: string | undefined;
44
+ }, {
46
45
  limit?: number | undefined;
46
+ search?: string | undefined;
47
47
  }>;
48
48
  /**
49
49
  * @hidden
@@ -1,9 +1,7 @@
1
1
  import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
- import { Agent, type Message } from "../agents/agent.js";
2
+ import { Agent, type AgentInvokeOptions, type Message } from "../agents/agent.js";
3
3
  import type { AIAgent } from "../agents/ai-agent.js";
4
4
  import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
5
- import type { Context } from "../aigne/context.js";
6
- import type { MemoryAgent } from "../memory/memory.js";
7
5
  import { ChatMessagesTemplate } from "./template.js";
8
6
  export declare const MESSAGE_KEY = "$message";
9
7
  export declare function createMessage<V extends Message>(message: string, variables?: V): {
@@ -17,9 +15,7 @@ export declare function getMessage(input: Message): string | undefined;
17
15
  export interface PromptBuilderOptions {
18
16
  instructions?: string | ChatMessagesTemplate;
19
17
  }
20
- export interface PromptBuildOptions {
21
- memory?: MemoryAgent | MemoryAgent[];
22
- context: Context;
18
+ export interface PromptBuildOptions extends AgentInvokeOptions {
23
19
  agent?: AIAgent;
24
20
  input?: Message;
25
21
  model?: ChatModel;
@@ -1,9 +1,9 @@
1
- import { readFile } from "node:fs/promises";
2
1
  import { stringify } from "yaml";
3
2
  import { ZodObject } from "zod";
4
3
  import { Agent } from "../agents/agent.js";
5
4
  import { outputSchemaToResponseFormatSchema } from "../utils/json-schema.js";
6
- import { isNil, orArrayToArray, unique } from "../utils/type-utils.js";
5
+ import { nodejs } from "../utils/nodejs.js";
6
+ import { isNil, unique } from "../utils/type-utils.js";
7
7
  import { MEMORY_MESSAGE_TEMPLATE } from "./prompts/memory-message-template.js";
8
8
  import { AgentMessageTemplate, ChatMessagesTemplate, PromptTemplate, SystemMessageTemplate, UserMessageTemplate, } from "./template.js";
9
9
  export const MESSAGE_KEY = "$message";
@@ -31,7 +31,7 @@ export class PromptBuilder {
31
31
  throw new Error(`Invalid instructions ${instructions}`);
32
32
  }
33
33
  static async fromFile(path) {
34
- const text = await readFile(path, "utf-8");
34
+ const text = await nodejs.fs.readFile(path, "utf-8");
35
35
  return PromptBuilder.from(text);
36
36
  }
37
37
  static fromMCPPromptResult(result) {
@@ -78,11 +78,15 @@ export class PromptBuilder {
78
78
  const messages = (typeof this.instructions === "string"
79
79
  ? ChatMessagesTemplate.from([SystemMessageTemplate.from(this.instructions)])
80
80
  : this.instructions)?.format(options.input) ?? [];
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));
81
+ const memories = [];
82
+ if (options.agent) {
83
+ memories.push(...(await options.agent.retrieveMemories({ search: options.input }, options)));
85
84
  }
85
+ if (options.memories?.length) {
86
+ memories.push(...options.memories);
87
+ }
88
+ if (memories.length)
89
+ messages.push(...this.convertMemoriesToMessages(memories, options));
86
90
  const content = input && getMessage(input);
87
91
  // add user input if it's not the same as the last message
88
92
  if (content && messages.at(-1)?.content !== content) {
@@ -1,7 +1,5 @@
1
- import { inspect } from "node:util";
2
1
  import Mustache from "mustache";
3
2
  import { z } from "zod";
4
- import { tryOrThrow } from "../utils/type-utils.js";
5
3
  export class PromptTemplate {
6
4
  template;
7
5
  static from(template) {
@@ -80,7 +78,7 @@ export class ToolMessageTemplate extends ChatMessageTemplate {
80
78
  constructor(content, toolCallId, name) {
81
79
  super("tool", typeof content === "string"
82
80
  ? content
83
- : tryOrThrow(() => JSON.stringify(content, (_, value) => typeof value === "bigint" ? value.toString() : value), `Failed to stringify tool content. toolCallId: ${toolCallId}, content: ${inspect(content)}`), name);
81
+ : JSON.stringify(content, (_, value) => typeof value === "bigint" ? value.toString() : value), name);
84
82
  this.toolCallId = toolCallId;
85
83
  }
86
84
  format(variables) {
@@ -1,5 +1,5 @@
1
- import { isatty } from "node:tty";
2
1
  import debug from "debug";
2
+ import { nodejs } from "./nodejs.js";
3
3
  export var LogLevel;
4
4
  (function (LogLevel) {
5
5
  LogLevel["ERROR"] = "error";
@@ -17,13 +17,13 @@ export class Logger {
17
17
  this.errorLogger = debug(`${options.ns}:error`);
18
18
  for (const logger of [this.debugLogger, this.infoLogger, this.warnLogger]) {
19
19
  // @ts-ignore
20
- logger.useColors = isatty(process.stdout.fd);
20
+ logger.useColors = nodejs.isStdoutATTY;
21
21
  logger.enabled = true;
22
22
  logger.log = (...args) => this.logMessage(...args);
23
23
  }
24
24
  this.errorLogger.log = (...args) => this.logError(...args);
25
25
  // @ts-ignore
26
- this.errorLogger.useColors = isatty(process.stderr.fd);
26
+ this.errorLogger.useColors = nodejs.isStderrATTY;
27
27
  this.errorLogger.enabled = true;
28
28
  }
29
29
  level;
@@ -0,0 +1,8 @@
1
+ export declare const nodejs: {
2
+ customInspect: any;
3
+ isStdoutATTY: boolean;
4
+ isStderrATTY: boolean;
5
+ env: NodeJS.ProcessEnv;
6
+ readonly fs: typeof import("node:fs/promises");
7
+ readonly path: typeof import("node:path");
8
+ };