@botbotgo/agent-harness 0.0.298 → 0.0.300
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 +78 -38
- package/README.zh.md +80 -31
- package/dist/acp.d.ts +3 -0
- package/dist/acp.js +10 -2
- package/dist/api.d.ts +14 -2
- package/dist/api.js +19 -3
- package/dist/cli.d.ts +18 -1
- package/dist/cli.js +1408 -319
- package/dist/client/acp.d.ts +9 -3
- package/dist/client/acp.js +55 -1
- package/dist/client/in-process.d.ts +5 -2
- package/dist/client/in-process.js +4 -6
- package/dist/client/index.d.ts +1 -1
- package/dist/client/types.d.ts +6 -5
- package/dist/config/agents/direct.yaml +7 -17
- package/dist/config/agents/orchestra.yaml +9 -65
- package/dist/config/catalogs/embedding-models.yaml +1 -1
- package/dist/config/catalogs/stores.yaml +1 -1
- package/dist/config/knowledge/knowledge-runtime.yaml +36 -2
- package/dist/config/knowledge/procedural-memory-runtime.yaml +78 -0
- package/dist/config/{catalogs/models.yaml → models.yaml} +2 -2
- package/dist/config/prompts/direct-system.md +16 -0
- package/dist/config/prompts/orchestra-system.md +62 -0
- package/dist/config/prompts/routing-system.md +14 -0
- package/dist/config/runtime/runtime-memory.yaml +39 -5
- package/dist/config/runtime/workspace.yaml +7 -16
- package/dist/contracts/runtime.d.ts +242 -1
- package/dist/contracts/workspace.d.ts +2 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +2 -1
- package/dist/init-project.js +178 -33
- package/dist/knowledge/contracts.d.ts +5 -0
- package/dist/knowledge/module.d.ts +5 -0
- package/dist/knowledge/module.js +340 -18
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/file-store.d.ts +5 -1
- package/dist/persistence/file-store.js +16 -0
- package/dist/persistence/sqlite-store.d.ts +4 -1
- package/dist/persistence/sqlite-store.js +88 -14
- package/dist/persistence/types.d.ts +4 -1
- package/dist/procedural/config.d.ts +63 -0
- package/dist/procedural/config.js +125 -0
- package/dist/procedural/index.d.ts +2 -0
- package/dist/procedural/index.js +1 -0
- package/dist/protocol/ag-ui/http.d.ts +3 -0
- package/dist/protocol/ag-ui/http.js +10 -0
- package/dist/request-events.d.ts +63 -0
- package/dist/request-events.js +400 -0
- package/dist/resource/isolation.js +11 -0
- package/dist/resource/resource-impl.d.ts +1 -0
- package/dist/resource/resource-impl.js +103 -12
- package/dist/resources/init-templates/agent-context/deep-research.md +5 -0
- package/dist/resources/init-templates/prompts/research-analyst-basic.md +1 -0
- package/dist/resources/init-templates/prompts/research-analyst-web-search.md +1 -0
- package/dist/resources/init-templates/prompts/research-host-deep-research-basic.md +1 -0
- package/dist/resources/init-templates/prompts/research-host-deep-research-web-search.md +1 -0
- package/dist/resources/init-templates/prompts/research-host-single-agent-basic.md +1 -0
- package/dist/resources/init-templates/prompts/research-host-single-agent-web-search.md +1 -0
- package/dist/resources/prompts/runtime/browser-capability-disclaimer-recovery.md +1 -0
- package/dist/resources/prompts/runtime/default-subagent.md +2 -0
- package/dist/resources/prompts/runtime/durable-memory-context.md +7 -0
- package/dist/resources/prompts/runtime/execution-with-tool-evidence-retry.md +1 -0
- package/dist/resources/prompts/runtime/execution-with-tool-evidence.md +1 -0
- package/dist/resources/prompts/runtime/invalid-tool-selection-recovery.md +1 -0
- package/dist/resources/prompts/runtime/memory-manager.md +31 -0
- package/dist/resources/prompts/runtime/memory-mutation-reconciliation.md +22 -0
- package/dist/resources/prompts/runtime/slash-command-skill.md +6 -0
- package/dist/resources/prompts/runtime/strict-tool-json.md +1 -0
- package/dist/resources/prompts/runtime/workspace-boundary-guidance.md +3 -0
- package/dist/resources/prompts/runtime/workspace-relative-path.md +1 -0
- package/dist/resources/prompts/runtime/write-todos-descriptive-content.md +1 -0
- package/dist/resources/prompts/runtime/write-todos-full-entry.md +1 -0
- package/dist/resources/prompts/runtime/write-todos-non-empty-initial-list.md +1 -0
- package/dist/resources/tools/_runtime_tool_helpers.mjs +152 -0
- package/dist/resources/tools/cancel_request.mjs +21 -0
- package/dist/resources/tools/fetch_url.mjs +23 -0
- package/dist/resources/tools/http_request.mjs +30 -0
- package/dist/resources/tools/inspect_approvals.mjs +27 -0
- package/dist/resources/tools/inspect_artifacts.mjs +21 -0
- package/dist/resources/tools/inspect_events.mjs +21 -0
- package/dist/resources/tools/inspect_requests.mjs +27 -0
- package/dist/resources/tools/inspect_sessions.mjs +21 -0
- package/dist/resources/tools/list_files.mjs +27 -0
- package/dist/resources/tools/read_artifact.mjs +22 -0
- package/dist/resources/tools/request_approval.mjs +27 -0
- package/dist/resources/tools/run_command.mjs +21 -0
- package/dist/resources/tools/schedule_task.mjs +76 -0
- package/dist/resources/tools/search_files.mjs +47 -0
- package/dist/resources/tools/send_message.mjs +23 -0
- package/dist/runtime/adapter/direct-builtin-utility.d.ts +1 -0
- package/dist/runtime/adapter/direct-builtin-utility.js +90 -0
- package/dist/runtime/adapter/flow/execution-context.d.ts +1 -1
- package/dist/runtime/adapter/flow/execution-context.js +1 -1
- package/dist/runtime/adapter/flow/invocation-flow.d.ts +1 -0
- package/dist/runtime/adapter/flow/invocation-flow.js +9 -1
- package/dist/runtime/adapter/flow/invoke-runtime.d.ts +1 -1
- package/dist/runtime/adapter/flow/stream-runtime.d.ts +5 -1
- package/dist/runtime/adapter/flow/stream-runtime.js +556 -35
- package/dist/runtime/adapter/invocation-result.js +3 -2
- package/dist/runtime/adapter/local-tool-invocation.d.ts +1 -1
- package/dist/runtime/adapter/local-tool-invocation.js +28 -4
- package/dist/runtime/adapter/middleware-assembly.js +3 -1
- package/dist/runtime/adapter/model/invocation-request.d.ts +4 -1
- package/dist/runtime/adapter/model/invocation-request.js +138 -16
- package/dist/runtime/adapter/model/message-assembly.js +2 -6
- package/dist/runtime/adapter/model/model-providers.js +103 -5
- package/dist/runtime/adapter/resilience.js +17 -2
- package/dist/runtime/adapter/runtime-adapter-support.d.ts +11 -7
- package/dist/runtime/adapter/runtime-adapter-support.js +39 -5
- package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +63 -1
- package/dist/runtime/adapter/tool/builtin-middleware-tools.js +193 -21
- package/dist/runtime/adapter/tool/tool-arguments.d.ts +3 -1
- package/dist/runtime/adapter/tool/tool-arguments.js +52 -17
- package/dist/runtime/adapter/tool-resolution.d.ts +1 -0
- package/dist/runtime/adapter/tool-resolution.js +4 -2
- package/dist/runtime/agent-runtime-adapter.d.ts +27 -0
- package/dist/runtime/agent-runtime-adapter.js +163 -11
- package/dist/runtime/harness/events/event-bus.d.ts +1 -0
- package/dist/runtime/harness/events/event-bus.js +3 -0
- package/dist/runtime/harness/events/event-sink.d.ts +3 -0
- package/dist/runtime/harness/events/event-sink.js +16 -7
- package/dist/runtime/harness/events/streaming.d.ts +18 -1
- package/dist/runtime/harness/events/streaming.js +23 -10
- package/dist/runtime/harness/run/inspection.js +26 -5
- package/dist/runtime/harness/run/stream-run.d.ts +13 -4
- package/dist/runtime/harness/run/stream-run.js +448 -4
- package/dist/runtime/harness/run/surface-semantics.js +7 -34
- package/dist/runtime/harness/system/runtime-memory-manager.d.ts +3 -0
- package/dist/runtime/harness/system/runtime-memory-manager.js +384 -69
- package/dist/runtime/harness/system/runtime-memory-policy.d.ts +20 -1
- package/dist/runtime/harness/system/runtime-memory-policy.js +65 -17
- package/dist/runtime/harness/system/runtime-memory-records.js +100 -0
- package/dist/runtime/harness/system/runtime-memory-sync.js +2 -2
- package/dist/runtime/harness/system/store.d.ts +4 -0
- package/dist/runtime/harness/system/store.js +153 -0
- package/dist/runtime/harness.d.ts +9 -1
- package/dist/runtime/harness.js +141 -7
- package/dist/runtime/maintenance/sqlite-checkpoint-saver.d.ts +8 -3
- package/dist/runtime/maintenance/sqlite-checkpoint-saver.js +152 -53
- package/dist/runtime/parsing/output-parsing.d.ts +10 -2
- package/dist/runtime/parsing/output-parsing.js +223 -16
- package/dist/runtime/parsing/stream-event-parsing.d.ts +7 -0
- package/dist/runtime/parsing/stream-event-parsing.js +51 -1
- package/dist/runtime/scheduling/system-schedule-manager.d.ts +41 -0
- package/dist/runtime/scheduling/system-schedule-manager.js +532 -0
- package/dist/runtime/support/embedding-models.d.ts +1 -1
- package/dist/runtime/support/embedding-models.js +5 -2
- package/dist/runtime/support/runtime-factories.js +1 -1
- package/dist/runtime/support/runtime-layout.d.ts +3 -0
- package/dist/runtime/support/runtime-layout.js +10 -1
- package/dist/runtime/support/runtime-prompts.d.ts +30 -0
- package/dist/runtime/support/runtime-prompts.js +55 -0
- package/dist/runtime/support/vector-stores.d.ts +1 -1
- package/dist/runtime/support/vector-stores.js +5 -2
- package/dist/upstream-events.js +8 -7
- package/dist/utils/bundled-text.d.ts +3 -0
- package/dist/utils/bundled-text.js +25 -0
- package/dist/utils/id.js +3 -2
- package/dist/workspace/agent-binding-compiler.js +53 -13
- package/dist/workspace/object-loader.js +64 -2
- package/dist/workspace/support/workspace-ref-utils.d.ts +2 -1
- package/dist/workspace/support/workspace-ref-utils.js +24 -5
- package/dist/workspace/yaml-object-reader.d.ts +1 -0
- package/dist/workspace/yaml-object-reader.js +95 -17
- package/package.json +11 -5
package/dist/knowledge/module.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createPersistentId } from "../utils/id.js";
|
|
|
2
2
|
import { findMemoryRecordById, getMemoryRecord, listMemoryRecordsForScopes, persistStructuredMemoryRecords, removeMemoryRecord, updateMemoryRecord, } from "../runtime/harness/system/runtime-memory-records.js";
|
|
3
3
|
import { consolidateStructuredMemoryScope } from "../runtime/harness/system/runtime-memory-consolidation.js";
|
|
4
4
|
import { renderMemoryCandidatesMarkdown } from "../runtime/harness/system/runtime-memory-candidates.js";
|
|
5
|
-
import { normalizeLangMemMemoryKind,
|
|
5
|
+
import { shouldRecallDurableMemory, normalizeLangMemMemoryKind, shouldStoreMemoryCandidate, } from "../runtime/harness/system/runtime-memory-policy.js";
|
|
6
6
|
const ALL_SCOPES = ["session", "agent", "workspace", "user", "project"];
|
|
7
7
|
const TITLE_BY_SCOPE = {
|
|
8
8
|
session: "Session Structured Memory",
|
|
@@ -25,6 +25,24 @@ function normalizeRuntimeContext(context) {
|
|
|
25
25
|
function summarizeMemoryContent(content) {
|
|
26
26
|
return (content.trim().split("\n")[0] || content.trim()).slice(0, 240);
|
|
27
27
|
}
|
|
28
|
+
function normalizeMemoryScope(scope) {
|
|
29
|
+
if (scope === "agent" || scope === "workspace" || scope === "user" || scope === "project") {
|
|
30
|
+
return scope;
|
|
31
|
+
}
|
|
32
|
+
return "session";
|
|
33
|
+
}
|
|
34
|
+
function extractCandidateScopeOptions(candidate) {
|
|
35
|
+
if (candidate.scope) {
|
|
36
|
+
return [normalizeMemoryScope(candidate.scope)];
|
|
37
|
+
}
|
|
38
|
+
const provenance = typeof candidate.provenance === "object" && candidate.provenance !== null && !Array.isArray(candidate.provenance)
|
|
39
|
+
? candidate.provenance
|
|
40
|
+
: undefined;
|
|
41
|
+
const scopeOptions = Array.isArray(provenance?.scopeOptions)
|
|
42
|
+
? provenance.scopeOptions.filter((item) => item === "session" || item === "agent" || item === "workspace" || item === "user" || item === "project")
|
|
43
|
+
: [];
|
|
44
|
+
return scopeOptions.length > 0 ? Array.from(new Set(scopeOptions)) : ["session"];
|
|
45
|
+
}
|
|
28
46
|
function resolveRecallScopes(input, context) {
|
|
29
47
|
if (Array.isArray(input.scopes) && input.scopes.length > 0) {
|
|
30
48
|
return Array.from(new Set(input.scopes));
|
|
@@ -88,14 +106,268 @@ function getMemoryScopeBoost(scope) {
|
|
|
88
106
|
function memoryFreshnessBoost(value) {
|
|
89
107
|
return Math.max(0, 1 - ((Date.now() - Date.parse(value)) / (1000 * 60 * 60 * 24 * 365)));
|
|
90
108
|
}
|
|
91
|
-
function scoreStructuredRecord(
|
|
92
|
-
return (
|
|
109
|
+
function scoreStructuredRecord(record) {
|
|
110
|
+
return (getMemoryScopeBoost(record.scope) +
|
|
93
111
|
memoryFreshnessBoost(record.lastConfirmedAt) +
|
|
94
112
|
record.confidence);
|
|
95
113
|
}
|
|
114
|
+
function characterGramSet(value) {
|
|
115
|
+
const normalized = normalizeCompareText(value).replace(/\s+/g, "");
|
|
116
|
+
const grams = new Set();
|
|
117
|
+
if (normalized.length < 2) {
|
|
118
|
+
if (normalized.length > 0) {
|
|
119
|
+
grams.add(normalized);
|
|
120
|
+
}
|
|
121
|
+
return grams;
|
|
122
|
+
}
|
|
123
|
+
for (let index = 0; index < normalized.length - 1; index += 1) {
|
|
124
|
+
grams.add(normalized.slice(index, index + 2));
|
|
125
|
+
}
|
|
126
|
+
return grams;
|
|
127
|
+
}
|
|
128
|
+
function characterGramSimilarity(left, right) {
|
|
129
|
+
const leftGrams = characterGramSet(left);
|
|
130
|
+
const rightGrams = characterGramSet(right);
|
|
131
|
+
if (leftGrams.size === 0 || rightGrams.size === 0) {
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
let intersection = 0;
|
|
135
|
+
for (const gram of leftGrams) {
|
|
136
|
+
if (rightGrams.has(gram)) {
|
|
137
|
+
intersection += 1;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const union = new Set([...leftGrams, ...rightGrams]).size;
|
|
141
|
+
return union === 0 ? 0 : intersection / union;
|
|
142
|
+
}
|
|
143
|
+
function textSimilarity(left, right) {
|
|
144
|
+
return Math.max(jaccardTextSimilarity(left, right), characterGramSimilarity(left, right));
|
|
145
|
+
}
|
|
146
|
+
function scoreStructuredRecordForQuery(record, query) {
|
|
147
|
+
let score = scoreStructuredRecord(record);
|
|
148
|
+
score += textSimilarity(record.summary, query) * 5;
|
|
149
|
+
score += textSimilarity(record.content, query) * 4;
|
|
150
|
+
if (record.knowledgeIdentity) {
|
|
151
|
+
score += textSimilarity(record.knowledgeIdentity, query) * 2;
|
|
152
|
+
}
|
|
153
|
+
if (record.operationalRule) {
|
|
154
|
+
score += textSimilarity(record.operationalRule.trigger, query) * 3;
|
|
155
|
+
score += textSimilarity(record.operationalRule.target, query) * 2;
|
|
156
|
+
if (record.operationalRule.effect === "invalidate" || record.knowledgeOperation === "delete") {
|
|
157
|
+
score += 0.5;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return score;
|
|
161
|
+
}
|
|
96
162
|
function normalizeMemoryDedupKey(record) {
|
|
97
163
|
return `${record.scope}::${record.summary.toLowerCase().replace(/\s+/g, " ").trim()}::${record.content.toLowerCase().replace(/\s+/g, " ").trim()}`;
|
|
98
164
|
}
|
|
165
|
+
function normalizeCompareText(value) {
|
|
166
|
+
return value.toLowerCase().replace(/\s+/g, " ").trim();
|
|
167
|
+
}
|
|
168
|
+
function tokenizeText(value) {
|
|
169
|
+
return new Set(value
|
|
170
|
+
.toLowerCase()
|
|
171
|
+
.split(/[^a-z0-9_]+/i)
|
|
172
|
+
.map((token) => token.trim())
|
|
173
|
+
.filter((token) => token.length > 2));
|
|
174
|
+
}
|
|
175
|
+
function jaccardTextSimilarity(left, right) {
|
|
176
|
+
const leftTokens = tokenizeText(left);
|
|
177
|
+
const rightTokens = tokenizeText(right);
|
|
178
|
+
if (leftTokens.size === 0 || rightTokens.size === 0) {
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
181
|
+
let intersection = 0;
|
|
182
|
+
for (const token of leftTokens) {
|
|
183
|
+
if (rightTokens.has(token)) {
|
|
184
|
+
intersection += 1;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const union = new Set([...leftTokens, ...rightTokens]).size;
|
|
188
|
+
return union === 0 ? 0 : intersection / union;
|
|
189
|
+
}
|
|
190
|
+
function containsDeletionSignal(value) {
|
|
191
|
+
const normalized = normalizeCompareText(value);
|
|
192
|
+
if (!normalized) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
return [
|
|
196
|
+
"delete",
|
|
197
|
+
"deleted",
|
|
198
|
+
"remove",
|
|
199
|
+
"removed",
|
|
200
|
+
"revoked",
|
|
201
|
+
"forbidden",
|
|
202
|
+
"not allowed",
|
|
203
|
+
"no longer",
|
|
204
|
+
"unavailable",
|
|
205
|
+
"disabled",
|
|
206
|
+
"deprecated",
|
|
207
|
+
"取消",
|
|
208
|
+
"撤销",
|
|
209
|
+
"删除",
|
|
210
|
+
"已删除",
|
|
211
|
+
"删掉",
|
|
212
|
+
"移除",
|
|
213
|
+
"不再",
|
|
214
|
+
"不可用",
|
|
215
|
+
"不能",
|
|
216
|
+
"无法",
|
|
217
|
+
"禁用",
|
|
218
|
+
"废弃",
|
|
219
|
+
].some((signal) => normalized.includes(signal));
|
|
220
|
+
}
|
|
221
|
+
function extractSalientLiterals(value) {
|
|
222
|
+
const results = new Set();
|
|
223
|
+
const normalized = value.trim();
|
|
224
|
+
if (!normalized) {
|
|
225
|
+
return results;
|
|
226
|
+
}
|
|
227
|
+
for (const match of normalized.matchAll(/[`'"]([^`'"]{1,64})[`'"]/g)) {
|
|
228
|
+
const literal = match[1]?.trim().toLowerCase();
|
|
229
|
+
if (literal && literal.length >= 2) {
|
|
230
|
+
results.add(literal);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
for (const match of normalized.matchAll(/\b[a-z][a-z0-9._/-]{1,63}\b/gi)) {
|
|
234
|
+
const token = match[0]?.trim().toLowerCase();
|
|
235
|
+
if (token && !["system", "startup", "command", "memory", "instruction", "user", "deleted"].includes(token)) {
|
|
236
|
+
results.add(token);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return results;
|
|
240
|
+
}
|
|
241
|
+
function sharesSalientLiteral(left, right) {
|
|
242
|
+
const leftLiterals = extractSalientLiterals(left);
|
|
243
|
+
const rightLiterals = extractSalientLiterals(right);
|
|
244
|
+
if (leftLiterals.size === 0 || rightLiterals.size === 0) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
for (const literal of leftLiterals) {
|
|
248
|
+
if (rightLiterals.has(literal)) {
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
function mergeScoredRecords(...groups) {
|
|
255
|
+
const merged = new Map();
|
|
256
|
+
for (const group of groups) {
|
|
257
|
+
for (const item of group) {
|
|
258
|
+
const existing = merged.get(item.record.id);
|
|
259
|
+
if (!existing || item.score > existing.score) {
|
|
260
|
+
merged.set(item.record.id, item);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return Array.from(merged.values())
|
|
265
|
+
.sort((left, right) => right.score - left.score || right.record.lastConfirmedAt.localeCompare(left.record.lastConfirmedAt))
|
|
266
|
+
.map((item) => item.record);
|
|
267
|
+
}
|
|
268
|
+
function selectRelevantExistingRecords(candidates, existingRecords) {
|
|
269
|
+
const scored = new Map();
|
|
270
|
+
for (const candidate of candidates) {
|
|
271
|
+
const candidateScopes = new Set(extractCandidateScopeOptions(candidate));
|
|
272
|
+
const content = normalizeCompareText(candidate.content);
|
|
273
|
+
const summary = normalizeCompareText(candidate.summary ?? summarizeMemoryContent(candidate.content));
|
|
274
|
+
const sourceRef = typeof candidate.sourceRef === "string" ? candidate.sourceRef.trim() : "";
|
|
275
|
+
const candidateText = `${candidate.summary ?? ""}\n${candidate.content}`;
|
|
276
|
+
const deletionSignal = containsDeletionSignal(candidateText);
|
|
277
|
+
for (const record of existingRecords) {
|
|
278
|
+
if (!candidateScopes.has(record.scope)) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
let score = 0;
|
|
282
|
+
let deterministicMatch = false;
|
|
283
|
+
if (sourceRef && record.sourceRefs.includes(sourceRef)) {
|
|
284
|
+
score += 10;
|
|
285
|
+
deterministicMatch = true;
|
|
286
|
+
}
|
|
287
|
+
if (normalizeCompareText(record.content) === content) {
|
|
288
|
+
score += 9;
|
|
289
|
+
deterministicMatch = true;
|
|
290
|
+
}
|
|
291
|
+
if (normalizeCompareText(record.summary) === summary) {
|
|
292
|
+
score += 8;
|
|
293
|
+
deterministicMatch = true;
|
|
294
|
+
}
|
|
295
|
+
const similarityScore = textSimilarity(record.summary, candidate.summary ?? candidate.content) * 4
|
|
296
|
+
+ textSimilarity(record.content, candidate.content) * 3;
|
|
297
|
+
score += similarityScore;
|
|
298
|
+
if (deletionSignal) {
|
|
299
|
+
const ruleTarget = record.operationalRule?.target?.trim().toLowerCase();
|
|
300
|
+
if (ruleTarget && candidateText.toLowerCase().includes(ruleTarget)) {
|
|
301
|
+
score += 12;
|
|
302
|
+
deterministicMatch = true;
|
|
303
|
+
}
|
|
304
|
+
if (sharesSalientLiteral(candidateText, `${record.summary}\n${record.content}`)) {
|
|
305
|
+
score += 8;
|
|
306
|
+
deterministicMatch = true;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (!deterministicMatch && similarityScore < 1) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
if (score <= 0) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
const existing = scored.get(record.id);
|
|
316
|
+
if (!existing || score > existing.score) {
|
|
317
|
+
scored.set(record.id, { record, score });
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return Array.from(scored.values())
|
|
322
|
+
.sort((left, right) => right.score - left.score || right.record.lastConfirmedAt.localeCompare(left.record.lastConfirmedAt))
|
|
323
|
+
.map((item) => item.record);
|
|
324
|
+
}
|
|
325
|
+
async function selectVectorRelevantExistingRecords(input) {
|
|
326
|
+
const vectorStore = await input.resolveVectorStore();
|
|
327
|
+
if (!vectorStore) {
|
|
328
|
+
return [];
|
|
329
|
+
}
|
|
330
|
+
const existingById = new Map(input.existingRecords.map((record) => [record.id, record]));
|
|
331
|
+
const scored = new Map();
|
|
332
|
+
try {
|
|
333
|
+
for (const candidate of input.candidates) {
|
|
334
|
+
const candidateScopes = new Set(extractCandidateScopeOptions(candidate));
|
|
335
|
+
const query = [candidate.summary?.trim(), candidate.content.trim()].filter((value) => !!value && value.length > 0).join("\n");
|
|
336
|
+
if (!query) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
const hits = await vectorStore.similaritySearch(query, 8);
|
|
340
|
+
for (const hit of hits) {
|
|
341
|
+
const metadata = typeof hit.metadata === "object" && hit.metadata !== null && !Array.isArray(hit.metadata)
|
|
342
|
+
? hit.metadata
|
|
343
|
+
: {};
|
|
344
|
+
const recordId = typeof metadata.recordId === "string" ? metadata.recordId : undefined;
|
|
345
|
+
if (!recordId) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
const record = existingById.get(recordId);
|
|
349
|
+
if (!record || record.status !== "active" || !candidateScopes.has(record.scope)) {
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
const score = (typeof hit.score === "number" ? hit.score : 0) + scoreStructuredRecordForQuery(record, query);
|
|
353
|
+
const existing = scored.get(record.id);
|
|
354
|
+
if (!existing || score > existing.score) {
|
|
355
|
+
scored.set(record.id, { record, score });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
return [];
|
|
362
|
+
}
|
|
363
|
+
return Array.from(scored.values())
|
|
364
|
+
.sort((left, right) => right.score - left.score || right.record.lastConfirmedAt.localeCompare(left.record.lastConfirmedAt));
|
|
365
|
+
}
|
|
366
|
+
function sortPromptRecallRecords(items) {
|
|
367
|
+
return [...items].sort((left, right) => left.record.observedAt.localeCompare(right.record.observedAt)
|
|
368
|
+
|| left.record.createdAt.localeCompare(right.record.createdAt)
|
|
369
|
+
|| left.record.id.localeCompare(right.record.id));
|
|
370
|
+
}
|
|
99
371
|
function inferMem0MemoryKind(hit) {
|
|
100
372
|
const candidates = [
|
|
101
373
|
...hit.categories,
|
|
@@ -187,7 +459,10 @@ export class DefaultKnowledgeModule {
|
|
|
187
459
|
requestId,
|
|
188
460
|
sessionId,
|
|
189
461
|
recordedAt,
|
|
190
|
-
}, {
|
|
462
|
+
}, {
|
|
463
|
+
storeCandidateLog: input.storeCandidateLog !== false,
|
|
464
|
+
forceStore: input.forceStore === true,
|
|
465
|
+
});
|
|
191
466
|
}
|
|
192
467
|
async recall(input, context) {
|
|
193
468
|
if (typeof input.query !== "string" || input.query.trim().length === 0) {
|
|
@@ -211,7 +486,10 @@ export class DefaultKnowledgeModule {
|
|
|
211
486
|
.map(({ record }) => record);
|
|
212
487
|
return { items };
|
|
213
488
|
}
|
|
214
|
-
async
|
|
489
|
+
async buildPromptRecall(input, context) {
|
|
490
|
+
if (!shouldRecallDurableMemory(input.query)) {
|
|
491
|
+
return { items: [] };
|
|
492
|
+
}
|
|
215
493
|
const normalizedContext = normalizeRuntimeContext(context);
|
|
216
494
|
const ranked = (await this.rankRecallCandidates({
|
|
217
495
|
query: input.query,
|
|
@@ -230,6 +508,8 @@ export class DefaultKnowledgeModule {
|
|
|
230
508
|
? 2
|
|
231
509
|
: 1;
|
|
232
510
|
return {
|
|
511
|
+
record: item.record,
|
|
512
|
+
scope: item.record.scope,
|
|
233
513
|
content: [
|
|
234
514
|
`# Durable ${item.record.scope[0].toUpperCase()}${item.record.scope.slice(1)} Memory`,
|
|
235
515
|
"",
|
|
@@ -237,20 +517,38 @@ export class DefaultKnowledgeModule {
|
|
|
237
517
|
`- kind: ${item.record.kind}`,
|
|
238
518
|
`- scope: ${item.record.scope}`,
|
|
239
519
|
`- confidence: ${item.record.confidence.toFixed(2)}`,
|
|
520
|
+
...(item.record.knowledgeIdentity
|
|
521
|
+
? [
|
|
522
|
+
`- knowledge_identity: ${item.record.knowledgeIdentity}`,
|
|
523
|
+
`- knowledge_operation: ${item.record.knowledgeOperation ?? "create"}`,
|
|
524
|
+
]
|
|
525
|
+
: []),
|
|
240
526
|
"",
|
|
241
527
|
item.record.content,
|
|
242
528
|
].join("\n"),
|
|
243
|
-
score:
|
|
529
|
+
score: scopeBoost +
|
|
244
530
|
memoryFreshnessBoost(item.record.lastConfirmedAt) +
|
|
245
531
|
item.record.confidence,
|
|
246
532
|
};
|
|
247
533
|
})
|
|
248
|
-
.sort((left, right) => right.score - left.score)
|
|
249
|
-
.slice(0, this.deps.policy?.retrieval.maxPromptMemories ?? 8);
|
|
534
|
+
.sort((left, right) => right.score - left.score);
|
|
250
535
|
if (ranked.length === 0) {
|
|
251
|
-
return
|
|
536
|
+
return { items: [] };
|
|
252
537
|
}
|
|
253
|
-
|
|
538
|
+
const maxPromptMemories = this.deps.policy?.retrieval.maxPromptMemories ?? 8;
|
|
539
|
+
const selected = ranked.slice(0, maxPromptMemories);
|
|
540
|
+
if (selected.length === 0) {
|
|
541
|
+
return { items: [] };
|
|
542
|
+
}
|
|
543
|
+
const orderedSelected = sortPromptRecallRecords(selected);
|
|
544
|
+
return {
|
|
545
|
+
items: orderedSelected.map((entry) => entry.record),
|
|
546
|
+
context: orderedSelected.map((entry) => entry.content).join("\n\n"),
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
async buildPromptContext(input, context) {
|
|
550
|
+
const promptRecall = await this.buildPromptRecall(input, context);
|
|
551
|
+
return promptRecall.context;
|
|
254
552
|
}
|
|
255
553
|
async list(input = {}, context) {
|
|
256
554
|
const normalizedContext = { ...context };
|
|
@@ -305,6 +603,12 @@ export class DefaultKnowledgeModule {
|
|
|
305
603
|
tags: Array.isArray(input.tags)
|
|
306
604
|
? Array.from(new Set(input.tags.map((item) => item.trim()).filter((item) => item.length > 0)))
|
|
307
605
|
: existing.tags,
|
|
606
|
+
knowledgeIdentity: typeof input.knowledgeIdentity === "string" && input.knowledgeIdentity.trim().length > 0
|
|
607
|
+
? input.knowledgeIdentity.trim()
|
|
608
|
+
: existing.knowledgeIdentity,
|
|
609
|
+
knowledgeOperation: input.knowledgeOperation === "create" || input.knowledgeOperation === "update" || input.knowledgeOperation === "delete"
|
|
610
|
+
? input.knowledgeOperation
|
|
611
|
+
: existing.knowledgeOperation,
|
|
308
612
|
observedAt: typeof input.observedAt === "string" && input.observedAt.trim().length > 0 ? input.observedAt : existing.observedAt,
|
|
309
613
|
lastConfirmedAt: typeof input.lastConfirmedAt === "string" && input.lastConfirmedAt.trim().length > 0
|
|
310
614
|
? input.lastConfirmedAt
|
|
@@ -339,21 +643,39 @@ export class DefaultKnowledgeModule {
|
|
|
339
643
|
if (validCandidates.length === 0) {
|
|
340
644
|
return { records: [], decisions: [] };
|
|
341
645
|
}
|
|
342
|
-
const
|
|
646
|
+
const relevantScopes = Array.from(new Set(validCandidates.flatMap((candidate) => extractCandidateScopeOptions(candidate))));
|
|
647
|
+
const existingRecords = await listMemoryRecordsForScopes(this.deps.store, relevantScopes);
|
|
648
|
+
const vectorRelatedExistingRecords = await selectVectorRelevantExistingRecords({
|
|
649
|
+
candidates: validCandidates,
|
|
650
|
+
existingRecords,
|
|
651
|
+
resolveVectorStore: this.deps.resolveVectorStore,
|
|
652
|
+
});
|
|
653
|
+
const deterministicRelatedExistingRecords = selectRelevantExistingRecords(validCandidates, existingRecords)
|
|
654
|
+
.map((record) => ({
|
|
655
|
+
record,
|
|
656
|
+
score: scoreStructuredRecord(record),
|
|
657
|
+
}));
|
|
658
|
+
const relatedExistingRecords = mergeScoredRecords(vectorRelatedExistingRecords, deterministicRelatedExistingRecords);
|
|
343
659
|
const transformedCandidates = this.deps.transformCandidates
|
|
344
|
-
? await this.deps.transformCandidates({ candidates: validCandidates, context: normalizedContext, existingRecords })
|
|
660
|
+
? await this.deps.transformCandidates({ candidates: validCandidates, context: normalizedContext, existingRecords: relatedExistingRecords })
|
|
345
661
|
: validCandidates;
|
|
662
|
+
const storedCandidates = options.forceStore === true
|
|
663
|
+
? transformedCandidates
|
|
664
|
+
: transformedCandidates.filter((candidate) => shouldStoreMemoryCandidate(this.deps.policy, candidate));
|
|
665
|
+
if (storedCandidates.length === 0) {
|
|
666
|
+
return { records: [], decisions: [] };
|
|
667
|
+
}
|
|
346
668
|
if (options.storeCandidateLog) {
|
|
347
669
|
await this.deps.store.put(["memories", "candidates", normalizedContext.sessionId ?? `memory-api-${normalizedContext.requestId ?? "unknown"}`], `${normalizedContext.requestId}.json`, {
|
|
348
670
|
requestId: normalizedContext.requestId,
|
|
349
671
|
sessionId: normalizedContext.sessionId,
|
|
350
672
|
storedAt: normalizedContext.recordedAt,
|
|
351
|
-
candidates:
|
|
673
|
+
candidates: storedCandidates,
|
|
352
674
|
});
|
|
353
675
|
}
|
|
354
676
|
const persisted = await persistStructuredMemoryRecords({
|
|
355
677
|
store: this.deps.store,
|
|
356
|
-
candidates:
|
|
678
|
+
candidates: storedCandidates,
|
|
357
679
|
sessionId: normalizedContext.sessionId ?? `memory-api-${normalizedContext.requestId ?? "unknown"}`,
|
|
358
680
|
requestId: normalizedContext.requestId ?? createPersistentId(new Date(normalizedContext.recordedAt ?? new Date().toISOString())),
|
|
359
681
|
agentId: normalizedContext.agentId,
|
|
@@ -363,7 +685,7 @@ export class DefaultKnowledgeModule {
|
|
|
363
685
|
recordedAt: normalizedContext.recordedAt ?? new Date().toISOString(),
|
|
364
686
|
});
|
|
365
687
|
await this.rebuildVectorIndex();
|
|
366
|
-
await this.refreshAfterWrite(
|
|
688
|
+
await this.refreshAfterWrite(storedCandidates, normalizedContext);
|
|
367
689
|
return persisted;
|
|
368
690
|
}
|
|
369
691
|
async refreshAfterWrite(candidates, context) {
|
|
@@ -489,7 +811,7 @@ export class DefaultKnowledgeModule {
|
|
|
489
811
|
.filter((record) => (input.kinds ? input.kinds.has(record.kind) : true))
|
|
490
812
|
.map((record) => ({
|
|
491
813
|
record,
|
|
492
|
-
score:
|
|
814
|
+
score: scoreStructuredRecordForQuery(record, input.query),
|
|
493
815
|
}));
|
|
494
816
|
const deduped = new Map();
|
|
495
817
|
for (const item of ranked) {
|
|
@@ -528,7 +850,7 @@ export class DefaultKnowledgeModule {
|
|
|
528
850
|
continue;
|
|
529
851
|
}
|
|
530
852
|
const key = normalizeMemoryDedupKey(canonical);
|
|
531
|
-
const score =
|
|
853
|
+
const score = scoreStructuredRecordForQuery(canonical, input.query) + (typeof hit.score === "number" ? hit.score : 0);
|
|
532
854
|
const existing = deduped.get(key);
|
|
533
855
|
if (!existing || score > existing.score) {
|
|
534
856
|
deduped.set(key, { record: canonical, score });
|
|
@@ -571,7 +893,7 @@ export class DefaultKnowledgeModule {
|
|
|
571
893
|
}
|
|
572
894
|
deduped.set(key, {
|
|
573
895
|
record,
|
|
574
|
-
score:
|
|
896
|
+
score: scoreStructuredRecordForQuery(record, input.query) + Math.max(0, Math.min(1, hit.score)) * 4,
|
|
575
897
|
});
|
|
576
898
|
}
|
|
577
899
|
return Array.from(deduped.values()).sort((left, right) => right.score - left.score);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.299";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.299";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ArtifactListing, ArtifactRecord, HarnessEvent, InternalApprovalRecord, RequestSummary, RequestState, SessionRequestRecord, SessionSummary, TranscriptMessage } from "../contracts/types.js";
|
|
1
|
+
import type { ArtifactListing, ArtifactRecord, HarnessEvent, InternalApprovalRecord, RequestPlanState, RequestSummary, RequestState, SessionRequestRecord, SessionSummary, TranscriptMessage } from "../contracts/types.js";
|
|
2
2
|
import type { ApprovalFilter, PersistedSessionListSummary, PersistedRequestInput, PersistedRequestControlRecord, PersistedRunInspection, PersistedRequestQueueRecord, PersistenceLifecycle as Lifecycle, PersistenceRequestMeta as RequestMeta, RuntimePersistence, RecoveryIntent, PersistenceSessionMeta as SessionMeta, RequestSummaryFilter, SessionSummaryFilter } from "./types.js";
|
|
3
3
|
type RequestIndexRecord = {
|
|
4
4
|
requestId: string;
|
|
@@ -17,6 +17,7 @@ export declare class FilePersistence implements RuntimePersistence {
|
|
|
17
17
|
private requestQueuePath;
|
|
18
18
|
private requestControlPath;
|
|
19
19
|
private traceItemsPath;
|
|
20
|
+
private requestPlanStatePath;
|
|
20
21
|
private writeSessionHead;
|
|
21
22
|
initialize(): Promise<void>;
|
|
22
23
|
sessionDir(sessionId: string): string;
|
|
@@ -73,6 +74,9 @@ export declare class FilePersistence implements RuntimePersistence {
|
|
|
73
74
|
clearRequestInput(sessionId: string, requestId: string): Promise<void>;
|
|
74
75
|
createApproval(record: InternalApprovalRecord): Promise<void>;
|
|
75
76
|
resolveApproval(sessionId: string, requestId: string, approvalId: string, status: InternalApprovalRecord["status"]): Promise<InternalApprovalRecord>;
|
|
77
|
+
saveRequestPlanState(sessionId: string, requestId: string, planState: RequestPlanState): Promise<void>;
|
|
78
|
+
getRequestPlanState(sessionId: string, requestId: string): Promise<RequestPlanState | null>;
|
|
79
|
+
clearRequestPlanState(sessionId: string, requestId: string): Promise<void>;
|
|
76
80
|
createRequestArtifact(sessionId: string, requestId: string, artifact: ArtifactRecord, content: unknown): Promise<ArtifactRecord>;
|
|
77
81
|
listRequestArtifacts(sessionId: string, requestId: string): Promise<ArtifactListing>;
|
|
78
82
|
readRequestArtifact(sessionId: string, requestId: string, artifactPath: string): Promise<unknown>;
|
|
@@ -31,6 +31,9 @@ export class FilePersistence {
|
|
|
31
31
|
traceItemsPath(sessionId, requestId) {
|
|
32
32
|
return path.join(this.requestDir(sessionId, requestId), "trace-items.ndjson");
|
|
33
33
|
}
|
|
34
|
+
requestPlanStatePath(sessionId, requestId) {
|
|
35
|
+
return path.join(this.requestDir(sessionId, requestId), "plan-state.json");
|
|
36
|
+
}
|
|
34
37
|
async writeSessionHead(sessionId, input) {
|
|
35
38
|
const sessionMetaPath = path.join(this.sessionDir(sessionId), "meta.json");
|
|
36
39
|
const sessionMeta = await readJson(sessionMetaPath);
|
|
@@ -540,6 +543,19 @@ export class FilePersistence {
|
|
|
540
543
|
]);
|
|
541
544
|
return updated;
|
|
542
545
|
}
|
|
546
|
+
async saveRequestPlanState(sessionId, requestId, planState) {
|
|
547
|
+
await writeJson(this.requestPlanStatePath(sessionId, requestId), planState);
|
|
548
|
+
}
|
|
549
|
+
async getRequestPlanState(sessionId, requestId) {
|
|
550
|
+
const planStatePath = this.requestPlanStatePath(sessionId, requestId);
|
|
551
|
+
if (!(await fileExists(planStatePath))) {
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
return readJson(planStatePath);
|
|
555
|
+
}
|
|
556
|
+
async clearRequestPlanState(sessionId, requestId) {
|
|
557
|
+
await rm(this.requestPlanStatePath(sessionId, requestId), { force: true });
|
|
558
|
+
}
|
|
543
559
|
async createRequestArtifact(sessionId, requestId, artifact, content) {
|
|
544
560
|
const requestDir = this.requestDir(sessionId, requestId);
|
|
545
561
|
await writeJson(path.join(requestDir, artifact.path), content);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ArtifactListing, ArtifactRecord, HarnessEvent, InternalApprovalRecord, RequestSummary, RequestState, SessionRequestRecord, SessionSummary, TranscriptMessage } from "../contracts/types.js";
|
|
1
|
+
import type { ArtifactListing, ArtifactRecord, HarnessEvent, InternalApprovalRecord, RequestPlanState, RequestSummary, RequestState, SessionRequestRecord, SessionSummary, TranscriptMessage } from "../contracts/types.js";
|
|
2
2
|
import type { PersistedSessionListSummary, PersistenceSessionMeta, PersistedRequestInput, PersistedRequestControlRecord, PersistedRunInspection, PersistedRequestQueueRecord, PersistenceLifecycle, PersistenceRequestMeta, RecoveryIntent, RuntimePersistence, ApprovalFilter, RequestSummaryFilter, SessionSummaryFilter } from "./types.js";
|
|
3
3
|
export declare function listProtectedCheckpointSessionIds(dbPath: string): Promise<Set<string>>;
|
|
4
4
|
export declare class SqlitePersistence implements RuntimePersistence {
|
|
@@ -92,6 +92,9 @@ export declare class SqlitePersistence implements RuntimePersistence {
|
|
|
92
92
|
clearRequestInput(sessionId: string, requestId: string): Promise<void>;
|
|
93
93
|
createApproval(record: InternalApprovalRecord): Promise<void>;
|
|
94
94
|
resolveApproval(sessionId: string, requestId: string, approvalId: string, status: InternalApprovalRecord["status"]): Promise<InternalApprovalRecord>;
|
|
95
|
+
saveRequestPlanState(sessionId: string, requestId: string, planState: RequestPlanState): Promise<void>;
|
|
96
|
+
getRequestPlanState(sessionId: string, requestId: string): Promise<RequestPlanState | null>;
|
|
97
|
+
clearRequestPlanState(sessionId: string, requestId: string): Promise<void>;
|
|
95
98
|
createRequestArtifact(sessionId: string, requestId: string, artifact: ArtifactRecord, content: unknown): Promise<ArtifactRecord>;
|
|
96
99
|
listRequestArtifacts(sessionId: string, requestId: string): Promise<ArtifactListing>;
|
|
97
100
|
appendSessionMessage(sessionId: string, message: TranscriptMessage): Promise<void>;
|