@botbotgo/agent-harness 0.0.151 → 0.0.152
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/dist/config/runtime/runtime-memory.yaml +4 -0
- package/dist/init-project.js +2 -0
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/harness/system/runtime-memory-sync.d.ts +9 -1
- package/dist/runtime/harness/system/runtime-memory-sync.js +12 -4
- package/dist/runtime/harness/system/thread-memory-sync.d.ts +5 -1
- package/dist/runtime/harness/system/thread-memory-sync.js +18 -12
- package/dist/runtime/harness.js +18 -2
- package/package.json +1 -1
|
@@ -66,6 +66,10 @@ spec:
|
|
|
66
66
|
writeOnApprovalResolution: true
|
|
67
67
|
writeOnRunCompletion: true
|
|
68
68
|
|
|
69
|
+
# agent-harness feature: optional thread snapshot projection for operational state and pending approvals.
|
|
70
|
+
threadMemorySync:
|
|
71
|
+
enabled: true
|
|
72
|
+
|
|
69
73
|
# agent-harness feature: optional Mem0 OSS ingestion engine for automatic long-term knowledge extraction.
|
|
70
74
|
mem0:
|
|
71
75
|
enabled: false
|
package/dist/init-project.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.151";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.151";
|
|
@@ -8,17 +8,25 @@ export type ResolvedRuntimeMemorySyncConfig = {
|
|
|
8
8
|
backgroundConsolidation: boolean;
|
|
9
9
|
maxMessagesPerRun: number;
|
|
10
10
|
};
|
|
11
|
+
type RuntimeMemorySyncOptions = {
|
|
12
|
+
resolveThreadNamespace?: (threadId: string) => string[];
|
|
13
|
+
resolveRunNamespace?: (threadId: string) => string[];
|
|
14
|
+
};
|
|
11
15
|
export declare function readRuntimeMemorySyncConfig(runtimeMemory: Record<string, unknown> | undefined): ResolvedRuntimeMemorySyncConfig | undefined;
|
|
12
16
|
export declare class RuntimeMemorySync implements HarnessEventProjection {
|
|
13
17
|
private readonly persistence;
|
|
14
18
|
readonly store: StoreLike;
|
|
15
19
|
private readonly config;
|
|
20
|
+
private readonly options;
|
|
16
21
|
private readonly pending;
|
|
17
22
|
private syncChain;
|
|
18
23
|
readonly name = "runtime-memory-sync";
|
|
19
|
-
constructor(persistence: RuntimePersistence, store: StoreLike, config: ResolvedRuntimeMemorySyncConfig);
|
|
24
|
+
constructor(persistence: RuntimePersistence, store: StoreLike, config: ResolvedRuntimeMemorySyncConfig, options?: RuntimeMemorySyncOptions);
|
|
20
25
|
shouldHandle(event: HarnessEvent): boolean;
|
|
21
26
|
handleEvent(event: HarnessEvent): Promise<void>;
|
|
22
27
|
private syncRun;
|
|
28
|
+
private resolveThreadNamespace;
|
|
29
|
+
private resolveRunNamespace;
|
|
23
30
|
close(): Promise<void>;
|
|
24
31
|
}
|
|
32
|
+
export {};
|
|
@@ -100,13 +100,15 @@ export class RuntimeMemorySync {
|
|
|
100
100
|
persistence;
|
|
101
101
|
store;
|
|
102
102
|
config;
|
|
103
|
+
options;
|
|
103
104
|
pending = new Set();
|
|
104
105
|
syncChain = Promise.resolve();
|
|
105
106
|
name = "runtime-memory-sync";
|
|
106
|
-
constructor(persistence, store, config) {
|
|
107
|
+
constructor(persistence, store, config, options = {}) {
|
|
107
108
|
this.persistence = persistence;
|
|
108
109
|
this.store = store;
|
|
109
110
|
this.config = config;
|
|
111
|
+
this.options = options;
|
|
110
112
|
}
|
|
111
113
|
shouldHandle(event) {
|
|
112
114
|
if (!RUNTIME_MEMORY_EVENT_TYPES.has(event.eventType)) {
|
|
@@ -161,8 +163,8 @@ export class RuntimeMemorySync {
|
|
|
161
163
|
approvals,
|
|
162
164
|
});
|
|
163
165
|
await Promise.all([
|
|
164
|
-
this.store.put(
|
|
165
|
-
this.store.put(
|
|
166
|
+
this.store.put(this.resolveRunNamespace(threadId), `${runId}.summary.md`, { content: `${summaryMarkdown}\n` }),
|
|
167
|
+
this.store.put(this.resolveRunNamespace(threadId), `${runId}.record.json`, {
|
|
166
168
|
kind: "summary",
|
|
167
169
|
scope: "thread",
|
|
168
170
|
threadId,
|
|
@@ -185,7 +187,13 @@ export class RuntimeMemorySync {
|
|
|
185
187
|
capturedAt,
|
|
186
188
|
messages,
|
|
187
189
|
});
|
|
188
|
-
await this.store.put(
|
|
190
|
+
await this.store.put(this.resolveThreadNamespace(threadId), "durable-summary.md", { content: `${digestMarkdown}\n` });
|
|
191
|
+
}
|
|
192
|
+
resolveThreadNamespace(threadId) {
|
|
193
|
+
return this.options.resolveThreadNamespace ? this.options.resolveThreadNamespace(threadId) : ["memories", "threads", threadId];
|
|
194
|
+
}
|
|
195
|
+
resolveRunNamespace(threadId) {
|
|
196
|
+
return this.options.resolveRunNamespace ? this.options.resolveRunNamespace(threadId) : ["memories", "runs", threadId];
|
|
189
197
|
}
|
|
190
198
|
async close() {
|
|
191
199
|
await Promise.allSettled(Array.from(this.pending));
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { HarnessEvent, HarnessEventProjection } from "../../../contracts/types.js";
|
|
2
2
|
import type { RuntimePersistence } from "../../../persistence/types.js";
|
|
3
|
+
type ThreadMemorySyncOptions = {
|
|
4
|
+
resolveThreadNamespace?: (threadId: string) => string[];
|
|
5
|
+
};
|
|
3
6
|
export declare class ThreadMemorySync implements HarnessEventProjection {
|
|
4
7
|
private readonly persistence;
|
|
5
8
|
private readonly store?;
|
|
9
|
+
private readonly options;
|
|
6
10
|
private readonly pending;
|
|
7
11
|
private syncChain;
|
|
8
12
|
readonly name = "thread-memory-sync";
|
|
9
13
|
constructor(persistence: RuntimePersistence, store?: {
|
|
10
14
|
put: (namespace: string[], key: string, value: Record<string, any>) => Promise<void>;
|
|
11
|
-
} | undefined);
|
|
15
|
+
} | undefined, options?: ThreadMemorySyncOptions);
|
|
12
16
|
shouldHandle(event: HarnessEvent): boolean;
|
|
13
17
|
handleEvent(event: HarnessEvent): Promise<void>;
|
|
14
18
|
private syncThread;
|
|
@@ -6,11 +6,11 @@ function excerpt(message) {
|
|
|
6
6
|
const normalized = extractMessageText(message.content).replace(/\s+/g, " ").trim();
|
|
7
7
|
return normalized.length > 240 ? `${normalized.slice(0, 237)}...` : normalized;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
9
|
+
function renderThreadSnapshotMarkdown(thread, messages, approvals) {
|
|
10
10
|
const userMessages = messages.filter((message) => message.role === "user");
|
|
11
11
|
const assistantMessages = messages.filter((message) => message.role === "assistant");
|
|
12
12
|
return [
|
|
13
|
-
"# Thread
|
|
13
|
+
"# Thread Snapshot",
|
|
14
14
|
"",
|
|
15
15
|
`- thread_id: ${thread.threadId}`,
|
|
16
16
|
`- latest_run_id: ${thread.latestRunId}`,
|
|
@@ -24,15 +24,17 @@ function renderStatusMarkdown(thread, messages) {
|
|
|
24
24
|
"## Recent Assistant Message",
|
|
25
25
|
excerpt(assistantMessages.at(-1)),
|
|
26
26
|
"",
|
|
27
|
+
...formatOpenApprovalsSection(approvals),
|
|
27
28
|
].join("\n");
|
|
28
29
|
}
|
|
29
|
-
function
|
|
30
|
+
function formatOpenApprovalsSection(approvals) {
|
|
31
|
+
const lines = ["## Open Approvals", ""];
|
|
30
32
|
if (approvals.length === 0) {
|
|
31
|
-
|
|
33
|
+
lines.push("(none)", "");
|
|
34
|
+
return lines;
|
|
32
35
|
}
|
|
33
|
-
const lines = ["# Open Approvals", ""];
|
|
34
36
|
for (const approval of approvals) {
|
|
35
|
-
lines.push(
|
|
37
|
+
lines.push(`### ${approval.approvalId}`);
|
|
36
38
|
lines.push(`- pending_action_id: ${approval.pendingActionId}`);
|
|
37
39
|
lines.push(`- tool: ${approval.toolName}`);
|
|
38
40
|
lines.push(`- run_id: ${approval.runId}`);
|
|
@@ -40,7 +42,10 @@ function renderOpenApprovalsMarkdown(approvals) {
|
|
|
40
42
|
lines.push(`- allowed: ${approval.allowedDecisions.join(", ")}`);
|
|
41
43
|
lines.push("");
|
|
42
44
|
}
|
|
43
|
-
return lines
|
|
45
|
+
return lines;
|
|
46
|
+
}
|
|
47
|
+
function resolveThreadNamespace(threadId, resolver) {
|
|
48
|
+
return resolver ? resolver(threadId) : ["memories", "threads", threadId];
|
|
44
49
|
}
|
|
45
50
|
const THREAD_MEMORY_EVENT_TYPES = new Set([
|
|
46
51
|
"run.state.changed",
|
|
@@ -52,12 +57,14 @@ const THREAD_MEMORY_EVENT_TYPES = new Set([
|
|
|
52
57
|
export class ThreadMemorySync {
|
|
53
58
|
persistence;
|
|
54
59
|
store;
|
|
60
|
+
options;
|
|
55
61
|
pending = new Set();
|
|
56
62
|
syncChain = Promise.resolve();
|
|
57
63
|
name = "thread-memory-sync";
|
|
58
|
-
constructor(persistence, store) {
|
|
64
|
+
constructor(persistence, store, options = {}) {
|
|
59
65
|
this.persistence = persistence;
|
|
60
66
|
this.store = store;
|
|
67
|
+
this.options = options;
|
|
61
68
|
}
|
|
62
69
|
shouldHandle(event) {
|
|
63
70
|
return THREAD_MEMORY_EVENT_TYPES.has(event.eventType);
|
|
@@ -93,10 +100,9 @@ export class ThreadMemorySync {
|
|
|
93
100
|
if (!this.store) {
|
|
94
101
|
return;
|
|
95
102
|
}
|
|
96
|
-
await
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
]);
|
|
103
|
+
await this.store.put(resolveThreadNamespace(threadId, this.options.resolveThreadNamespace), "snapshot.md", {
|
|
104
|
+
content: `${renderThreadSnapshotMarkdown(thread, messages, pendingApprovals)}\n`,
|
|
105
|
+
});
|
|
100
106
|
}
|
|
101
107
|
async close() {
|
|
102
108
|
await Promise.allSettled(Array.from(this.pending));
|
package/dist/runtime/harness.js
CHANGED
|
@@ -144,7 +144,15 @@ export class AgentHarnessRuntime {
|
|
|
144
144
|
this.routingRules = getRoutingRules(workspace.refs);
|
|
145
145
|
this.routingDefaultAgentId = getRoutingDefaultAgentId(workspace.refs);
|
|
146
146
|
if (isThreadMemorySyncEnabled(workspace)) {
|
|
147
|
-
this.threadMemorySync = new ThreadMemorySync(this.persistence, this.runtimeMemoryStore
|
|
147
|
+
this.threadMemorySync = new ThreadMemorySync(this.persistence, this.runtimeMemoryStore, {
|
|
148
|
+
resolveThreadNamespace: (threadId) => {
|
|
149
|
+
const binding = this.defaultRuntimeEntryBinding;
|
|
150
|
+
if (!binding) {
|
|
151
|
+
return ["memories", "threads", threadId];
|
|
152
|
+
}
|
|
153
|
+
return this.resolveMemoryNamespace("thread", binding, { threadId });
|
|
154
|
+
},
|
|
155
|
+
});
|
|
148
156
|
this.unregisterThreadMemorySync = this.eventBus.registerProjection(this.threadMemorySync);
|
|
149
157
|
}
|
|
150
158
|
else {
|
|
@@ -153,7 +161,15 @@ export class AgentHarnessRuntime {
|
|
|
153
161
|
}
|
|
154
162
|
const runtimeMemorySyncConfig = readRuntimeMemorySyncConfig(this.defaultRuntimeEntryBinding?.harnessRuntime.runtimeMemory);
|
|
155
163
|
if (runtimeMemorySyncConfig) {
|
|
156
|
-
this.runtimeMemorySync = new RuntimeMemorySync(this.persistence, this.runtimeMemoryStore, runtimeMemorySyncConfig
|
|
164
|
+
this.runtimeMemorySync = new RuntimeMemorySync(this.persistence, this.runtimeMemoryStore, runtimeMemorySyncConfig, {
|
|
165
|
+
resolveThreadNamespace: (threadId) => {
|
|
166
|
+
const binding = this.defaultRuntimeEntryBinding;
|
|
167
|
+
if (!binding) {
|
|
168
|
+
return ["memories", "threads", threadId];
|
|
169
|
+
}
|
|
170
|
+
return this.resolveMemoryNamespace("thread", binding, { threadId });
|
|
171
|
+
},
|
|
172
|
+
});
|
|
157
173
|
this.unregisterRuntimeMemorySync = this.eventBus.registerProjection(this.runtimeMemorySync);
|
|
158
174
|
}
|
|
159
175
|
else {
|