@aigne/core 1.72.0-beta.6 → 1.72.0-beta.8

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 (68) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/lib/cjs/agents/agent.d.ts +23 -27
  3. package/lib/cjs/agents/agent.js +16 -8
  4. package/lib/cjs/agents/ai-agent.d.ts +20 -4
  5. package/lib/cjs/agents/ai-agent.js +47 -55
  6. package/lib/cjs/agents/chat-model.d.ts +1 -0
  7. package/lib/cjs/agents/image-model.d.ts +4 -4
  8. package/lib/cjs/agents/mcp-agent.d.ts +2 -2
  9. package/lib/cjs/agents/video-model.d.ts +4 -4
  10. package/lib/cjs/index.d.ts +1 -0
  11. package/lib/cjs/index.js +1 -0
  12. package/lib/cjs/loader/index.d.ts +2 -2
  13. package/lib/cjs/memory/recorder.d.ts +4 -4
  14. package/lib/cjs/memory/retriever.d.ts +4 -4
  15. package/lib/cjs/prompt/agent-session.d.ts +53 -0
  16. package/lib/cjs/prompt/agent-session.js +341 -0
  17. package/lib/cjs/prompt/compact/compactor.d.ts +7 -0
  18. package/lib/cjs/prompt/compact/compactor.js +48 -0
  19. package/lib/cjs/prompt/compact/types.d.ts +79 -0
  20. package/lib/cjs/prompt/compact/types.js +19 -0
  21. package/lib/cjs/prompt/context/afs/history.d.ts +5 -1
  22. package/lib/cjs/prompt/context/afs/history.js +3 -2
  23. package/lib/cjs/prompt/context/afs/index.js +8 -1
  24. package/lib/cjs/prompt/prompt-builder.d.ts +11 -9
  25. package/lib/cjs/prompt/prompt-builder.js +77 -117
  26. package/lib/cjs/prompt/template.d.ts +16 -16
  27. package/lib/dts/agents/agent.d.ts +23 -27
  28. package/lib/dts/agents/ai-agent.d.ts +20 -4
  29. package/lib/dts/agents/chat-model.d.ts +1 -0
  30. package/lib/dts/agents/image-model.d.ts +4 -4
  31. package/lib/dts/agents/mcp-agent.d.ts +2 -2
  32. package/lib/dts/agents/video-model.d.ts +4 -4
  33. package/lib/dts/index.d.ts +1 -0
  34. package/lib/dts/loader/index.d.ts +2 -2
  35. package/lib/dts/memory/recorder.d.ts +4 -4
  36. package/lib/dts/memory/retriever.d.ts +4 -4
  37. package/lib/dts/prompt/agent-session.d.ts +53 -0
  38. package/lib/dts/prompt/compact/compactor.d.ts +7 -0
  39. package/lib/dts/prompt/compact/types.d.ts +79 -0
  40. package/lib/dts/prompt/context/afs/history.d.ts +5 -1
  41. package/lib/dts/prompt/prompt-builder.d.ts +11 -9
  42. package/lib/dts/prompt/template.d.ts +16 -16
  43. package/lib/esm/agents/agent.d.ts +23 -27
  44. package/lib/esm/agents/agent.js +16 -8
  45. package/lib/esm/agents/ai-agent.d.ts +20 -4
  46. package/lib/esm/agents/ai-agent.js +47 -55
  47. package/lib/esm/agents/chat-model.d.ts +1 -0
  48. package/lib/esm/agents/image-model.d.ts +4 -4
  49. package/lib/esm/agents/mcp-agent.d.ts +2 -2
  50. package/lib/esm/agents/video-model.d.ts +4 -4
  51. package/lib/esm/index.d.ts +1 -0
  52. package/lib/esm/index.js +1 -0
  53. package/lib/esm/loader/index.d.ts +2 -2
  54. package/lib/esm/memory/recorder.d.ts +4 -4
  55. package/lib/esm/memory/retriever.d.ts +4 -4
  56. package/lib/esm/prompt/agent-session.d.ts +53 -0
  57. package/lib/esm/prompt/agent-session.js +304 -0
  58. package/lib/esm/prompt/compact/compactor.d.ts +7 -0
  59. package/lib/esm/prompt/compact/compactor.js +44 -0
  60. package/lib/esm/prompt/compact/types.d.ts +79 -0
  61. package/lib/esm/prompt/compact/types.js +16 -0
  62. package/lib/esm/prompt/context/afs/history.d.ts +5 -1
  63. package/lib/esm/prompt/context/afs/history.js +3 -2
  64. package/lib/esm/prompt/context/afs/index.js +8 -1
  65. package/lib/esm/prompt/prompt-builder.d.ts +11 -9
  66. package/lib/esm/prompt/prompt-builder.js +78 -118
  67. package/lib/esm/prompt/template.d.ts +16 -16
  68. package/package.json +4 -4
@@ -1,5 +1,5 @@
1
- import { AFSHistory } from "@aigne/afs-history";
2
1
  import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
2
+ import { v7 } from "@aigne/uuid";
3
3
  import { stringify } from "yaml";
4
4
  import { ZodObject } from "zod";
5
5
  import { zodToJsonSchema } from "zod-to-json-schema";
@@ -8,9 +8,9 @@ import { DEFAULT_OUTPUT_FILE_KEY, DEFAULT_OUTPUT_KEY } from "../agents/ai-agent.
8
8
  import { fileUnionContentsSchema } from "../agents/model.js";
9
9
  import { optionalize } from "../loader/schema.js";
10
10
  import { outputSchemaToResponseFormatSchema } from "../utils/json-schema.js";
11
- import { checkArguments, flat, isNonNullable, isRecord, partition, unique, } from "../utils/type-utils.js";
11
+ import { checkArguments, flat, isRecord, partition, unique } from "../utils/type-utils.js";
12
+ import { AgentSession } from "./agent-session.js";
12
13
  import { createPromptBuilderContext } from "./context/index.js";
13
- import { AFS_EXECUTABLE_TOOLS_PROMPT_TEMPLATE } from "./prompts/afs-builtin-prompt.js";
14
14
  import { MEMORY_MESSAGE_TEMPLATE } from "./prompts/memory-message-template.js";
15
15
  import { STRUCTURED_STREAM_INSTRUCTIONS } from "./prompts/structured-stream-instructions.js";
16
16
  import { getAFSSkills } from "./skills/afs/index.js";
@@ -70,13 +70,28 @@ export class PromptBuilder {
70
70
  });
71
71
  }
72
72
  async build(options) {
73
+ let { userId, sessionId } = options.context?.userContext || {};
74
+ const agentId = options.agent?.name;
75
+ const afs = options.agent?.afs;
76
+ sessionId ||= v7();
77
+ const session = new AgentSession({
78
+ agentId,
79
+ userId,
80
+ sessionId,
81
+ afs,
82
+ compact: options.agent?.compact,
83
+ });
84
+ const { systemMessage, userMessage } = await this.buildMessages(options);
85
+ if (systemMessage)
86
+ await session.setSystemMessages(systemMessage);
73
87
  return {
74
- messages: await this.buildMessages(options),
88
+ userMessage,
75
89
  responseFormat: options.agent?.structuredStreamMode
76
90
  ? undefined
77
91
  : this.buildResponseFormat(options),
78
92
  outputFileType: options.agent?.outputFileType,
79
93
  ...(await this.buildTools(options)),
94
+ session,
80
95
  };
81
96
  }
82
97
  async buildPrompt(options) {
@@ -99,84 +114,41 @@ export class PromptBuilder {
99
114
  const { input } = options;
100
115
  const inputKey = options.agent?.inputKey;
101
116
  const message = inputKey && typeof input?.[inputKey] === "string" ? input[inputKey] : undefined;
102
- const [messages, otherCustomMessages] = partition((await (typeof this.instructions === "string"
117
+ const template = typeof this.instructions === "string"
103
118
  ? ChatMessagesTemplate.from([SystemMessageTemplate.from(this.instructions)])
104
- : this.instructions)?.format(this.getTemplateVariables(options), { workingDir: this.workingDir })) ?? [], (i) => i.role === "system");
119
+ : this.instructions;
120
+ const [systemMessages, userMessages] = partition((await template?.format(this.getTemplateVariables(options), {
121
+ workingDir: this.workingDir,
122
+ })) ?? [], (i) => i.role === "system");
105
123
  const inputFileKey = options.agent?.inputFileKey;
106
124
  const files = flat(inputFileKey
107
125
  ? checkArguments("Check input files", optionalize(fileUnionContentsSchema), input?.[inputFileKey])
108
126
  : null);
109
- const memories = [];
110
- if (options.agent && options.context) {
111
- memories.push(...(await options.agent.retrieveMemories({ search: message }, { context: options.context })));
112
- }
113
- if (options.agent?.useMemoriesFromContext && options.context?.memories?.length) {
114
- memories.push(...options.context.memories);
115
- }
116
- const afs = options.agent?.afs;
117
- if (afs && options.agent?.historyConfig?.disabled !== true) {
118
- const historyModule = (await afs.listModules()).find((m) => m.module instanceof AFSHistory);
119
- if (historyModule) {
120
- const history = await afs.list(historyModule.path, {
121
- limit: options.agent?.maxRetrieveMemoryCount || 10,
122
- orderBy: [["createdAt", "desc"]],
123
- });
124
- memories.push(...history.data
125
- .reverse()
126
- .filter((i) => isNonNullable(i.content)));
127
- if (message) {
128
- const result = (await afs.search("/", message)).data;
129
- const ms = result
130
- .map((entry) => {
131
- if (entry.metadata?.execute)
132
- return null;
133
- const content = entry.content || entry.summary;
134
- if (!content)
135
- return null;
136
- return {
137
- content,
138
- description: entry.description,
139
- };
140
- })
141
- .filter(isNonNullable);
142
- memories.push(...ms);
143
- const executable = result.filter((i) => !!i.metadata?.execute);
144
- if (executable.length) {
145
- messages.push({
146
- role: "system",
147
- content: await PromptTemplate.from(AFS_EXECUTABLE_TOOLS_PROMPT_TEMPLATE).format({
148
- tools: executable.map((entry) => ({
149
- path: entry.path,
150
- name: entry.metadata.execute.name,
151
- description: entry.metadata.execute.description,
152
- inputSchema: entry.metadata.execute.inputSchema,
153
- outputSchema: entry.metadata.execute.outputSchema,
154
- })),
155
- }),
156
- });
157
- }
158
- }
159
- }
127
+ if (options.agent?.memories.length || options.context?.memories.length) {
128
+ const deprecatedMemories = await this.deprecatedMemories(message, options);
129
+ if (deprecatedMemories.length)
130
+ systemMessages.push(...deprecatedMemories);
160
131
  }
161
- if (memories.length)
162
- messages.push(...(await this.convertMemoriesToMessages(memories, options)));
163
132
  // if the agent is using structured stream mode, add the instructions
164
133
  const { structuredStreamMode, outputSchema } = options.agent || {};
165
134
  if (structuredStreamMode && outputSchema) {
166
135
  const instructions = options.agent?.customStructuredStreamInstructions?.instructions ||
167
136
  PromptBuilder.from(STRUCTURED_STREAM_INSTRUCTIONS.instructions);
168
- messages.push(...(await instructions.buildMessages({
169
- input: {
170
- ...input,
171
- outputJsonSchema: zodToJsonSchema(outputSchema),
172
- },
173
- })));
137
+ systemMessages.push({
138
+ role: "system",
139
+ content: (await instructions.buildPrompt({
140
+ input: {
141
+ ...input,
142
+ outputJsonSchema: zodToJsonSchema(outputSchema),
143
+ },
144
+ })).prompt,
145
+ });
174
146
  }
175
147
  if (message || files.length) {
176
148
  const content = [];
177
149
  if (message &&
178
- // avoid duplicate user messages: developer may have already included the message in the custom user messages
179
- !otherCustomMessages.some((i) => i.role === "user" &&
150
+ // avoid duplicate user messages: developer may have already included the message in the messages
151
+ !userMessages.some((i) => i.role === "user" &&
180
152
  (typeof i.content === "string"
181
153
  ? i.content.includes(message)
182
154
  : i.content?.some((c) => c.type === "text" && c.text.includes(message))))) {
@@ -185,63 +157,51 @@ export class PromptBuilder {
185
157
  if (files.length)
186
158
  content.push(...files);
187
159
  if (content.length) {
188
- messages.push({ role: "user", content });
160
+ userMessages.push({ role: "user", content });
189
161
  }
190
162
  }
191
- messages.push(...otherCustomMessages);
192
- return this.refineMessages(options, messages);
163
+ let systemMessage = this.mergeMessages(systemMessages, "system");
164
+ if (!systemMessage.content?.length)
165
+ systemMessage = undefined;
166
+ let userMessage = this.mergeMessages(userMessages, "user");
167
+ if (!userMessage.content?.length) {
168
+ userMessage = { role: "user", content: systemMessage?.content };
169
+ systemMessage = undefined;
170
+ }
171
+ if (!userMessage.content?.length)
172
+ throw new Error("User message cannot be empty.");
173
+ return {
174
+ systemMessage,
175
+ userMessage,
176
+ };
193
177
  }
194
- async getHistories(options) {
195
- const { agent } = options;
196
- const afs = agent?.afs;
197
- if (!afs)
198
- return [];
199
- const historyModule = (await afs.listModules()).find((m) => m.module instanceof AFSHistory);
200
- if (!historyModule)
201
- return [];
202
- const history = (await afs.list(historyModule.path, {
203
- limit: agent.historyConfig?.maxItems || 10,
204
- orderBy: [["createdAt", "desc"]],
205
- })).data;
206
- return history
207
- .reverse()
208
- .map((i) => {
209
- if (!i.content)
210
- return;
211
- const { input, output } = i.content;
212
- if (!input || !output)
213
- return;
214
- return [
215
- { role: "user", content: input },
216
- { role: "agent", content: output },
217
- ];
218
- })
219
- .filter(isNonNullable)
220
- .flat();
178
+ mergeMessages(messages, role) {
179
+ const content = [];
180
+ for (const message of messages) {
181
+ if (typeof message.content === "string") {
182
+ content.push({ type: "text", text: message.content });
183
+ }
184
+ else if (Array.isArray(message.content)) {
185
+ content.push(...message.content);
186
+ }
187
+ else if (message.content) {
188
+ throw new Error(`Unsupported message content type: ${typeof message.content}`);
189
+ }
190
+ }
191
+ return { role, content };
221
192
  }
222
- refineMessages(options, messages) {
223
- const { autoReorderSystemMessages, autoMergeSystemMessages } = options.agent ?? {};
224
- if (!autoReorderSystemMessages && !autoMergeSystemMessages)
225
- return messages;
226
- const [systemMessages, otherMessages] = partition(messages, (m) => m.role === "system");
227
- if (!autoMergeSystemMessages) {
228
- return systemMessages.concat(otherMessages);
193
+ async deprecatedMemories(message, options) {
194
+ const messages = [];
195
+ const memories = [];
196
+ if (options.agent && options.context) {
197
+ memories.push(...(await options.agent.retrieveMemories({ search: message }, { context: options.context })));
229
198
  }
230
- const result = [];
231
- if (systemMessages.length) {
232
- result.push({
233
- role: "system",
234
- content: systemMessages
235
- .map((i) => typeof i.content === "string"
236
- ? i.content
237
- : i.content
238
- ?.map((c) => (c.type === "text" ? c.text : null))
239
- .filter(isNonNullable)
240
- .join("\n"))
241
- .join("\n"),
242
- });
199
+ if (options.agent?.useMemoriesFromContext && options.context?.memories?.length) {
200
+ memories.push(...options.context.memories);
243
201
  }
244
- return result.concat(otherMessages);
202
+ if (memories.length)
203
+ messages.push(...(await this.convertMemoriesToMessages(memories, options)));
204
+ return messages;
245
205
  }
246
206
  async convertMemoriesToMessages(memories, options) {
247
207
  const messages = [];
@@ -42,7 +42,7 @@ export declare class AgentMessageTemplate extends ChatMessageTemplate {
42
42
  static from(template?: ChatModelInputMessage["content"], toolCalls?: ChatModelOutputToolCall[], name?: string, options?: FormatOptions, cacheControl?: ChatModelInputMessage["cacheControl"]): AgentMessageTemplate;
43
43
  constructor(content?: ChatModelInputMessage["content"], toolCalls?: ChatModelOutputToolCall[] | undefined, name?: string, options?: FormatOptions, cacheControl?: ChatModelInputMessage["cacheControl"]);
44
44
  format(_variables?: Record<string, unknown>, _options?: FormatOptions): Promise<{
45
- role: "system" | "user" | "agent" | "tool";
45
+ role: "agent" | "user" | "system" | "tool";
46
46
  name: string | undefined;
47
47
  content: ChatModelInputMessageContent | undefined;
48
48
  toolCalls: ChatModelOutputToolCall[] | undefined;
@@ -54,7 +54,7 @@ export declare class ToolMessageTemplate extends ChatMessageTemplate {
54
54
  static from(content: object | string, toolCallId: string, name?: string, options?: FormatOptions, cacheControl?: ChatModelInputMessage["cacheControl"]): ToolMessageTemplate;
55
55
  constructor(content: object | string, toolCallId: string, name?: string, options?: FormatOptions, cacheControl?: ChatModelInputMessage["cacheControl"]);
56
56
  format(_variables?: Record<string, unknown>, _options?: FormatOptions): Promise<{
57
- role: "system" | "user" | "agent" | "tool";
57
+ role: "agent" | "user" | "system" | "tool";
58
58
  name: string | undefined;
59
59
  content: ChatModelInputMessageContent | undefined;
60
60
  toolCallId: string;
@@ -83,21 +83,21 @@ declare const chatMessageSchema: z.ZodUnion<[z.ZodObject<{
83
83
  ttl?: "5m" | "1h" | undefined;
84
84
  }>>;
85
85
  }, "strip", z.ZodTypeAny, {
86
- content: string;
87
86
  role: "system";
87
+ content: string;
88
+ name?: string | undefined;
88
89
  cacheControl?: {
89
90
  type: "ephemeral";
90
91
  ttl?: "5m" | "1h" | undefined;
91
92
  } | undefined;
92
- name?: string | undefined;
93
93
  }, {
94
- content: string;
95
94
  role: "system";
95
+ content: string;
96
+ name?: string | undefined;
96
97
  cacheControl?: {
97
98
  type: "ephemeral";
98
99
  ttl?: "5m" | "1h" | undefined;
99
100
  } | undefined;
100
- name?: string | undefined;
101
101
  }>, z.ZodObject<{
102
102
  role: z.ZodLiteral<"user">;
103
103
  content: z.ZodString;
@@ -113,21 +113,21 @@ declare const chatMessageSchema: z.ZodUnion<[z.ZodObject<{
113
113
  ttl?: "5m" | "1h" | undefined;
114
114
  }>>;
115
115
  }, "strip", z.ZodTypeAny, {
116
- content: string;
117
116
  role: "user";
117
+ content: string;
118
+ name?: string | undefined;
118
119
  cacheControl?: {
119
120
  type: "ephemeral";
120
121
  ttl?: "5m" | "1h" | undefined;
121
122
  } | undefined;
122
- name?: string | undefined;
123
123
  }, {
124
- content: string;
125
124
  role: "user";
125
+ content: string;
126
+ name?: string | undefined;
126
127
  cacheControl?: {
127
128
  type: "ephemeral";
128
129
  ttl?: "5m" | "1h" | undefined;
129
130
  } | undefined;
130
- name?: string | undefined;
131
131
  }>, z.ZodObject<{
132
132
  role: z.ZodLiteral<"agent">;
133
133
  content: z.ZodOptional<z.ZodString>;
@@ -172,6 +172,7 @@ declare const chatMessageSchema: z.ZodUnion<[z.ZodObject<{
172
172
  }>>;
173
173
  }, "strip", z.ZodTypeAny, {
174
174
  role: "agent";
175
+ name?: string | undefined;
175
176
  content?: string | undefined;
176
177
  cacheControl?: {
177
178
  type: "ephemeral";
@@ -185,9 +186,9 @@ declare const chatMessageSchema: z.ZodUnion<[z.ZodObject<{
185
186
  type: "function";
186
187
  id: string;
187
188
  }[] | undefined;
188
- name?: string | undefined;
189
189
  }, {
190
190
  role: "agent";
191
+ name?: string | undefined;
191
192
  content?: string | undefined;
192
193
  cacheControl?: {
193
194
  type: "ephemeral";
@@ -201,7 +202,6 @@ declare const chatMessageSchema: z.ZodUnion<[z.ZodObject<{
201
202
  type: "function";
202
203
  id: string;
203
204
  }[] | undefined;
204
- name?: string | undefined;
205
205
  }>, z.ZodObject<{
206
206
  role: z.ZodLiteral<"tool">;
207
207
  content: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>, string, string | Record<string, unknown>>;
@@ -218,23 +218,23 @@ declare const chatMessageSchema: z.ZodUnion<[z.ZodObject<{
218
218
  ttl?: "5m" | "1h" | undefined;
219
219
  }>>;
220
220
  }, "strip", z.ZodTypeAny, {
221
- content: string;
222
221
  role: "tool";
222
+ content: string;
223
223
  toolCallId: string;
224
+ name?: string | undefined;
224
225
  cacheControl?: {
225
226
  type: "ephemeral";
226
227
  ttl?: "5m" | "1h" | undefined;
227
228
  } | undefined;
228
- name?: string | undefined;
229
229
  }, {
230
- content: string | Record<string, unknown>;
231
230
  role: "tool";
231
+ content: string | Record<string, unknown>;
232
232
  toolCallId: string;
233
+ name?: string | undefined;
233
234
  cacheControl?: {
234
235
  type: "ephemeral";
235
236
  ttl?: "5m" | "1h" | undefined;
236
237
  } | undefined;
237
- name?: string | undefined;
238
238
  }>]>;
239
239
  export declare function safeParseChatMessages(messages: unknown): ChatMessageTemplate[] | undefined;
240
240
  export declare function parseChatMessages(messages: (z.infer<typeof chatMessageSchema> & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.72.0-beta.6",
3
+ "version": "1.72.0-beta.8",
4
4
  "description": "The functional core of agentic AI",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -93,10 +93,10 @@
93
93
  "zod": "^3.25.67",
94
94
  "zod-from-json-schema": "^0.0.5",
95
95
  "zod-to-json-schema": "^3.24.6",
96
- "@aigne/afs": "^1.4.0-beta.3",
97
- "@aigne/afs-history": "^1.2.0-beta.3",
96
+ "@aigne/observability-api": "^0.11.14-beta.1",
98
97
  "@aigne/platform-helpers": "^0.6.7-beta",
99
- "@aigne/observability-api": "^0.11.14-beta.1"
98
+ "@aigne/afs": "^1.4.0-beta.5",
99
+ "@aigne/afs-history": "^1.2.0-beta.5"
100
100
  },
101
101
  "devDependencies": {
102
102
  "@types/bun": "^1.2.22",