@openviking/openclaw-plugin 2026.6.2 → 2026.6.17-dev.2
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/INSTALL-AGENT.md +4 -4
- package/INSTALL-ZH.md +68 -8
- package/INSTALL.md +12 -8
- package/README.md +45 -35
- package/adapters/http-transport.ts +3 -0
- package/adapters/resource-packager.ts +141 -0
- package/auto-recall.ts +258 -27
- package/client.ts +201 -177
- package/commands/setup.ts +200 -33
- package/config/feature-gates.json +10 -0
- package/config.ts +428 -85
- package/context-engine.ts +71 -1402
- package/dist/adapters/http-transport.js +1 -0
- package/dist/adapters/resource-packager.js +114 -0
- package/dist/auto-recall.js +201 -25
- package/dist/client.js +125 -161
- package/dist/commands/setup.js +170 -32
- package/dist/config.js +285 -64
- package/dist/context-engine.js +62 -1173
- package/dist/index.js +209 -1489
- package/dist/memory-ranking.js +35 -12
- package/dist/plugin/command-registration.js +5 -0
- package/dist/plugin/openviking-archive-tools.js +210 -0
- package/dist/plugin/openviking-bypass-runtime.js +8 -0
- package/dist/plugin/openviking-client-runtime.js +28 -0
- package/dist/plugin/openviking-command-args.js +146 -0
- package/dist/plugin/openviking-command-definitions.js +206 -0
- package/dist/plugin/openviking-context-engine-ref.js +11 -0
- package/dist/plugin/openviking-context-engine-registration.js +23 -0
- package/dist/plugin/openviking-feature-gates.js +250 -0
- package/dist/plugin/openviking-import-runtime.js +50 -0
- package/dist/plugin/openviking-import-tools.js +86 -0
- package/dist/plugin/openviking-lifecycle-hooks.js +33 -0
- package/dist/plugin/openviking-memory-recall-tools.js +233 -0
- package/dist/plugin/openviking-memory-tools.js +199 -0
- package/dist/plugin/openviking-query-config-command.js +203 -0
- package/dist/plugin/openviking-query-runtime.js +367 -0
- package/dist/plugin/openviking-query-tools.js +91 -0
- package/dist/plugin/openviking-recall-trace-runtime.js +387 -0
- package/dist/plugin/openviking-recall-trace-tools.js +38 -0
- package/dist/plugin/openviking-runtime-state.js +26 -0
- package/dist/plugin/openviking-runtime-utils.js +62 -0
- package/dist/plugin/openviking-services.js +20 -0
- package/dist/plugin/openviking-session-routing-runtime.js +61 -0
- package/dist/plugin/openviking-tool-result-tools.js +268 -0
- package/dist/plugin/recall-trace-routes.js +77 -0
- package/dist/plugin/tool-registration.js +23 -0
- package/dist/process-manager.js +1 -1
- package/dist/query-config.js +336 -0
- package/dist/recall-trace.js +309 -0
- package/dist/registries/recall-resource-types.js +58 -0
- package/dist/routing/identity-routing.js +152 -0
- package/dist/routing/memory-uri.js +7 -0
- package/dist/services/context-lifecycle-service.js +847 -0
- package/dist/services/context-message-adapter.js +340 -0
- package/dist/session-transcript-repair.js +0 -1
- package/dist/text-utils.js +14 -31
- package/index.ts +271 -1873
- package/install-manifest.json +10 -1
- package/memory-ranking.ts +46 -10
- package/openclaw.plugin.json +198 -36
- package/package.json +14 -4
- package/plugin/command-registration.ts +34 -0
- package/plugin/openviking-archive-tools.ts +301 -0
- package/plugin/openviking-bypass-runtime.ts +26 -0
- package/plugin/openviking-client-runtime.ts +74 -0
- package/plugin/openviking-command-args.ts +187 -0
- package/plugin/openviking-command-definitions.ts +294 -0
- package/plugin/openviking-context-engine-ref.ts +16 -0
- package/plugin/openviking-context-engine-registration.ts +97 -0
- package/plugin/openviking-feature-gates.ts +335 -0
- package/plugin/openviking-import-runtime.ts +105 -0
- package/plugin/openviking-import-tools.ts +133 -0
- package/plugin/openviking-lifecycle-hooks.ts +65 -0
- package/plugin/openviking-memory-recall-tools.ts +368 -0
- package/plugin/openviking-memory-tools.ts +299 -0
- package/plugin/openviking-query-config-command.ts +230 -0
- package/plugin/openviking-query-formatters.ts +108 -0
- package/plugin/openviking-query-runtime.ts +476 -0
- package/plugin/openviking-query-tools.ts +161 -0
- package/plugin/openviking-recall-trace-runtime.ts +482 -0
- package/plugin/openviking-recall-trace-tools.ts +99 -0
- package/plugin/openviking-runtime-state.ts +52 -0
- package/plugin/openviking-runtime-utils.ts +67 -0
- package/plugin/openviking-services.ts +49 -0
- package/plugin/openviking-session-routing-runtime.ts +105 -0
- package/plugin/openviking-tool-result-tools.ts +397 -0
- package/plugin/recall-trace-routes.ts +133 -0
- package/plugin/tool-registration.ts +51 -0
- package/process-manager.ts +1 -1
- package/query-config.ts +400 -0
- package/recall-trace.ts +442 -0
- package/registries/openviking-tools.ts +84 -0
- package/registries/recall-resource-types.ts +74 -0
- package/routing/identity-routing.ts +210 -0
- package/routing/memory-uri.ts +8 -0
- package/services/context-lifecycle-service.ts +1209 -0
- package/services/context-message-adapter.ts +375 -0
- package/services/setup/config-writer.ts +125 -0
- package/services/setup/exit-utils.ts +5 -0
- package/services/setup/package-metadata.ts +56 -0
- package/services/setup/probe-service.ts +143 -0
- package/services/setup/setup-flow.ts +306 -0
- package/services/setup/version-compatibility.ts +41 -0
- package/session-transcript-repair.ts +0 -2
- package/skills/install-openviking-memory/SKILL.md +123 -50
- package/skills/openviking-context-database/SKILL.md +286 -0
- package/text-utils.ts +15 -34
package/auto-recall.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FindResult, FindResultItem, OpenVikingClient } from "./client.js";
|
|
2
2
|
import type { MemoryOpenVikingConfig } from "./config.js";
|
|
3
|
+
import type { EffectiveQueryConfig } from "./query-config.js";
|
|
3
4
|
import {
|
|
4
5
|
pickMemoriesForInjection,
|
|
5
6
|
postProcessMemories,
|
|
@@ -7,6 +8,14 @@ import {
|
|
|
7
8
|
toJsonLog,
|
|
8
9
|
} from "./memory-ranking.js";
|
|
9
10
|
import { quickRecallPrecheck, withTimeout } from "./process-manager.js";
|
|
11
|
+
import {
|
|
12
|
+
resolveRecallSearchPlan,
|
|
13
|
+
type RecallResourceType,
|
|
14
|
+
} from "./registries/recall-resource-types.js";
|
|
15
|
+
import {
|
|
16
|
+
type RecallTraceEntry,
|
|
17
|
+
type RecallTraceResult,
|
|
18
|
+
} from "./recall-trace.js";
|
|
10
19
|
import { sanitizeUserTextForCapture } from "./text-utils.js";
|
|
11
20
|
import { estimateTextTokens } from "./token-estimator.js";
|
|
12
21
|
|
|
@@ -19,6 +28,34 @@ type Logger = {
|
|
|
19
28
|
warn?: (msg: string) => void;
|
|
20
29
|
};
|
|
21
30
|
|
|
31
|
+
const WRITE_OR_EFFECT_RE =
|
|
32
|
+
/\b(write|edit|modify|delete|remove|migrate|deploy|release|publish|configure|patch)\b|写|改|修改|删除|迁移|部署|发布|配置|打补丁/i;
|
|
33
|
+
const EXECUTION_RE =
|
|
34
|
+
/\b(fix|debug|test|build|run|implement|refactor|integrate|repair|troubleshoot)\b|修复|调试|测试|构建|运行|实现|重构|对接|排查/i;
|
|
35
|
+
const FAILURE_RE =
|
|
36
|
+
/\b(error|exception|traceback|failed|failure|retry|exit code|test failed)\b|报错|异常|失败|重试|挂了|不通过/i;
|
|
37
|
+
const ENGINEERING_OBJECT_RE =
|
|
38
|
+
/(?:^|\s)(?:[\w.-]+\/[\w./-]+|[\w./-]+\.(?:ts|tsx|js|jsx|py|go|rs|java|md|json|ya?ml|toml|sh|sql))\b|`[^`]+`|\b(?:repo|workspace|plugin|service|component|hook|api|tool|package|module)\b|仓库|工作区|插件|服务|组件|接口|工具|模块|文件/i;
|
|
39
|
+
const EXPERIENCE_INTENT_RE =
|
|
40
|
+
/经验|踩坑|最佳实践|不要再|按之前|avoid|best practice|lesson|pitfall/i;
|
|
41
|
+
const QUESTION_ONLY_RE =
|
|
42
|
+
/^(?:什么是|是什么|区别|解释|讲讲|怎么看|为什么|如何理解|where is|what is|explain|difference between)\b|[??]$/i;
|
|
43
|
+
const CASUAL_RE = /闲聊|翻译|总结当前对话|天气|笑话|hello|hi\b|你好/i;
|
|
44
|
+
|
|
45
|
+
export type ExperienceRecallTrigger =
|
|
46
|
+
| "task_start"
|
|
47
|
+
| "skill_load"
|
|
48
|
+
| "subagent_start"
|
|
49
|
+
| "write_preflight"
|
|
50
|
+
| "cron_start";
|
|
51
|
+
|
|
52
|
+
export type ExperienceRecallDecision = {
|
|
53
|
+
recall: boolean;
|
|
54
|
+
trigger?: ExperienceRecallTrigger;
|
|
55
|
+
score: number;
|
|
56
|
+
reason: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
22
59
|
export type PreparedRecallQuery = {
|
|
23
60
|
query: string;
|
|
24
61
|
truncated: boolean;
|
|
@@ -185,15 +222,111 @@ export function buildRecallContextBlock(memoryLines: string[]): string {
|
|
|
185
222
|
].join("\n");
|
|
186
223
|
}
|
|
187
224
|
|
|
225
|
+
function newTraceId(): string {
|
|
226
|
+
return `recall_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function preview(value: string | undefined, maxChars: number): string | undefined {
|
|
230
|
+
const trimmed = value?.trim();
|
|
231
|
+
if (!trimmed) return undefined;
|
|
232
|
+
return trimmed.length > maxChars ? trimmed.slice(0, maxChars) : trimmed;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function toTraceResults(items: FindResultItem[], resourceType: RecallResourceType): RecallTraceResult[] {
|
|
236
|
+
return items.map((item) => ({
|
|
237
|
+
uri: item.uri,
|
|
238
|
+
resourceType,
|
|
239
|
+
category: item.category,
|
|
240
|
+
score: item.score,
|
|
241
|
+
level: item.level,
|
|
242
|
+
abstractPreview: preview(item.abstract ?? item.overview, 240),
|
|
243
|
+
resultType: resourceType === "resource" ? "resource" : "memory",
|
|
244
|
+
}));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function boundTraceQuery(query: string, maxChars: number): { query: string; queryTruncated?: boolean } {
|
|
248
|
+
if (query.length <= maxChars) {
|
|
249
|
+
return { query };
|
|
250
|
+
}
|
|
251
|
+
return { query: query.slice(0, maxChars), queryTruncated: true };
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function runtimeFlag(runtimeContext: unknown, key: string): unknown {
|
|
255
|
+
return runtimeContext && typeof runtimeContext === "object"
|
|
256
|
+
? (runtimeContext as Record<string, unknown>)[key]
|
|
257
|
+
: undefined;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export function isCronSession(sessionKey?: string, runtimeContext?: unknown): boolean {
|
|
261
|
+
return Boolean(
|
|
262
|
+
sessionKey?.includes(":cron:") ||
|
|
263
|
+
runtimeFlag(runtimeContext, "isCron") === true ||
|
|
264
|
+
runtimeFlag(runtimeContext, "automationKind") === "cron",
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export function shouldRecallAgentExperience(input: {
|
|
269
|
+
latestUserText: string;
|
|
270
|
+
sessionKey?: string;
|
|
271
|
+
runtimeContext?: unknown;
|
|
272
|
+
triggerHint?: ExperienceRecallTrigger;
|
|
273
|
+
minQueryChars?: number;
|
|
274
|
+
isBypassed?: boolean;
|
|
275
|
+
}): ExperienceRecallDecision {
|
|
276
|
+
const text = sanitizeUserTextForCapture(input.latestUserText).trim();
|
|
277
|
+
const minQueryChars = input.minQueryChars ?? 12;
|
|
278
|
+
|
|
279
|
+
if (input.isBypassed) {
|
|
280
|
+
return { recall: false, score: 0, reason: "session_bypassed" };
|
|
281
|
+
}
|
|
282
|
+
if (!text || text.length < minQueryChars) {
|
|
283
|
+
return { recall: false, score: 0, reason: "query_too_short" };
|
|
284
|
+
}
|
|
285
|
+
if (/<openviking-context\b/i.test(input.latestUserText)) {
|
|
286
|
+
return { recall: false, score: 0, reason: "already_injected" };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const trigger = input.triggerHint ?? (isCronSession(input.sessionKey, input.runtimeContext) ? "cron_start" : "task_start");
|
|
290
|
+
if (trigger !== "task_start") {
|
|
291
|
+
return { recall: true, trigger, score: 99, reason: "forced_trigger" };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
let score = 0;
|
|
295
|
+
if (WRITE_OR_EFFECT_RE.test(text)) score += 3;
|
|
296
|
+
if (EXECUTION_RE.test(text)) score += 2;
|
|
297
|
+
if (FAILURE_RE.test(text)) score += 2;
|
|
298
|
+
if (ENGINEERING_OBJECT_RE.test(text)) score += 2;
|
|
299
|
+
if (EXPERIENCE_INTENT_RE.test(text)) score += 1;
|
|
300
|
+
|
|
301
|
+
if (CASUAL_RE.test(text)) score -= 3;
|
|
302
|
+
if (QUESTION_ONLY_RE.test(text) && !ENGINEERING_OBJECT_RE.test(text) && !EXECUTION_RE.test(text)) {
|
|
303
|
+
score -= 2;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (score >= 3) {
|
|
307
|
+
return { recall: true, trigger: "task_start", score, reason: "task_execution" };
|
|
308
|
+
}
|
|
309
|
+
return { recall: false, score, reason: score < 0 ? "non_execution" : "below_threshold" };
|
|
310
|
+
}
|
|
311
|
+
|
|
188
312
|
export async function buildAutoRecallContext(params: {
|
|
189
313
|
cfg: Required<MemoryOpenVikingConfig>;
|
|
314
|
+
queryConfig?: EffectiveQueryConfig;
|
|
190
315
|
client: OpenVikingClient;
|
|
191
316
|
agentId: string;
|
|
192
317
|
queryText: string;
|
|
193
318
|
logger: Logger;
|
|
194
319
|
verbose?: (message: string) => void;
|
|
320
|
+
traceRecorder?: { record(entry: RecallTraceEntry): void; recordAndFlush?: (entry: RecallTraceEntry) => Promise<unknown> };
|
|
321
|
+
sessionId?: string;
|
|
322
|
+
sessionKey?: string;
|
|
323
|
+
ovSessionId?: string;
|
|
324
|
+
rawUserTextPreview?: string;
|
|
325
|
+
queryTruncated?: boolean;
|
|
326
|
+
resourceTypes?: RecallResourceType[];
|
|
195
327
|
}): Promise<{ block?: string; memoryCount: number; estimatedTokens: number }> {
|
|
196
328
|
const { cfg, client, agentId, queryText, logger, verbose } = params;
|
|
329
|
+
const queryConfig = params.queryConfig;
|
|
197
330
|
|
|
198
331
|
if (!cfg.autoRecall || queryText.length < 5) {
|
|
199
332
|
return { memoryCount: 0, estimatedTokens: 0 };
|
|
@@ -207,36 +340,89 @@ export async function buildAutoRecallContext(params: {
|
|
|
207
340
|
|
|
208
341
|
return withTimeout(
|
|
209
342
|
(async () => {
|
|
210
|
-
const candidateLimit = Math.max(cfg.recallLimit * 4, 20);
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
343
|
+
const candidateLimit = queryConfig?.candidateLimit ?? Math.max(cfg.recallLimit * 4, 20);
|
|
344
|
+
const scoreThreshold = queryConfig?.scoreThreshold ?? cfg.recallScoreThreshold;
|
|
345
|
+
const recallLimit = queryConfig?.recallLimit ?? cfg.recallLimit;
|
|
346
|
+
const maxInjectedChars = queryConfig?.maxInjectedChars ?? cfg.recallMaxInjectedChars;
|
|
347
|
+
const recallPreferAbstract = queryConfig?.recallPreferAbstract ?? cfg.recallPreferAbstract;
|
|
348
|
+
const searchPlan = resolveRecallSearchPlan(params.resourceTypes ?? queryConfig?.resourceTypes ?? cfg.recallTargetTypes, {
|
|
349
|
+
ovSessionId: params.ovSessionId,
|
|
350
|
+
agentId,
|
|
351
|
+
});
|
|
352
|
+
const traceSearches: RecallTraceEntry["searches"] = searchPlan.skipped.map((skipped) => ({
|
|
353
|
+
resourceType: skipped.resourceType,
|
|
354
|
+
limit: candidateLimit,
|
|
355
|
+
scoreThreshold: 0,
|
|
356
|
+
durationMs: 0,
|
|
357
|
+
total: 0,
|
|
358
|
+
results: [],
|
|
359
|
+
error: skipped.reason,
|
|
360
|
+
}));
|
|
361
|
+
const autoRecallPromises: Promise<{
|
|
362
|
+
resourceType: RecallResourceType;
|
|
363
|
+
targetUri?: string;
|
|
364
|
+
result?: FindResult;
|
|
365
|
+
durationMs: number;
|
|
366
|
+
}>[] = searchPlan.searches.map(async (search) => {
|
|
367
|
+
const start = Date.now();
|
|
368
|
+
const result = await client.find(queryText, {
|
|
369
|
+
targetUri: search.targetUri,
|
|
219
370
|
limit: candidateLimit,
|
|
220
371
|
scoreThreshold: 0,
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
372
|
+
contextType: search.contextType,
|
|
373
|
+
actorPeerId: agentId,
|
|
374
|
+
});
|
|
375
|
+
return {
|
|
376
|
+
resourceType: search.resourceType,
|
|
377
|
+
targetUri: search.targetUri,
|
|
378
|
+
result,
|
|
379
|
+
durationMs: Date.now() - start,
|
|
380
|
+
};
|
|
381
|
+
});
|
|
232
382
|
const autoRecallSettled = await Promise.allSettled(autoRecallPromises);
|
|
233
383
|
|
|
234
384
|
const allMemories: FindResultItem[] = [];
|
|
235
385
|
for (const s of autoRecallSettled) {
|
|
236
386
|
if (s.status === "fulfilled") {
|
|
237
|
-
|
|
387
|
+
const result = s.value.result ?? {};
|
|
388
|
+
const memories = result.memories ?? [];
|
|
389
|
+
const resources = result.resources ?? [];
|
|
390
|
+
allMemories.push(...memories, ...resources);
|
|
391
|
+
traceSearches.push({
|
|
392
|
+
resourceType: s.value.resourceType,
|
|
393
|
+
targetUriInput: s.value.targetUri,
|
|
394
|
+
limit: candidateLimit,
|
|
395
|
+
scoreThreshold: 0,
|
|
396
|
+
durationMs: s.value.durationMs,
|
|
397
|
+
total: result.total ?? memories.length + resources.length + (result.skills?.length ?? 0),
|
|
398
|
+
results: [
|
|
399
|
+
...toTraceResults(memories, s.value.resourceType),
|
|
400
|
+
...toTraceResults(resources, "resource"),
|
|
401
|
+
...(result.skills ?? []).map((item): RecallTraceResult => ({
|
|
402
|
+
uri: item.uri,
|
|
403
|
+
resourceType: s.value.resourceType,
|
|
404
|
+
category: item.category,
|
|
405
|
+
score: item.score,
|
|
406
|
+
level: item.level,
|
|
407
|
+
abstractPreview: preview(item.abstract ?? item.overview, 240),
|
|
408
|
+
resultType: "skill",
|
|
409
|
+
})),
|
|
410
|
+
].slice(0, cfg.traceRecallMaxResultsPerSearch),
|
|
411
|
+
});
|
|
238
412
|
} else {
|
|
239
413
|
logger.warn?.(`openviking: auto-recall search failed: ${String(s.reason)}`);
|
|
414
|
+
const failedIndex = traceSearches.length;
|
|
415
|
+
const search = searchPlan.searches[failedIndex - searchPlan.skipped.length];
|
|
416
|
+
traceSearches.push({
|
|
417
|
+
resourceType: search?.resourceType ?? "user",
|
|
418
|
+
targetUriInput: search?.targetUri,
|
|
419
|
+
limit: candidateLimit,
|
|
420
|
+
scoreThreshold: 0,
|
|
421
|
+
durationMs: 0,
|
|
422
|
+
total: 0,
|
|
423
|
+
results: [],
|
|
424
|
+
error: String(s.reason),
|
|
425
|
+
});
|
|
240
426
|
}
|
|
241
427
|
}
|
|
242
428
|
|
|
@@ -246,11 +432,54 @@ export async function buildAutoRecallContext(params: {
|
|
|
246
432
|
const leafOnly = uniqueMemories.filter((m) => !m.level || m.level === 2);
|
|
247
433
|
const processed = postProcessMemories(leafOnly, {
|
|
248
434
|
limit: candidateLimit,
|
|
249
|
-
scoreThreshold
|
|
435
|
+
scoreThreshold,
|
|
250
436
|
});
|
|
251
|
-
const memories = pickMemoriesForInjection(processed,
|
|
437
|
+
const memories = pickMemoriesForInjection(processed, recallLimit, queryText, scoreThreshold, queryConfig ? {
|
|
438
|
+
weights: queryConfig.rankingWeights,
|
|
439
|
+
categoryWeights: queryConfig.categoryWeights,
|
|
440
|
+
resourceTypeWeights: queryConfig.resourceTypeWeights,
|
|
441
|
+
} : undefined);
|
|
442
|
+
|
|
443
|
+
const recordTrace = async (injectedMemories: FindResultItem[], injectedCount: number, estimatedTokens?: number) => {
|
|
444
|
+
const entry: RecallTraceEntry = {
|
|
445
|
+
schemaVersion: "1.0",
|
|
446
|
+
traceId: newTraceId(),
|
|
447
|
+
ts: Date.now(),
|
|
448
|
+
sessionId: params.sessionId,
|
|
449
|
+
sessionKey: params.sessionKey,
|
|
450
|
+
ovSessionId: params.ovSessionId,
|
|
451
|
+
agentId,
|
|
452
|
+
source: "auto_recall",
|
|
453
|
+
operationType: "semantic_find",
|
|
454
|
+
resourceTypes: searchPlan.resourceTypes,
|
|
455
|
+
trigger: {
|
|
456
|
+
rawUserTextPreview: params.rawUserTextPreview,
|
|
457
|
+
...boundTraceQuery(queryText, cfg.traceRecallQueryMaxChars),
|
|
458
|
+
derivedKeywords: [],
|
|
459
|
+
queryTruncated: params.queryTruncated || queryText.length > cfg.traceRecallQueryMaxChars,
|
|
460
|
+
},
|
|
461
|
+
searches: traceSearches,
|
|
462
|
+
selected: injectedMemories.map((memory) => ({
|
|
463
|
+
uri: memory.uri,
|
|
464
|
+
resourceType: memory.uri.startsWith("viking://resources") ? "resource" : undefined,
|
|
465
|
+
category: memory.category,
|
|
466
|
+
score: memory.score,
|
|
467
|
+
abstractPreview: preview(memory.abstract ?? memory.overview, cfg.traceRecallPreviewChars),
|
|
468
|
+
injected: true,
|
|
469
|
+
})),
|
|
470
|
+
stats: {
|
|
471
|
+
candidateCount: allMemories.length,
|
|
472
|
+
selectedCount: injectedMemories.length,
|
|
473
|
+
injectedCount,
|
|
474
|
+
estimatedTokens,
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
// Trace persistence is diagnostic best-effort; never put JSONL flush latency on the auto-recall critical path.
|
|
478
|
+
params.traceRecorder?.record(entry);
|
|
479
|
+
};
|
|
252
480
|
|
|
253
481
|
if (memories.length === 0) {
|
|
482
|
+
await recordTrace([], 0, 0);
|
|
254
483
|
return { memoryCount: 0, estimatedTokens: 0 };
|
|
255
484
|
}
|
|
256
485
|
|
|
@@ -258,27 +487,29 @@ export async function buildAutoRecallContext(params: {
|
|
|
258
487
|
memories,
|
|
259
488
|
(uri) => client.read(uri, agentId),
|
|
260
489
|
{
|
|
261
|
-
recallPreferAbstract
|
|
262
|
-
recallMaxInjectedChars:
|
|
490
|
+
recallPreferAbstract,
|
|
491
|
+
recallMaxInjectedChars: maxInjectedChars,
|
|
263
492
|
includeUri: true,
|
|
264
493
|
},
|
|
265
494
|
);
|
|
266
495
|
|
|
267
496
|
if (memoryLines.length === 0) {
|
|
268
497
|
verbose?.(
|
|
269
|
-
`openviking: skipping auto-recall injection; no complete memories fit maxInjectedChars=${
|
|
498
|
+
`openviking: skipping auto-recall injection; no complete memories fit maxInjectedChars=${maxInjectedChars}`,
|
|
270
499
|
);
|
|
500
|
+
await recordTrace([], 0, 0);
|
|
271
501
|
return { memoryCount: 0, estimatedTokens: 0 };
|
|
272
502
|
}
|
|
273
503
|
|
|
274
504
|
const block = buildRecallContextBlock(memoryLines);
|
|
275
505
|
verbose?.(
|
|
276
|
-
`openviking: injecting ${memoryLines.length} memories (${block.length} chars, ~${estimatedTokens} tokens, maxInjectedChars=${
|
|
506
|
+
`openviking: injecting ${memoryLines.length} memories (${block.length} chars, ~${estimatedTokens} tokens, maxInjectedChars=${maxInjectedChars})`,
|
|
277
507
|
);
|
|
278
508
|
verbose?.(
|
|
279
509
|
`openviking: inject-detail ${toJsonLog({ count: memories.length, memories: summarizeInjectionMemories(memories) })}`,
|
|
280
510
|
);
|
|
281
511
|
|
|
512
|
+
await recordTrace(memories.slice(0, memoryLines.length), memoryLines.length, estimatedTokens);
|
|
282
513
|
return { block, memoryCount: memoryLines.length, estimatedTokens };
|
|
283
514
|
})(),
|
|
284
515
|
AUTO_RECALL_TIMEOUT_MS,
|