@botbotgo/agent-harness 0.0.281 → 0.0.283
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/README.md +20 -9
- package/README.zh.md +20 -9
- package/dist/config/catalogs/stores.yaml +1 -1
- package/dist/config/catalogs/vector-stores.yaml +1 -1
- package/dist/config/knowledge/knowledge-runtime.yaml +60 -0
- package/dist/config/runtime/runtime-memory.yaml +3 -3
- package/dist/contracts/runtime.d.ts +9 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/init-project.js +50 -4
- package/dist/knowledge/config.d.ts +11 -0
- package/dist/knowledge/config.js +32 -0
- package/dist/knowledge/contracts.d.ts +45 -0
- package/dist/knowledge/contracts.js +1 -0
- package/dist/knowledge/index.d.ts +4 -0
- package/dist/knowledge/index.js +2 -0
- package/dist/knowledge/module.d.ts +21 -0
- package/dist/knowledge/module.js +594 -0
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/file-store.d.ts +1 -0
- package/dist/persistence/file-store.js +29 -25
- package/dist/persistence/sqlite-store.js +1 -1
- package/dist/runtime/harness/run/resources.js +4 -2
- package/dist/runtime/harness/system/runtime-memory-policy.js +1 -1
- package/dist/runtime/harness/system/runtime-memory-records.js +4 -0
- package/dist/runtime/harness/system/runtime-memory-sync.js +2 -2
- package/dist/runtime/harness/system/thread-memory-sync.js +1 -1
- package/dist/runtime/harness.d.ts +1 -16
- package/dist/runtime/harness.js +95 -613
- package/dist/runtime/maintenance/checkpoint-maintenance.js +2 -1
- package/dist/runtime/maintenance/runtime-record-maintenance.js +2 -1
- package/dist/runtime/support/llamaindex.js +1 -1
- package/dist/runtime/support/runtime-factories.js +6 -3
- package/dist/runtime/support/runtime-layout.d.ts +6 -0
- package/dist/runtime/support/runtime-layout.js +19 -0
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { appendFile, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { ensureDir, fileExists, readJson, writeJson } from "../utils/fs.js";
|
|
4
|
+
import { resolveRuntimeArtifactsRoot } from "../runtime/support/runtime-layout.js";
|
|
4
5
|
function nowIso() {
|
|
5
6
|
return new Date(Date.now()).toISOString();
|
|
6
7
|
}
|
|
@@ -9,39 +10,42 @@ export class FilePersistence {
|
|
|
9
10
|
constructor(runRoot) {
|
|
10
11
|
this.runRoot = runRoot;
|
|
11
12
|
}
|
|
13
|
+
artifactsRoot() {
|
|
14
|
+
return resolveRuntimeArtifactsRoot(this.runRoot);
|
|
15
|
+
}
|
|
12
16
|
threadIndexPath(threadId) {
|
|
13
|
-
return path.join(this.
|
|
17
|
+
return path.join(this.artifactsRoot(), "indexes", "sessions", `${threadId}.json`);
|
|
14
18
|
}
|
|
15
19
|
runIndexPath(runId) {
|
|
16
|
-
return path.join(this.
|
|
20
|
+
return path.join(this.artifactsRoot(), "indexes", "requests", `${runId}.json`);
|
|
17
21
|
}
|
|
18
22
|
approvalIndexPath(approvalId) {
|
|
19
|
-
return path.join(this.
|
|
23
|
+
return path.join(this.artifactsRoot(), "indexes", "approvals", `${approvalId}.json`);
|
|
20
24
|
}
|
|
21
25
|
runQueuePath(runId) {
|
|
22
|
-
return path.join(this.
|
|
26
|
+
return path.join(this.artifactsRoot(), "indexes", "requests-queue", `${runId}.json`);
|
|
23
27
|
}
|
|
24
28
|
runControlPath(runId) {
|
|
25
|
-
return path.join(this.
|
|
29
|
+
return path.join(this.artifactsRoot(), "indexes", "requests-control", `${runId}.json`);
|
|
26
30
|
}
|
|
27
31
|
traceItemsPath(threadId, runId) {
|
|
28
32
|
return path.join(this.runDir(threadId, runId), "trace-items.ndjson");
|
|
29
33
|
}
|
|
30
34
|
async initialize() {
|
|
31
35
|
await Promise.all([
|
|
32
|
-
"indexes/
|
|
33
|
-
"indexes/
|
|
36
|
+
"indexes/sessions",
|
|
37
|
+
"indexes/requests",
|
|
34
38
|
"indexes/approvals",
|
|
35
|
-
"indexes/queue",
|
|
36
|
-
"indexes/
|
|
37
|
-
"
|
|
38
|
-
].map((segment) => ensureDir(path.join(this.
|
|
39
|
+
"indexes/requests-queue",
|
|
40
|
+
"indexes/requests-control",
|
|
41
|
+
"sessions",
|
|
42
|
+
].map((segment) => ensureDir(path.join(this.artifactsRoot(), segment))));
|
|
39
43
|
}
|
|
40
44
|
threadDir(threadId) {
|
|
41
|
-
return path.join(this.
|
|
45
|
+
return path.join(this.artifactsRoot(), "sessions", threadId);
|
|
42
46
|
}
|
|
43
47
|
runDir(threadId, runId) {
|
|
44
|
-
return path.join(this.threadDir(threadId), "
|
|
48
|
+
return path.join(this.threadDir(threadId), "requests", runId);
|
|
45
49
|
}
|
|
46
50
|
async createThread(input) {
|
|
47
51
|
const meta = {
|
|
@@ -58,7 +62,7 @@ export class FilePersistence {
|
|
|
58
62
|
threadId: input.threadId,
|
|
59
63
|
items: [],
|
|
60
64
|
});
|
|
61
|
-
await writeJson(
|
|
65
|
+
await writeJson(this.threadIndexPath(input.threadId), {
|
|
62
66
|
threadId: input.threadId,
|
|
63
67
|
status: input.status,
|
|
64
68
|
latestRunId: input.runId,
|
|
@@ -118,7 +122,7 @@ export class FilePersistence {
|
|
|
118
122
|
hasError: false,
|
|
119
123
|
lastError: null,
|
|
120
124
|
}),
|
|
121
|
-
writeJson(
|
|
125
|
+
writeJson(this.runIndexPath(input.runId), {
|
|
122
126
|
runId: input.runId,
|
|
123
127
|
threadId: input.threadId,
|
|
124
128
|
state: "running",
|
|
@@ -175,7 +179,7 @@ export class FilePersistence {
|
|
|
175
179
|
kind: "langgraph-checkpoint",
|
|
176
180
|
});
|
|
177
181
|
}
|
|
178
|
-
await writeJson(
|
|
182
|
+
await writeJson(this.runIndexPath(runId), {
|
|
179
183
|
runId,
|
|
180
184
|
threadId,
|
|
181
185
|
state,
|
|
@@ -188,7 +192,7 @@ export class FilePersistence {
|
|
|
188
192
|
threadMeta.updatedAt = now;
|
|
189
193
|
threadMeta.latestRunId = runId;
|
|
190
194
|
await writeJson(threadMetaPath, threadMeta);
|
|
191
|
-
await writeJson(
|
|
195
|
+
await writeJson(this.threadIndexPath(threadId), {
|
|
192
196
|
threadId,
|
|
193
197
|
status: state,
|
|
194
198
|
latestRunId: runId,
|
|
@@ -208,7 +212,7 @@ export class FilePersistence {
|
|
|
208
212
|
]);
|
|
209
213
|
}
|
|
210
214
|
async listSessions(filter = {}) {
|
|
211
|
-
const threadIndexDir = path.join(this.
|
|
215
|
+
const threadIndexDir = path.join(this.artifactsRoot(), "indexes", "sessions");
|
|
212
216
|
if (!(await fileExists(threadIndexDir))) {
|
|
213
217
|
return [];
|
|
214
218
|
}
|
|
@@ -253,7 +257,7 @@ export class FilePersistence {
|
|
|
253
257
|
return summaries.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
254
258
|
}
|
|
255
259
|
async listRunIndexes() {
|
|
256
|
-
const runIndexDir = path.join(this.
|
|
260
|
+
const runIndexDir = path.join(this.artifactsRoot(), "indexes", "requests");
|
|
257
261
|
if (!(await fileExists(runIndexDir))) {
|
|
258
262
|
return [];
|
|
259
263
|
}
|
|
@@ -314,7 +318,7 @@ export class FilePersistence {
|
|
|
314
318
|
return this.readRunSummary(index.threadId, index.runId);
|
|
315
319
|
}
|
|
316
320
|
async getSession(threadId) {
|
|
317
|
-
const filePath =
|
|
321
|
+
const filePath = this.threadIndexPath(threadId);
|
|
318
322
|
if (!(await fileExists(filePath))) {
|
|
319
323
|
return null;
|
|
320
324
|
}
|
|
@@ -360,7 +364,7 @@ export class FilePersistence {
|
|
|
360
364
|
return Promise.all(entries.map((entry) => readJson(path.join(eventsDir, entry))));
|
|
361
365
|
}
|
|
362
366
|
async listApprovals(filter = {}) {
|
|
363
|
-
const approvalsDir = path.join(this.
|
|
367
|
+
const approvalsDir = path.join(this.artifactsRoot(), "indexes", "approvals");
|
|
364
368
|
if (!(await fileExists(approvalsDir))) {
|
|
365
369
|
return [];
|
|
366
370
|
}
|
|
@@ -380,7 +384,7 @@ export class FilePersistence {
|
|
|
380
384
|
});
|
|
381
385
|
}
|
|
382
386
|
async getApproval(approvalId) {
|
|
383
|
-
const approvalPath =
|
|
387
|
+
const approvalPath = this.approvalIndexPath(approvalId);
|
|
384
388
|
if (!(await fileExists(approvalPath))) {
|
|
385
389
|
return null;
|
|
386
390
|
}
|
|
@@ -496,7 +500,7 @@ export class FilePersistence {
|
|
|
496
500
|
};
|
|
497
501
|
await Promise.all([
|
|
498
502
|
writeJson(path.join(this.runDir(sessionId, requestId), "approvals", `${record.approvalId}.json`), normalized),
|
|
499
|
-
writeJson(
|
|
503
|
+
writeJson(this.approvalIndexPath(record.approvalId), normalized),
|
|
500
504
|
]);
|
|
501
505
|
}
|
|
502
506
|
async resolveApproval(threadId, runId, approvalId, status) {
|
|
@@ -509,7 +513,7 @@ export class FilePersistence {
|
|
|
509
513
|
};
|
|
510
514
|
await Promise.all([
|
|
511
515
|
writeJson(approvalPath, updated),
|
|
512
|
-
writeJson(
|
|
516
|
+
writeJson(this.approvalIndexPath(approvalId), updated),
|
|
513
517
|
]);
|
|
514
518
|
return updated;
|
|
515
519
|
}
|
|
@@ -668,7 +672,7 @@ export class FilePersistence {
|
|
|
668
672
|
});
|
|
669
673
|
}
|
|
670
674
|
async listExpiredClaimedRuns(cutoffIso) {
|
|
671
|
-
const queueDir = path.join(this.
|
|
675
|
+
const queueDir = path.join(this.artifactsRoot(), "indexes", "requests-queue");
|
|
672
676
|
if (!(await fileExists(queueDir))) {
|
|
673
677
|
return [];
|
|
674
678
|
}
|
|
@@ -111,7 +111,7 @@ export class SqlitePersistence {
|
|
|
111
111
|
}
|
|
112
112
|
async getClient() {
|
|
113
113
|
if (!this.client) {
|
|
114
|
-
await mkdir(this.
|
|
114
|
+
await mkdir(path.dirname(this.dbPath), { recursive: true });
|
|
115
115
|
this.client = createClient({ url: toSqliteUrl(this.dbPath) });
|
|
116
116
|
}
|
|
117
117
|
return this.client;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createCheckpointerForConfig, createStoreForConfig } from "../../support/runtime-factories.js";
|
|
2
2
|
import { resolveCompiledEmbeddingModel, resolveCompiledEmbeddingModelRef } from "../../support/embedding-models.js";
|
|
3
3
|
import { resolveCompiledVectorStore, resolveCompiledVectorStoreRef } from "../../support/vector-stores.js";
|
|
4
|
+
import { resolveRuntimeCheckpointerPath } from "../../support/runtime-layout.js";
|
|
4
5
|
export function resolveStoreFromConfig(stores, storeConfig, runRoot) {
|
|
5
6
|
const cacheKey = storeConfig ? `${runRoot}:${JSON.stringify(storeConfig)}` : undefined;
|
|
6
7
|
if (!storeConfig || !cacheKey) {
|
|
@@ -42,12 +43,13 @@ export async function resolveVectorStore(workspace, vectorStores, vectorStoreRef
|
|
|
42
43
|
return resolved;
|
|
43
44
|
}
|
|
44
45
|
export function resolveCheckpointer(checkpointers, binding) {
|
|
45
|
-
const key = `${binding.harnessRuntime.runRoot}:${JSON.stringify(binding.harnessRuntime.checkpointer ?? { kind: "FileCheckpointer", path: "checkpoints.json" })}`;
|
|
46
|
+
const key = `${binding.harnessRuntime.runRoot}:${JSON.stringify(binding.harnessRuntime.checkpointer ?? { kind: "FileCheckpointer", path: resolveRuntimeCheckpointerPath(binding.harnessRuntime.runRoot, "checkpoints.json") })}`;
|
|
46
47
|
const existing = checkpointers.get(key);
|
|
47
48
|
if (existing) {
|
|
48
49
|
return existing;
|
|
49
50
|
}
|
|
50
|
-
const resolvedConfig = binding.harnessRuntime.checkpointer ??
|
|
51
|
+
const resolvedConfig = binding.harnessRuntime.checkpointer ??
|
|
52
|
+
{ kind: "FileCheckpointer", path: resolveRuntimeCheckpointerPath(binding.harnessRuntime.runRoot, "checkpoints.json") };
|
|
51
53
|
if (typeof resolvedConfig === "boolean") {
|
|
52
54
|
checkpointers.set(key, resolvedConfig);
|
|
53
55
|
return resolvedConfig;
|
|
@@ -35,7 +35,7 @@ export function readRuntimeMemoryPolicyConfig(runtimeMemory, workspaceRoot) {
|
|
|
35
35
|
maxPromptMemories: asPositiveInteger(retrieval?.maxPromptMemories) ?? 8,
|
|
36
36
|
},
|
|
37
37
|
namespaces: {
|
|
38
|
-
thread: asString(namespaces?.
|
|
38
|
+
thread: asString(namespaces?.sessions) ?? "memories/sessions/{sessionId}",
|
|
39
39
|
workspace: asString(namespaces?.workspaces) ?? `memories/workspaces/${workspaceId}`,
|
|
40
40
|
agent: asString(namespaces?.agents) ?? "memories/agents/{agentId}",
|
|
41
41
|
user: asString(namespaces?.users) ?? "memories/users/{userId}",
|
|
@@ -440,6 +440,10 @@ export async function persistStructuredMemoryRecords(options) {
|
|
|
440
440
|
const evaluated = evaluateDecision(existing, incoming, options.recordedAt);
|
|
441
441
|
const recordsToWrite = [evaluated.primaryRecord, ...evaluated.additionalRecords];
|
|
442
442
|
for (const record of recordsToWrite) {
|
|
443
|
+
const priorRecord = existingRecords.find((item) => item.id === record.id);
|
|
444
|
+
if (priorRecord) {
|
|
445
|
+
await deleteRecordIndexes(options.store, priorRecord);
|
|
446
|
+
}
|
|
443
447
|
await putRecordWithIndexes(options.store, record, options.recordedAt);
|
|
444
448
|
const existingIndex = existingRecords.findIndex((item) => item.id === record.id);
|
|
445
449
|
if (existingIndex >= 0) {
|
|
@@ -192,10 +192,10 @@ export class RuntimeMemorySync {
|
|
|
192
192
|
await this.store.put(this.resolveThreadNamespace(threadId), "durable-summary.md", { content: `${digestMarkdown}\n` });
|
|
193
193
|
}
|
|
194
194
|
resolveThreadNamespace(threadId) {
|
|
195
|
-
return this.options.resolveThreadNamespace ? this.options.resolveThreadNamespace(threadId) : ["memories", "
|
|
195
|
+
return this.options.resolveThreadNamespace ? this.options.resolveThreadNamespace(threadId) : ["memories", "sessions", threadId];
|
|
196
196
|
}
|
|
197
197
|
resolveRunNamespace(threadId) {
|
|
198
|
-
return this.options.resolveRunNamespace ? this.options.resolveRunNamespace(threadId) : ["memories", "
|
|
198
|
+
return this.options.resolveRunNamespace ? this.options.resolveRunNamespace(threadId) : ["memories", "requests", threadId];
|
|
199
199
|
}
|
|
200
200
|
async close() {
|
|
201
201
|
await Promise.allSettled(Array.from(this.pending));
|
|
@@ -47,7 +47,7 @@ function formatOpenApprovalsSection(approvals) {
|
|
|
47
47
|
return lines;
|
|
48
48
|
}
|
|
49
49
|
function resolveThreadNamespace(threadId, resolver) {
|
|
50
|
-
return resolver ? resolver(threadId) : ["memories", "
|
|
50
|
+
return resolver ? resolver(threadId) : ["memories", "sessions", threadId];
|
|
51
51
|
}
|
|
52
52
|
const THREAD_MEMORY_EVENT_TYPES = new Set([
|
|
53
53
|
"run.state.changed",
|
|
@@ -32,6 +32,7 @@ export declare class AgentHarnessRuntime {
|
|
|
32
32
|
private readonly mem0SemanticRecall;
|
|
33
33
|
private readonly runtimeMemoryFormationConfig;
|
|
34
34
|
private readonly runtimeMemoryManager;
|
|
35
|
+
private readonly knowledgeModule;
|
|
35
36
|
private readonly runtimeMemoryFormationSync;
|
|
36
37
|
private readonly unregisterRuntimeMemoryFormationSync;
|
|
37
38
|
private readonly resolvedRuntimeAdapterOptions;
|
|
@@ -136,24 +137,8 @@ export declare class AgentHarnessRuntime {
|
|
|
136
137
|
private invokeWithHistory;
|
|
137
138
|
private resolveMemoryNamespace;
|
|
138
139
|
private getWorkspaceId;
|
|
139
|
-
private summarizeMemoryContent;
|
|
140
|
-
private matchesMemoryFilters;
|
|
141
|
-
private resolveRecallScopes;
|
|
142
|
-
private matchesRecallScope;
|
|
143
|
-
private getMemoryScopeBoost;
|
|
144
|
-
private memoryFreshnessBoost;
|
|
145
|
-
private scoreStructuredRecord;
|
|
146
|
-
private normalizeMemoryDedupKey;
|
|
147
|
-
private inferMem0MemoryKind;
|
|
148
|
-
private inferMem0MemoryScope;
|
|
149
|
-
private createMem0MemoryRecord;
|
|
150
|
-
private rankRecallCandidates;
|
|
151
|
-
private rebuildRuntimeMemoryVectorIndex;
|
|
152
|
-
private refreshStructuredMemoryScope;
|
|
153
140
|
private buildRuntimeMemoryContext;
|
|
154
141
|
private persistRuntimeMemoryCandidates;
|
|
155
|
-
private persistStructuredMemoryCandidates;
|
|
156
|
-
private appendMemoryDigest;
|
|
157
142
|
private resolvePersistedRunPriority;
|
|
158
143
|
private enqueuePendingRunSlot;
|
|
159
144
|
private executeQueuedRun;
|