@openviking/openclaw-plugin 2026.5.26 → 2026.6.17-dev.1
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 +355 -355
- package/INSTALL-ZH.md +405 -345
- package/INSTALL.md +366 -362
- package/README.md +364 -338
- package/adapters/http-transport.ts +3 -0
- package/adapters/resource-packager.ts +141 -0
- package/auto-recall.ts +518 -257
- package/client.ts +963 -939
- package/commands/setup.ts +1169 -1002
- package/config/feature-gates.json +10 -0
- package/config.ts +819 -476
- package/context-engine.ts +408 -1737
- package/dist/adapters/http-transport.js +1 -0
- package/dist/adapters/resource-packager.js +114 -0
- package/dist/auto-recall.js +228 -32
- package/dist/client.js +125 -161
- package/dist/commands/setup.js +170 -32
- package/dist/config.js +285 -64
- package/dist/context-engine.js +64 -1179
- package/dist/index.js +209 -1470
- 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 +5 -17
- 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/dist/token-estimator.js +51 -0
- package/index.ts +408 -1985
- package/install-manifest.json +57 -47
- package/memory-ranking.ts +303 -267
- package/openclaw.plugin.json +497 -335
- package/package.json +86 -76
- 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 +41 -45
- 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/runtime-utils.ts +5 -5
- 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 +528 -530
- package/skills/install-openviking-memory/SKILL.md +752 -665
- package/skills/openviking-context-database/SKILL.md +286 -0
- package/text-utils.ts +488 -507
- package/token-estimator.ts +65 -0
- package/tool-call-id.ts +331 -331
package/config.ts
CHANGED
|
@@ -1,476 +1,819 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
typeof
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
)
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
|
|
3
|
+
import { getEnv } from "./runtime-utils.js";
|
|
4
|
+
|
|
5
|
+
export type MemoryOpenVikingConfig = {
|
|
6
|
+
mode?: "remote";
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
peer_role?: "none" | "assistant" | "person";
|
|
9
|
+
peer_prefix?: string;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
/** Advanced option. Only needed when explicitly sending tenant identity headers. With a user key the server derives identity from the key. */
|
|
12
|
+
accountId?: string;
|
|
13
|
+
/** Advanced option. Only needed when explicitly sending tenant identity headers. */
|
|
14
|
+
userId?: string;
|
|
15
|
+
targetUri?: string;
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
autoCapture?: boolean;
|
|
18
|
+
captureMode?: "semantic" | "keyword";
|
|
19
|
+
captureMaxLength?: number;
|
|
20
|
+
autoRecall?: boolean;
|
|
21
|
+
/** Outer time budget for the whole auto-recall flow, including search, ranking, and reads. */
|
|
22
|
+
autoRecallTimeoutMs?: number;
|
|
23
|
+
/** Include resources in auto-recall and default memory_recall search. Default false. */
|
|
24
|
+
recallResources?: boolean;
|
|
25
|
+
recallLimit?: number;
|
|
26
|
+
recallScoreThreshold?: number;
|
|
27
|
+
/** Maximum total characters injected by auto-recall. */
|
|
28
|
+
recallMaxInjectedChars?: number;
|
|
29
|
+
/** @deprecated Auto-recall no longer truncates individual memories. */
|
|
30
|
+
recallMaxContentChars?: number;
|
|
31
|
+
recallPreferAbstract?: boolean;
|
|
32
|
+
/** @deprecated Use recallMaxInjectedChars. */
|
|
33
|
+
recallTokenBudget?: number;
|
|
34
|
+
commitTokenThreshold?: number;
|
|
35
|
+
/**
|
|
36
|
+
* WM v2: number of most-recent messages to keep live after an afterTurn
|
|
37
|
+
* commit so the next turn still has immediate context. Forwarded to the
|
|
38
|
+
* server as `keep_recent_count`. Default 10. The compact path ignores this
|
|
39
|
+
* value and always passes 0.
|
|
40
|
+
*/
|
|
41
|
+
commitKeepRecentCount?: number;
|
|
42
|
+
bypassSessionPatterns?: string[];
|
|
43
|
+
/**
|
|
44
|
+
* When true (default), emit structured `openviking: diag {...}` lines (and any future
|
|
45
|
+
* standard-diagnostics file writes) for assemble/afterTurn. Set false to disable.
|
|
46
|
+
*/
|
|
47
|
+
emitStandardDiagnostics?: boolean;
|
|
48
|
+
/** When true, log tenant routing for semantic find and session writes (messages/commit) to the plugin logger. */
|
|
49
|
+
logFindRequests?: boolean;
|
|
50
|
+
/** Enable recall trace recording. Default false. */
|
|
51
|
+
traceRecall?: boolean;
|
|
52
|
+
/** Persist recall traces to local JSONL files. Default false. */
|
|
53
|
+
traceRecallPersist?: boolean;
|
|
54
|
+
/** Directory for JSONL recall trace files. */
|
|
55
|
+
traceRecallDir?: string;
|
|
56
|
+
/** Number of days to retain persisted trace files. */
|
|
57
|
+
traceRecallRetentionDays?: number;
|
|
58
|
+
/** Number of recent persisted days to preload on startup. */
|
|
59
|
+
traceRecallLoadRecentDays?: number;
|
|
60
|
+
/** Maximum in-memory recall trace entries. */
|
|
61
|
+
traceRecallMaxEntries?: number;
|
|
62
|
+
/** Maximum candidate results stored per search in trace. */
|
|
63
|
+
traceRecallMaxResultsPerSearch?: number;
|
|
64
|
+
/** Preview character limit for persisted trace summaries. */
|
|
65
|
+
traceRecallPreviewChars?: number;
|
|
66
|
+
/** Maximum query characters preserved in trace. */
|
|
67
|
+
traceRecallQueryMaxChars?: number;
|
|
68
|
+
/** Maximum days to scan when querying persisted traces without explicit time bounds. */
|
|
69
|
+
traceRecallQueryMaxDays?: number;
|
|
70
|
+
/** Whether trace queries include full content by default. */
|
|
71
|
+
traceRecallIncludeContentByDefault?: boolean;
|
|
72
|
+
/** Whether raw user text preview may be persisted. Default false. */
|
|
73
|
+
traceRecallIncludeRawUserPreview?: boolean;
|
|
74
|
+
/** Auto-recall target resource types. Empty means the backward-compatible memory recall set. */
|
|
75
|
+
recallTargetTypes?: Array<"resource" | "user" | "agent"> | string;
|
|
76
|
+
/** Agent-visible add_resource tool is disabled by default; manual /add-resource remains available. */
|
|
77
|
+
enableAddResourceTool?: boolean;
|
|
78
|
+
/** Agent-visible tool allowlist. Supports exact tool names or groups such as "memory" and "resource_query". */
|
|
79
|
+
enabledTools?: string[] | string;
|
|
80
|
+
/** Agent-visible tool blocklist applied after enabledTools. Supports exact tool names or groups. */
|
|
81
|
+
disabledTools?: string[] | string;
|
|
82
|
+
/** Optional JSON file path for runtime query config overrides. Empty means in-memory only. */
|
|
83
|
+
runtimeQueryConfigPath?: string;
|
|
84
|
+
agentExperience?: {
|
|
85
|
+
enabled?: boolean;
|
|
86
|
+
recallLimit?: number;
|
|
87
|
+
scoreThreshold?: number;
|
|
88
|
+
maxInjectedChars?: number;
|
|
89
|
+
minQueryChars?: number;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** Runtime config after memoryOpenVikingConfigSchema.parse() has applied defaults. */
|
|
94
|
+
export type ParsedMemoryOpenVikingConfig = Required<
|
|
95
|
+
Omit<MemoryOpenVikingConfig, "agentExperience" | "recallTargetTypes">
|
|
96
|
+
> & {
|
|
97
|
+
agentExperience: Required<NonNullable<MemoryOpenVikingConfig["agentExperience"]>>;
|
|
98
|
+
recallTargetTypes: Array<"resource" | "user" | "agent">;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const DEFAULT_BASE_URL = "http://127.0.0.1:1933";
|
|
102
|
+
const DEFAULT_TARGET_URI = "viking://user/memories";
|
|
103
|
+
const DEFAULT_TIMEOUT_MS = 15000;
|
|
104
|
+
const DEFAULT_CAPTURE_MODE = "semantic";
|
|
105
|
+
const DEFAULT_CAPTURE_MAX_LENGTH = 24000;
|
|
106
|
+
const DEFAULT_AUTO_RECALL_TIMEOUT_MS = 5000;
|
|
107
|
+
const DEFAULT_RECALL_LIMIT = 6;
|
|
108
|
+
const DEFAULT_RECALL_SCORE_THRESHOLD = 0.15;
|
|
109
|
+
const DEFAULT_RECALL_MAX_CONTENT_CHARS = 5000;
|
|
110
|
+
const DEFAULT_RECALL_PREFER_ABSTRACT = false;
|
|
111
|
+
const DEFAULT_RECALL_MAX_INJECTED_CHARS = 4000;
|
|
112
|
+
const DEFAULT_COMMIT_TOKEN_THRESHOLD = 20000;
|
|
113
|
+
const DEFAULT_COMMIT_KEEP_RECENT_COUNT = 10;
|
|
114
|
+
const DEFAULT_BYPASS_SESSION_PATTERNS: string[] = [];
|
|
115
|
+
const DEFAULT_EMIT_STANDARD_DIAGNOSTICS = false;
|
|
116
|
+
const DEFAULT_PEER_ROLE = "assistant" as const;
|
|
117
|
+
const DEFAULT_PEER_PREFIX = "";
|
|
118
|
+
const DEFAULT_TRACE_RECALL_DIR = "~/.openclaw/openviking/recall-traces";
|
|
119
|
+
const DEFAULT_TRACE_RECALL_RETENTION_DAYS = 14;
|
|
120
|
+
const DEFAULT_TRACE_RECALL_LOAD_RECENT_DAYS = 2;
|
|
121
|
+
const DEFAULT_TRACE_RECALL_MAX_ENTRIES = 1000;
|
|
122
|
+
const DEFAULT_TRACE_RECALL_MAX_RESULTS_PER_SEARCH = 20;
|
|
123
|
+
const DEFAULT_TRACE_RECALL_PREVIEW_CHARS = 240;
|
|
124
|
+
const DEFAULT_TRACE_RECALL_QUERY_MAX_CHARS = 4000;
|
|
125
|
+
const DEFAULT_TRACE_RECALL_QUERY_MAX_DAYS = 14;
|
|
126
|
+
const ALLOWED_RECALL_TARGET_TYPES = ["resource", "user", "agent"] as const;
|
|
127
|
+
const DEFAULT_RECALL_TARGET_TYPES = ["user", "agent"] as const;
|
|
128
|
+
type RecallTargetType = typeof ALLOWED_RECALL_TARGET_TYPES[number];
|
|
129
|
+
export const OPENVIKING_ADD_RESOURCE_TOOL_NAME = "add_resource" as const;
|
|
130
|
+
export const OPENVIKING_DEFAULT_ENABLED_TOOL_NAMES = [
|
|
131
|
+
"add_skill",
|
|
132
|
+
"ov_search",
|
|
133
|
+
"ov_read",
|
|
134
|
+
"ov_multi_read",
|
|
135
|
+
"ov_list",
|
|
136
|
+
"memory_recall",
|
|
137
|
+
"ov_recall_trace",
|
|
138
|
+
"memory_store",
|
|
139
|
+
"memory_forget",
|
|
140
|
+
"ov_archive_search",
|
|
141
|
+
"ov_archive_expand",
|
|
142
|
+
"openviking_tool_result_read",
|
|
143
|
+
"openviking_tool_result_search",
|
|
144
|
+
"openviking_tool_result_list",
|
|
145
|
+
] as const;
|
|
146
|
+
export const OPENVIKING_ALL_TOOL_NAMES = [
|
|
147
|
+
OPENVIKING_ADD_RESOURCE_TOOL_NAME,
|
|
148
|
+
...OPENVIKING_DEFAULT_ENABLED_TOOL_NAMES,
|
|
149
|
+
] as const;
|
|
150
|
+
export type OpenVikingToolName = typeof OPENVIKING_ALL_TOOL_NAMES[number];
|
|
151
|
+
export const OPENVIKING_TOOL_GROUPS: Record<string, readonly OpenVikingToolName[]> = {
|
|
152
|
+
all: OPENVIKING_ALL_TOOL_NAMES,
|
|
153
|
+
default: OPENVIKING_DEFAULT_ENABLED_TOOL_NAMES,
|
|
154
|
+
memory: ["memory_recall", "memory_store", "memory_forget"],
|
|
155
|
+
resource_query: ["ov_search", "ov_read", "ov_multi_read", "ov_list"],
|
|
156
|
+
import: ["add_resource", "add_skill"],
|
|
157
|
+
recall_trace: ["ov_recall_trace"],
|
|
158
|
+
archive: ["ov_archive_search", "ov_archive_expand"],
|
|
159
|
+
tool_result: [
|
|
160
|
+
"openviking_tool_result_read",
|
|
161
|
+
"openviking_tool_result_search",
|
|
162
|
+
"openviking_tool_result_list",
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
const DEFAULT_AGENT_EXPERIENCE = {
|
|
166
|
+
enabled: false,
|
|
167
|
+
recallLimit: 3,
|
|
168
|
+
scoreThreshold: 0.35,
|
|
169
|
+
maxInjectedChars: 6000,
|
|
170
|
+
minQueryChars: 12,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
function resolvePeerPrefix(configured: unknown): string {
|
|
174
|
+
if (typeof configured === "string" && configured.trim()) {
|
|
175
|
+
const trimmed = configured.trim();
|
|
176
|
+
return trimmed === "default" ? DEFAULT_PEER_PREFIX : trimmed;
|
|
177
|
+
}
|
|
178
|
+
return DEFAULT_PEER_PREFIX;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function resolvePeerRole(configured: unknown) {
|
|
182
|
+
if (typeof configured === "string") {
|
|
183
|
+
const role = configured.trim().toLowerCase();
|
|
184
|
+
if (role === "none" || role === "assistant" || role === "person") {
|
|
185
|
+
return role;
|
|
186
|
+
}
|
|
187
|
+
throw new Error(`openviking peer_role must be "none", "assistant", or "person"`);
|
|
188
|
+
}
|
|
189
|
+
if (configured !== undefined) {
|
|
190
|
+
throw new Error(`openviking peer_role must be "none", "assistant", or "person"`);
|
|
191
|
+
}
|
|
192
|
+
return DEFAULT_PEER_ROLE;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function resolveEnvVars(value: string): string {
|
|
196
|
+
return value.replace(/\$\{([^}]+)\}/g, (_, envVar) => {
|
|
197
|
+
const envValue = getEnv(envVar);
|
|
198
|
+
if (!envValue) {
|
|
199
|
+
throw new Error(`Environment variable ${envVar} is not set`);
|
|
200
|
+
}
|
|
201
|
+
return envValue;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function expandHomeDir(value: string): string {
|
|
206
|
+
if (value === "~") {
|
|
207
|
+
return homedir();
|
|
208
|
+
}
|
|
209
|
+
if (value.startsWith("~/")) {
|
|
210
|
+
return `${homedir()}${value.slice(1)}`;
|
|
211
|
+
}
|
|
212
|
+
return value;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function toNumber(value: unknown, fallback: number): number {
|
|
216
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
220
|
+
const parsed = Number(value);
|
|
221
|
+
if (Number.isFinite(parsed)) {
|
|
222
|
+
return parsed;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return fallback;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function toStringArray(value: unknown, fallback: string[]): string[] {
|
|
229
|
+
if (Array.isArray(value)) {
|
|
230
|
+
return value
|
|
231
|
+
.filter((entry): entry is string => typeof entry === "string")
|
|
232
|
+
.map((entry) => entry.trim())
|
|
233
|
+
.filter(Boolean);
|
|
234
|
+
}
|
|
235
|
+
if (typeof value === "string") {
|
|
236
|
+
return value
|
|
237
|
+
.split(/[,\n]/)
|
|
238
|
+
.map((entry) => entry.trim())
|
|
239
|
+
.filter(Boolean);
|
|
240
|
+
}
|
|
241
|
+
return fallback;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function toIntegerInRange(value: unknown, fallback: number, min: number, max: number): number {
|
|
245
|
+
return Math.max(min, Math.min(max, Math.floor(toNumber(value, fallback))));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function normalizeRecallTargetTypes(value: unknown, includeResources = false): RecallTargetType[] {
|
|
249
|
+
const entries = toStringArray(value, [...DEFAULT_RECALL_TARGET_TYPES]);
|
|
250
|
+
const seen = new Set<RecallTargetType>();
|
|
251
|
+
const normalized: RecallTargetType[] = [];
|
|
252
|
+
const unknown: string[] = [];
|
|
253
|
+
|
|
254
|
+
for (const entry of entries) {
|
|
255
|
+
if ((ALLOWED_RECALL_TARGET_TYPES as readonly string[]).includes(entry)) {
|
|
256
|
+
const typed = entry as RecallTargetType;
|
|
257
|
+
if (!seen.has(typed)) {
|
|
258
|
+
seen.add(typed);
|
|
259
|
+
normalized.push(typed);
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
unknown.push(entry);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (unknown.length > 0) {
|
|
267
|
+
throw new Error(`openviking recallTargetTypes contains unknown resource types: ${unknown.join(", ")}`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const result = normalized.length > 0 ? normalized : [...DEFAULT_RECALL_TARGET_TYPES];
|
|
271
|
+
if (includeResources && !seen.has("resource")) {
|
|
272
|
+
result.push("resource");
|
|
273
|
+
}
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function toRecord(value: unknown): Record<string, unknown> {
|
|
278
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
279
|
+
? value as Record<string, unknown>
|
|
280
|
+
: {};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function expandToolSelectors(value: unknown, fallback: string[], label: string): OpenVikingToolName[] {
|
|
284
|
+
const entries = toStringArray(value, fallback);
|
|
285
|
+
const seen = new Set<OpenVikingToolName>();
|
|
286
|
+
const normalized: OpenVikingToolName[] = [];
|
|
287
|
+
const unknown: string[] = [];
|
|
288
|
+
|
|
289
|
+
for (const rawEntry of entries) {
|
|
290
|
+
const entry = rawEntry.trim();
|
|
291
|
+
const group = OPENVIKING_TOOL_GROUPS[entry];
|
|
292
|
+
const tools = group ??
|
|
293
|
+
((OPENVIKING_ALL_TOOL_NAMES as readonly string[]).includes(entry)
|
|
294
|
+
? [entry as OpenVikingToolName]
|
|
295
|
+
: undefined);
|
|
296
|
+
if (!tools) {
|
|
297
|
+
unknown.push(entry);
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
for (const tool of tools) {
|
|
301
|
+
if (!seen.has(tool)) {
|
|
302
|
+
seen.add(tool);
|
|
303
|
+
normalized.push(tool);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (unknown.length > 0) {
|
|
309
|
+
throw new Error(`openviking ${label} contains unknown tool selectors: ${unknown.join(", ")}`);
|
|
310
|
+
}
|
|
311
|
+
return normalized;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function normalizeEnabledTools(cfg: Record<string, unknown>): {
|
|
315
|
+
enabledTools: OpenVikingToolName[];
|
|
316
|
+
disabledTools: OpenVikingToolName[];
|
|
317
|
+
} {
|
|
318
|
+
const enableAddResourceTool = cfg.enableAddResourceTool === true;
|
|
319
|
+
const defaultTools = enableAddResourceTool
|
|
320
|
+
? [OPENVIKING_ADD_RESOURCE_TOOL_NAME, ...OPENVIKING_DEFAULT_ENABLED_TOOL_NAMES]
|
|
321
|
+
: [...OPENVIKING_DEFAULT_ENABLED_TOOL_NAMES];
|
|
322
|
+
const selected = expandToolSelectors(cfg.enabledTools, defaultTools, "enabledTools");
|
|
323
|
+
const disabled = expandToolSelectors(cfg.disabledTools, [], "disabledTools");
|
|
324
|
+
const disabledSet = new Set(disabled);
|
|
325
|
+
if (!enableAddResourceTool) {
|
|
326
|
+
disabledSet.add(OPENVIKING_ADD_RESOURCE_TOOL_NAME);
|
|
327
|
+
}
|
|
328
|
+
const enabledTools = selected.filter((tool) =>
|
|
329
|
+
!disabledSet.has(tool) &&
|
|
330
|
+
(tool !== OPENVIKING_ADD_RESOURCE_TOOL_NAME || enableAddResourceTool)
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
enabledTools,
|
|
335
|
+
disabledTools: Array.from(disabledSet),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** True when env is 1 / true / yes (case-insensitive). Used for debug flags without editing plugin JSON. */
|
|
340
|
+
function envFlag(name: string): boolean {
|
|
341
|
+
const v = getEnv(name);
|
|
342
|
+
if (v == null || v === "") {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
const t = String(v).trim().toLowerCase();
|
|
346
|
+
return t === "1" || t === "true" || t === "yes";
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function assertAllowedKeys(value: Record<string, unknown>, allowed: string[], label: string) {
|
|
350
|
+
const unknown = Object.keys(value).filter((key) => !allowed.includes(key));
|
|
351
|
+
if (unknown.length === 0) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
throw new Error(`${label} has unknown keys: ${unknown.join(", ")}`);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function resolveDefaultBaseUrl(): string {
|
|
358
|
+
const fromEnv = getEnv("OPENVIKING_BASE_URL") || getEnv("OPENVIKING_URL");
|
|
359
|
+
if (fromEnv) {
|
|
360
|
+
return fromEnv;
|
|
361
|
+
}
|
|
362
|
+
return DEFAULT_BASE_URL;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export const memoryOpenVikingConfigSchema = {
|
|
366
|
+
parse(value: unknown): ParsedMemoryOpenVikingConfig {
|
|
367
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
368
|
+
value = {};
|
|
369
|
+
}
|
|
370
|
+
const cfg = value as Record<string, unknown>;
|
|
371
|
+
assertAllowedKeys(
|
|
372
|
+
cfg,
|
|
373
|
+
[
|
|
374
|
+
"mode",
|
|
375
|
+
"baseUrl",
|
|
376
|
+
"peer_role",
|
|
377
|
+
"peer_prefix",
|
|
378
|
+
"serverAuthMode",
|
|
379
|
+
"apiKey",
|
|
380
|
+
"accountId",
|
|
381
|
+
"userId",
|
|
382
|
+
"targetUri",
|
|
383
|
+
"timeoutMs",
|
|
384
|
+
"autoCapture",
|
|
385
|
+
"captureMode",
|
|
386
|
+
"captureMaxLength",
|
|
387
|
+
"autoRecall",
|
|
388
|
+
"autoRecallTimeoutMs",
|
|
389
|
+
"recallResources",
|
|
390
|
+
"recallLimit",
|
|
391
|
+
"recallScoreThreshold",
|
|
392
|
+
"recallMaxInjectedChars",
|
|
393
|
+
"recallMaxContentChars",
|
|
394
|
+
"recallPreferAbstract",
|
|
395
|
+
"recallTokenBudget",
|
|
396
|
+
"commitTokenThreshold",
|
|
397
|
+
"commitKeepRecentCount",
|
|
398
|
+
"bypassSessionPatterns",
|
|
399
|
+
"ingestReplyAssist",
|
|
400
|
+
"ingestReplyAssistMinSpeakerTurns",
|
|
401
|
+
"ingestReplyAssistMinChars",
|
|
402
|
+
"ingestReplyAssistIgnoreSessionPatterns",
|
|
403
|
+
"emitStandardDiagnostics",
|
|
404
|
+
"logFindRequests",
|
|
405
|
+
"traceRecall",
|
|
406
|
+
"traceRecallPersist",
|
|
407
|
+
"traceRecallDir",
|
|
408
|
+
"traceRecallRetentionDays",
|
|
409
|
+
"traceRecallLoadRecentDays",
|
|
410
|
+
"traceRecallMaxEntries",
|
|
411
|
+
"traceRecallMaxResultsPerSearch",
|
|
412
|
+
"traceRecallPreviewChars",
|
|
413
|
+
"traceRecallQueryMaxChars",
|
|
414
|
+
"traceRecallQueryMaxDays",
|
|
415
|
+
"traceRecallIncludeContentByDefault",
|
|
416
|
+
"traceRecallIncludeRawUserPreview",
|
|
417
|
+
"recallTargetTypes",
|
|
418
|
+
"enableAddResourceTool",
|
|
419
|
+
"enabledTools",
|
|
420
|
+
"disabledTools",
|
|
421
|
+
"runtimeQueryConfigPath",
|
|
422
|
+
"agentExperience",
|
|
423
|
+
],
|
|
424
|
+
"openviking config",
|
|
425
|
+
);
|
|
426
|
+
const agentExperienceRaw = toRecord(cfg.agentExperience);
|
|
427
|
+
assertAllowedKeys(
|
|
428
|
+
agentExperienceRaw,
|
|
429
|
+
["enabled", "recallLimit", "scoreThreshold", "maxInjectedChars", "minQueryChars"],
|
|
430
|
+
"openviking config agentExperience",
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
const mode = "remote" as const;
|
|
434
|
+
const peerRole = resolvePeerRole(cfg.peer_role);
|
|
435
|
+
const peerPrefix = resolvePeerPrefix(cfg.peer_prefix);
|
|
436
|
+
const rawBaseUrl = typeof cfg.baseUrl === "string" ? cfg.baseUrl : resolveDefaultBaseUrl();
|
|
437
|
+
const resolvedBaseUrl = resolveEnvVars(rawBaseUrl).replace(/\/+$/, "");
|
|
438
|
+
const rawApiKey = typeof cfg.apiKey === "string" ? cfg.apiKey : getEnv("OPENVIKING_API_KEY");
|
|
439
|
+
const captureMode = cfg.captureMode;
|
|
440
|
+
if (
|
|
441
|
+
typeof captureMode !== "undefined" &&
|
|
442
|
+
captureMode !== "semantic" &&
|
|
443
|
+
captureMode !== "keyword"
|
|
444
|
+
) {
|
|
445
|
+
throw new Error(`openviking captureMode must be "semantic" or "keyword"`);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const accountId =
|
|
449
|
+
typeof cfg.accountId === "string" && cfg.accountId.trim()
|
|
450
|
+
? cfg.accountId.trim()
|
|
451
|
+
: (getEnv("OPENVIKING_ACCOUNT_ID")?.trim() || "");
|
|
452
|
+
const userId =
|
|
453
|
+
typeof cfg.userId === "string" && cfg.userId.trim()
|
|
454
|
+
? cfg.userId.trim()
|
|
455
|
+
: (getEnv("OPENVIKING_USER_ID")?.trim() || "");
|
|
456
|
+
|
|
457
|
+
const recallMaxInjectedChars = Math.max(
|
|
458
|
+
100,
|
|
459
|
+
Math.min(
|
|
460
|
+
50000,
|
|
461
|
+
Math.floor(
|
|
462
|
+
toNumber(
|
|
463
|
+
cfg.recallMaxInjectedChars,
|
|
464
|
+
toNumber(cfg.recallTokenBudget, DEFAULT_RECALL_MAX_INJECTED_CHARS),
|
|
465
|
+
),
|
|
466
|
+
),
|
|
467
|
+
),
|
|
468
|
+
);
|
|
469
|
+
const recallResources = cfg.recallResources === true || envFlag("OPENVIKING_RECALL_RESOURCES");
|
|
470
|
+
const recallTargetTypes = normalizeRecallTargetTypes(
|
|
471
|
+
cfg.recallTargetTypes,
|
|
472
|
+
!("recallTargetTypes" in cfg) && recallResources,
|
|
473
|
+
);
|
|
474
|
+
const { enabledTools, disabledTools } = normalizeEnabledTools(cfg);
|
|
475
|
+
|
|
476
|
+
return {
|
|
477
|
+
mode,
|
|
478
|
+
baseUrl: resolvedBaseUrl,
|
|
479
|
+
peer_role: peerRole,
|
|
480
|
+
peer_prefix: peerPrefix,
|
|
481
|
+
apiKey: rawApiKey ? resolveEnvVars(rawApiKey) : "",
|
|
482
|
+
accountId,
|
|
483
|
+
userId,
|
|
484
|
+
targetUri: typeof cfg.targetUri === "string" ? cfg.targetUri : DEFAULT_TARGET_URI,
|
|
485
|
+
timeoutMs: Math.max(1000, Math.floor(toNumber(cfg.timeoutMs, DEFAULT_TIMEOUT_MS))),
|
|
486
|
+
autoCapture: cfg.autoCapture !== false,
|
|
487
|
+
captureMode: captureMode ?? DEFAULT_CAPTURE_MODE,
|
|
488
|
+
captureMaxLength: Math.max(
|
|
489
|
+
200,
|
|
490
|
+
Math.min(200_000, Math.floor(toNumber(cfg.captureMaxLength, DEFAULT_CAPTURE_MAX_LENGTH))),
|
|
491
|
+
),
|
|
492
|
+
autoRecall: cfg.autoRecall !== false,
|
|
493
|
+
autoRecallTimeoutMs: Math.max(
|
|
494
|
+
1000,
|
|
495
|
+
Math.min(300_000, Math.floor(toNumber(cfg.autoRecallTimeoutMs, DEFAULT_AUTO_RECALL_TIMEOUT_MS))),
|
|
496
|
+
),
|
|
497
|
+
recallResources,
|
|
498
|
+
recallLimit: Math.max(1, Math.floor(toNumber(cfg.recallLimit, DEFAULT_RECALL_LIMIT))),
|
|
499
|
+
recallScoreThreshold: Math.min(
|
|
500
|
+
1,
|
|
501
|
+
Math.max(0, toNumber(cfg.recallScoreThreshold, DEFAULT_RECALL_SCORE_THRESHOLD)),
|
|
502
|
+
),
|
|
503
|
+
recallMaxContentChars: Math.max(
|
|
504
|
+
50,
|
|
505
|
+
Math.min(10000, Math.floor(toNumber(cfg.recallMaxContentChars, DEFAULT_RECALL_MAX_CONTENT_CHARS))),
|
|
506
|
+
),
|
|
507
|
+
recallPreferAbstract:
|
|
508
|
+
typeof cfg.recallPreferAbstract === "boolean"
|
|
509
|
+
? cfg.recallPreferAbstract
|
|
510
|
+
: DEFAULT_RECALL_PREFER_ABSTRACT,
|
|
511
|
+
recallMaxInjectedChars,
|
|
512
|
+
recallTokenBudget: recallMaxInjectedChars,
|
|
513
|
+
commitTokenThreshold: Math.max(
|
|
514
|
+
0,
|
|
515
|
+
Math.min(100_000, Math.floor(toNumber(cfg.commitTokenThreshold, DEFAULT_COMMIT_TOKEN_THRESHOLD))),
|
|
516
|
+
),
|
|
517
|
+
commitKeepRecentCount: Math.max(
|
|
518
|
+
0,
|
|
519
|
+
Math.min(
|
|
520
|
+
1_000,
|
|
521
|
+
Math.floor(toNumber(cfg.commitKeepRecentCount, DEFAULT_COMMIT_KEEP_RECENT_COUNT)),
|
|
522
|
+
),
|
|
523
|
+
),
|
|
524
|
+
bypassSessionPatterns: toStringArray(
|
|
525
|
+
cfg.bypassSessionPatterns,
|
|
526
|
+
toStringArray(
|
|
527
|
+
cfg.ingestReplyAssistIgnoreSessionPatterns,
|
|
528
|
+
DEFAULT_BYPASS_SESSION_PATTERNS,
|
|
529
|
+
),
|
|
530
|
+
),
|
|
531
|
+
emitStandardDiagnostics:
|
|
532
|
+
typeof cfg.emitStandardDiagnostics === "boolean"
|
|
533
|
+
? cfg.emitStandardDiagnostics
|
|
534
|
+
: DEFAULT_EMIT_STANDARD_DIAGNOSTICS,
|
|
535
|
+
logFindRequests:
|
|
536
|
+
cfg.logFindRequests === true ||
|
|
537
|
+
envFlag("OPENVIKING_LOG_ROUTING") ||
|
|
538
|
+
envFlag("OPENVIKING_DEBUG"),
|
|
539
|
+
traceRecall: cfg.traceRecall === true,
|
|
540
|
+
traceRecallPersist: cfg.traceRecallPersist === true,
|
|
541
|
+
traceRecallDir:
|
|
542
|
+
typeof cfg.traceRecallDir === "string" && cfg.traceRecallDir.trim()
|
|
543
|
+
? expandHomeDir(cfg.traceRecallDir.trim())
|
|
544
|
+
: expandHomeDir(DEFAULT_TRACE_RECALL_DIR),
|
|
545
|
+
traceRecallRetentionDays: toIntegerInRange(
|
|
546
|
+
cfg.traceRecallRetentionDays,
|
|
547
|
+
DEFAULT_TRACE_RECALL_RETENTION_DAYS,
|
|
548
|
+
1,
|
|
549
|
+
3650,
|
|
550
|
+
),
|
|
551
|
+
traceRecallLoadRecentDays: toIntegerInRange(
|
|
552
|
+
cfg.traceRecallLoadRecentDays,
|
|
553
|
+
DEFAULT_TRACE_RECALL_LOAD_RECENT_DAYS,
|
|
554
|
+
0,
|
|
555
|
+
3650,
|
|
556
|
+
),
|
|
557
|
+
traceRecallMaxEntries: toIntegerInRange(
|
|
558
|
+
cfg.traceRecallMaxEntries,
|
|
559
|
+
DEFAULT_TRACE_RECALL_MAX_ENTRIES,
|
|
560
|
+
1,
|
|
561
|
+
1_000_000,
|
|
562
|
+
),
|
|
563
|
+
traceRecallMaxResultsPerSearch: toIntegerInRange(
|
|
564
|
+
cfg.traceRecallMaxResultsPerSearch,
|
|
565
|
+
DEFAULT_TRACE_RECALL_MAX_RESULTS_PER_SEARCH,
|
|
566
|
+
1,
|
|
567
|
+
1_000,
|
|
568
|
+
),
|
|
569
|
+
traceRecallPreviewChars: toIntegerInRange(
|
|
570
|
+
cfg.traceRecallPreviewChars,
|
|
571
|
+
DEFAULT_TRACE_RECALL_PREVIEW_CHARS,
|
|
572
|
+
20,
|
|
573
|
+
10_000,
|
|
574
|
+
),
|
|
575
|
+
traceRecallQueryMaxChars: toIntegerInRange(
|
|
576
|
+
cfg.traceRecallQueryMaxChars,
|
|
577
|
+
DEFAULT_TRACE_RECALL_QUERY_MAX_CHARS,
|
|
578
|
+
200,
|
|
579
|
+
200_000,
|
|
580
|
+
),
|
|
581
|
+
traceRecallQueryMaxDays: toIntegerInRange(
|
|
582
|
+
cfg.traceRecallQueryMaxDays,
|
|
583
|
+
DEFAULT_TRACE_RECALL_QUERY_MAX_DAYS,
|
|
584
|
+
1,
|
|
585
|
+
3650,
|
|
586
|
+
),
|
|
587
|
+
traceRecallIncludeContentByDefault: cfg.traceRecallIncludeContentByDefault === true,
|
|
588
|
+
traceRecallIncludeRawUserPreview: cfg.traceRecallIncludeRawUserPreview === true,
|
|
589
|
+
recallTargetTypes,
|
|
590
|
+
enableAddResourceTool: cfg.enableAddResourceTool === true,
|
|
591
|
+
enabledTools,
|
|
592
|
+
disabledTools,
|
|
593
|
+
runtimeQueryConfigPath:
|
|
594
|
+
typeof cfg.runtimeQueryConfigPath === "string" && cfg.runtimeQueryConfigPath.trim()
|
|
595
|
+
? expandHomeDir(cfg.runtimeQueryConfigPath.trim())
|
|
596
|
+
: "",
|
|
597
|
+
agentExperience: {
|
|
598
|
+
enabled:
|
|
599
|
+
typeof agentExperienceRaw.enabled === "boolean"
|
|
600
|
+
? agentExperienceRaw.enabled
|
|
601
|
+
: DEFAULT_AGENT_EXPERIENCE.enabled,
|
|
602
|
+
recallLimit: Math.max(
|
|
603
|
+
1,
|
|
604
|
+
Math.min(
|
|
605
|
+
10,
|
|
606
|
+
Math.floor(toNumber(agentExperienceRaw.recallLimit, DEFAULT_AGENT_EXPERIENCE.recallLimit)),
|
|
607
|
+
),
|
|
608
|
+
),
|
|
609
|
+
scoreThreshold: Math.min(
|
|
610
|
+
1,
|
|
611
|
+
Math.max(0, toNumber(agentExperienceRaw.scoreThreshold, DEFAULT_AGENT_EXPERIENCE.scoreThreshold)),
|
|
612
|
+
),
|
|
613
|
+
maxInjectedChars: Math.max(
|
|
614
|
+
500,
|
|
615
|
+
Math.min(
|
|
616
|
+
50_000,
|
|
617
|
+
Math.floor(toNumber(agentExperienceRaw.maxInjectedChars, DEFAULT_AGENT_EXPERIENCE.maxInjectedChars)),
|
|
618
|
+
),
|
|
619
|
+
),
|
|
620
|
+
minQueryChars: Math.max(
|
|
621
|
+
1,
|
|
622
|
+
Math.min(
|
|
623
|
+
500,
|
|
624
|
+
Math.floor(toNumber(agentExperienceRaw.minQueryChars, DEFAULT_AGENT_EXPERIENCE.minQueryChars)),
|
|
625
|
+
),
|
|
626
|
+
),
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
},
|
|
630
|
+
uiHints: {
|
|
631
|
+
baseUrl: {
|
|
632
|
+
label: "OpenViking Base URL",
|
|
633
|
+
placeholder: DEFAULT_BASE_URL,
|
|
634
|
+
help: "HTTP URL when mode is remote (or use ${OPENVIKING_BASE_URL})",
|
|
635
|
+
},
|
|
636
|
+
peer_role: {
|
|
637
|
+
label: "Peer Role",
|
|
638
|
+
placeholder: DEFAULT_PEER_ROLE,
|
|
639
|
+
help: 'Controls which session messages get peer_id: "none", "assistant", or "person".',
|
|
640
|
+
},
|
|
641
|
+
peer_prefix: {
|
|
642
|
+
label: "Peer Prefix",
|
|
643
|
+
placeholder: "optional-prefix",
|
|
644
|
+
help: "Optional prefix applied to assistant peer_id values derived from OpenClaw runtime agent IDs.",
|
|
645
|
+
},
|
|
646
|
+
apiKey: {
|
|
647
|
+
label: "OpenViking API Key",
|
|
648
|
+
sensitive: true,
|
|
649
|
+
placeholder: "${OPENVIKING_API_KEY}",
|
|
650
|
+
help: "Optional API key for OpenViking server",
|
|
651
|
+
},
|
|
652
|
+
accountId: {
|
|
653
|
+
label: "Account ID",
|
|
654
|
+
placeholder: "(derived from API key)",
|
|
655
|
+
help: "Advanced option. Tenant account ID. Only needed when explicitly sending identity headers, such as root-key or trusted deployments. With a user key the server derives identity from the key.",
|
|
656
|
+
advanced: true,
|
|
657
|
+
},
|
|
658
|
+
userId: {
|
|
659
|
+
label: "User ID",
|
|
660
|
+
placeholder: "(derived from API key)",
|
|
661
|
+
help: "Advanced option. Tenant user ID. Only needed when explicitly sending identity headers.",
|
|
662
|
+
advanced: true,
|
|
663
|
+
},
|
|
664
|
+
targetUri: {
|
|
665
|
+
label: "Search Target URI",
|
|
666
|
+
placeholder: DEFAULT_TARGET_URI,
|
|
667
|
+
help: "Default OpenViking target URI for memory search",
|
|
668
|
+
},
|
|
669
|
+
timeoutMs: {
|
|
670
|
+
label: "Request Timeout (ms)",
|
|
671
|
+
placeholder: String(DEFAULT_TIMEOUT_MS),
|
|
672
|
+
advanced: true,
|
|
673
|
+
},
|
|
674
|
+
autoCapture: {
|
|
675
|
+
label: "Auto-Capture",
|
|
676
|
+
help: "Extract memories from recent conversation messages via OpenViking sessions",
|
|
677
|
+
},
|
|
678
|
+
captureMode: {
|
|
679
|
+
label: "Capture Mode",
|
|
680
|
+
placeholder: DEFAULT_CAPTURE_MODE,
|
|
681
|
+
advanced: true,
|
|
682
|
+
help: '"semantic" captures all eligible user text and relies on OpenViking extraction; "keyword" uses trigger regex first.',
|
|
683
|
+
},
|
|
684
|
+
captureMaxLength: {
|
|
685
|
+
label: "Capture Max Length",
|
|
686
|
+
placeholder: String(DEFAULT_CAPTURE_MAX_LENGTH),
|
|
687
|
+
advanced: true,
|
|
688
|
+
help: "Maximum sanitized user text length allowed for auto-capture.",
|
|
689
|
+
},
|
|
690
|
+
autoRecall: {
|
|
691
|
+
label: "Auto-Recall",
|
|
692
|
+
help: "Inject relevant OpenViking memories into agent context",
|
|
693
|
+
},
|
|
694
|
+
autoRecallTimeoutMs: {
|
|
695
|
+
label: "Auto-Recall Timeout (ms)",
|
|
696
|
+
placeholder: String(DEFAULT_AUTO_RECALL_TIMEOUT_MS),
|
|
697
|
+
advanced: true,
|
|
698
|
+
help: "Outer time budget for the whole auto-recall flow, including search, ranking, and memory reads.",
|
|
699
|
+
},
|
|
700
|
+
recallResources: {
|
|
701
|
+
label: "Recall Resources",
|
|
702
|
+
help: "Include resources (viking://resources) in auto-recall and default memory_recall search. Enables account-level shared knowledge retrieval.",
|
|
703
|
+
advanced: true,
|
|
704
|
+
},
|
|
705
|
+
recallTargetTypes: {
|
|
706
|
+
label: "Recall Target Types",
|
|
707
|
+
placeholder: "user,agent",
|
|
708
|
+
help: "Comma-separated auto-recall and default memory_recall targets: user, agent, resource. Session history is available through ov_archive_search and ov_archive_expand.",
|
|
709
|
+
advanced: true,
|
|
710
|
+
},
|
|
711
|
+
recallLimit: {
|
|
712
|
+
label: "Recall Limit",
|
|
713
|
+
placeholder: String(DEFAULT_RECALL_LIMIT),
|
|
714
|
+
advanced: true,
|
|
715
|
+
},
|
|
716
|
+
recallScoreThreshold: {
|
|
717
|
+
label: "Recall Score Threshold",
|
|
718
|
+
placeholder: String(DEFAULT_RECALL_SCORE_THRESHOLD),
|
|
719
|
+
advanced: true,
|
|
720
|
+
},
|
|
721
|
+
recallMaxInjectedChars: {
|
|
722
|
+
label: "Recall Max Injected Chars",
|
|
723
|
+
placeholder: String(DEFAULT_RECALL_MAX_INJECTED_CHARS),
|
|
724
|
+
advanced: true,
|
|
725
|
+
help: "Maximum total characters for auto-recall memory injection. Complete memories that do not fit are skipped, not truncated.",
|
|
726
|
+
},
|
|
727
|
+
recallMaxContentChars: {
|
|
728
|
+
label: "Deprecated Recall Max Content Chars",
|
|
729
|
+
placeholder: String(DEFAULT_RECALL_MAX_CONTENT_CHARS),
|
|
730
|
+
advanced: true,
|
|
731
|
+
help: "Deprecated compatibility option and will be removed in a future release. Auto-recall now keeps individual memories intact and uses recallMaxInjectedChars.",
|
|
732
|
+
},
|
|
733
|
+
recallPreferAbstract: {
|
|
734
|
+
label: "Recall Prefer Abstract",
|
|
735
|
+
advanced: true,
|
|
736
|
+
help: "Use memory abstract instead of fetching full content when abstract is available. Reduces token usage.",
|
|
737
|
+
},
|
|
738
|
+
recallTokenBudget: {
|
|
739
|
+
label: "Deprecated Recall Token Budget",
|
|
740
|
+
placeholder: String(DEFAULT_RECALL_MAX_INJECTED_CHARS),
|
|
741
|
+
advanced: true,
|
|
742
|
+
help: "Deprecated compatibility alias and will be removed in a future release. Use recallMaxInjectedChars.",
|
|
743
|
+
},
|
|
744
|
+
bypassSessionPatterns: {
|
|
745
|
+
label: "Bypass Session Patterns",
|
|
746
|
+
placeholder: "agent:*:cron:**",
|
|
747
|
+
help: "Completely bypass OpenViking for matching session keys. Use * within one segment and ** across segments.",
|
|
748
|
+
advanced: true,
|
|
749
|
+
},
|
|
750
|
+
commitTokenThreshold: {
|
|
751
|
+
label: "Commit Token Threshold",
|
|
752
|
+
placeholder: String(DEFAULT_COMMIT_TOKEN_THRESHOLD),
|
|
753
|
+
advanced: true,
|
|
754
|
+
help: "Minimum estimated pending tokens before auto-commit triggers. Set to 0 to commit every turn.",
|
|
755
|
+
},
|
|
756
|
+
commitKeepRecentCount: {
|
|
757
|
+
label: "Commit Keep Recent Count",
|
|
758
|
+
placeholder: String(DEFAULT_COMMIT_KEEP_RECENT_COUNT),
|
|
759
|
+
advanced: true,
|
|
760
|
+
help:
|
|
761
|
+
"Number of most-recent messages to keep live after an afterTurn commit. " +
|
|
762
|
+
"Forwarded as keep_recent_count to the server. Compact path always uses 0.",
|
|
763
|
+
},
|
|
764
|
+
emitStandardDiagnostics: {
|
|
765
|
+
label: "Standard diagnostics (diag JSON lines)",
|
|
766
|
+
advanced: true,
|
|
767
|
+
help: "When enabled, emit structured openviking: diag {...} lines for assemble and afterTurn. Disable to reduce log noise.",
|
|
768
|
+
},
|
|
769
|
+
logFindRequests: {
|
|
770
|
+
label: "Log find requests",
|
|
771
|
+
help:
|
|
772
|
+
"Log tenant routing: POST /api/v1/search/find (query, target_uri) and session POST .../messages + .../commit (sessionId, X-OpenViking-*). Never logs apiKey. " +
|
|
773
|
+
"Or set env OPENVIKING_LOG_ROUTING=1 or OPENVIKING_DEBUG=1 (no JSON edit).",
|
|
774
|
+
advanced: true,
|
|
775
|
+
},
|
|
776
|
+
traceRecall: {
|
|
777
|
+
label: "Trace Recall",
|
|
778
|
+
placeholder: "false",
|
|
779
|
+
help: "Enable best-effort recall trace recording for debugging recall and search decisions.",
|
|
780
|
+
advanced: true,
|
|
781
|
+
},
|
|
782
|
+
traceRecallPersist: {
|
|
783
|
+
label: "Persist Recall Trace",
|
|
784
|
+
placeholder: "false",
|
|
785
|
+
help: "Persist recall traces to local JSONL files. Disabled by default.",
|
|
786
|
+
advanced: true,
|
|
787
|
+
},
|
|
788
|
+
traceRecallDir: {
|
|
789
|
+
label: "Recall Trace Directory",
|
|
790
|
+
placeholder: DEFAULT_TRACE_RECALL_DIR,
|
|
791
|
+
help: "Directory for persisted recall trace JSONL files.",
|
|
792
|
+
advanced: true,
|
|
793
|
+
},
|
|
794
|
+
enableAddResourceTool: {
|
|
795
|
+
label: "Enable Add Resource Tool",
|
|
796
|
+
placeholder: "false",
|
|
797
|
+
help: "Disabled by default so search and read flows cannot call add_resource. Set true only when agents should import resources; manual /add-resource remains available.",
|
|
798
|
+
advanced: true,
|
|
799
|
+
},
|
|
800
|
+
enabledTools: {
|
|
801
|
+
label: "Enabled Tools",
|
|
802
|
+
placeholder: "default",
|
|
803
|
+
help: "Agent-visible tool allowlist. Accepts tool names or groups: default, all, memory, resource_query, import, recall_trace, archive, tool_result. add_resource also requires enableAddResourceTool=true.",
|
|
804
|
+
advanced: true,
|
|
805
|
+
},
|
|
806
|
+
disabledTools: {
|
|
807
|
+
label: "Disabled Tools",
|
|
808
|
+
placeholder: "memory",
|
|
809
|
+
help: "Agent-visible tool blocklist applied after enabledTools. Accepts the same tool names or groups.",
|
|
810
|
+
advanced: true,
|
|
811
|
+
},
|
|
812
|
+
runtimeQueryConfigPath: {
|
|
813
|
+
label: "Runtime Query Config Path",
|
|
814
|
+
placeholder: "~/.openclaw/openviking/runtime-query-config.json",
|
|
815
|
+
help: "Optional JSON file for /ov-query-config runtime overrides. Empty keeps overrides in memory only.",
|
|
816
|
+
advanced: true,
|
|
817
|
+
},
|
|
818
|
+
},
|
|
819
|
+
};
|