@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/client.ts
CHANGED
|
@@ -7,6 +7,12 @@ import { basename, dirname, join, relative } from "node:path";
|
|
|
7
7
|
|
|
8
8
|
import { Zip, ZipDeflate } from "fflate";
|
|
9
9
|
|
|
10
|
+
import { defaultHttpTransport, type HttpTransport } from "./adapters/http-transport.js";
|
|
11
|
+
import {
|
|
12
|
+
defaultResourcePackager,
|
|
13
|
+
type ResourcePackager,
|
|
14
|
+
} from "./adapters/resource-packager.js";
|
|
15
|
+
|
|
10
16
|
export type FindResultItem = {
|
|
11
17
|
uri: string;
|
|
12
18
|
level?: number;
|
|
@@ -24,13 +30,22 @@ export type FindResult = {
|
|
|
24
30
|
total?: number;
|
|
25
31
|
};
|
|
26
32
|
|
|
33
|
+
export type FsListEntry = string | Record<string, unknown>;
|
|
34
|
+
|
|
35
|
+
export type FsListResult = FsListEntry[];
|
|
36
|
+
|
|
27
37
|
export type CaptureMode = "semantic" | "keyword";
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
function userSessionUri(sessionId: string): string {
|
|
39
|
+
return `viking://user/sessions/${encodeURIComponent(sessionId)}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type OpenVikingClientOptions = {
|
|
43
|
+
transport?: HttpTransport;
|
|
44
|
+
resourcePackager?: ResourcePackager;
|
|
45
|
+
now?: () => number;
|
|
46
|
+
sleep?: (ms: number) => Promise<void>;
|
|
33
47
|
};
|
|
48
|
+
|
|
34
49
|
export type CommitSessionResult = {
|
|
35
50
|
session_id: string;
|
|
36
51
|
/** "accepted" (async), "completed", "failed", or "timeout" (wait mode). */
|
|
@@ -44,6 +59,16 @@ export type CommitSessionResult = {
|
|
|
44
59
|
trace_id?: string;
|
|
45
60
|
};
|
|
46
61
|
|
|
62
|
+
export type OVMemoryPolicySwitch = {
|
|
63
|
+
enabled?: boolean;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type OVMemoryPolicy = {
|
|
67
|
+
self?: OVMemoryPolicySwitch;
|
|
68
|
+
peer?: OVMemoryPolicySwitch;
|
|
69
|
+
memory_types?: string[];
|
|
70
|
+
};
|
|
71
|
+
|
|
47
72
|
export type TaskResult = {
|
|
48
73
|
task_id: string;
|
|
49
74
|
task_type: string;
|
|
@@ -195,18 +220,8 @@ function sleep(ms: number): Promise<void> {
|
|
|
195
220
|
}
|
|
196
221
|
|
|
197
222
|
const MEMORY_URI_PATTERNS = [
|
|
198
|
-
/^viking:\/\/user\/(?:[^/]
|
|
199
|
-
/^viking:\/\/agent\/(?:[^/]+(?:\/user\/[^/]+)?\/)?memories(?:\/|$)/,
|
|
223
|
+
/^viking:\/\/user\/(?:[^/]+\/)?memories(?:\/|$)/,
|
|
200
224
|
];
|
|
201
|
-
const USER_STRUCTURE_DIRS = new Set(["memories", "profile.md", ".abstract.md", ".overview.md"]);
|
|
202
|
-
const AGENT_STRUCTURE_DIRS = new Set([
|
|
203
|
-
"memories",
|
|
204
|
-
"skills",
|
|
205
|
-
"instructions",
|
|
206
|
-
"workspaces",
|
|
207
|
-
".abstract.md",
|
|
208
|
-
".overview.md",
|
|
209
|
-
]);
|
|
210
225
|
const REMOTE_RESOURCE_PREFIXES = ["http://", "https://", "git@", "ssh://", "git://"];
|
|
211
226
|
|
|
212
227
|
export function isMemoryUri(uri: string): boolean {
|
|
@@ -238,7 +253,10 @@ async function cleanupUploadTempPath(path?: string): Promise<void> {
|
|
|
238
253
|
}
|
|
239
254
|
|
|
240
255
|
export class OpenVikingClient {
|
|
241
|
-
private
|
|
256
|
+
private readonly transport: HttpTransport;
|
|
257
|
+
private readonly now: () => number;
|
|
258
|
+
private readonly sleep: (ms: number) => Promise<void>;
|
|
259
|
+
private readonly resourcePackager: ResourcePackager;
|
|
242
260
|
|
|
243
261
|
constructor(
|
|
244
262
|
private readonly baseUrl: string,
|
|
@@ -250,27 +268,24 @@ export class OpenVikingClient {
|
|
|
250
268
|
private readonly userId: string = "",
|
|
251
269
|
/** When set, logs routing for find + session writes (tenant headers + paths; never apiKey). */
|
|
252
270
|
private readonly routingDebugLog?: (message: string) => void,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
271
|
+
optionsOrLegacyUserScope: OpenVikingClientOptions | boolean = {},
|
|
272
|
+
_legacyAgentScope?: boolean,
|
|
273
|
+
legacyOptions?: OpenVikingClientOptions,
|
|
274
|
+
) {
|
|
275
|
+
const options =
|
|
276
|
+
typeof optionsOrLegacyUserScope === "object" && optionsOrLegacyUserScope !== null
|
|
277
|
+
? optionsOrLegacyUserScope
|
|
278
|
+
: (legacyOptions ?? {});
|
|
279
|
+
this.transport = options.transport ?? defaultHttpTransport;
|
|
280
|
+
this.now = options.now ?? Date.now;
|
|
281
|
+
this.sleep = options.sleep ?? sleep;
|
|
282
|
+
this.resourcePackager = options.resourcePackager ?? defaultResourcePackager;
|
|
283
|
+
}
|
|
256
284
|
|
|
257
285
|
getDefaultAgentId(): string {
|
|
258
286
|
return this.defaultAgentId;
|
|
259
287
|
}
|
|
260
288
|
|
|
261
|
-
private resolveEffectiveAgentId(agentId?: string): string {
|
|
262
|
-
const explicit = agentId?.trim();
|
|
263
|
-
if (explicit) {
|
|
264
|
-
return explicit;
|
|
265
|
-
}
|
|
266
|
-
const prefix = this.defaultAgentId.trim();
|
|
267
|
-
return prefix ? `${prefix}_main` : "main";
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
async getResolvedIdentity(agentId?: string): Promise<RuntimeIdentity> {
|
|
271
|
-
return this.getRuntimeIdentity(agentId);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
289
|
private resolveTenantHeaders():
|
|
275
290
|
| { apiKey?: string; accountId?: string; userId?: string }
|
|
276
291
|
{
|
|
@@ -284,27 +299,35 @@ export class OpenVikingClient {
|
|
|
284
299
|
};
|
|
285
300
|
}
|
|
286
301
|
|
|
302
|
+
private resolveActorPeerHeader(actorPeerId?: string): string | undefined {
|
|
303
|
+
const value = actorPeerId?.trim();
|
|
304
|
+
return value || undefined;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private resolveDefaultActorPeerHeader(): string {
|
|
308
|
+
const peerPrefix = this.defaultAgentId.trim();
|
|
309
|
+
return peerPrefix ? `${peerPrefix}_main` : "main";
|
|
310
|
+
}
|
|
311
|
+
|
|
287
312
|
private async emitRoutingDebug(
|
|
288
313
|
label: string,
|
|
289
314
|
detail: Record<string, unknown>,
|
|
290
|
-
|
|
315
|
+
actorPeerId?: string,
|
|
291
316
|
): Promise<void> {
|
|
292
317
|
if (!this.routingDebugLog) {
|
|
293
318
|
return;
|
|
294
319
|
}
|
|
295
|
-
const effectiveAgentId = this.resolveEffectiveAgentId(agentId);
|
|
296
|
-
const identity = await this.getRuntimeIdentity(agentId);
|
|
297
320
|
const tenantHeaders = this.resolveTenantHeaders();
|
|
321
|
+
const actorPeerHeader = this.resolveActorPeerHeader(actorPeerId);
|
|
298
322
|
this.routingDebugLog(
|
|
299
323
|
`openviking: ${label} ` +
|
|
300
324
|
JSON.stringify({
|
|
301
325
|
...detail,
|
|
302
|
-
X_OpenViking_Agent: effectiveAgentId,
|
|
303
326
|
X_OpenViking_Account: tenantHeaders.accountId ?? null,
|
|
304
327
|
X_OpenViking_User: tenantHeaders.userId ?? null,
|
|
305
|
-
|
|
328
|
+
X_OpenViking_Actor_Peer: actorPeerHeader ?? null,
|
|
306
329
|
session_vfs_hint: detail.sessionId
|
|
307
|
-
?
|
|
330
|
+
? userSessionUri(String(detail.sessionId))
|
|
308
331
|
: undefined,
|
|
309
332
|
}),
|
|
310
333
|
);
|
|
@@ -313,10 +336,9 @@ export class OpenVikingClient {
|
|
|
313
336
|
private async request<T>(
|
|
314
337
|
path: string,
|
|
315
338
|
init: RequestInit = {},
|
|
316
|
-
agentId?: string,
|
|
317
339
|
requestTimeoutMs?: number,
|
|
340
|
+
actorPeerId?: string,
|
|
318
341
|
): Promise<T> {
|
|
319
|
-
const effectiveAgentId = this.resolveEffectiveAgentId(agentId);
|
|
320
342
|
const controller = new AbortController();
|
|
321
343
|
const timer = setTimeout(() => controller.abort(), requestTimeoutMs ?? this.timeoutMs);
|
|
322
344
|
try {
|
|
@@ -331,14 +353,15 @@ export class OpenVikingClient {
|
|
|
331
353
|
if (tenantHeaders.userId) {
|
|
332
354
|
headers.set("X-OpenViking-User", tenantHeaders.userId);
|
|
333
355
|
}
|
|
334
|
-
|
|
335
|
-
|
|
356
|
+
const actorPeerHeader = this.resolveActorPeerHeader(actorPeerId);
|
|
357
|
+
if (actorPeerHeader) {
|
|
358
|
+
headers.set("X-OpenViking-Actor-Peer", actorPeerHeader);
|
|
336
359
|
}
|
|
337
360
|
if (init.body && !(init.body instanceof FormData) && !headers.has("Content-Type")) {
|
|
338
361
|
headers.set("Content-Type", "application/json");
|
|
339
362
|
}
|
|
340
363
|
|
|
341
|
-
const response = await
|
|
364
|
+
const response = await this.transport(`${this.baseUrl}${path}`, {
|
|
342
365
|
...init,
|
|
343
366
|
headers,
|
|
344
367
|
signal: controller.signal,
|
|
@@ -362,96 +385,81 @@ export class OpenVikingClient {
|
|
|
362
385
|
}
|
|
363
386
|
}
|
|
364
387
|
|
|
365
|
-
async healthCheck(
|
|
366
|
-
await this.request<{ status: string }>(
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
if (cached) {
|
|
373
|
-
return cached;
|
|
374
|
-
}
|
|
375
|
-
const fallback: RuntimeIdentity = { userId: "default", agentId: effectiveAgentId };
|
|
376
|
-
try {
|
|
377
|
-
const status = await this.request<{ user?: unknown }>("/api/v1/system/status", {}, agentId);
|
|
378
|
-
const userId =
|
|
379
|
-
typeof status.user === "string" && status.user.trim() ? status.user.trim() : "default";
|
|
380
|
-
const identity: RuntimeIdentity = { userId, agentId: effectiveAgentId };
|
|
381
|
-
this.identityCache.set(effectiveAgentId, identity);
|
|
382
|
-
return identity;
|
|
383
|
-
} catch {
|
|
384
|
-
this.identityCache.set(effectiveAgentId, fallback);
|
|
385
|
-
return fallback;
|
|
386
|
-
}
|
|
388
|
+
async healthCheck(requestTimeoutMs?: number, actorPeerId?: string): Promise<void> {
|
|
389
|
+
await this.request<{ status: string }>(
|
|
390
|
+
"/health",
|
|
391
|
+
{},
|
|
392
|
+
requestTimeoutMs,
|
|
393
|
+
actorPeerId ?? this.resolveDefaultActorPeerHeader(),
|
|
394
|
+
);
|
|
387
395
|
}
|
|
388
396
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
397
|
+
async createSession(
|
|
398
|
+
sessionId: string,
|
|
399
|
+
options?: { memoryPolicy?: OVMemoryPolicy },
|
|
400
|
+
): Promise<{ session_id: string; user?: unknown }> {
|
|
401
|
+
const body: Record<string, unknown> = { session_id: sessionId };
|
|
402
|
+
if (options?.memoryPolicy) {
|
|
403
|
+
body.memory_policy = options.memoryPolicy;
|
|
396
404
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
:
|
|
400
|
-
|
|
405
|
+
return this.request<{ session_id: string; user?: unknown }>(
|
|
406
|
+
"/api/v1/sessions",
|
|
407
|
+
{ method: "POST", body: JSON.stringify(body) },
|
|
408
|
+
);
|
|
401
409
|
}
|
|
402
410
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
return trimmed;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
const reservedDirs = scope === "user" ? USER_STRUCTURE_DIRS : AGENT_STRUCTURE_DIRS;
|
|
420
|
-
if (!reservedDirs.has(parts[0]!)) {
|
|
421
|
-
return trimmed;
|
|
411
|
+
async ensureSession(
|
|
412
|
+
sessionId: string,
|
|
413
|
+
options?: { memoryPolicy?: OVMemoryPolicy },
|
|
414
|
+
): Promise<boolean> {
|
|
415
|
+
try {
|
|
416
|
+
await this.createSession(sessionId, options);
|
|
417
|
+
return true;
|
|
418
|
+
} catch (err) {
|
|
419
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
420
|
+
if (message.includes("[ALREADY_EXISTS]")) {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
throw err;
|
|
422
424
|
}
|
|
423
|
-
|
|
424
|
-
const root = await this.buildCanonicalRoot(scope, agentId);
|
|
425
|
-
return `${root}/${parts.join("/")}`;
|
|
426
425
|
}
|
|
427
426
|
|
|
428
427
|
async find(
|
|
429
428
|
query: string,
|
|
430
429
|
options: {
|
|
431
|
-
targetUri
|
|
432
|
-
limit
|
|
430
|
+
targetUri?: string;
|
|
431
|
+
limit?: number;
|
|
433
432
|
scoreThreshold?: number;
|
|
433
|
+
contextType?: string | string[];
|
|
434
|
+
actorPeerId?: string;
|
|
434
435
|
},
|
|
435
|
-
|
|
436
|
+
legacyActorPeerId?: string,
|
|
436
437
|
): Promise<FindResult> {
|
|
437
|
-
const
|
|
438
|
-
const body
|
|
438
|
+
const targetUri = options.targetUri?.trim().replace(/\/+$/, "") ?? "";
|
|
439
|
+
const body: {
|
|
440
|
+
query: string;
|
|
441
|
+
target_uri?: string;
|
|
442
|
+
limit?: number;
|
|
443
|
+
score_threshold?: number;
|
|
444
|
+
context_type?: string | string[];
|
|
445
|
+
} = {
|
|
439
446
|
query,
|
|
440
|
-
target_uri: normalizedTargetUri,
|
|
441
447
|
limit: options.limit,
|
|
442
448
|
score_threshold: options.scoreThreshold,
|
|
449
|
+
context_type: options.contextType,
|
|
443
450
|
};
|
|
444
|
-
|
|
445
|
-
|
|
451
|
+
if (targetUri) {
|
|
452
|
+
body.target_uri = targetUri;
|
|
453
|
+
}
|
|
454
|
+
const actorPeerId = this.resolveActorPeerHeader(options.actorPeerId ?? legacyActorPeerId);
|
|
446
455
|
const tenantHeaders = this.resolveTenantHeaders();
|
|
447
456
|
this.routingDebugLog?.(
|
|
448
457
|
`openviking: find POST ${this.baseUrl}/api/v1/search/find ` +
|
|
449
458
|
JSON.stringify({
|
|
450
|
-
X_OpenViking_Agent: effectiveAgentId,
|
|
451
459
|
X_OpenViking_Account: tenantHeaders.accountId ?? null,
|
|
452
460
|
X_OpenViking_User: tenantHeaders.userId ?? null,
|
|
453
|
-
|
|
454
|
-
target_uri:
|
|
461
|
+
X_OpenViking_Actor_Peer: actorPeerId ?? null,
|
|
462
|
+
target_uri: targetUri || null,
|
|
455
463
|
target_uri_input: options.targetUri,
|
|
456
464
|
query:
|
|
457
465
|
query.length > 4000
|
|
@@ -459,19 +467,51 @@ export class OpenVikingClient {
|
|
|
459
467
|
: query,
|
|
460
468
|
limit: body.limit,
|
|
461
469
|
score_threshold: body.score_threshold ?? null,
|
|
470
|
+
context_type: body.context_type ?? null,
|
|
462
471
|
}),
|
|
463
472
|
);
|
|
464
473
|
return this.request<FindResult>("/api/v1/search/find", {
|
|
465
474
|
method: "POST",
|
|
466
475
|
body: JSON.stringify(body),
|
|
467
|
-
},
|
|
476
|
+
}, undefined, actorPeerId);
|
|
468
477
|
}
|
|
469
478
|
|
|
470
|
-
async read(uri: string,
|
|
479
|
+
async read(uri: string, actorPeerId?: string): Promise<string> {
|
|
471
480
|
return this.request<string>(
|
|
472
481
|
`/api/v1/content/read?uri=${encodeURIComponent(uri)}`,
|
|
473
482
|
{},
|
|
474
|
-
|
|
483
|
+
undefined,
|
|
484
|
+
actorPeerId,
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
async list(
|
|
489
|
+
uri: string,
|
|
490
|
+
options?: {
|
|
491
|
+
recursive?: boolean;
|
|
492
|
+
simple?: boolean;
|
|
493
|
+
output?: "agent" | "original";
|
|
494
|
+
absLimit?: number;
|
|
495
|
+
showAllHidden?: boolean;
|
|
496
|
+
nodeLimit?: number;
|
|
497
|
+
actorPeerId?: string;
|
|
498
|
+
},
|
|
499
|
+
): Promise<FsListResult> {
|
|
500
|
+
const normalizedUri = uri.trim().replace(/\/+$/, "");
|
|
501
|
+
const params = new URLSearchParams({
|
|
502
|
+
uri: normalizedUri,
|
|
503
|
+
recursive: String(options?.recursive ?? false),
|
|
504
|
+
simple: String(options?.simple ?? false),
|
|
505
|
+
output: options?.output ?? "agent",
|
|
506
|
+
abs_limit: String(options?.absLimit ?? 256),
|
|
507
|
+
show_all_hidden: String(options?.showAllHidden ?? false),
|
|
508
|
+
node_limit: String(options?.nodeLimit ?? 1000),
|
|
509
|
+
});
|
|
510
|
+
return this.request<FsListResult>(
|
|
511
|
+
`/api/v1/fs/ls?${params.toString()}`,
|
|
512
|
+
{},
|
|
513
|
+
undefined,
|
|
514
|
+
options?.actorPeerId,
|
|
475
515
|
);
|
|
476
516
|
}
|
|
477
517
|
|
|
@@ -479,7 +519,6 @@ export class OpenVikingClient {
|
|
|
479
519
|
sessionId: string,
|
|
480
520
|
toolResultId: string,
|
|
481
521
|
options?: { offset?: number; limit?: number; includeMetadata?: boolean },
|
|
482
|
-
agentId?: string,
|
|
483
522
|
): Promise<ToolResultReadResult> {
|
|
484
523
|
const params = new URLSearchParams();
|
|
485
524
|
if (options?.offset !== undefined) params.set("offset", String(options.offset));
|
|
@@ -491,7 +530,6 @@ export class OpenVikingClient {
|
|
|
491
530
|
return this.request<ToolResultReadResult>(
|
|
492
531
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results/${encodeURIComponent(toolResultId)}${query ? `?${query}` : ""}`,
|
|
493
532
|
{},
|
|
494
|
-
agentId,
|
|
495
533
|
);
|
|
496
534
|
}
|
|
497
535
|
|
|
@@ -500,7 +538,6 @@ export class OpenVikingClient {
|
|
|
500
538
|
toolResultId: string,
|
|
501
539
|
queryText: string,
|
|
502
540
|
options?: { limit?: number; contextChars?: number },
|
|
503
|
-
agentId?: string,
|
|
504
541
|
): Promise<ToolResultSearchResult> {
|
|
505
542
|
const params = new URLSearchParams({ q: queryText });
|
|
506
543
|
if (options?.limit !== undefined) params.set("limit", String(options.limit));
|
|
@@ -510,14 +547,12 @@ export class OpenVikingClient {
|
|
|
510
547
|
return this.request<ToolResultSearchResult>(
|
|
511
548
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results/${encodeURIComponent(toolResultId)}/search?${params.toString()}`,
|
|
512
549
|
{},
|
|
513
|
-
agentId,
|
|
514
550
|
);
|
|
515
551
|
}
|
|
516
552
|
|
|
517
553
|
async listToolResults(
|
|
518
554
|
sessionId: string,
|
|
519
555
|
options?: { toolName?: string; limit?: number },
|
|
520
|
-
agentId?: string,
|
|
521
556
|
): Promise<ToolResultListResult> {
|
|
522
557
|
const params = new URLSearchParams();
|
|
523
558
|
if (options?.toolName) params.set("tool_name", options.toolName);
|
|
@@ -526,22 +561,16 @@ export class OpenVikingClient {
|
|
|
526
561
|
return this.request<ToolResultListResult>(
|
|
527
562
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results${query ? `?${query}` : ""}`,
|
|
528
563
|
{},
|
|
529
|
-
agentId,
|
|
530
564
|
);
|
|
531
565
|
}
|
|
532
566
|
|
|
533
|
-
async uploadTempFile(filePath: string,
|
|
534
|
-
const
|
|
535
|
-
const form = new FormData();
|
|
536
|
-
form.append(
|
|
537
|
-
"file",
|
|
538
|
-
new Blob([toBlobPart(fileBytes)], { type: "application/octet-stream" }),
|
|
539
|
-
basename(filePath),
|
|
540
|
-
);
|
|
567
|
+
async uploadTempFile(filePath: string, actorPeerId?: string): Promise<string> {
|
|
568
|
+
const form = await this.resourcePackager.createTempUploadBody(filePath);
|
|
541
569
|
const result = await this.request<{ temp_file_id: string }>(
|
|
542
570
|
"/api/v1/resources/temp_upload",
|
|
543
571
|
{ method: "POST", body: form },
|
|
544
|
-
|
|
572
|
+
undefined,
|
|
573
|
+
actorPeerId,
|
|
545
574
|
);
|
|
546
575
|
if (!result.temp_file_id) {
|
|
547
576
|
throw new Error("OpenViking temp upload did not return temp_file_id");
|
|
@@ -606,7 +635,7 @@ export class OpenVikingClient {
|
|
|
606
635
|
return zipPath;
|
|
607
636
|
}
|
|
608
637
|
|
|
609
|
-
async addResource(input: AddResourceInput,
|
|
638
|
+
async addResource(input: AddResourceInput, actorPeerId?: string): Promise<AddResourceResult> {
|
|
610
639
|
const pathOrUrl = input.pathOrUrl.trim();
|
|
611
640
|
if (!pathOrUrl) {
|
|
612
641
|
throw new Error("pathOrUrl is required");
|
|
@@ -631,36 +660,31 @@ export class OpenVikingClient {
|
|
|
631
660
|
body.preserve_structure = input.preserveStructure;
|
|
632
661
|
}
|
|
633
662
|
|
|
634
|
-
let
|
|
663
|
+
let packagedSource: Awaited<ReturnType<ResourcePackager["prepareResourceSource"]>> | undefined;
|
|
635
664
|
const requestTimeoutMs =
|
|
636
665
|
input.wait ? resolveWaitRequestTimeoutMs(this.timeoutMs, input.timeout) : undefined;
|
|
637
666
|
try {
|
|
638
|
-
|
|
639
|
-
|
|
667
|
+
packagedSource = await this.resourcePackager.prepareResourceSource(pathOrUrl);
|
|
668
|
+
if (packagedSource.kind === "remote") {
|
|
669
|
+
body.path = packagedSource.path;
|
|
640
670
|
} else {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
if (localStats.isDirectory()) {
|
|
644
|
-
uploadPath = await this.zipDirectoryForUpload(pathOrUrl);
|
|
645
|
-
cleanupPath = uploadPath;
|
|
646
|
-
body.source_name = basename(pathOrUrl);
|
|
647
|
-
} else if (!localStats.isFile()) {
|
|
648
|
-
throw new Error(`Path is not a file or directory: ${pathOrUrl}`);
|
|
671
|
+
if (packagedSource.sourceName) {
|
|
672
|
+
body.source_name = packagedSource.sourceName;
|
|
649
673
|
}
|
|
650
|
-
body.temp_file_id = await this.uploadTempFile(uploadPath,
|
|
674
|
+
body.temp_file_id = await this.uploadTempFile(packagedSource.uploadPath, actorPeerId);
|
|
651
675
|
}
|
|
652
676
|
return this.request<AddResourceResult>(
|
|
653
677
|
"/api/v1/resources",
|
|
654
678
|
{ method: "POST", body: JSON.stringify(body) },
|
|
655
|
-
agentId,
|
|
656
679
|
requestTimeoutMs,
|
|
680
|
+
actorPeerId,
|
|
657
681
|
);
|
|
658
682
|
} finally {
|
|
659
|
-
await
|
|
683
|
+
await this.resourcePackager.cleanup(packagedSource);
|
|
660
684
|
}
|
|
661
685
|
}
|
|
662
686
|
|
|
663
|
-
async addSkill(input: AddSkillInput,
|
|
687
|
+
async addSkill(input: AddSkillInput, actorPeerId?: string): Promise<AddSkillResult> {
|
|
664
688
|
const hasPath = typeof input.path === "string" && input.path.trim().length > 0;
|
|
665
689
|
const hasData = input.data !== undefined && input.data !== null;
|
|
666
690
|
if (hasPath === hasData) {
|
|
@@ -671,32 +695,28 @@ export class OpenVikingClient {
|
|
|
671
695
|
wait: input.wait ?? false,
|
|
672
696
|
timeout: input.timeout,
|
|
673
697
|
};
|
|
674
|
-
let
|
|
698
|
+
let packagedSource: Awaited<ReturnType<ResourcePackager["prepareLocalUploadSource"]>> | undefined;
|
|
675
699
|
const requestTimeoutMs =
|
|
676
700
|
input.wait ? resolveWaitRequestTimeoutMs(this.timeoutMs, input.timeout) : undefined;
|
|
677
701
|
try {
|
|
678
702
|
if (hasPath) {
|
|
679
703
|
const skillPath = input.path!.trim();
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
if (localStats.isDirectory()) {
|
|
683
|
-
uploadPath = await this.zipDirectoryForUpload(skillPath);
|
|
684
|
-
cleanupPath = uploadPath;
|
|
685
|
-
} else if (!localStats.isFile()) {
|
|
704
|
+
packagedSource = await this.resourcePackager.prepareLocalUploadSource(skillPath);
|
|
705
|
+
if (packagedSource.kind !== "upload") {
|
|
686
706
|
throw new Error(`Path is not a file or directory: ${skillPath}`);
|
|
687
707
|
}
|
|
688
|
-
body.temp_file_id = await this.uploadTempFile(uploadPath,
|
|
708
|
+
body.temp_file_id = await this.uploadTempFile(packagedSource.uploadPath, actorPeerId);
|
|
689
709
|
} else {
|
|
690
710
|
body.data = input.data;
|
|
691
711
|
}
|
|
692
712
|
return this.request<AddSkillResult>(
|
|
693
713
|
"/api/v1/skills",
|
|
694
714
|
{ method: "POST", body: JSON.stringify(body) },
|
|
695
|
-
agentId,
|
|
696
715
|
requestTimeoutMs,
|
|
716
|
+
actorPeerId,
|
|
697
717
|
);
|
|
698
718
|
} finally {
|
|
699
|
-
await
|
|
719
|
+
await this.resourcePackager.cleanup(packagedSource);
|
|
700
720
|
}
|
|
701
721
|
}
|
|
702
722
|
|
|
@@ -729,7 +749,7 @@ export class OpenVikingClient {
|
|
|
729
749
|
abstract?: string;
|
|
730
750
|
context_type?: "memory" | "resource" | "skill";
|
|
731
751
|
}>,
|
|
732
|
-
|
|
752
|
+
actorPeerId?: string,
|
|
733
753
|
createdAt?: string,
|
|
734
754
|
roleId?: string,
|
|
735
755
|
): Promise<void> {
|
|
@@ -755,7 +775,7 @@ export class OpenVikingClient {
|
|
|
755
775
|
partCount: parts.length,
|
|
756
776
|
created_at: createdAt ?? null,
|
|
757
777
|
},
|
|
758
|
-
|
|
778
|
+
actorPeerId,
|
|
759
779
|
);
|
|
760
780
|
await this.request<{ session_id: string }>(
|
|
761
781
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}/messages`,
|
|
@@ -763,12 +783,13 @@ export class OpenVikingClient {
|
|
|
763
783
|
method: "POST",
|
|
764
784
|
body: JSON.stringify(body),
|
|
765
785
|
},
|
|
766
|
-
|
|
786
|
+
undefined,
|
|
787
|
+
actorPeerId,
|
|
767
788
|
);
|
|
768
789
|
}
|
|
769
790
|
|
|
770
791
|
/** GET session — server auto-creates if absent; returns session meta including message stats and token usage. */
|
|
771
|
-
async getSession(sessionId: string,
|
|
792
|
+
async getSession(sessionId: string, actorPeerId?: string): Promise<{
|
|
772
793
|
message_count?: number;
|
|
773
794
|
commit_count?: number;
|
|
774
795
|
last_commit_at?: string;
|
|
@@ -784,7 +805,8 @@ export class OpenVikingClient {
|
|
|
784
805
|
}>(
|
|
785
806
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}`,
|
|
786
807
|
{ method: "GET" },
|
|
787
|
-
|
|
808
|
+
undefined,
|
|
809
|
+
actorPeerId,
|
|
788
810
|
);
|
|
789
811
|
}
|
|
790
812
|
|
|
@@ -800,13 +822,13 @@ export class OpenVikingClient {
|
|
|
800
822
|
options?: {
|
|
801
823
|
wait?: boolean;
|
|
802
824
|
timeoutMs?: number;
|
|
803
|
-
agentId?: string;
|
|
804
825
|
/**
|
|
805
826
|
* WM v2: number of most-recent messages to keep live after commit.
|
|
806
827
|
* Forwarded as `keep_recent_count` in the POST body. 0 (default)
|
|
807
828
|
* preserves the pre-v2 "archive everything" behavior.
|
|
808
|
-
|
|
829
|
+
*/
|
|
809
830
|
keepRecentCount?: number;
|
|
831
|
+
agentId?: string;
|
|
810
832
|
},
|
|
811
833
|
): Promise<CommitSessionResult> {
|
|
812
834
|
const keepRecentCount =
|
|
@@ -830,6 +852,7 @@ export class OpenVikingClient {
|
|
|
830
852
|
const result = await this.request<CommitSessionResult>(
|
|
831
853
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}/commit`,
|
|
832
854
|
{ method: "POST", body: JSON.stringify(body) },
|
|
855
|
+
undefined,
|
|
833
856
|
options?.agentId,
|
|
834
857
|
);
|
|
835
858
|
|
|
@@ -838,10 +861,10 @@ export class OpenVikingClient {
|
|
|
838
861
|
}
|
|
839
862
|
|
|
840
863
|
// Client-side poll until Phase 2 finishes
|
|
841
|
-
const deadline =
|
|
864
|
+
const deadline = this.now() + (options.timeoutMs ?? DEFAULT_PHASE2_POLL_TIMEOUT_MS);
|
|
842
865
|
const pollInterval = 500;
|
|
843
|
-
while (
|
|
844
|
-
await sleep(pollInterval);
|
|
866
|
+
while (this.now() < deadline) {
|
|
867
|
+
await this.sleep(pollInterval);
|
|
845
868
|
const task = await this.getTask(result.task_id, options.agentId).catch(() => null);
|
|
846
869
|
if (!task) break;
|
|
847
870
|
if (task.status === "completed") {
|
|
@@ -862,35 +885,38 @@ export class OpenVikingClient {
|
|
|
862
885
|
}
|
|
863
886
|
|
|
864
887
|
/** Poll a background task by ID. */
|
|
865
|
-
async getTask(taskId: string,
|
|
888
|
+
async getTask(taskId: string, actorPeerId?: string): Promise<TaskResult> {
|
|
866
889
|
return this.request<TaskResult>(
|
|
867
890
|
`/api/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
868
891
|
{ method: "GET" },
|
|
869
|
-
|
|
892
|
+
undefined,
|
|
893
|
+
actorPeerId,
|
|
870
894
|
);
|
|
871
895
|
}
|
|
872
896
|
|
|
873
897
|
async getSessionContext(
|
|
874
898
|
sessionId: string,
|
|
875
899
|
tokenBudget: number = 128_000,
|
|
876
|
-
|
|
900
|
+
actorPeerId?: string,
|
|
877
901
|
): Promise<SessionContextResult> {
|
|
878
902
|
return this.request(
|
|
879
903
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}/context?token_budget=${tokenBudget}`,
|
|
880
904
|
{ method: "GET" },
|
|
881
|
-
|
|
905
|
+
undefined,
|
|
906
|
+
actorPeerId,
|
|
882
907
|
);
|
|
883
908
|
}
|
|
884
909
|
|
|
885
910
|
async getSessionArchive(
|
|
886
911
|
sessionId: string,
|
|
887
912
|
archiveId: string,
|
|
888
|
-
|
|
913
|
+
actorPeerId?: string,
|
|
889
914
|
): Promise<SessionArchiveResult> {
|
|
890
915
|
return this.request(
|
|
891
916
|
`/api/v1/sessions/${encodeURIComponent(sessionId)}/archives/${encodeURIComponent(archiveId)}`,
|
|
892
917
|
{ method: "GET" },
|
|
893
|
-
|
|
918
|
+
undefined,
|
|
919
|
+
actorPeerId,
|
|
894
920
|
);
|
|
895
921
|
}
|
|
896
922
|
|
|
@@ -902,7 +928,6 @@ export class OpenVikingClient {
|
|
|
902
928
|
caseInsensitive?: boolean;
|
|
903
929
|
nodeLimit?: number;
|
|
904
930
|
levelLimit?: number;
|
|
905
|
-
agentId?: string;
|
|
906
931
|
} = {},
|
|
907
932
|
): Promise<{
|
|
908
933
|
matches: Array<{ line: number; uri: string; content: string }>;
|
|
@@ -910,7 +935,7 @@ export class OpenVikingClient {
|
|
|
910
935
|
match_count?: number;
|
|
911
936
|
files_scanned?: number;
|
|
912
937
|
}> {
|
|
913
|
-
const baseUri =
|
|
938
|
+
const baseUri = `${userSessionUri(sessionId)}/history`;
|
|
914
939
|
const uri = options.archiveId ? `${baseUri}/${options.archiveId}` : baseUri;
|
|
915
940
|
return this.request(
|
|
916
941
|
"/api/v1/search/grep",
|
|
@@ -924,16 +949,15 @@ export class OpenVikingClient {
|
|
|
924
949
|
...(options.levelLimit !== undefined ? { level_limit: options.levelLimit } : {}),
|
|
925
950
|
}),
|
|
926
951
|
},
|
|
927
|
-
options.agentId,
|
|
928
952
|
);
|
|
929
953
|
}
|
|
930
954
|
|
|
931
|
-
async deleteSession(sessionId: string
|
|
932
|
-
await this.request(`/api/v1/sessions/${encodeURIComponent(sessionId)}`, { method: "DELETE" }
|
|
955
|
+
async deleteSession(sessionId: string): Promise<void> {
|
|
956
|
+
await this.request(`/api/v1/sessions/${encodeURIComponent(sessionId)}`, { method: "DELETE" });
|
|
933
957
|
}
|
|
934
|
-
async deleteUri(uri: string,
|
|
958
|
+
async deleteUri(uri: string, actorPeerId?: string): Promise<void> {
|
|
935
959
|
await this.request(`/api/v1/fs?uri=${encodeURIComponent(uri)}&recursive=false`, {
|
|
936
960
|
method: "DELETE",
|
|
937
|
-
},
|
|
961
|
+
}, undefined, actorPeerId);
|
|
938
962
|
}
|
|
939
963
|
}
|