@aigne/core 1.63.0-beta.3 → 1.63.0-beta.5

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.63.0-beta.5](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta.4...core-v1.63.0-beta.5) (2025-10-13)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **core:** auto merge multiple system messages ([#619](https://github.com/AIGNE-io/aigne-framework/issues/619)) ([e9e62c0](https://github.com/AIGNE-io/aigne-framework/commit/e9e62c03c45f5a9b75d44a07588b2b179e262aad))
9
+
10
+ ## [1.63.0-beta.4](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta.3...core-v1.63.0-beta.4) (2025-10-12)
11
+
12
+
13
+ ### Features
14
+
15
+ * **afs:** add configurable history injection to AFS system ([#611](https://github.com/AIGNE-io/aigne-framework/issues/611)) ([689b5d7](https://github.com/AIGNE-io/aigne-framework/commit/689b5d76d8cc82f548e8be74e63f18e7a6216c31))
16
+
3
17
  ## [1.63.0-beta.3](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta.2...core-v1.63.0-beta.3) (2025-10-11)
4
18
 
5
19
 
@@ -122,6 +122,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
122
122
  */
123
123
  memory?: MemoryAgent | MemoryAgent[];
124
124
  afs?: true | AFSOptions | AFS | ((afs: AFS) => AFS);
125
+ afsConfig?: AFSConfig;
125
126
  asyncMemoryRecord?: boolean;
126
127
  /**
127
128
  * Maximum number of memory items to retrieve
@@ -130,6 +131,10 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
130
131
  hooks?: AgentHooks<I, O> | AgentHooks<I, O>[];
131
132
  retryOnError?: Agent<I, O>["retryOnError"] | boolean;
132
133
  }
134
+ export interface AFSConfig {
135
+ injectHistory?: boolean;
136
+ historyWindowSize?: number;
137
+ }
133
138
  export declare const agentOptionsSchema: ZodObject<{
134
139
  [key in keyof AgentOptions]: ZodType<AgentOptions[key]>;
135
140
  }>;
@@ -212,6 +217,7 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
212
217
  */
213
218
  readonly memories: MemoryAgent[];
214
219
  afs?: AFS;
220
+ afsConfig?: AFSConfig;
215
221
  asyncMemoryRecord?: boolean;
216
222
  tag?: string;
217
223
  /**
@@ -161,6 +161,7 @@ class Agent {
161
161
  : options.afs instanceof afs_1.AFS
162
162
  ? options.afs
163
163
  : new afs_1.AFS(options.afs);
164
+ this.afsConfig = options.afsConfig;
164
165
  this.asyncMemoryRecord = options.asyncMemoryRecord;
165
166
  this.maxRetrieveMemoryCount = options.maxRetrieveMemoryCount;
166
167
  this.hooks = (0, type_utils_js_1.flat)(options.hooks);
@@ -179,6 +180,7 @@ class Agent {
179
180
  */
180
181
  memories = [];
181
182
  afs;
183
+ afsConfig;
182
184
  asyncMemoryRecord;
183
185
  tag;
184
186
  /**
@@ -1,6 +1,6 @@
1
1
  import type { AFSOptions } from "@aigne/afs";
2
2
  import { type ZodType, z } from "zod";
3
- import type { AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
3
+ import type { AFSConfig, AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
4
4
  import { AIAgentToolChoice } from "../agents/ai-agent.js";
5
5
  import { type Role } from "../agents/chat-model.js";
6
6
  import { ProcessMode, type ReflectionMode } from "../agents/team-agent.js";
@@ -44,6 +44,7 @@ export interface BaseAgentSchema {
44
44
  afs?: boolean | (Omit<AFSOptions, "modules"> & {
45
45
  modules?: AFSModuleSchema[];
46
46
  });
47
+ afsConfig?: AFSConfig;
47
48
  }
48
49
  export type Instructions = {
49
50
  role: Exclude<Role, "tool">;
@@ -68,6 +68,10 @@ async function parseAgentFile(path, data) {
68
68
  ]))),
69
69
  })),
70
70
  ])),
71
+ afsConfig: (0, schema_js_1.optionalize)((0, schema_js_1.camelizeSchema)(zod_1.z.object({
72
+ injectHistory: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
73
+ historyWindowSize: (0, schema_js_1.optionalize)(zod_1.z.number().int().min(1)),
74
+ }))),
71
75
  });
72
76
  const instructionItemSchema = zod_1.z.union([
73
77
  zod_1.z.object({
@@ -31,6 +31,7 @@ export declare class PromptBuilder {
31
31
  prompt: string;
32
32
  }>;
33
33
  private buildMessages;
34
+ private mergeSystemMessages;
34
35
  private convertMemoriesToMessages;
35
36
  private buildResponseFormat;
36
37
  private buildTools;
@@ -102,17 +102,19 @@ class PromptBuilder {
102
102
  memories.push(...options.context.memories);
103
103
  }
104
104
  if (options.agent?.afs) {
105
- const history = await options.agent.afs.list(afs_1.AFSHistory.Path, {
106
- limit: options.agent.maxRetrieveMemoryCount ?? 10,
107
- orderBy: [["createdAt", "desc"]],
108
- });
109
- if (message) {
110
- const result = await options.agent.afs.search("/", message);
111
- const ms = result.list.map((entry) => ({ content: (0, yaml_1.stringify)(entry.content) }));
112
- memories.push(...ms);
113
- }
114
- memories.push(...history.list.filter((i) => (0, type_utils_js_1.isNonNullable)(i.content)));
115
105
  messages.push(template_js_1.SystemMessageTemplate.from(await (0, afs_builtin_prompt_js_1.getAFSSystemPrompt)(options.agent.afs)));
106
+ if (options.agent.afsConfig?.injectHistory) {
107
+ const history = await options.agent.afs.list(afs_1.AFSHistory.Path, {
108
+ limit: options.agent.afsConfig.historyWindowSize || 10,
109
+ orderBy: [["createdAt", "desc"]],
110
+ });
111
+ if (message) {
112
+ const result = await options.agent.afs.search("/", message);
113
+ const ms = result.list.map((entry) => ({ content: (0, yaml_1.stringify)(entry.content) }));
114
+ memories.push(...ms);
115
+ }
116
+ memories.push(...history.list.filter((i) => (0, type_utils_js_1.isNonNullable)(i.content)));
117
+ }
116
118
  }
117
119
  if (memories.length)
118
120
  messages.push(...(await this.convertMemoriesToMessages(memories, options)));
@@ -136,7 +138,25 @@ class PromptBuilder {
136
138
  content.push(...files);
137
139
  messages.push({ role: "user", content });
138
140
  }
139
- return messages;
141
+ return this.mergeSystemMessages(messages);
142
+ }
143
+ mergeSystemMessages(messages) {
144
+ const [systemMessages, otherMessages] = (0, type_utils_js_1.partition)(messages, (m) => m.role === "system");
145
+ const result = [];
146
+ if (systemMessages.length) {
147
+ result.push({
148
+ role: "system",
149
+ content: systemMessages
150
+ .map((i) => typeof i.content === "string"
151
+ ? i.content
152
+ : i.content
153
+ ?.map((c) => (c.type === "text" ? c.text : null))
154
+ .filter(type_utils_js_1.isNonNullable)
155
+ .join("\n"))
156
+ .join("\n"),
157
+ });
158
+ }
159
+ return result.concat(otherMessages);
140
160
  }
141
161
  async convertMemoriesToMessages(memories, options) {
142
162
  const messages = [];
@@ -27,3 +27,4 @@ export declare function createAccessorArray<T>(array: T[], accessor: (array: T[]
27
27
  export declare function checkArguments<T extends ZodType>(prefix: string, schema: T, args: unknown): z.infer<T>;
28
28
  export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error: string | Error | ((error: Error) => Error)): P;
29
29
  export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error?: Nullish<string | Error | ((error: Error) => Nullish<Error>)>): P | undefined;
30
+ export declare function partition<T>(array: T[], predicate: (item: T) => boolean): [T[], T[]];
@@ -17,6 +17,7 @@ exports.flat = flat;
17
17
  exports.createAccessorArray = createAccessorArray;
18
18
  exports.checkArguments = checkArguments;
19
19
  exports.tryOrThrow = tryOrThrow;
20
+ exports.partition = partition;
20
21
  const zod_1 = require("zod");
21
22
  function isNil(value) {
22
23
  return value === null || value === undefined;
@@ -196,3 +197,16 @@ function tryOrThrow(fn, error) {
196
197
  throw error;
197
198
  }
198
199
  }
200
+ function partition(array, predicate) {
201
+ const pass = [];
202
+ const fail = [];
203
+ for (const item of array) {
204
+ if (predicate(item)) {
205
+ pass.push(item);
206
+ }
207
+ else {
208
+ fail.push(item);
209
+ }
210
+ }
211
+ return [pass, fail];
212
+ }
@@ -122,6 +122,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
122
122
  */
123
123
  memory?: MemoryAgent | MemoryAgent[];
124
124
  afs?: true | AFSOptions | AFS | ((afs: AFS) => AFS);
125
+ afsConfig?: AFSConfig;
125
126
  asyncMemoryRecord?: boolean;
126
127
  /**
127
128
  * Maximum number of memory items to retrieve
@@ -130,6 +131,10 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
130
131
  hooks?: AgentHooks<I, O> | AgentHooks<I, O>[];
131
132
  retryOnError?: Agent<I, O>["retryOnError"] | boolean;
132
133
  }
134
+ export interface AFSConfig {
135
+ injectHistory?: boolean;
136
+ historyWindowSize?: number;
137
+ }
133
138
  export declare const agentOptionsSchema: ZodObject<{
134
139
  [key in keyof AgentOptions]: ZodType<AgentOptions[key]>;
135
140
  }>;
@@ -212,6 +217,7 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
212
217
  */
213
218
  readonly memories: MemoryAgent[];
214
219
  afs?: AFS;
220
+ afsConfig?: AFSConfig;
215
221
  asyncMemoryRecord?: boolean;
216
222
  tag?: string;
217
223
  /**
@@ -1,6 +1,6 @@
1
1
  import type { AFSOptions } from "@aigne/afs";
2
2
  import { type ZodType, z } from "zod";
3
- import type { AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
3
+ import type { AFSConfig, AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
4
4
  import { AIAgentToolChoice } from "../agents/ai-agent.js";
5
5
  import { type Role } from "../agents/chat-model.js";
6
6
  import { ProcessMode, type ReflectionMode } from "../agents/team-agent.js";
@@ -44,6 +44,7 @@ export interface BaseAgentSchema {
44
44
  afs?: boolean | (Omit<AFSOptions, "modules"> & {
45
45
  modules?: AFSModuleSchema[];
46
46
  });
47
+ afsConfig?: AFSConfig;
47
48
  }
48
49
  export type Instructions = {
49
50
  role: Exclude<Role, "tool">;
@@ -31,6 +31,7 @@ export declare class PromptBuilder {
31
31
  prompt: string;
32
32
  }>;
33
33
  private buildMessages;
34
+ private mergeSystemMessages;
34
35
  private convertMemoriesToMessages;
35
36
  private buildResponseFormat;
36
37
  private buildTools;
@@ -27,3 +27,4 @@ export declare function createAccessorArray<T>(array: T[], accessor: (array: T[]
27
27
  export declare function checkArguments<T extends ZodType>(prefix: string, schema: T, args: unknown): z.infer<T>;
28
28
  export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error: string | Error | ((error: Error) => Error)): P;
29
29
  export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error?: Nullish<string | Error | ((error: Error) => Nullish<Error>)>): P | undefined;
30
+ export declare function partition<T>(array: T[], predicate: (item: T) => boolean): [T[], T[]];
@@ -122,6 +122,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
122
122
  */
123
123
  memory?: MemoryAgent | MemoryAgent[];
124
124
  afs?: true | AFSOptions | AFS | ((afs: AFS) => AFS);
125
+ afsConfig?: AFSConfig;
125
126
  asyncMemoryRecord?: boolean;
126
127
  /**
127
128
  * Maximum number of memory items to retrieve
@@ -130,6 +131,10 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
130
131
  hooks?: AgentHooks<I, O> | AgentHooks<I, O>[];
131
132
  retryOnError?: Agent<I, O>["retryOnError"] | boolean;
132
133
  }
134
+ export interface AFSConfig {
135
+ injectHistory?: boolean;
136
+ historyWindowSize?: number;
137
+ }
133
138
  export declare const agentOptionsSchema: ZodObject<{
134
139
  [key in keyof AgentOptions]: ZodType<AgentOptions[key]>;
135
140
  }>;
@@ -212,6 +217,7 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
212
217
  */
213
218
  readonly memories: MemoryAgent[];
214
219
  afs?: AFS;
220
+ afsConfig?: AFSConfig;
215
221
  asyncMemoryRecord?: boolean;
216
222
  tag?: string;
217
223
  /**
@@ -113,6 +113,7 @@ export class Agent {
113
113
  : options.afs instanceof AFS
114
114
  ? options.afs
115
115
  : new AFS(options.afs);
116
+ this.afsConfig = options.afsConfig;
116
117
  this.asyncMemoryRecord = options.asyncMemoryRecord;
117
118
  this.maxRetrieveMemoryCount = options.maxRetrieveMemoryCount;
118
119
  this.hooks = flat(options.hooks);
@@ -131,6 +132,7 @@ export class Agent {
131
132
  */
132
133
  memories = [];
133
134
  afs;
135
+ afsConfig;
134
136
  asyncMemoryRecord;
135
137
  tag;
136
138
  /**
@@ -1,6 +1,6 @@
1
1
  import type { AFSOptions } from "@aigne/afs";
2
2
  import { type ZodType, z } from "zod";
3
- import type { AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
3
+ import type { AFSConfig, AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
4
4
  import { AIAgentToolChoice } from "../agents/ai-agent.js";
5
5
  import { type Role } from "../agents/chat-model.js";
6
6
  import { ProcessMode, type ReflectionMode } from "../agents/team-agent.js";
@@ -44,6 +44,7 @@ export interface BaseAgentSchema {
44
44
  afs?: boolean | (Omit<AFSOptions, "modules"> & {
45
45
  modules?: AFSModuleSchema[];
46
46
  });
47
+ afsConfig?: AFSConfig;
47
48
  }
48
49
  export type Instructions = {
49
50
  role: Exclude<Role, "tool">;
@@ -64,6 +64,10 @@ export async function parseAgentFile(path, data) {
64
64
  ]))),
65
65
  })),
66
66
  ])),
67
+ afsConfig: optionalize(camelizeSchema(z.object({
68
+ injectHistory: optionalize(z.boolean()),
69
+ historyWindowSize: optionalize(z.number().int().min(1)),
70
+ }))),
67
71
  });
68
72
  const instructionItemSchema = z.union([
69
73
  z.object({
@@ -31,6 +31,7 @@ export declare class PromptBuilder {
31
31
  prompt: string;
32
32
  }>;
33
33
  private buildMessages;
34
+ private mergeSystemMessages;
34
35
  private convertMemoriesToMessages;
35
36
  private buildResponseFormat;
36
37
  private buildTools;
@@ -8,7 +8,7 @@ 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, unique } from "../utils/type-utils.js";
11
+ import { checkArguments, flat, isNonNullable, isRecord, partition, unique, } from "../utils/type-utils.js";
12
12
  import { getAFSSystemPrompt } from "./prompts/afs-builtin-prompt.js";
13
13
  import { MEMORY_MESSAGE_TEMPLATE } from "./prompts/memory-message-template.js";
14
14
  import { STRUCTURED_STREAM_INSTRUCTIONS } from "./prompts/structured-stream-instructions.js";
@@ -99,17 +99,19 @@ export class PromptBuilder {
99
99
  memories.push(...options.context.memories);
100
100
  }
101
101
  if (options.agent?.afs) {
102
- const history = await options.agent.afs.list(AFSHistory.Path, {
103
- limit: options.agent.maxRetrieveMemoryCount ?? 10,
104
- orderBy: [["createdAt", "desc"]],
105
- });
106
- if (message) {
107
- const result = await options.agent.afs.search("/", message);
108
- const ms = result.list.map((entry) => ({ content: stringify(entry.content) }));
109
- memories.push(...ms);
110
- }
111
- memories.push(...history.list.filter((i) => isNonNullable(i.content)));
112
102
  messages.push(SystemMessageTemplate.from(await getAFSSystemPrompt(options.agent.afs)));
103
+ if (options.agent.afsConfig?.injectHistory) {
104
+ const history = await options.agent.afs.list(AFSHistory.Path, {
105
+ limit: options.agent.afsConfig.historyWindowSize || 10,
106
+ orderBy: [["createdAt", "desc"]],
107
+ });
108
+ if (message) {
109
+ const result = await options.agent.afs.search("/", message);
110
+ const ms = result.list.map((entry) => ({ content: stringify(entry.content) }));
111
+ memories.push(...ms);
112
+ }
113
+ memories.push(...history.list.filter((i) => isNonNullable(i.content)));
114
+ }
113
115
  }
114
116
  if (memories.length)
115
117
  messages.push(...(await this.convertMemoriesToMessages(memories, options)));
@@ -133,7 +135,25 @@ export class PromptBuilder {
133
135
  content.push(...files);
134
136
  messages.push({ role: "user", content });
135
137
  }
136
- return messages;
138
+ return this.mergeSystemMessages(messages);
139
+ }
140
+ mergeSystemMessages(messages) {
141
+ const [systemMessages, otherMessages] = partition(messages, (m) => m.role === "system");
142
+ const result = [];
143
+ if (systemMessages.length) {
144
+ result.push({
145
+ role: "system",
146
+ content: systemMessages
147
+ .map((i) => typeof i.content === "string"
148
+ ? i.content
149
+ : i.content
150
+ ?.map((c) => (c.type === "text" ? c.text : null))
151
+ .filter(isNonNullable)
152
+ .join("\n"))
153
+ .join("\n"),
154
+ });
155
+ }
156
+ return result.concat(otherMessages);
137
157
  }
138
158
  async convertMemoriesToMessages(memories, options) {
139
159
  const messages = [];
@@ -27,3 +27,4 @@ export declare function createAccessorArray<T>(array: T[], accessor: (array: T[]
27
27
  export declare function checkArguments<T extends ZodType>(prefix: string, schema: T, args: unknown): z.infer<T>;
28
28
  export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error: string | Error | ((error: Error) => Error)): P;
29
29
  export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error?: Nullish<string | Error | ((error: Error) => Nullish<Error>)>): P | undefined;
30
+ export declare function partition<T>(array: T[], predicate: (item: T) => boolean): [T[], T[]];
@@ -177,3 +177,16 @@ export function tryOrThrow(fn, error) {
177
177
  throw error;
178
178
  }
179
179
  }
180
+ export function partition(array, predicate) {
181
+ const pass = [];
182
+ const fail = [];
183
+ for (const item of array) {
184
+ if (predicate(item)) {
185
+ pass.push(item);
186
+ }
187
+ else {
188
+ fail.push(item);
189
+ }
190
+ }
191
+ return [pass, fail];
192
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.63.0-beta.3",
3
+ "version": "1.63.0-beta.5",
4
4
  "description": "The functional core of agentic AI",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -92,9 +92,9 @@
92
92
  "zod": "^3.25.67",
93
93
  "zod-from-json-schema": "^0.0.5",
94
94
  "zod-to-json-schema": "^3.24.6",
95
+ "@aigne/afs": "^1.1.0-beta",
95
96
  "@aigne/observability-api": "^0.11.2-beta.1",
96
- "@aigne/platform-helpers": "^0.6.3",
97
- "@aigne/afs": "^1.1.0-beta"
97
+ "@aigne/platform-helpers": "^0.6.3"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@types/bun": "^1.2.22",