@openviking/openclaw-plugin 2026.5.8 → 2026.5.21
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 +10 -10
- package/INSTALL-ZH.md +8 -8
- package/INSTALL.md +8 -8
- package/README.md +60 -37
- package/auto-recall.ts +257 -257
- package/client.ts +939 -828
- package/commands/setup.ts +1002 -1002
- package/config.ts +476 -476
- package/context-engine.ts +1737 -1700
- package/dist/client.js +30 -0
- package/dist/context-engine.js +40 -8
- package/dist/index.js +389 -69
- package/dist/process-manager.js +0 -87
- package/dist/runtime-utils.js +0 -3
- package/dist/text-utils.js +31 -51
- package/images/openclaw-plugin-engine-overview.png +0 -0
- package/images/openclaw-plugin-recall-flow.png +0 -0
- package/images/openclaw-plugin-runtime-routing.png +0 -0
- package/images/openclaw-plugin-session-lifecycle.png +0 -0
- package/index.ts +1985 -1597
- package/install-manifest.json +47 -47
- package/memory-ranking.ts +267 -267
- package/openclaw.plugin.json +335 -331
- package/package.json +2 -1
- package/process-manager.ts +45 -169
- package/runtime-utils.ts +5 -8
- package/session-transcript-repair.ts +530 -530
- package/skills/install-openviking-memory/SKILL.md +665 -665
- package/text-utils.ts +507 -524
- package/tool-call-id.ts +331 -331
package/dist/client.js
CHANGED
|
@@ -245,6 +245,36 @@ export class OpenVikingClient {
|
|
|
245
245
|
async read(uri, agentId) {
|
|
246
246
|
return this.request(`/api/v1/content/read?uri=${encodeURIComponent(uri)}`, {}, agentId);
|
|
247
247
|
}
|
|
248
|
+
async readToolResult(sessionId, toolResultId, options, agentId) {
|
|
249
|
+
const params = new URLSearchParams();
|
|
250
|
+
if (options?.offset !== undefined)
|
|
251
|
+
params.set("offset", String(options.offset));
|
|
252
|
+
if (options?.limit !== undefined)
|
|
253
|
+
params.set("limit", String(options.limit));
|
|
254
|
+
if (options?.includeMetadata !== undefined) {
|
|
255
|
+
params.set("include_metadata", String(options.includeMetadata));
|
|
256
|
+
}
|
|
257
|
+
const query = params.toString();
|
|
258
|
+
return this.request(`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results/${encodeURIComponent(toolResultId)}${query ? `?${query}` : ""}`, {}, agentId);
|
|
259
|
+
}
|
|
260
|
+
async searchToolResult(sessionId, toolResultId, queryText, options, agentId) {
|
|
261
|
+
const params = new URLSearchParams({ q: queryText });
|
|
262
|
+
if (options?.limit !== undefined)
|
|
263
|
+
params.set("limit", String(options.limit));
|
|
264
|
+
if (options?.contextChars !== undefined) {
|
|
265
|
+
params.set("context_chars", String(options.contextChars));
|
|
266
|
+
}
|
|
267
|
+
return this.request(`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results/${encodeURIComponent(toolResultId)}/search?${params.toString()}`, {}, agentId);
|
|
268
|
+
}
|
|
269
|
+
async listToolResults(sessionId, options, agentId) {
|
|
270
|
+
const params = new URLSearchParams();
|
|
271
|
+
if (options?.toolName)
|
|
272
|
+
params.set("tool_name", options.toolName);
|
|
273
|
+
if (options?.limit !== undefined)
|
|
274
|
+
params.set("limit", String(options.limit));
|
|
275
|
+
const query = params.toString();
|
|
276
|
+
return this.request(`/api/v1/sessions/${encodeURIComponent(sessionId)}/tool-results${query ? `?${query}` : ""}`, {}, agentId);
|
|
277
|
+
}
|
|
248
278
|
async uploadTempFile(filePath, agentId) {
|
|
249
279
|
const fileBytes = await readFile(filePath);
|
|
250
280
|
const form = new FormData();
|
package/dist/context-engine.js
CHANGED
|
@@ -29,9 +29,6 @@ function allocateContextBudget(totalBudget, instructionTokens = 0) {
|
|
|
29
29
|
const sessionContext = Math.max(usableBudget - archiveMemory, 0);
|
|
30
30
|
return { archiveMemory, sessionContext, reserved };
|
|
31
31
|
}
|
|
32
|
-
function estimateTokens(messages) {
|
|
33
|
-
return Math.max(1, messages.length * 80);
|
|
34
|
-
}
|
|
35
32
|
function roughEstimate(messages) {
|
|
36
33
|
return Math.ceil(JSON.stringify(messages).length / 4);
|
|
37
34
|
}
|
|
@@ -265,6 +262,10 @@ export function convertToAgentMessages(msg) {
|
|
|
265
262
|
const toolName = typeof p.tool_name === "string" ? p.tool_name : undefined;
|
|
266
263
|
const status = typeof p.tool_status === "string" ? p.tool_status : "unknown";
|
|
267
264
|
const output = typeof p.tool_output === "string" ? p.tool_output : "";
|
|
265
|
+
const ref = typeof p.tool_output_ref === "string" ? p.tool_output_ref : "";
|
|
266
|
+
const originalChars = typeof p.tool_output_original_chars === "number"
|
|
267
|
+
? p.tool_output_original_chars
|
|
268
|
+
: undefined;
|
|
268
269
|
if (toolId) {
|
|
269
270
|
// Structured path: emit canonical toolCall + toolResult pair (works for any role)
|
|
270
271
|
toolCallBlocks.push({
|
|
@@ -273,9 +274,15 @@ export function convertToAgentMessages(msg) {
|
|
|
273
274
|
name: toolName ?? "unknown",
|
|
274
275
|
arguments: p.tool_input ?? {},
|
|
275
276
|
});
|
|
276
|
-
|
|
277
|
+
let resultText = (status === "completed" || status === "error")
|
|
277
278
|
? (output || "(no output)")
|
|
278
279
|
: "(interrupted — tool did not complete)";
|
|
280
|
+
if (ref && !resultText.includes(ref)) {
|
|
281
|
+
const suffix = originalChars !== undefined
|
|
282
|
+
? `\n[tool-result-ref] ${ref} original_chars=${originalChars}`
|
|
283
|
+
: `\n[tool-result-ref] ${ref}`;
|
|
284
|
+
resultText += suffix;
|
|
285
|
+
}
|
|
279
286
|
const resultPayload = {
|
|
280
287
|
role: "toolResult",
|
|
281
288
|
toolCallId: toolId,
|
|
@@ -330,6 +337,32 @@ export function convertToAgentMessages(msg) {
|
|
|
330
337
|
}
|
|
331
338
|
return result;
|
|
332
339
|
}
|
|
340
|
+
function isToolOnlyMessage(msg) {
|
|
341
|
+
return msg.role === "user" && msg.parts.length > 0 && msg.parts.every((part) => part.type === "tool");
|
|
342
|
+
}
|
|
343
|
+
function coalesceConsecutiveToolMessages(messages) {
|
|
344
|
+
const result = [];
|
|
345
|
+
let pendingTools;
|
|
346
|
+
const flush = () => {
|
|
347
|
+
if (pendingTools) {
|
|
348
|
+
result.push(pendingTools);
|
|
349
|
+
pendingTools = undefined;
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
for (const msg of messages) {
|
|
353
|
+
if (isToolOnlyMessage(msg)) {
|
|
354
|
+
if (!pendingTools) {
|
|
355
|
+
pendingTools = { role: "user", parts: [] };
|
|
356
|
+
}
|
|
357
|
+
pendingTools.parts.push(...msg.parts);
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
flush();
|
|
361
|
+
result.push(msg);
|
|
362
|
+
}
|
|
363
|
+
flush();
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
333
366
|
function normalizeAssistantContent(messages) {
|
|
334
367
|
for (let i = 0; i < messages.length; i++) {
|
|
335
368
|
const msg = messages[i];
|
|
@@ -965,7 +998,8 @@ export function createMemoryOpenVikingContextEngine(params) {
|
|
|
965
998
|
afterTurnParams.prePromptMessageCount >= 0
|
|
966
999
|
? afterTurnParams.prePromptMessageCount
|
|
967
1000
|
: 0;
|
|
968
|
-
const { messages:
|
|
1001
|
+
const { messages: extractedMessagesRaw, newCount } = extractNewTurnMessages(messages, start);
|
|
1002
|
+
const extractedMessages = coalesceConsecutiveToolMessages(extractedMessagesRaw);
|
|
969
1003
|
if (extractedMessages.length === 0) {
|
|
970
1004
|
diag("afterTurn_skip", OVSessionId, {
|
|
971
1005
|
reason: "no_new_turn_messages",
|
|
@@ -1055,9 +1089,7 @@ export function createMemoryOpenVikingContextEngine(params) {
|
|
|
1055
1089
|
if (commitResult.task_id && cfg.logFindRequests) {
|
|
1056
1090
|
logger.info(`openviking: Phase2 memory extraction runs asynchronously on the server (task_id=${commitResult.task_id}). ` +
|
|
1057
1091
|
"memories_extracted appears only after that task completes — not in this immediate response.");
|
|
1058
|
-
|
|
1059
|
-
void pollPhase2ExtractionOutcome(getClient, commitResult.task_id, agentId, logger, OVSessionId);
|
|
1060
|
-
}
|
|
1092
|
+
void pollPhase2ExtractionOutcome(getClient, commitResult.task_id, agentId, logger, OVSessionId);
|
|
1061
1093
|
}
|
|
1062
1094
|
}
|
|
1063
1095
|
catch (err) {
|