@botbotgo/agent-harness 0.0.153 → 0.0.155
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 +40 -3
- package/README.zh.md +47 -3
- package/dist/api.d.ts +4 -1
- package/dist/api.js +6 -0
- package/dist/config/catalogs/stores.yaml +3 -3
- package/dist/config/catalogs/vector-stores.yaml +8 -1
- package/dist/config/runtime/runtime-memory.yaml +17 -0
- package/dist/contracts/runtime.d.ts +44 -1
- package/dist/contracts/workspace.d.ts +6 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/init-project.js +18 -0
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/harness/system/mem0-ingestion-sync.d.ts +28 -2
- package/dist/runtime/harness/system/mem0-ingestion-sync.js +112 -1
- package/dist/runtime/harness/system/runtime-memory-manager.d.ts +90 -0
- package/dist/runtime/harness/system/runtime-memory-manager.js +371 -0
- package/dist/runtime/harness/system/runtime-memory-records.d.ts +4 -0
- package/dist/runtime/harness/system/runtime-memory-records.js +12 -0
- package/dist/runtime/harness/system/store.d.ts +27 -0
- package/dist/runtime/harness/system/store.js +96 -0
- package/dist/runtime/harness.d.ts +22 -1
- package/dist/runtime/harness.js +461 -41
- package/dist/runtime/support/runtime-factories.js +5 -1
- package/dist/runtime/support/vector-stores.js +97 -0
- package/dist/workspace/resource-compilers.js +19 -0
- package/dist/workspace/yaml-object-reader.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,7 +118,7 @@ That means:
|
|
|
118
118
|
|
|
119
119
|
The runtime provides:
|
|
120
120
|
|
|
121
|
-
- `createAgentHarness(workspaceRoot)`, `run(...)`, `resolveApproval(...)`, `subscribe(...)`, inspection methods, and `stop(...)`
|
|
121
|
+
- `createAgentHarness(workspaceRoot)`, `run(...)`, `memorize(...)`, `recall(...)`, `resolveApproval(...)`, `subscribe(...)`, inspection methods, and `stop(...)`
|
|
122
122
|
- YAML-defined workspace assembly for routing, models, tools, stores, backends, MCP, recovery, and maintenance
|
|
123
123
|
- backend-adapted execution with current LangChain v1 and DeepAgents adapters
|
|
124
124
|
- local `resources/tools/` `tool({...})` modules and `resources/skills/` discovery
|
|
@@ -291,6 +291,7 @@ If you want the shortest possible mental model:
|
|
|
291
291
|
- structured output and multimodal content preservation in run results
|
|
292
292
|
- MCP bridge support for agent-declared MCP servers
|
|
293
293
|
- MCP server support for exposing harness tools outward
|
|
294
|
+
- optional `mem0` semantic recall augmentation over canonical SQLite durable memory
|
|
294
295
|
|
|
295
296
|
### Runtime Strengths
|
|
296
297
|
|
|
@@ -389,6 +390,36 @@ const result = await run(
|
|
|
389
390
|
|
|
390
391
|
Use `normalizeUserChatInput(...)` when a product already has chat-style user messages and wants to project one user turn onto the stable `run(..., { input, invocation })` surface without introducing a separate harness-owned chat API.
|
|
391
392
|
|
|
393
|
+
### Store And Recall Durable Runtime Memory
|
|
394
|
+
|
|
395
|
+
```ts
|
|
396
|
+
import { memorize, recall } from "@botbotgo/agent-harness";
|
|
397
|
+
|
|
398
|
+
await memorize(runtime, {
|
|
399
|
+
threadId: "thread-123",
|
|
400
|
+
records: [
|
|
401
|
+
{
|
|
402
|
+
content: "The release checklist requires a smoke test before publish.",
|
|
403
|
+
summary: "Run a smoke test before publish",
|
|
404
|
+
scope: "workspace",
|
|
405
|
+
kind: "procedural",
|
|
406
|
+
sourceRef: "docs/release-checklist.md",
|
|
407
|
+
},
|
|
408
|
+
],
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
const recalled = await recall(runtime, {
|
|
412
|
+
query: "What does the release checklist require?",
|
|
413
|
+
scopes: ["workspace"],
|
|
414
|
+
});
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Use `memorize(...)` and `recall(...)` when an application needs a stable public runtime memory surface without importing internal `runtime/harness/system/*` modules.
|
|
418
|
+
|
|
419
|
+
- `memorize(...)` returns stable `MemoryRecord` and `MemoryDecision` results while leaving merge, review, archive, and storage layout runtime-managed
|
|
420
|
+
- `recall(...)` returns ranked `MemoryRecord` items filtered by runtime memory scope and kind
|
|
421
|
+
- app-specific knowledge taxonomy, review UI, and admin surfaces still belong in the application layer
|
|
422
|
+
|
|
392
423
|
### Let The Runtime Route
|
|
393
424
|
|
|
394
425
|
```ts
|
|
@@ -636,8 +667,8 @@ kind: Stores
|
|
|
636
667
|
spec:
|
|
637
668
|
- kind: Store
|
|
638
669
|
name: default
|
|
639
|
-
storeKind:
|
|
640
|
-
path: store.
|
|
670
|
+
storeKind: SqliteStore
|
|
671
|
+
path: store.sqlite
|
|
641
672
|
- kind: Checkpointer
|
|
642
673
|
name: default
|
|
643
674
|
checkpointerKind: MemorySaver
|
|
@@ -653,6 +684,12 @@ Use this singleton file for runtime-owned durable long-term memory defaults.
|
|
|
653
684
|
|
|
654
685
|
Keep bootstrap context in `config/agent-context.md`. Keep resumable execution state in the checkpointer. Use `RuntimeMemory` for durable memory policy and retrieval defaults.
|
|
655
686
|
|
|
687
|
+
`RuntimeMemory` also carries LangMem-style formation defaults:
|
|
688
|
+
|
|
689
|
+
- `formation.hotPath` for immediate write-time capture
|
|
690
|
+
- `formation.manager` for rule-driven or model-driven candidate normalization before persistence
|
|
691
|
+
- `formation.background` for reflection after run completion or approval resolution
|
|
692
|
+
|
|
656
693
|
### `config/catalogs/backends.yaml`
|
|
657
694
|
|
|
658
695
|
Use reusable DeepAgents backend presets so filesystem and `/memories/*` topology stays in YAML:
|
package/README.zh.md
CHANGED
|
@@ -118,7 +118,7 @@ AI 让 agent 逻辑、工具调用和工作流代码更容易生成,真正更
|
|
|
118
118
|
|
|
119
119
|
运行时提供:
|
|
120
120
|
|
|
121
|
-
- `createAgentHarness(workspaceRoot)`、`run(...)`、`resolveApproval(...)`、`subscribe(...)`、各类查询方法,以及 `stop(...)`
|
|
121
|
+
- `createAgentHarness(workspaceRoot)`、`run(...)`、`memorize(...)`、`recall(...)`、`resolveApproval(...)`、`subscribe(...)`、各类查询方法,以及 `stop(...)`
|
|
122
122
|
- 以 YAML 描述的工作区装配:路由、模型、工具、存储、后端、MCP、恢复与维护等
|
|
123
123
|
- 通过适配器对接当前的 LangChain v1 与 DeepAgents 执行
|
|
124
124
|
- 本地 `resources/tools/` 中 `tool({...})` 工具模块与 `resources/skills/` 的发现
|
|
@@ -360,6 +360,38 @@ const result = await run(runtime, {
|
|
|
360
360
|
- `invocation.inputs`:结构化运行时输入
|
|
361
361
|
- `invocation.attachments`:当前后端可解释的类附件负载
|
|
362
362
|
|
|
363
|
+
可选地,runtime memory 还可以在 SQLite canonical durable memory 之上叠加 `mem0` 语义召回增强,用于更强的长期知识命中,而不改变正式知识记录的 contract。
|
|
364
|
+
|
|
365
|
+
### 写入与召回 durable runtime memory
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
import { memorize, recall } from "@botbotgo/agent-harness";
|
|
369
|
+
|
|
370
|
+
await memorize(runtime, {
|
|
371
|
+
threadId: "thread-123",
|
|
372
|
+
records: [
|
|
373
|
+
{
|
|
374
|
+
content: "The release checklist requires a smoke test before publish.",
|
|
375
|
+
summary: "Run a smoke test before publish",
|
|
376
|
+
scope: "workspace",
|
|
377
|
+
kind: "procedural",
|
|
378
|
+
sourceRef: "docs/release-checklist.md",
|
|
379
|
+
},
|
|
380
|
+
],
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const recalled = await recall(runtime, {
|
|
384
|
+
query: "What does the release checklist require?",
|
|
385
|
+
scopes: ["workspace"],
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
当应用需要稳定的公开 runtime memory 接口,而不想依赖内部 `runtime/harness/system/*` 模块时,使用 `memorize(...)` 与 `recall(...)`。
|
|
390
|
+
|
|
391
|
+
- `memorize(...)` 返回稳定的 `MemoryRecord` 与 `MemoryDecision` 结果,而 merge、review、archive 与存储布局仍由 runtime 内部托管
|
|
392
|
+
- `recall(...)` 返回按相关性排序、并按 scope / kind 过滤后的 `MemoryRecord`
|
|
393
|
+
- 业务知识分类、review UI 与管理后台仍应留在应用层
|
|
394
|
+
|
|
363
395
|
### 由运行时路由
|
|
364
396
|
|
|
365
397
|
```ts
|
|
@@ -604,8 +636,8 @@ kind: Stores
|
|
|
604
636
|
spec:
|
|
605
637
|
- kind: Store
|
|
606
638
|
name: default
|
|
607
|
-
storeKind:
|
|
608
|
-
path: store.
|
|
639
|
+
storeKind: SqliteStore
|
|
640
|
+
path: store.sqlite
|
|
609
641
|
- kind: Checkpointer
|
|
610
642
|
name: default
|
|
611
643
|
checkpointerKind: MemorySaver
|
|
@@ -615,6 +647,18 @@ spec:
|
|
|
615
647
|
path: checkpoints.sqlite
|
|
616
648
|
```
|
|
617
649
|
|
|
650
|
+
### `config/runtime/runtime-memory.yaml`
|
|
651
|
+
|
|
652
|
+
这个单例文件用于配置 runtime 持有的 durable long-term memory 默认值。
|
|
653
|
+
|
|
654
|
+
把稳定启动上下文放在 `config/agent-context.md`,把可恢复执行状态留给 checkpointer,把长期记忆策略与检索默认值放在 `RuntimeMemory`。
|
|
655
|
+
|
|
656
|
+
`RuntimeMemory` 也承载 LangMem 风格的 formation 默认值:
|
|
657
|
+
|
|
658
|
+
- `formation.hotPath`:运行中的即时捕获
|
|
659
|
+
- `formation.manager`:持久化前的规则式或模型式 candidate 归一化
|
|
660
|
+
- `formation.background`:在 run 完成或 approval resolve 后做 reflection
|
|
661
|
+
|
|
618
662
|
### `config/catalogs/backends.yaml`
|
|
619
663
|
|
|
620
664
|
可复用的 DeepAgents 后端预设,使文件系统与 `/memories/*` 拓扑保留在 YAML 中:
|
package/dist/api.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { CancelOptions, InvocationEnvelope, MessageContent, RequestRecord, RequestSummary, ResumeOptions, RunDecisionOptions, RunResult, RunStartOptions, RuntimeHealthSnapshot, RuntimeAdapterOptions, SessionRecord, SessionSummary, WorkspaceLoadOptions } from "./contracts/types.js";
|
|
1
|
+
import type { CancelOptions, InvocationEnvelope, MemorizeInput, MemorizeResult, MessageContent, RecallInput, RecallResult, RequestRecord, RequestSummary, ResumeOptions, RunDecisionOptions, RunResult, RunStartOptions, RuntimeHealthSnapshot, RuntimeAdapterOptions, SessionRecord, SessionSummary, WorkspaceLoadOptions } from "./contracts/types.js";
|
|
2
2
|
import { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
3
3
|
import type { InventoryAgentRecord, InventorySkillRecord } from "./runtime/harness/system/inventory.js";
|
|
4
4
|
import type { RequirementAssessmentOptions } from "./runtime/harness/system/skill-requirements.js";
|
|
5
5
|
import type { ToolMcpServerOptions } from "./mcp.js";
|
|
6
6
|
export { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
7
7
|
export { createUpstreamTimelineReducer } from "./upstream-events.js";
|
|
8
|
+
export type { MemoryDecision, MemoryKind, MemoryRecord, MemoryScope, MemorizeInput, MemorizeResult, RecallInput, RecallResult, } from "./contracts/types.js";
|
|
8
9
|
type PublicApprovalRecord = {
|
|
9
10
|
approvalId: string;
|
|
10
11
|
pendingActionId: string;
|
|
@@ -54,6 +55,8 @@ export declare function createAgentHarness(): Promise<AgentHarnessRuntime>;
|
|
|
54
55
|
export declare function createAgentHarness(workspaceRoot: string, options?: CreateAgentHarnessOptions): Promise<AgentHarnessRuntime>;
|
|
55
56
|
export declare function normalizeUserChatInput(input: UserChatInput, options?: NormalizeUserChatInputOptions): Pick<RunStartOptions, "input" | "invocation">;
|
|
56
57
|
export declare function run(runtime: AgentHarnessRuntime, options: PublicRunOptions): Promise<PublicRunResult>;
|
|
58
|
+
export declare function memorize(runtime: AgentHarnessRuntime, input: MemorizeInput): Promise<MemorizeResult>;
|
|
59
|
+
export declare function recall(runtime: AgentHarnessRuntime, input: RecallInput): Promise<RecallResult>;
|
|
57
60
|
export declare function subscribe(runtime: AgentHarnessRuntime, listener: Parameters<AgentHarnessRuntime["subscribe"]>[0]): () => void;
|
|
58
61
|
export declare function listSessions(runtime: AgentHarnessRuntime, filter?: Parameters<AgentHarnessRuntime["listThreads"]>[0]): Promise<SessionSummary[]>;
|
|
59
62
|
export declare function listRequests(runtime: AgentHarnessRuntime, filter?: {
|
package/dist/api.js
CHANGED
|
@@ -128,6 +128,12 @@ export function normalizeUserChatInput(input, options = {}) {
|
|
|
128
128
|
export async function run(runtime, options) {
|
|
129
129
|
return toPublicRunResult(await runtime.run(toInternalRunOptions(options)));
|
|
130
130
|
}
|
|
131
|
+
export async function memorize(runtime, input) {
|
|
132
|
+
return runtime.memorize(input);
|
|
133
|
+
}
|
|
134
|
+
export async function recall(runtime, input) {
|
|
135
|
+
return runtime.recall(input);
|
|
136
|
+
}
|
|
131
137
|
export function subscribe(runtime, listener) {
|
|
132
138
|
return runtime.subscribe(listener);
|
|
133
139
|
}
|
|
@@ -6,9 +6,9 @@ spec:
|
|
|
6
6
|
# agent-harness feature: reusable store preset for agent backends that need a durable key-value store.
|
|
7
7
|
- kind: Store
|
|
8
8
|
name: default
|
|
9
|
-
description: Default
|
|
10
|
-
storeKind:
|
|
11
|
-
path: store.
|
|
9
|
+
description: Default sqlite-backed store preset for runtime-managed agent state and durable memory.
|
|
10
|
+
storeKind: SqliteStore
|
|
11
|
+
path: store.sqlite
|
|
12
12
|
|
|
13
13
|
# agent-harness feature: reusable checkpointer preset for resumable execution state.
|
|
14
14
|
- kind: Checkpointer
|
|
@@ -9,7 +9,7 @@ spec:
|
|
|
9
9
|
# LangChain v1 Features
|
|
10
10
|
# ====================
|
|
11
11
|
# LangChain aligned feature: concrete vector store implementation.
|
|
12
|
-
# The built-in runtime currently supports `LibSQLVectorStore`
|
|
12
|
+
# The built-in runtime currently supports `LibSQLVectorStore`, `QdrantVectorStore`, and `LlamaIndexSimpleVectorStore`.
|
|
13
13
|
storeKind: LibSQLVectorStore
|
|
14
14
|
# LangChain aligned feature: libSQL connection URL.
|
|
15
15
|
# Local SQLite files use the `file:` prefix.
|
|
@@ -23,3 +23,10 @@ spec:
|
|
|
23
23
|
# ======================
|
|
24
24
|
# Retrieval tools use this to resolve their default embeddings when indexing or querying this vector store.
|
|
25
25
|
embeddingModelRef: embedding-model/default
|
|
26
|
+
|
|
27
|
+
- name: qdrant
|
|
28
|
+
storeKind: QdrantVectorStore
|
|
29
|
+
host: 127.0.0.1
|
|
30
|
+
port: 6333
|
|
31
|
+
collection: runtime_memory
|
|
32
|
+
embeddingModelRef: embedding-model/default
|
|
@@ -66,6 +66,23 @@ spec:
|
|
|
66
66
|
writeOnApprovalResolution: true
|
|
67
67
|
writeOnRunCompletion: true
|
|
68
68
|
|
|
69
|
+
# agent-harness feature: LangMem-style memory formation defaults for hot-path and background reflection.
|
|
70
|
+
formation:
|
|
71
|
+
hotPath:
|
|
72
|
+
enabled: true
|
|
73
|
+
manager:
|
|
74
|
+
enabled: true
|
|
75
|
+
strategy: rules
|
|
76
|
+
maxContextRecords: 12
|
|
77
|
+
background:
|
|
78
|
+
enabled: true
|
|
79
|
+
scopes:
|
|
80
|
+
- thread
|
|
81
|
+
stateStorePath: runtime-memory-formation-state.json
|
|
82
|
+
maxMessagesPerRun: 40
|
|
83
|
+
writeOnApprovalResolution: true
|
|
84
|
+
writeOnRunCompletion: true
|
|
85
|
+
|
|
69
86
|
# agent-harness feature: optional thread snapshot projection for operational state and pending approvals.
|
|
70
87
|
threadMemorySync:
|
|
71
88
|
enabled: true
|
|
@@ -118,13 +118,14 @@ export type MemoryCandidate = {
|
|
|
118
118
|
noStore?: boolean;
|
|
119
119
|
provenance?: Record<string, unknown>;
|
|
120
120
|
};
|
|
121
|
+
export type MemoryKind = "semantic" | "episodic" | "procedural";
|
|
121
122
|
export type MemoryScope = "thread" | "agent" | "workspace" | "user" | "project";
|
|
122
123
|
export type MemoryRecordStatus = "active" | "stale" | "conflicted" | "archived" | "pending_review";
|
|
123
124
|
export type MemoryDecisionAction = "reject" | "store" | "merge" | "refresh" | "supersede" | "archive" | "review";
|
|
124
125
|
export type MemoryRecord = {
|
|
125
126
|
id: string;
|
|
126
127
|
canonicalKey: string;
|
|
127
|
-
kind:
|
|
128
|
+
kind: MemoryKind;
|
|
128
129
|
scope: MemoryScope;
|
|
129
130
|
content: string;
|
|
130
131
|
summary: string;
|
|
@@ -152,6 +153,48 @@ export type MemoryDecision = {
|
|
|
152
153
|
maintenance?: "none" | "dedupe" | "merge" | "review";
|
|
153
154
|
reviewRequired?: boolean;
|
|
154
155
|
};
|
|
156
|
+
export type MemorizeInputRecord = {
|
|
157
|
+
content: string;
|
|
158
|
+
summary?: string;
|
|
159
|
+
kind?: MemoryKind;
|
|
160
|
+
scope?: MemoryScope;
|
|
161
|
+
confidence?: number;
|
|
162
|
+
tags?: string[];
|
|
163
|
+
sourceType?: string;
|
|
164
|
+
sourceRef?: string;
|
|
165
|
+
observedAt?: string;
|
|
166
|
+
sensitivity?: string;
|
|
167
|
+
provenance?: Record<string, unknown>;
|
|
168
|
+
noStore?: boolean;
|
|
169
|
+
};
|
|
170
|
+
export type MemorizeInput = {
|
|
171
|
+
records: MemorizeInputRecord[];
|
|
172
|
+
threadId?: string;
|
|
173
|
+
runId?: string;
|
|
174
|
+
agentId?: string;
|
|
175
|
+
userId?: string;
|
|
176
|
+
projectId?: string;
|
|
177
|
+
recordedAt?: string;
|
|
178
|
+
};
|
|
179
|
+
export type MemorizeResult = {
|
|
180
|
+
records: MemoryRecord[];
|
|
181
|
+
decisions: MemoryDecision[];
|
|
182
|
+
};
|
|
183
|
+
export type RecallInput = {
|
|
184
|
+
query: string;
|
|
185
|
+
scopes?: MemoryScope[];
|
|
186
|
+
kinds?: MemoryKind[];
|
|
187
|
+
topK?: number;
|
|
188
|
+
includeStale?: boolean;
|
|
189
|
+
threadId?: string;
|
|
190
|
+
agentId?: string;
|
|
191
|
+
workspaceId?: string;
|
|
192
|
+
userId?: string;
|
|
193
|
+
projectId?: string;
|
|
194
|
+
};
|
|
195
|
+
export type RecallResult = {
|
|
196
|
+
items: MemoryRecord[];
|
|
197
|
+
};
|
|
155
198
|
/**
|
|
156
199
|
* Operator-facing projection of tool execution policy already compiled into a binding.
|
|
157
200
|
* This summarizes existing timeout, retry, validation, and retry-safety hints without
|
|
@@ -52,9 +52,12 @@ export type ParsedVectorStoreObject = {
|
|
|
52
52
|
id: string;
|
|
53
53
|
kind: string;
|
|
54
54
|
url?: string;
|
|
55
|
+
host?: string;
|
|
56
|
+
port?: number;
|
|
55
57
|
authToken?: string;
|
|
56
58
|
table?: string;
|
|
57
59
|
column?: string;
|
|
60
|
+
collection?: string;
|
|
58
61
|
embeddingModelRef?: string;
|
|
59
62
|
metadata?: Record<string, unknown>;
|
|
60
63
|
sourcePath: string;
|
|
@@ -112,9 +115,12 @@ export type CompiledVectorStore = {
|
|
|
112
115
|
id: string;
|
|
113
116
|
kind: string;
|
|
114
117
|
url?: string;
|
|
118
|
+
host?: string;
|
|
119
|
+
port?: number;
|
|
115
120
|
authToken?: string;
|
|
116
121
|
table?: string;
|
|
117
122
|
column?: string;
|
|
123
|
+
collection?: string;
|
|
118
124
|
embeddingModelRef?: string;
|
|
119
125
|
runtimeValue: string;
|
|
120
126
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { AgentHarnessRuntime, cancelRun, createAgentHarness, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, getAgent, getApproval, getRequest, getHealth, getSession, listAgentSkills, listApprovals, listRequests, listSessions, normalizeUserChatInput, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
2
|
-
export type { NormalizeUserChatInputOptions, UserChatInput, UserChatMessage } from "./api.js";
|
|
1
|
+
export { AgentHarnessRuntime, cancelRun, createAgentHarness, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, getAgent, getApproval, getRequest, getHealth, getSession, listAgentSkills, listApprovals, listRequests, listSessions, memorize, normalizeUserChatInput, recall, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
2
|
+
export type { MemoryDecision, MemoryKind, MemoryRecord, MemoryScope, MemorizeInput, MemorizeResult, NormalizeUserChatInputOptions, RecallInput, RecallResult, UserChatInput, UserChatMessage, } from "./api.js";
|
|
3
3
|
export type { ToolMcpServerOptions } from "./mcp.js";
|
|
4
4
|
export { tool } from "./tools.js";
|
|
5
5
|
export type { UpstreamTimelineProjection, UpstreamTimelineReducer } from "./upstream-events.js";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { AgentHarnessRuntime, cancelRun, createAgentHarness, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, getAgent, getApproval, getRequest, getHealth, getSession, listAgentSkills, listApprovals, listRequests, listSessions, normalizeUserChatInput, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
1
|
+
export { AgentHarnessRuntime, cancelRun, createAgentHarness, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, getAgent, getApproval, getRequest, getHealth, getSession, listAgentSkills, listApprovals, listRequests, listSessions, memorize, normalizeUserChatInput, recall, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
2
2
|
export { tool } from "./tools.js";
|
package/dist/init-project.js
CHANGED
|
@@ -138,6 +138,9 @@ metadata:
|
|
|
138
138
|
name: default
|
|
139
139
|
spec:
|
|
140
140
|
enabled: true
|
|
141
|
+
store:
|
|
142
|
+
kind: SqliteStore
|
|
143
|
+
path: runtime-memory.sqlite
|
|
141
144
|
namespaces:
|
|
142
145
|
users: memories/users/{userId}
|
|
143
146
|
projects: memories/projects/{projectId}
|
|
@@ -162,6 +165,21 @@ spec:
|
|
|
162
165
|
backgroundConsolidation: true
|
|
163
166
|
writeOnApprovalResolution: true
|
|
164
167
|
writeOnRunCompletion: true
|
|
168
|
+
formation:
|
|
169
|
+
hotPath:
|
|
170
|
+
enabled: true
|
|
171
|
+
manager:
|
|
172
|
+
enabled: true
|
|
173
|
+
strategy: rules
|
|
174
|
+
maxContextRecords: 12
|
|
175
|
+
background:
|
|
176
|
+
enabled: true
|
|
177
|
+
scopes:
|
|
178
|
+
- thread
|
|
179
|
+
stateStorePath: runtime-memory-formation-state.json
|
|
180
|
+
maxMessagesPerRun: 40
|
|
181
|
+
writeOnApprovalResolution: true
|
|
182
|
+
writeOnRunCompletion: true
|
|
165
183
|
threadMemorySync:
|
|
166
184
|
enabled: true
|
|
167
185
|
mem0:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.154";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.154";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Message as Mem0Message } from "mem0ai";
|
|
1
|
+
import { type Memory as Mem0Memory, type Message as Mem0Message } from "mem0ai";
|
|
2
2
|
import type { HarnessEvent, HarnessEventProjection } from "../../../contracts/types.js";
|
|
3
3
|
import type { RuntimePersistence } from "../../../persistence/types.js";
|
|
4
4
|
import { type StoreLike } from "./store.js";
|
|
@@ -19,8 +19,26 @@ export type ResolvedMem0Config = {
|
|
|
19
19
|
};
|
|
20
20
|
type Mem0ClientLike = {
|
|
21
21
|
add(messages: Mem0Message[], options?: Record<string, unknown>): Promise<unknown>;
|
|
22
|
+
search(query: string, options?: Record<string, unknown>): Promise<Mem0Memory[]>;
|
|
23
|
+
};
|
|
24
|
+
export type Mem0ClientFactory = (config: ResolvedMem0Config) => Promise<Mem0ClientLike> | Mem0ClientLike;
|
|
25
|
+
export type Mem0SearchInput = {
|
|
26
|
+
query: string;
|
|
27
|
+
topK: number;
|
|
28
|
+
agentId?: string;
|
|
29
|
+
threadId?: string;
|
|
30
|
+
};
|
|
31
|
+
export type Mem0SearchResult = {
|
|
32
|
+
id: string;
|
|
33
|
+
memory: string;
|
|
34
|
+
score: number;
|
|
35
|
+
categories: string[];
|
|
36
|
+
metadata: Record<string, unknown>;
|
|
37
|
+
createdAt: string;
|
|
38
|
+
updatedAt: string;
|
|
39
|
+
agentId?: string;
|
|
40
|
+
runId?: string;
|
|
22
41
|
};
|
|
23
|
-
type Mem0ClientFactory = (config: ResolvedMem0Config) => Promise<Mem0ClientLike> | Mem0ClientLike;
|
|
24
42
|
export declare function readMem0RuntimeConfig(runtimeMemory: Record<string, unknown> | undefined, workspaceRoot: string): ResolvedMem0Config | undefined;
|
|
25
43
|
export declare class Mem0IngestionSync implements HarnessEventProjection {
|
|
26
44
|
private readonly persistence;
|
|
@@ -39,4 +57,12 @@ export declare class Mem0IngestionSync implements HarnessEventProjection {
|
|
|
39
57
|
private syncRun;
|
|
40
58
|
close(): Promise<void>;
|
|
41
59
|
}
|
|
60
|
+
export declare class Mem0SemanticRecall {
|
|
61
|
+
private readonly config;
|
|
62
|
+
private readonly clientFactory;
|
|
63
|
+
private clientPromise;
|
|
64
|
+
constructor(config: ResolvedMem0Config, clientFactory?: Mem0ClientFactory);
|
|
65
|
+
private getClient;
|
|
66
|
+
search(input: Mem0SearchInput): Promise<Mem0SearchResult[]>;
|
|
67
|
+
}
|
|
42
68
|
export {};
|
|
@@ -69,7 +69,10 @@ export function readMem0RuntimeConfig(runtimeMemory, workspaceRoot) {
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
async function createDefaultMem0Client(config) {
|
|
72
|
-
const apiKey = process.env[config.apiKeyEnv];
|
|
72
|
+
const apiKey = process.env[config.apiKeyEnv]?.trim();
|
|
73
|
+
if (!apiKey && config.host) {
|
|
74
|
+
return createSelfHostedMem0Client(config);
|
|
75
|
+
}
|
|
73
76
|
if (!apiKey) {
|
|
74
77
|
throw new Error(`runtimeMemory.mem0 is enabled but environment variable ${config.apiKeyEnv} is not set`);
|
|
75
78
|
}
|
|
@@ -82,6 +85,47 @@ async function createDefaultMem0Client(config) {
|
|
|
82
85
|
...(config.projectId ? { projectId: config.projectId } : {}),
|
|
83
86
|
});
|
|
84
87
|
}
|
|
88
|
+
function normalizeMem0Host(host) {
|
|
89
|
+
return host.replace(/\/+$/, "");
|
|
90
|
+
}
|
|
91
|
+
async function selfHostedMem0Request(config, pathname, options = {}) {
|
|
92
|
+
if (!config.host) {
|
|
93
|
+
throw new Error("Self-hosted mem0 client requires runtimeMemory.mem0.host.");
|
|
94
|
+
}
|
|
95
|
+
const response = await fetch(`${normalizeMem0Host(config.host)}${pathname}`, {
|
|
96
|
+
method: options.method ?? "GET",
|
|
97
|
+
headers: {
|
|
98
|
+
"Content-Type": "application/json",
|
|
99
|
+
},
|
|
100
|
+
...(options.body ? { body: JSON.stringify(options.body) } : {}),
|
|
101
|
+
});
|
|
102
|
+
if (!response.ok) {
|
|
103
|
+
throw new Error(`Self-hosted mem0 request failed: ${response.status} ${response.statusText}`);
|
|
104
|
+
}
|
|
105
|
+
return response.json();
|
|
106
|
+
}
|
|
107
|
+
function createSelfHostedMem0Client(config) {
|
|
108
|
+
return {
|
|
109
|
+
async add(messages, options = {}) {
|
|
110
|
+
return selfHostedMem0Request(config, "/v1/memories/", {
|
|
111
|
+
method: "POST",
|
|
112
|
+
body: {
|
|
113
|
+
messages,
|
|
114
|
+
...options,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
async search(query, options = {}) {
|
|
119
|
+
return selfHostedMem0Request(config, "/v1/memories/search/", {
|
|
120
|
+
method: "POST",
|
|
121
|
+
body: {
|
|
122
|
+
query,
|
|
123
|
+
...options,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
85
129
|
export class Mem0IngestionSync {
|
|
86
130
|
persistence;
|
|
87
131
|
config;
|
|
@@ -179,3 +223,70 @@ export class Mem0IngestionSync {
|
|
|
179
223
|
await Promise.allSettled(Array.from(this.pending));
|
|
180
224
|
}
|
|
181
225
|
}
|
|
226
|
+
function toIsoString(value) {
|
|
227
|
+
if (value instanceof Date && !Number.isNaN(value.getTime())) {
|
|
228
|
+
return value.toISOString();
|
|
229
|
+
}
|
|
230
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
231
|
+
const parsed = new Date(value);
|
|
232
|
+
return Number.isNaN(parsed.getTime()) ? undefined : parsed.toISOString();
|
|
233
|
+
}
|
|
234
|
+
return undefined;
|
|
235
|
+
}
|
|
236
|
+
export class Mem0SemanticRecall {
|
|
237
|
+
config;
|
|
238
|
+
clientFactory;
|
|
239
|
+
clientPromise = null;
|
|
240
|
+
constructor(config, clientFactory = createDefaultMem0Client) {
|
|
241
|
+
this.config = config;
|
|
242
|
+
this.clientFactory = clientFactory;
|
|
243
|
+
}
|
|
244
|
+
async getClient() {
|
|
245
|
+
if (!this.clientPromise) {
|
|
246
|
+
this.clientPromise = Promise.resolve(this.clientFactory(this.config));
|
|
247
|
+
}
|
|
248
|
+
return this.clientPromise;
|
|
249
|
+
}
|
|
250
|
+
async search(input) {
|
|
251
|
+
if (input.query.trim().length === 0 || input.topK <= 0) {
|
|
252
|
+
return [];
|
|
253
|
+
}
|
|
254
|
+
const client = await this.getClient();
|
|
255
|
+
const records = await client.search(input.query, {
|
|
256
|
+
top_k: input.topK,
|
|
257
|
+
limit: input.topK,
|
|
258
|
+
app_id: this.config.appId,
|
|
259
|
+
...(input.agentId ? { agent_id: input.agentId } : {}),
|
|
260
|
+
...(input.threadId && this.config.userIdPrefix ? { user_id: `${this.config.userIdPrefix}${input.threadId}` } : {}),
|
|
261
|
+
});
|
|
262
|
+
return records
|
|
263
|
+
.map((record) => {
|
|
264
|
+
const memory = typeof record.memory === "string" && record.memory.trim().length > 0
|
|
265
|
+
? record.memory.trim()
|
|
266
|
+
: typeof record.data?.memory === "string" && record.data.memory.trim().length > 0
|
|
267
|
+
? record.data.memory.trim()
|
|
268
|
+
: "";
|
|
269
|
+
if (!memory) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
const createdAt = toIsoString(record.created_at) ?? new Date(0).toISOString();
|
|
273
|
+
const updatedAt = toIsoString(record.updated_at) ?? createdAt;
|
|
274
|
+
return {
|
|
275
|
+
id: record.id,
|
|
276
|
+
memory,
|
|
277
|
+
score: typeof record.score === "number" && Number.isFinite(record.score) ? record.score : 0,
|
|
278
|
+
categories: Array.isArray(record.categories)
|
|
279
|
+
? record.categories.filter((item) => typeof item === "string" && item.trim().length > 0)
|
|
280
|
+
: [],
|
|
281
|
+
metadata: typeof record.metadata === "object" && record.metadata && !Array.isArray(record.metadata)
|
|
282
|
+
? { ...record.metadata }
|
|
283
|
+
: {},
|
|
284
|
+
createdAt,
|
|
285
|
+
updatedAt,
|
|
286
|
+
agentId: typeof record.agent_id === "string" && record.agent_id.trim().length > 0 ? record.agent_id : undefined,
|
|
287
|
+
runId: typeof record.run_id === "string" && record.run_id.trim().length > 0 ? record.run_id : undefined,
|
|
288
|
+
};
|
|
289
|
+
})
|
|
290
|
+
.filter((record) => record !== null);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { CompiledAgentBinding, CompiledModel, HarnessEvent, HarnessEventProjection, InternalApprovalRecord, MemoryCandidate, MemoryRecord, MemoryScope, ThreadSummary, TranscriptMessage, WorkspaceBundle } from "../../../contracts/types.js";
|
|
2
|
+
import type { RuntimePersistence } from "../../../persistence/types.js";
|
|
3
|
+
import { type StoreLike } from "./store.js";
|
|
4
|
+
export type ResolvedRuntimeMemoryFormationConfig = {
|
|
5
|
+
enabled: true;
|
|
6
|
+
hotPath: {
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
};
|
|
9
|
+
manager: {
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
strategy: "rules" | "model";
|
|
12
|
+
modelRef?: string;
|
|
13
|
+
maxContextRecords: number;
|
|
14
|
+
};
|
|
15
|
+
background: {
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
maxMessagesPerRun: number;
|
|
18
|
+
scopes: MemoryScope[];
|
|
19
|
+
stateStorePath: string;
|
|
20
|
+
writeOnApprovalResolution: boolean;
|
|
21
|
+
writeOnRunCompletion: boolean;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
type RuntimeMemoryFormationWriter = (input: {
|
|
25
|
+
candidates: MemoryCandidate[];
|
|
26
|
+
threadId: string;
|
|
27
|
+
runId: string;
|
|
28
|
+
agentId: string;
|
|
29
|
+
userId?: string;
|
|
30
|
+
projectId?: string;
|
|
31
|
+
recordedAt: string;
|
|
32
|
+
}) => Promise<void>;
|
|
33
|
+
type RuntimeMemoryFormationOptions = {
|
|
34
|
+
userId?: string;
|
|
35
|
+
projectId?: string;
|
|
36
|
+
};
|
|
37
|
+
type RuntimeMemoryManagerLike = {
|
|
38
|
+
transform(input: {
|
|
39
|
+
candidates: MemoryCandidate[];
|
|
40
|
+
binding: CompiledAgentBinding;
|
|
41
|
+
threadId: string;
|
|
42
|
+
runId: string;
|
|
43
|
+
recordedAt: string;
|
|
44
|
+
existingRecords: MemoryRecord[];
|
|
45
|
+
}): Promise<MemoryCandidate[]>;
|
|
46
|
+
};
|
|
47
|
+
export declare function readRuntimeMemoryFormationConfig(runtimeMemory: Record<string, unknown> | undefined, workspaceRoot: string): ResolvedRuntimeMemoryFormationConfig | undefined;
|
|
48
|
+
export declare function createBackgroundMemoryCandidates(input: {
|
|
49
|
+
thread: ThreadSummary;
|
|
50
|
+
runId: string;
|
|
51
|
+
agentId: string;
|
|
52
|
+
trigger: "approval.resolved" | "run.completed";
|
|
53
|
+
recordedAt: string;
|
|
54
|
+
messages: TranscriptMessage[];
|
|
55
|
+
approvals: InternalApprovalRecord[];
|
|
56
|
+
scopes: MemoryScope[];
|
|
57
|
+
}): MemoryCandidate[];
|
|
58
|
+
export declare function runModelMemoryManager(input: {
|
|
59
|
+
workspace: WorkspaceBundle;
|
|
60
|
+
binding: CompiledAgentBinding;
|
|
61
|
+
model: CompiledModel;
|
|
62
|
+
candidates: MemoryCandidate[];
|
|
63
|
+
threadId: string;
|
|
64
|
+
runId: string;
|
|
65
|
+
recordedAt: string;
|
|
66
|
+
existingRecords: MemoryRecord[];
|
|
67
|
+
modelResolver?: (modelId: string) => unknown;
|
|
68
|
+
}): Promise<MemoryCandidate[]>;
|
|
69
|
+
export declare function createRuntimeMemoryManager(input: {
|
|
70
|
+
workspace: WorkspaceBundle;
|
|
71
|
+
binding: CompiledAgentBinding;
|
|
72
|
+
config: ResolvedRuntimeMemoryFormationConfig;
|
|
73
|
+
modelResolver?: (modelId: string) => unknown;
|
|
74
|
+
}): RuntimeMemoryManagerLike;
|
|
75
|
+
export declare class RuntimeMemoryFormationSync implements HarnessEventProjection {
|
|
76
|
+
private readonly persistence;
|
|
77
|
+
private readonly config;
|
|
78
|
+
private readonly writer;
|
|
79
|
+
private readonly stateStore;
|
|
80
|
+
private readonly options;
|
|
81
|
+
private readonly pending;
|
|
82
|
+
private syncChain;
|
|
83
|
+
readonly name = "runtime-memory-formation-sync";
|
|
84
|
+
constructor(persistence: RuntimePersistence, config: ResolvedRuntimeMemoryFormationConfig, writer: RuntimeMemoryFormationWriter, runRoot: string, stateStore?: StoreLike, options?: RuntimeMemoryFormationOptions);
|
|
85
|
+
shouldHandle(event: HarnessEvent): boolean;
|
|
86
|
+
handleEvent(event: HarnessEvent): Promise<void>;
|
|
87
|
+
private reflectRun;
|
|
88
|
+
close(): Promise<void>;
|
|
89
|
+
}
|
|
90
|
+
export {};
|