@aigne/agent-library 1.15.0 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -27
- package/lib/cjs/default-memory/default-memory-storage/index.d.ts +3 -0
- package/lib/cjs/default-memory/default-memory-storage/index.js +43 -15
- package/lib/cjs/default-memory/default-memory-storage/migrations/001-init.js +6 -0
- package/lib/cjs/default-memory/index.d.ts +27 -1
- package/lib/cjs/default-memory/index.js +82 -28
- package/lib/cjs/fs-memory/index.js +6 -8
- package/lib/dts/default-memory/default-memory-storage/index.d.ts +3 -0
- package/lib/dts/default-memory/index.d.ts +27 -1
- package/lib/esm/default-memory/default-memory-storage/index.d.ts +3 -0
- package/lib/esm/default-memory/default-memory-storage/index.js +44 -16
- package/lib/esm/default-memory/default-memory-storage/migrations/001-init.js +6 -0
- package/lib/esm/default-memory/index.d.ts +27 -1
- package/lib/esm/default-memory/index.js +82 -25
- package/lib/esm/fs-memory/index.js +6 -8
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,24 +1,47 @@
|
|
|
1
|
-
## [1.
|
|
1
|
+
## [1.15.0](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.14.0...agent-library-v1.15.0) (2025-06-24)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Features
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* support observability for cli and blocklet ([#155](https://github.com/AIGNE-io/aigne-framework/issues/155)) ([5baa705](https://github.com/AIGNE-io/aigne-framework/commit/5baa705a33cfdba1efc5ccbe18674c27513ca97d))
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
### Dependencies
|
|
10
|
+
|
|
11
|
+
* The following workspace dependencies were updated
|
|
12
|
+
* dependencies
|
|
13
|
+
* @aigne/core bumped to 1.22.0
|
|
14
|
+
* @aigne/openai bumped to 0.3.4
|
|
15
|
+
|
|
16
|
+
## [1.16.1](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.16.0...agent-library-v1.16.1) (2025-06-25)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* **core:** pass input/output to MemoryAgent directily ([#178](https://github.com/AIGNE-io/aigne-framework/issues/178)) ([3b20e33](https://github.com/AIGNE-io/aigne-framework/commit/3b20e33f1eefc81ac1e009b1afff14fca46644b1))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Dependencies
|
|
25
|
+
|
|
26
|
+
* The following workspace dependencies were updated
|
|
27
|
+
* dependencies
|
|
28
|
+
* @aigne/core bumped to 1.23.1
|
|
29
|
+
* @aigne/openai bumped to 0.3.6
|
|
30
|
+
|
|
31
|
+
## [1.16.0](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.15.0...agent-library-v1.16.0) (2025-06-25)
|
|
9
32
|
|
|
10
33
|
|
|
11
34
|
### Features
|
|
12
35
|
|
|
13
|
-
* support
|
|
36
|
+
* support remember custom fields from message ([#174](https://github.com/AIGNE-io/aigne-framework/issues/174)) ([664069d](https://github.com/AIGNE-io/aigne-framework/commit/664069d343137f69d0c103b2b5eff545ab0051fb))
|
|
14
37
|
|
|
15
38
|
|
|
16
39
|
### Dependencies
|
|
17
40
|
|
|
18
41
|
* The following workspace dependencies were updated
|
|
19
42
|
* dependencies
|
|
20
|
-
* @aigne/core bumped to 1.
|
|
21
|
-
* @aigne/openai bumped to 0.3.
|
|
43
|
+
* @aigne/core bumped to 1.23.0
|
|
44
|
+
* @aigne/openai bumped to 0.3.5
|
|
22
45
|
|
|
23
46
|
## [1.14.0](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.13.2...agent-library-v1.14.0) (2025-06-20)
|
|
24
47
|
|
|
@@ -157,6 +180,15 @@
|
|
|
157
180
|
* @aigne/openai bumped to 0.2.1
|
|
158
181
|
* @aigne/sqlite bumped to 0.1.0
|
|
159
182
|
|
|
183
|
+
|
|
184
|
+
## [1.11.0](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.10.0...agent-library-v1.11.0) (2025-05-27)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
### Features
|
|
188
|
+
|
|
189
|
+
* add schema transform ([#35](https://github.com/AIGNE-io/aigne-framework/issues/35)) ([c7d9a2c](https://github.com/AIGNE-io/aigne-framework/commit/c7d9a2c9fcab8d384d4198db5ff6ba4603846cdf))
|
|
190
|
+
|
|
191
|
+
|
|
160
192
|
## [1.10.0](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.9.0...agent-library-v1.10.0) (2025-05-25)
|
|
161
193
|
|
|
162
194
|
|
|
@@ -295,24 +327,3 @@
|
|
|
295
327
|
### Bug Fixes
|
|
296
328
|
|
|
297
329
|
* rename @aigne/core-next to @aigne/core ([3a81009](https://github.com/AIGNE-io/aigne-framework/commit/3a8100962c81813217b687ae28e8de604419c622))
|
|
298
|
-
|
|
299
|
-
## 1.1.0-beta.17 (2025-3-18)
|
|
300
|
-
|
|
301
|
-
- chore: add support for esm module
|
|
302
|
-
|
|
303
|
-
## 1.1.0-beta.16 (2025-3-18)
|
|
304
|
-
|
|
305
|
-
- chore: add puppeteer in linux need docker_container
|
|
306
|
-
|
|
307
|
-
## 1.1.0-beta.15 (2025-3-18)
|
|
308
|
-
|
|
309
|
-
- chore: make coverage report as text to terminal
|
|
310
|
-
- chore: update contributing docs
|
|
311
|
-
|
|
312
|
-
## 1.1.0-beta.14 (2025-3-18)
|
|
313
|
-
|
|
314
|
-
- chore(example): add code-execution example
|
|
315
|
-
|
|
316
|
-
## 1.1.0-beta.13 (2025-3-18)
|
|
317
|
-
|
|
318
|
-
- feat: add OrchestratorAgent in agent library
|
|
@@ -5,6 +5,7 @@ import { MemoryStorage } from "../storage.js";
|
|
|
5
5
|
export interface DefaultMemoryStorageOptions {
|
|
6
6
|
url?: string;
|
|
7
7
|
getSessionId?: (context: Context) => PromiseOrValue<string>;
|
|
8
|
+
enableFTS?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
10
11
|
options?: DefaultMemoryStorageOptions | undefined;
|
|
@@ -14,6 +15,7 @@ export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
|
14
15
|
get db(): Promise<SqliteRemoteDatabase<Record<string, never>>>;
|
|
15
16
|
private convertMemory;
|
|
16
17
|
search(query: {
|
|
18
|
+
search?: string;
|
|
17
19
|
limit?: number;
|
|
18
20
|
}, { context }: AgentInvokeOptions): Promise<{
|
|
19
21
|
result: Memory[];
|
|
@@ -21,4 +23,5 @@ export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
|
21
23
|
create(memory: Pick<Memory, "content">, { context }: AgentInvokeOptions): Promise<{
|
|
22
24
|
result: Memory;
|
|
23
25
|
}>;
|
|
26
|
+
protected segment(str: string): string[];
|
|
24
27
|
}
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DefaultMemoryStorage = void 0;
|
|
4
4
|
const sqlite_1 = require("@aigne/sqlite");
|
|
5
5
|
const drizzle_orm_1 = require("drizzle-orm");
|
|
6
|
+
const uuid_1 = require("uuid");
|
|
7
|
+
const yaml_1 = require("yaml");
|
|
6
8
|
const storage_js_1 = require("../storage.js");
|
|
7
9
|
const migrate_js_1 = require("./migrate.js");
|
|
8
10
|
const memory_js_1 = require("./models/memory.js");
|
|
@@ -35,13 +37,23 @@ class DefaultMemoryStorage extends storage_js_1.MemoryStorage {
|
|
|
35
37
|
const { limit = DEFAULT_MAX_MEMORY_COUNT } = query;
|
|
36
38
|
const sessionId = (await this.options?.getSessionId?.(context)) ?? null;
|
|
37
39
|
const db = await this.db;
|
|
38
|
-
const memories =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const memories = this.options?.enableFTS && query.search
|
|
41
|
+
? await db
|
|
42
|
+
.select()
|
|
43
|
+
.from(memory_js_1.Memories)
|
|
44
|
+
.innerJoin((0, drizzle_orm_1.sql) `Memories_fts`, (0, drizzle_orm_1.sql) `Memories_fts.id = ${memory_js_1.Memories.id}`)
|
|
45
|
+
.where((0, drizzle_orm_1.sql) `Memories_fts MATCH ${drizzle_orm_1.sql.param(this.segment(query.search).join(" OR "))}`)
|
|
46
|
+
.orderBy((0, drizzle_orm_1.sql) `bm25(Memories_fts)`)
|
|
47
|
+
.limit(limit)
|
|
48
|
+
.execute()
|
|
49
|
+
.then((rows) => rows.map((row) => row.Memories))
|
|
50
|
+
: await db
|
|
51
|
+
.select()
|
|
52
|
+
.from(memory_js_1.Memories)
|
|
53
|
+
.where(sessionId ? (0, drizzle_orm_1.eq)(memory_js_1.Memories.sessionId, sessionId) : (0, drizzle_orm_1.isNull)(memory_js_1.Memories.sessionId))
|
|
54
|
+
.orderBy((0, drizzle_orm_1.desc)(memory_js_1.Memories.id))
|
|
55
|
+
.limit(limit)
|
|
56
|
+
.execute();
|
|
45
57
|
return {
|
|
46
58
|
result: memories.reverse().map(this.convertMemory),
|
|
47
59
|
};
|
|
@@ -49,17 +61,33 @@ class DefaultMemoryStorage extends storage_js_1.MemoryStorage {
|
|
|
49
61
|
async create(memory, { context }) {
|
|
50
62
|
const sessionId = (await this.options?.getSessionId?.(context)) ?? null;
|
|
51
63
|
const db = await this.db;
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
const id = (0, uuid_1.v7)();
|
|
65
|
+
const [[result]] = await Promise.all([
|
|
66
|
+
db
|
|
67
|
+
.insert(memory_js_1.Memories)
|
|
68
|
+
.values({
|
|
69
|
+
...memory,
|
|
70
|
+
id,
|
|
71
|
+
content: memory.content,
|
|
72
|
+
sessionId,
|
|
73
|
+
})
|
|
74
|
+
.returning()
|
|
75
|
+
.execute(),
|
|
76
|
+
this.options?.enableFTS &&
|
|
77
|
+
db.run((0, drizzle_orm_1.sql) `\
|
|
78
|
+
insert into Memories_fts (id, content)
|
|
79
|
+
values (${drizzle_orm_1.sql.param(id)}, ${drizzle_orm_1.sql.param(this.segment((0, yaml_1.stringify)(memory.content)).join(" "))})`),
|
|
80
|
+
]);
|
|
60
81
|
if (!result)
|
|
61
82
|
throw new Error("Failed to create memory");
|
|
62
83
|
return { result: this.convertMemory(result) };
|
|
63
84
|
}
|
|
85
|
+
segment(str) {
|
|
86
|
+
return (Array.from(new Intl.Segmenter(undefined, { granularity: "word" }).segment(str))
|
|
87
|
+
.map((i) => i.segment)
|
|
88
|
+
// Remove non-alphanumeric characters and trim whitespace
|
|
89
|
+
.map((i) => i.replace(/[^\p{L}\p{N}\s]/gu, "").trim())
|
|
90
|
+
.filter(Boolean));
|
|
91
|
+
}
|
|
64
92
|
}
|
|
65
93
|
exports.DefaultMemoryStorage = DefaultMemoryStorage;
|
|
@@ -1,10 +1,36 @@
|
|
|
1
|
-
import { MemoryAgent, type MemoryAgentOptions } from "@aigne/core";
|
|
1
|
+
import { type AgentInvokeOptions, type AgentOptions, MemoryAgent, type MemoryAgentOptions, type MemoryRecorderInput, type MemoryRecorderOutput, MemoryRetriever, type MemoryRetrieverInput, type MemoryRetrieverOutput } from "@aigne/core";
|
|
2
2
|
import { type DefaultMemoryStorageOptions } from "./default-memory-storage/index.js";
|
|
3
3
|
import { MemoryStorage } from "./storage.js";
|
|
4
4
|
export interface DefaultMemoryOptions extends Partial<MemoryAgentOptions> {
|
|
5
5
|
storage?: MemoryStorage | DefaultMemoryStorageOptions;
|
|
6
|
+
recorderOptions?: Omit<DefaultMemoryRecorderOptions, "storage">;
|
|
7
|
+
retrieverOptions?: Omit<DefaultMemoryRetrieverOptions, "storage">;
|
|
8
|
+
messageKey?: string | string[];
|
|
6
9
|
}
|
|
7
10
|
export declare class DefaultMemory extends MemoryAgent {
|
|
8
11
|
constructor(options?: DefaultMemoryOptions);
|
|
9
12
|
storage: MemoryStorage;
|
|
10
13
|
}
|
|
14
|
+
export interface DefaultMemoryRetrieverOptions extends AgentOptions<MemoryRetrieverInput, MemoryRetrieverOutput> {
|
|
15
|
+
storage: MemoryStorage;
|
|
16
|
+
defaultRetrieveMemoryCount?: number;
|
|
17
|
+
retrieveFromMessageKey?: string | string[];
|
|
18
|
+
getSearchPattern?: DefaultMemoryRetriever["getSearchPattern"];
|
|
19
|
+
formatMessage?: DefaultMemoryRetriever["formatMessage"];
|
|
20
|
+
formatMemory?: DefaultMemoryRetriever["formatMemory"];
|
|
21
|
+
}
|
|
22
|
+
declare class DefaultMemoryRetriever extends MemoryRetriever {
|
|
23
|
+
constructor(options: DefaultMemoryRetrieverOptions);
|
|
24
|
+
private storage;
|
|
25
|
+
private defaultRetrieveMemoryCount?;
|
|
26
|
+
private retrieveFromMessageKey?;
|
|
27
|
+
private getSearchPattern;
|
|
28
|
+
private formatMessage;
|
|
29
|
+
private formatMemory;
|
|
30
|
+
process(input: MemoryRetrieverInput, options: AgentInvokeOptions): Promise<MemoryRetrieverOutput>;
|
|
31
|
+
}
|
|
32
|
+
export interface DefaultMemoryRecorderOptions extends AgentOptions<MemoryRecorderInput, MemoryRecorderOutput> {
|
|
33
|
+
storage: MemoryStorage;
|
|
34
|
+
rememberFromMessageKey?: string | string[];
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -1,57 +1,111 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.DefaultMemory = void 0;
|
|
7
4
|
const core_1 = require("@aigne/core");
|
|
8
|
-
const
|
|
5
|
+
const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
|
|
9
6
|
const index_js_1 = require("./default-memory-storage/index.js");
|
|
10
7
|
const storage_js_1 = require("./storage.js");
|
|
11
8
|
const DEFAULT_RETRIEVE_MEMORY_COUNT = 10;
|
|
12
9
|
class DefaultMemory extends core_1.MemoryAgent {
|
|
13
10
|
constructor(options = {}) {
|
|
11
|
+
const storage = options.storage instanceof storage_js_1.MemoryStorage
|
|
12
|
+
? options.storage
|
|
13
|
+
: new index_js_1.DefaultMemoryStorage(options.storage);
|
|
14
14
|
super({
|
|
15
15
|
...options,
|
|
16
|
+
recorder: options.recorder ??
|
|
17
|
+
new DefaultMemoryRecorder({
|
|
18
|
+
...options.recorderOptions,
|
|
19
|
+
rememberFromMessageKey: options.recorderOptions?.rememberFromMessageKey ?? options.messageKey,
|
|
20
|
+
storage,
|
|
21
|
+
}),
|
|
22
|
+
retriever: options.retriever ??
|
|
23
|
+
new DefaultMemoryRetriever({
|
|
24
|
+
...options.retrieverOptions,
|
|
25
|
+
retrieveFromMessageKey: options.retrieverOptions?.retrieveFromMessageKey ?? options.messageKey,
|
|
26
|
+
storage,
|
|
27
|
+
}),
|
|
16
28
|
autoUpdate: options.autoUpdate ?? true,
|
|
17
29
|
});
|
|
18
|
-
this.storage =
|
|
19
|
-
options.storage instanceof storage_js_1.MemoryStorage
|
|
20
|
-
? options.storage
|
|
21
|
-
: new index_js_1.DefaultMemoryStorage(options.storage);
|
|
22
|
-
if (!this.recorder)
|
|
23
|
-
this.recorder = new DefaultMemoryRecorder(this);
|
|
24
|
-
if (!this.retriever)
|
|
25
|
-
this.retriever = new DefaultMemoryRetriever(this);
|
|
30
|
+
this.storage = storage;
|
|
26
31
|
}
|
|
27
32
|
storage;
|
|
28
33
|
}
|
|
29
34
|
exports.DefaultMemory = DefaultMemory;
|
|
30
35
|
class DefaultMemoryRetriever extends core_1.MemoryRetriever {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.
|
|
36
|
+
constructor(options) {
|
|
37
|
+
super(options);
|
|
38
|
+
this.storage = options.storage;
|
|
39
|
+
this.defaultRetrieveMemoryCount = options.defaultRetrieveMemoryCount;
|
|
40
|
+
this.retrieveFromMessageKey = options.retrieveFromMessageKey;
|
|
41
|
+
if (options.getSearchPattern)
|
|
42
|
+
this.getSearchPattern = options.getSearchPattern;
|
|
43
|
+
if (options.formatMessage)
|
|
44
|
+
this.formatMessage = options.formatMessage;
|
|
45
|
+
if (options.formatMemory)
|
|
46
|
+
this.formatMemory = options.formatMemory;
|
|
35
47
|
}
|
|
48
|
+
storage;
|
|
49
|
+
defaultRetrieveMemoryCount;
|
|
50
|
+
retrieveFromMessageKey;
|
|
51
|
+
getSearchPattern = (search) => {
|
|
52
|
+
if (!search || typeof search === "string")
|
|
53
|
+
return search;
|
|
54
|
+
const obj = search && this.retrieveFromMessageKey ? (0, type_utils_js_1.pick)(search, this.retrieveFromMessageKey) : search;
|
|
55
|
+
return Object.values(obj)
|
|
56
|
+
.map((v) => (typeof v === "string" ? v : undefined))
|
|
57
|
+
.join("\n");
|
|
58
|
+
};
|
|
59
|
+
formatMessage = (content) => {
|
|
60
|
+
if (!this.retrieveFromMessageKey || !(0, type_utils_js_1.isRecord)(content))
|
|
61
|
+
return content;
|
|
62
|
+
const obj = (0, type_utils_js_1.pick)(content, this.retrieveFromMessageKey);
|
|
63
|
+
return Object.values(obj)
|
|
64
|
+
.map((v) => (typeof v === "string" ? v : undefined))
|
|
65
|
+
.join("\n");
|
|
66
|
+
};
|
|
67
|
+
formatMemory = (content) => {
|
|
68
|
+
if (!(0, type_utils_js_1.isRecord)(content))
|
|
69
|
+
return content;
|
|
70
|
+
if ("input" in content || "output" in content) {
|
|
71
|
+
return {
|
|
72
|
+
user: this.formatMessage(content.input),
|
|
73
|
+
agent: this.formatMessage(content.output),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
};
|
|
36
77
|
async process(input, options) {
|
|
37
|
-
const { result } = await this.
|
|
38
|
-
|
|
78
|
+
const { result } = await this.storage.search({
|
|
79
|
+
...input,
|
|
80
|
+
search: this.getSearchPattern(input.search),
|
|
81
|
+
limit: input.limit ?? this.defaultRetrieveMemoryCount ?? DEFAULT_RETRIEVE_MEMORY_COUNT,
|
|
82
|
+
}, options);
|
|
83
|
+
return { memories: result.map((i) => ({ ...i, content: this.formatMemory(i.content) })) };
|
|
39
84
|
}
|
|
40
85
|
}
|
|
41
86
|
class DefaultMemoryRecorder extends core_1.MemoryRecorder {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
this.
|
|
87
|
+
constructor(options) {
|
|
88
|
+
super(options);
|
|
89
|
+
this.storage = options.storage;
|
|
90
|
+
this.rememberFromMessageKey = options.rememberFromMessageKey;
|
|
46
91
|
}
|
|
92
|
+
storage;
|
|
93
|
+
rememberFromMessageKey;
|
|
47
94
|
async process(input, options) {
|
|
48
95
|
const newMemories = [];
|
|
49
|
-
for (const
|
|
50
|
-
const { result
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
96
|
+
for (const item of input.content) {
|
|
97
|
+
const { result } = await this.storage.create({
|
|
98
|
+
content: {
|
|
99
|
+
input: item.input && this.rememberFromMessageKey
|
|
100
|
+
? (0, type_utils_js_1.pick)(item.input, this.rememberFromMessageKey)
|
|
101
|
+
: item.input,
|
|
102
|
+
output: item.output && this.rememberFromMessageKey
|
|
103
|
+
? (0, type_utils_js_1.pick)(item.output, this.rememberFromMessageKey)
|
|
104
|
+
: item.output,
|
|
105
|
+
source: item.source,
|
|
106
|
+
},
|
|
107
|
+
}, options);
|
|
108
|
+
newMemories.push(result);
|
|
55
109
|
}
|
|
56
110
|
return {
|
|
57
111
|
memories: newMemories,
|
|
@@ -27,20 +27,18 @@ class FSMemory extends index_js_1.MemoryAgent {
|
|
|
27
27
|
const memoryFileName = (0, node_path_1.join)(rootDir, exports.MEMORY_FILE_NAME);
|
|
28
28
|
super({
|
|
29
29
|
...options,
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
this.recorder =
|
|
33
|
-
options.recorder ??
|
|
30
|
+
recorder: options.recorder ??
|
|
34
31
|
new FSMemoryRecorder({
|
|
35
32
|
memoryFileName,
|
|
36
33
|
...options.recorderOptions,
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
options.retriever ??
|
|
34
|
+
}),
|
|
35
|
+
retriever: options.retriever ??
|
|
40
36
|
new FSMemoryRetriever({
|
|
41
37
|
memoryFileName,
|
|
42
38
|
...options.retrieverOptions,
|
|
43
|
-
})
|
|
39
|
+
}),
|
|
40
|
+
autoUpdate: options.autoUpdate ?? true,
|
|
41
|
+
});
|
|
44
42
|
}
|
|
45
43
|
}
|
|
46
44
|
exports.FSMemory = FSMemory;
|
|
@@ -5,6 +5,7 @@ import { MemoryStorage } from "../storage.js";
|
|
|
5
5
|
export interface DefaultMemoryStorageOptions {
|
|
6
6
|
url?: string;
|
|
7
7
|
getSessionId?: (context: Context) => PromiseOrValue<string>;
|
|
8
|
+
enableFTS?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
10
11
|
options?: DefaultMemoryStorageOptions | undefined;
|
|
@@ -14,6 +15,7 @@ export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
|
14
15
|
get db(): Promise<SqliteRemoteDatabase<Record<string, never>>>;
|
|
15
16
|
private convertMemory;
|
|
16
17
|
search(query: {
|
|
18
|
+
search?: string;
|
|
17
19
|
limit?: number;
|
|
18
20
|
}, { context }: AgentInvokeOptions): Promise<{
|
|
19
21
|
result: Memory[];
|
|
@@ -21,4 +23,5 @@ export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
|
21
23
|
create(memory: Pick<Memory, "content">, { context }: AgentInvokeOptions): Promise<{
|
|
22
24
|
result: Memory;
|
|
23
25
|
}>;
|
|
26
|
+
protected segment(str: string): string[];
|
|
24
27
|
}
|
|
@@ -1,10 +1,36 @@
|
|
|
1
|
-
import { MemoryAgent, type MemoryAgentOptions } from "@aigne/core";
|
|
1
|
+
import { type AgentInvokeOptions, type AgentOptions, MemoryAgent, type MemoryAgentOptions, type MemoryRecorderInput, type MemoryRecorderOutput, MemoryRetriever, type MemoryRetrieverInput, type MemoryRetrieverOutput } from "@aigne/core";
|
|
2
2
|
import { type DefaultMemoryStorageOptions } from "./default-memory-storage/index.js";
|
|
3
3
|
import { MemoryStorage } from "./storage.js";
|
|
4
4
|
export interface DefaultMemoryOptions extends Partial<MemoryAgentOptions> {
|
|
5
5
|
storage?: MemoryStorage | DefaultMemoryStorageOptions;
|
|
6
|
+
recorderOptions?: Omit<DefaultMemoryRecorderOptions, "storage">;
|
|
7
|
+
retrieverOptions?: Omit<DefaultMemoryRetrieverOptions, "storage">;
|
|
8
|
+
messageKey?: string | string[];
|
|
6
9
|
}
|
|
7
10
|
export declare class DefaultMemory extends MemoryAgent {
|
|
8
11
|
constructor(options?: DefaultMemoryOptions);
|
|
9
12
|
storage: MemoryStorage;
|
|
10
13
|
}
|
|
14
|
+
export interface DefaultMemoryRetrieverOptions extends AgentOptions<MemoryRetrieverInput, MemoryRetrieverOutput> {
|
|
15
|
+
storage: MemoryStorage;
|
|
16
|
+
defaultRetrieveMemoryCount?: number;
|
|
17
|
+
retrieveFromMessageKey?: string | string[];
|
|
18
|
+
getSearchPattern?: DefaultMemoryRetriever["getSearchPattern"];
|
|
19
|
+
formatMessage?: DefaultMemoryRetriever["formatMessage"];
|
|
20
|
+
formatMemory?: DefaultMemoryRetriever["formatMemory"];
|
|
21
|
+
}
|
|
22
|
+
declare class DefaultMemoryRetriever extends MemoryRetriever {
|
|
23
|
+
constructor(options: DefaultMemoryRetrieverOptions);
|
|
24
|
+
private storage;
|
|
25
|
+
private defaultRetrieveMemoryCount?;
|
|
26
|
+
private retrieveFromMessageKey?;
|
|
27
|
+
private getSearchPattern;
|
|
28
|
+
private formatMessage;
|
|
29
|
+
private formatMemory;
|
|
30
|
+
process(input: MemoryRetrieverInput, options: AgentInvokeOptions): Promise<MemoryRetrieverOutput>;
|
|
31
|
+
}
|
|
32
|
+
export interface DefaultMemoryRecorderOptions extends AgentOptions<MemoryRecorderInput, MemoryRecorderOutput> {
|
|
33
|
+
storage: MemoryStorage;
|
|
34
|
+
rememberFromMessageKey?: string | string[];
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -5,6 +5,7 @@ import { MemoryStorage } from "../storage.js";
|
|
|
5
5
|
export interface DefaultMemoryStorageOptions {
|
|
6
6
|
url?: string;
|
|
7
7
|
getSessionId?: (context: Context) => PromiseOrValue<string>;
|
|
8
|
+
enableFTS?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
10
11
|
options?: DefaultMemoryStorageOptions | undefined;
|
|
@@ -14,6 +15,7 @@ export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
|
14
15
|
get db(): Promise<SqliteRemoteDatabase<Record<string, never>>>;
|
|
15
16
|
private convertMemory;
|
|
16
17
|
search(query: {
|
|
18
|
+
search?: string;
|
|
17
19
|
limit?: number;
|
|
18
20
|
}, { context }: AgentInvokeOptions): Promise<{
|
|
19
21
|
result: Memory[];
|
|
@@ -21,4 +23,5 @@ export declare class DefaultMemoryStorage extends MemoryStorage {
|
|
|
21
23
|
create(memory: Pick<Memory, "content">, { context }: AgentInvokeOptions): Promise<{
|
|
22
24
|
result: Memory;
|
|
23
25
|
}>;
|
|
26
|
+
protected segment(str: string): string[];
|
|
24
27
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { initDatabase } from "@aigne/sqlite";
|
|
2
|
-
import { desc, eq, isNull } from "drizzle-orm";
|
|
2
|
+
import { desc, eq, isNull, sql } from "drizzle-orm";
|
|
3
|
+
import { v7 } from "uuid";
|
|
4
|
+
import { stringify } from "yaml";
|
|
3
5
|
import { MemoryStorage } from "../storage.js";
|
|
4
6
|
import { migrate } from "./migrate.js";
|
|
5
7
|
import { Memories } from "./models/memory.js";
|
|
@@ -32,13 +34,23 @@ export class DefaultMemoryStorage extends MemoryStorage {
|
|
|
32
34
|
const { limit = DEFAULT_MAX_MEMORY_COUNT } = query;
|
|
33
35
|
const sessionId = (await this.options?.getSessionId?.(context)) ?? null;
|
|
34
36
|
const db = await this.db;
|
|
35
|
-
const memories =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const memories = this.options?.enableFTS && query.search
|
|
38
|
+
? await db
|
|
39
|
+
.select()
|
|
40
|
+
.from(Memories)
|
|
41
|
+
.innerJoin(sql `Memories_fts`, sql `Memories_fts.id = ${Memories.id}`)
|
|
42
|
+
.where(sql `Memories_fts MATCH ${sql.param(this.segment(query.search).join(" OR "))}`)
|
|
43
|
+
.orderBy(sql `bm25(Memories_fts)`)
|
|
44
|
+
.limit(limit)
|
|
45
|
+
.execute()
|
|
46
|
+
.then((rows) => rows.map((row) => row.Memories))
|
|
47
|
+
: await db
|
|
48
|
+
.select()
|
|
49
|
+
.from(Memories)
|
|
50
|
+
.where(sessionId ? eq(Memories.sessionId, sessionId) : isNull(Memories.sessionId))
|
|
51
|
+
.orderBy(desc(Memories.id))
|
|
52
|
+
.limit(limit)
|
|
53
|
+
.execute();
|
|
42
54
|
return {
|
|
43
55
|
result: memories.reverse().map(this.convertMemory),
|
|
44
56
|
};
|
|
@@ -46,16 +58,32 @@ export class DefaultMemoryStorage extends MemoryStorage {
|
|
|
46
58
|
async create(memory, { context }) {
|
|
47
59
|
const sessionId = (await this.options?.getSessionId?.(context)) ?? null;
|
|
48
60
|
const db = await this.db;
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
const id = v7();
|
|
62
|
+
const [[result]] = await Promise.all([
|
|
63
|
+
db
|
|
64
|
+
.insert(Memories)
|
|
65
|
+
.values({
|
|
66
|
+
...memory,
|
|
67
|
+
id,
|
|
68
|
+
content: memory.content,
|
|
69
|
+
sessionId,
|
|
70
|
+
})
|
|
71
|
+
.returning()
|
|
72
|
+
.execute(),
|
|
73
|
+
this.options?.enableFTS &&
|
|
74
|
+
db.run(sql `\
|
|
75
|
+
insert into Memories_fts (id, content)
|
|
76
|
+
values (${sql.param(id)}, ${sql.param(this.segment(stringify(memory.content)).join(" "))})`),
|
|
77
|
+
]);
|
|
57
78
|
if (!result)
|
|
58
79
|
throw new Error("Failed to create memory");
|
|
59
80
|
return { result: this.convertMemory(result) };
|
|
60
81
|
}
|
|
82
|
+
segment(str) {
|
|
83
|
+
return (Array.from(new Intl.Segmenter(undefined, { granularity: "word" }).segment(str))
|
|
84
|
+
.map((i) => i.segment)
|
|
85
|
+
// Remove non-alphanumeric characters and trim whitespace
|
|
86
|
+
.map((i) => i.replace(/[^\p{L}\p{N}\s]/gu, "").trim())
|
|
87
|
+
.filter(Boolean));
|
|
88
|
+
}
|
|
61
89
|
}
|
|
@@ -1,10 +1,36 @@
|
|
|
1
|
-
import { MemoryAgent, type MemoryAgentOptions } from "@aigne/core";
|
|
1
|
+
import { type AgentInvokeOptions, type AgentOptions, MemoryAgent, type MemoryAgentOptions, type MemoryRecorderInput, type MemoryRecorderOutput, MemoryRetriever, type MemoryRetrieverInput, type MemoryRetrieverOutput } from "@aigne/core";
|
|
2
2
|
import { type DefaultMemoryStorageOptions } from "./default-memory-storage/index.js";
|
|
3
3
|
import { MemoryStorage } from "./storage.js";
|
|
4
4
|
export interface DefaultMemoryOptions extends Partial<MemoryAgentOptions> {
|
|
5
5
|
storage?: MemoryStorage | DefaultMemoryStorageOptions;
|
|
6
|
+
recorderOptions?: Omit<DefaultMemoryRecorderOptions, "storage">;
|
|
7
|
+
retrieverOptions?: Omit<DefaultMemoryRetrieverOptions, "storage">;
|
|
8
|
+
messageKey?: string | string[];
|
|
6
9
|
}
|
|
7
10
|
export declare class DefaultMemory extends MemoryAgent {
|
|
8
11
|
constructor(options?: DefaultMemoryOptions);
|
|
9
12
|
storage: MemoryStorage;
|
|
10
13
|
}
|
|
14
|
+
export interface DefaultMemoryRetrieverOptions extends AgentOptions<MemoryRetrieverInput, MemoryRetrieverOutput> {
|
|
15
|
+
storage: MemoryStorage;
|
|
16
|
+
defaultRetrieveMemoryCount?: number;
|
|
17
|
+
retrieveFromMessageKey?: string | string[];
|
|
18
|
+
getSearchPattern?: DefaultMemoryRetriever["getSearchPattern"];
|
|
19
|
+
formatMessage?: DefaultMemoryRetriever["formatMessage"];
|
|
20
|
+
formatMemory?: DefaultMemoryRetriever["formatMemory"];
|
|
21
|
+
}
|
|
22
|
+
declare class DefaultMemoryRetriever extends MemoryRetriever {
|
|
23
|
+
constructor(options: DefaultMemoryRetrieverOptions);
|
|
24
|
+
private storage;
|
|
25
|
+
private defaultRetrieveMemoryCount?;
|
|
26
|
+
private retrieveFromMessageKey?;
|
|
27
|
+
private getSearchPattern;
|
|
28
|
+
private formatMessage;
|
|
29
|
+
private formatMemory;
|
|
30
|
+
process(input: MemoryRetrieverInput, options: AgentInvokeOptions): Promise<MemoryRetrieverOutput>;
|
|
31
|
+
}
|
|
32
|
+
export interface DefaultMemoryRecorderOptions extends AgentOptions<MemoryRecorderInput, MemoryRecorderOutput> {
|
|
33
|
+
storage: MemoryStorage;
|
|
34
|
+
rememberFromMessageKey?: string | string[];
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -1,50 +1,107 @@
|
|
|
1
1
|
import { MemoryAgent, MemoryRecorder, MemoryRetriever, } from "@aigne/core";
|
|
2
|
-
import
|
|
2
|
+
import { isRecord, pick } from "@aigne/core/utils/type-utils.js";
|
|
3
3
|
import { DefaultMemoryStorage, } from "./default-memory-storage/index.js";
|
|
4
4
|
import { MemoryStorage } from "./storage.js";
|
|
5
5
|
const DEFAULT_RETRIEVE_MEMORY_COUNT = 10;
|
|
6
6
|
export class DefaultMemory extends MemoryAgent {
|
|
7
7
|
constructor(options = {}) {
|
|
8
|
+
const storage = options.storage instanceof MemoryStorage
|
|
9
|
+
? options.storage
|
|
10
|
+
: new DefaultMemoryStorage(options.storage);
|
|
8
11
|
super({
|
|
9
12
|
...options,
|
|
13
|
+
recorder: options.recorder ??
|
|
14
|
+
new DefaultMemoryRecorder({
|
|
15
|
+
...options.recorderOptions,
|
|
16
|
+
rememberFromMessageKey: options.recorderOptions?.rememberFromMessageKey ?? options.messageKey,
|
|
17
|
+
storage,
|
|
18
|
+
}),
|
|
19
|
+
retriever: options.retriever ??
|
|
20
|
+
new DefaultMemoryRetriever({
|
|
21
|
+
...options.retrieverOptions,
|
|
22
|
+
retrieveFromMessageKey: options.retrieverOptions?.retrieveFromMessageKey ?? options.messageKey,
|
|
23
|
+
storage,
|
|
24
|
+
}),
|
|
10
25
|
autoUpdate: options.autoUpdate ?? true,
|
|
11
26
|
});
|
|
12
|
-
this.storage =
|
|
13
|
-
options.storage instanceof MemoryStorage
|
|
14
|
-
? options.storage
|
|
15
|
-
: new DefaultMemoryStorage(options.storage);
|
|
16
|
-
if (!this.recorder)
|
|
17
|
-
this.recorder = new DefaultMemoryRecorder(this);
|
|
18
|
-
if (!this.retriever)
|
|
19
|
-
this.retriever = new DefaultMemoryRetriever(this);
|
|
27
|
+
this.storage = storage;
|
|
20
28
|
}
|
|
21
29
|
storage;
|
|
22
30
|
}
|
|
23
31
|
class DefaultMemoryRetriever extends MemoryRetriever {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.
|
|
32
|
+
constructor(options) {
|
|
33
|
+
super(options);
|
|
34
|
+
this.storage = options.storage;
|
|
35
|
+
this.defaultRetrieveMemoryCount = options.defaultRetrieveMemoryCount;
|
|
36
|
+
this.retrieveFromMessageKey = options.retrieveFromMessageKey;
|
|
37
|
+
if (options.getSearchPattern)
|
|
38
|
+
this.getSearchPattern = options.getSearchPattern;
|
|
39
|
+
if (options.formatMessage)
|
|
40
|
+
this.formatMessage = options.formatMessage;
|
|
41
|
+
if (options.formatMemory)
|
|
42
|
+
this.formatMemory = options.formatMemory;
|
|
28
43
|
}
|
|
44
|
+
storage;
|
|
45
|
+
defaultRetrieveMemoryCount;
|
|
46
|
+
retrieveFromMessageKey;
|
|
47
|
+
getSearchPattern = (search) => {
|
|
48
|
+
if (!search || typeof search === "string")
|
|
49
|
+
return search;
|
|
50
|
+
const obj = search && this.retrieveFromMessageKey ? pick(search, this.retrieveFromMessageKey) : search;
|
|
51
|
+
return Object.values(obj)
|
|
52
|
+
.map((v) => (typeof v === "string" ? v : undefined))
|
|
53
|
+
.join("\n");
|
|
54
|
+
};
|
|
55
|
+
formatMessage = (content) => {
|
|
56
|
+
if (!this.retrieveFromMessageKey || !isRecord(content))
|
|
57
|
+
return content;
|
|
58
|
+
const obj = pick(content, this.retrieveFromMessageKey);
|
|
59
|
+
return Object.values(obj)
|
|
60
|
+
.map((v) => (typeof v === "string" ? v : undefined))
|
|
61
|
+
.join("\n");
|
|
62
|
+
};
|
|
63
|
+
formatMemory = (content) => {
|
|
64
|
+
if (!isRecord(content))
|
|
65
|
+
return content;
|
|
66
|
+
if ("input" in content || "output" in content) {
|
|
67
|
+
return {
|
|
68
|
+
user: this.formatMessage(content.input),
|
|
69
|
+
agent: this.formatMessage(content.output),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
};
|
|
29
73
|
async process(input, options) {
|
|
30
|
-
const { result } = await this.
|
|
31
|
-
|
|
74
|
+
const { result } = await this.storage.search({
|
|
75
|
+
...input,
|
|
76
|
+
search: this.getSearchPattern(input.search),
|
|
77
|
+
limit: input.limit ?? this.defaultRetrieveMemoryCount ?? DEFAULT_RETRIEVE_MEMORY_COUNT,
|
|
78
|
+
}, options);
|
|
79
|
+
return { memories: result.map((i) => ({ ...i, content: this.formatMemory(i.content) })) };
|
|
32
80
|
}
|
|
33
81
|
}
|
|
34
82
|
class DefaultMemoryRecorder extends MemoryRecorder {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.
|
|
83
|
+
constructor(options) {
|
|
84
|
+
super(options);
|
|
85
|
+
this.storage = options.storage;
|
|
86
|
+
this.rememberFromMessageKey = options.rememberFromMessageKey;
|
|
39
87
|
}
|
|
88
|
+
storage;
|
|
89
|
+
rememberFromMessageKey;
|
|
40
90
|
async process(input, options) {
|
|
41
91
|
const newMemories = [];
|
|
42
|
-
for (const
|
|
43
|
-
const { result
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
92
|
+
for (const item of input.content) {
|
|
93
|
+
const { result } = await this.storage.create({
|
|
94
|
+
content: {
|
|
95
|
+
input: item.input && this.rememberFromMessageKey
|
|
96
|
+
? pick(item.input, this.rememberFromMessageKey)
|
|
97
|
+
: item.input,
|
|
98
|
+
output: item.output && this.rememberFromMessageKey
|
|
99
|
+
? pick(item.output, this.rememberFromMessageKey)
|
|
100
|
+
: item.output,
|
|
101
|
+
source: item.source,
|
|
102
|
+
},
|
|
103
|
+
}, options);
|
|
104
|
+
newMemories.push(result);
|
|
48
105
|
}
|
|
49
106
|
return {
|
|
50
107
|
memories: newMemories,
|
|
@@ -24,20 +24,18 @@ export class FSMemory extends MemoryAgent {
|
|
|
24
24
|
const memoryFileName = join(rootDir, MEMORY_FILE_NAME);
|
|
25
25
|
super({
|
|
26
26
|
...options,
|
|
27
|
-
|
|
28
|
-
});
|
|
29
|
-
this.recorder =
|
|
30
|
-
options.recorder ??
|
|
27
|
+
recorder: options.recorder ??
|
|
31
28
|
new FSMemoryRecorder({
|
|
32
29
|
memoryFileName,
|
|
33
30
|
...options.recorderOptions,
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
options.retriever ??
|
|
31
|
+
}),
|
|
32
|
+
retriever: options.retriever ??
|
|
37
33
|
new FSMemoryRetriever({
|
|
38
34
|
memoryFileName,
|
|
39
35
|
...options.retrieverOptions,
|
|
40
|
-
})
|
|
36
|
+
}),
|
|
37
|
+
autoUpdate: options.autoUpdate ?? true,
|
|
38
|
+
});
|
|
41
39
|
}
|
|
42
40
|
}
|
|
43
41
|
class FSMemoryRetriever extends MemoryRetriever {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/agent-library",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.1",
|
|
4
4
|
"description": "Collection of agent libraries for AIGNE framework",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"uuid": "^11.1.0",
|
|
48
48
|
"yaml": "^2.7.1",
|
|
49
49
|
"zod": "^3.24.4",
|
|
50
|
-
"@aigne/core": "^1.
|
|
50
|
+
"@aigne/core": "^1.23.1",
|
|
51
51
|
"@aigne/sqlite": "^0.1.1",
|
|
52
|
-
"@aigne/openai": "^0.3.
|
|
52
|
+
"@aigne/openai": "^0.3.6"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/bun": "^1.2.12",
|