@remnic/plugin-openclaw 9.69.40 → 9.69.42
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/dist/index.js +751 -801
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -13,83 +13,27 @@ import {
|
|
|
13
13
|
__reExport
|
|
14
14
|
} from "./chunk-I2KLQ2HA.js";
|
|
15
15
|
|
|
16
|
-
// ../../src/day-summary.ts
|
|
17
|
-
var day_summary_exports = {};
|
|
18
|
-
__reExport(day_summary_exports, day_summary_star);
|
|
19
|
-
import * as day_summary_star from "@remnic/core/day-summary";
|
|
20
|
-
|
|
21
16
|
// ../../src/index.ts
|
|
17
|
+
import { loadDaySummaryPrompt } from "@remnic/core/day-summary";
|
|
22
18
|
import OpenAI from "openai";
|
|
23
19
|
import { createRequire } from "module";
|
|
24
20
|
import { createHash as createHash4 } from "crypto";
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// ../../src/logger.ts
|
|
32
|
-
var logger_exports = {};
|
|
33
|
-
__reExport(logger_exports, logger_star);
|
|
34
|
-
import * as logger_star from "@remnic/core/logger";
|
|
35
|
-
|
|
36
|
-
// ../../src/sdk-compat.ts
|
|
37
|
-
import { detectSdkCapabilities } from "@remnic/core/sdk-compat";
|
|
38
|
-
|
|
39
|
-
// ../../src/index.ts
|
|
21
|
+
import { parseConfig } from "@remnic/core/config";
|
|
22
|
+
import { initLogger, log as log8 } from "@remnic/core/logger";
|
|
23
|
+
import {
|
|
24
|
+
detectSdkCapabilities
|
|
25
|
+
} from "@remnic/core/sdk-compat";
|
|
40
26
|
import {
|
|
41
27
|
Orchestrator,
|
|
42
28
|
sanitizeSessionKeyForFilename,
|
|
43
29
|
defaultWorkspaceDir
|
|
44
30
|
} from "@remnic/core/orchestrator";
|
|
45
|
-
import { beginCodexSubscriptionShutdown, getCodexSubscriptionRunnerForOwner } from "@remnic/core";
|
|
31
|
+
import { beginCodexSubscriptionShutdown, getCodexSubscriptionRunnerForOwner, terminateActiveCodexSubscriptionChildren } from "@remnic/core";
|
|
46
32
|
|
|
47
33
|
// ../../src/tools.ts
|
|
48
34
|
import { createHash as createHash2 } from "crypto";
|
|
49
|
-
import { Type } from "@sinclair/typebox";
|
|
50
|
-
|
|
51
|
-
// ../../src/temporal-index.ts
|
|
52
|
-
var temporal_index_exports = {};
|
|
53
|
-
__export(temporal_index_exports, {
|
|
54
|
-
clearIndexes: () => clearIndexes,
|
|
55
|
-
clearIndexesAsync: () => clearIndexesAsync,
|
|
56
|
-
deindexMemory: () => deindexMemory,
|
|
57
|
-
deindexMemoryAsync: () => deindexMemoryAsync,
|
|
58
|
-
extractTagsFromPrompt: () => extractTagsFromPrompt,
|
|
59
|
-
indexMemoriesBatch: () => indexMemoriesBatch,
|
|
60
|
-
indexMemoriesBatchAsync: () => indexMemoriesBatchAsync,
|
|
61
|
-
indexMemory: () => indexMemory,
|
|
62
|
-
indexMemoryAsync: () => indexMemoryAsync,
|
|
63
|
-
indexesExist: () => indexesExist,
|
|
64
|
-
indexesExistAsync: () => indexesExistAsync,
|
|
65
|
-
isTemporalQuery: () => isTemporalQuery,
|
|
66
|
-
queryByDateRangeAsync: () => queryByDateRangeAsync,
|
|
67
|
-
queryByTagsAsync: () => queryByTagsAsync,
|
|
68
|
-
recencyWindowBoundsFromPrompt: () => recencyWindowBoundsFromPrompt,
|
|
69
|
-
recencyWindowFromPrompt: () => recencyWindowFromPrompt,
|
|
70
|
-
resolvePromptTagPrefilterAsync: () => resolvePromptTagPrefilterAsync
|
|
71
|
-
});
|
|
72
|
-
__reExport(temporal_index_exports, temporal_index_star);
|
|
73
|
-
import {
|
|
74
|
-
clearIndexes,
|
|
75
|
-
clearIndexesAsync,
|
|
76
|
-
deindexMemory,
|
|
77
|
-
deindexMemoryAsync,
|
|
78
|
-
extractTagsFromPrompt,
|
|
79
|
-
indexMemoriesBatch,
|
|
80
|
-
indexMemoriesBatchAsync,
|
|
81
|
-
indexMemory,
|
|
82
|
-
indexMemoryAsync,
|
|
83
|
-
indexesExist,
|
|
84
|
-
indexesExistAsync,
|
|
85
|
-
isTemporalQuery,
|
|
86
|
-
queryByDateRangeAsync,
|
|
87
|
-
queryByTagsAsync,
|
|
88
|
-
recencyWindowBoundsFromPrompt,
|
|
89
|
-
recencyWindowFromPrompt,
|
|
90
|
-
resolvePromptTagPrefilterAsync
|
|
91
|
-
} from "@remnic/core/temporal-index";
|
|
92
|
-
import * as temporal_index_star from "@remnic/core/temporal-index";
|
|
35
|
+
import { Type as Type2 } from "@sinclair/typebox";
|
|
36
|
+
import { indexMemoryAsync as indexMemoryAsync2, indexesExistAsync as indexesExistAsync2 } from "@remnic/core/temporal-index";
|
|
93
37
|
|
|
94
38
|
// ../../src/explicit-capture.ts
|
|
95
39
|
import {
|
|
@@ -114,6 +58,7 @@ function mergeInlineCaptureDedupeKeys(messageKeys, fallbackDedupeKeys = []) {
|
|
|
114
58
|
}
|
|
115
59
|
|
|
116
60
|
// ../../src/tools.ts
|
|
61
|
+
import { log } from "@remnic/core/logger";
|
|
117
62
|
import { composeSalvagedEnvelope as composeSalvagedEnvelope2 } from "@remnic/core/salvage-envelope";
|
|
118
63
|
|
|
119
64
|
// ../../src/memory-promote.ts
|
|
@@ -127,6 +72,7 @@ import { stripAttributesSuffix } from "@remnic/core/storage";
|
|
|
127
72
|
import { isSupportPassportPrivateMemory } from "@remnic/core/support-passport";
|
|
128
73
|
import { displayErrorDetail } from "@remnic/core/runtime/better-sqlite";
|
|
129
74
|
import { isSafeRouteNamespace } from "@remnic/core/routing/engine";
|
|
75
|
+
import { indexMemoryAsync, indexesExistAsync } from "@remnic/core/temporal-index";
|
|
130
76
|
function buildPromotionOrigin(srcNamespace, memoryId) {
|
|
131
77
|
const memoryIdHash = createHash("sha256").update(memoryId).digest("hex");
|
|
132
78
|
const fullTag = `promotedFrom:${srcNamespace}:${memoryId}`;
|
|
@@ -213,6 +159,10 @@ async function executeMemoryPromote(orchestrator, params) {
|
|
|
213
159
|
return `Promoted ${srcNs}:${memoryId} \u2192 ${dstNs}:${newId}`;
|
|
214
160
|
}
|
|
215
161
|
|
|
162
|
+
// ../../src/shared-context-tools.ts
|
|
163
|
+
import { Type } from "@sinclair/typebox";
|
|
164
|
+
import { parseSharedWriteOutputControls } from "@remnic/core/shared-context/write-output-controls";
|
|
165
|
+
|
|
216
166
|
// ../../src/tool-write-origin.ts
|
|
217
167
|
var UNATTRIBUTED_TOOL_WRITE_ORIGIN = "unattributed:openclaw-host";
|
|
218
168
|
function openClawToolWriteOrigin(runtimeAgentId, requestedAgentId) {
|
|
@@ -223,18 +173,204 @@ function openClawToolWriteOrigin(runtimeAgentId, requestedAgentId) {
|
|
|
223
173
|
return { agentId: requestedAgentId, unattributedOrigin: UNATTRIBUTED_TOOL_WRITE_ORIGIN };
|
|
224
174
|
}
|
|
225
175
|
|
|
176
|
+
// ../../src/shared-context-tools.ts
|
|
177
|
+
function toolResult(text) {
|
|
178
|
+
return { content: [{ type: "text", text }], details: void 0 };
|
|
179
|
+
}
|
|
180
|
+
function registerSharedContextTools(api, orchestrator, hostRuntimeAgentId) {
|
|
181
|
+
api.registerTool(
|
|
182
|
+
{
|
|
183
|
+
name: "shared_context_write_output",
|
|
184
|
+
label: "Write Shared Agent Output",
|
|
185
|
+
description: "Write an agent work product into the shared-context directory (v4.0). Other agents can read these files to coordinate without explicit message passing.",
|
|
186
|
+
parameters: Type.Object({
|
|
187
|
+
// Provenance is server-derived from the host runtime agent; a
|
|
188
|
+
// mismatching value here is rejected, never used as the origin.
|
|
189
|
+
agentId: Type.String({ description: "Agent ID producing this output; must match this host's runtime agent id when the host exposes one." }),
|
|
190
|
+
title: Type.String({ description: "Short title for the output." }),
|
|
191
|
+
content: Type.String({ description: "Markdown content to write." }),
|
|
192
|
+
authority: Type.Optional(Type.String({
|
|
193
|
+
enum: ["informational", "advisory", "binding"],
|
|
194
|
+
description: "Envelope authority class. `binding` additionally requires the operator config `sharedContextAllowBindingAuthority: true`."
|
|
195
|
+
})),
|
|
196
|
+
expiresAt: Type.Optional(Type.String({
|
|
197
|
+
description: "ISO-8601 instant strictly after the write time and at most 10 years out. Past, invalid, or over-bound values are rejected."
|
|
198
|
+
})),
|
|
199
|
+
supersedes: Type.Optional(Type.String({
|
|
200
|
+
description: "Id of the shared item this output supersedes (non-empty, single line)."
|
|
201
|
+
}))
|
|
202
|
+
}),
|
|
203
|
+
async execute(_toolCallId, params) {
|
|
204
|
+
const { agentId, title, content } = params;
|
|
205
|
+
if (!orchestrator.sharedContext) {
|
|
206
|
+
return toolResult(
|
|
207
|
+
"Shared context is disabled. Enable `sharedContextEnabled: true` to use shared-context tools."
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
const controls = parseSharedWriteOutputControls(params);
|
|
212
|
+
const fp = await orchestrator.sharedContext.writeAgentOutput({
|
|
213
|
+
title,
|
|
214
|
+
content,
|
|
215
|
+
...openClawToolWriteOrigin(hostRuntimeAgentId, agentId),
|
|
216
|
+
...controls
|
|
217
|
+
});
|
|
218
|
+
return toolResult(`Wrote shared agent output: ${fp}`);
|
|
219
|
+
} catch (err) {
|
|
220
|
+
return toolResult(`shared_context_write_output error: ${err instanceof Error ? err.message : String(err)}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
{ name: "shared_context_write_output" }
|
|
225
|
+
);
|
|
226
|
+
api.registerTool(
|
|
227
|
+
{
|
|
228
|
+
name: "shared_feedback_record",
|
|
229
|
+
label: "Record Shared Feedback",
|
|
230
|
+
description: "Append an approval/rejection decision into shared-context feedback inbox (v4.0/v5.0). Intended to power compounding learning.",
|
|
231
|
+
parameters: Type.Object({
|
|
232
|
+
agent: Type.String({ description: "Agent name that produced the recommendation/output." }),
|
|
233
|
+
decision: Type.String({
|
|
234
|
+
enum: ["approved", "approved_with_feedback", "rejected"],
|
|
235
|
+
description: "Decision outcome."
|
|
236
|
+
}),
|
|
237
|
+
reason: Type.String({ description: "Why the decision was made (short but specific)." }),
|
|
238
|
+
date: Type.Optional(Type.String({ description: "ISO timestamp. Defaults to now." })),
|
|
239
|
+
learning: Type.Optional(Type.String({ description: "Optional distilled learning/pattern." })),
|
|
240
|
+
outcome: Type.Optional(Type.String({ description: "Optional downstream outcome (day-one supported; may be empty initially)." })),
|
|
241
|
+
severity: Type.Optional(Type.String({
|
|
242
|
+
enum: ["low", "medium", "high"],
|
|
243
|
+
description: "Optional severity rating for the mistake/outcome."
|
|
244
|
+
})),
|
|
245
|
+
confidence: Type.Optional(Type.Number({ description: "Optional confidence score from 0 to 1." })),
|
|
246
|
+
workflow: Type.Optional(Type.String({ description: "Optional workflow or playbook name associated with the feedback." })),
|
|
247
|
+
tags: Type.Optional(Type.Array(Type.String(), { description: "Optional tags for rubric grouping and recall matching." })),
|
|
248
|
+
evidenceWindowStart: Type.Optional(Type.String({ description: "Optional start timestamp for the evidence window." })),
|
|
249
|
+
evidenceWindowEnd: Type.Optional(Type.String({ description: "Optional end timestamp for the evidence window." })),
|
|
250
|
+
refs: Type.Optional(Type.Array(Type.String(), { description: "Optional references (URLs, IDs, filenames)." }))
|
|
251
|
+
}),
|
|
252
|
+
async execute(_toolCallId, params) {
|
|
253
|
+
if (!orchestrator.sharedContext) {
|
|
254
|
+
return toolResult(
|
|
255
|
+
"Shared context is disabled. Enable `sharedContextEnabled: true` to record shared feedback."
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
const p = params;
|
|
259
|
+
const isDecision = (v) => v === "approved" || v === "approved_with_feedback" || v === "rejected";
|
|
260
|
+
if (!isDecision(p.decision)) {
|
|
261
|
+
return toolResult(
|
|
262
|
+
"shared_feedback_record error: decision must be one of approved, approved_with_feedback, rejected"
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
const isSeverity = (v) => v === "low" || v === "medium" || v === "high";
|
|
266
|
+
const entry = {
|
|
267
|
+
agent: typeof p.agent === "string" ? p.agent : "",
|
|
268
|
+
decision: p.decision,
|
|
269
|
+
reason: typeof p.reason === "string" ? p.reason : "",
|
|
270
|
+
date: typeof p.date === "string" && p.date.length > 0 ? p.date : (/* @__PURE__ */ new Date()).toISOString(),
|
|
271
|
+
learning: typeof p.learning === "string" ? p.learning : void 0,
|
|
272
|
+
outcome: typeof p.outcome === "string" ? p.outcome : void 0,
|
|
273
|
+
severity: isSeverity(p.severity) ? p.severity : void 0,
|
|
274
|
+
confidence: typeof p.confidence === "number" && Number.isFinite(p.confidence) ? p.confidence : void 0,
|
|
275
|
+
workflow: typeof p.workflow === "string" ? p.workflow : void 0,
|
|
276
|
+
tags: Array.isArray(p.tags) ? p.tags.map(String) : void 0,
|
|
277
|
+
evidenceWindowStart: typeof p.evidenceWindowStart === "string" ? p.evidenceWindowStart : void 0,
|
|
278
|
+
evidenceWindowEnd: typeof p.evidenceWindowEnd === "string" ? p.evidenceWindowEnd : void 0,
|
|
279
|
+
refs: Array.isArray(p.refs) ? p.refs.map(String) : void 0
|
|
280
|
+
};
|
|
281
|
+
await orchestrator.sharedContext.appendFeedback(entry);
|
|
282
|
+
return toolResult("OK");
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
{ name: "shared_feedback_record" }
|
|
286
|
+
);
|
|
287
|
+
api.registerTool(
|
|
288
|
+
{
|
|
289
|
+
name: "shared_priorities_append",
|
|
290
|
+
label: "Append Priorities Inbox",
|
|
291
|
+
description: "Append text into shared-context priorities inbox. A curator run should merge this into priorities.md.",
|
|
292
|
+
parameters: Type.Object({
|
|
293
|
+
agentId: Type.String({ description: "Agent ID appending priorities." }),
|
|
294
|
+
text: Type.String({ description: "Priority notes to append (markdown)." })
|
|
295
|
+
}),
|
|
296
|
+
async execute(_toolCallId, params) {
|
|
297
|
+
if (!orchestrator.sharedContext) {
|
|
298
|
+
return toolResult(
|
|
299
|
+
"Shared context is disabled. Enable `sharedContextEnabled: true` to write priorities inbox."
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
const { agentId, text } = params;
|
|
303
|
+
await orchestrator.sharedContext.appendPrioritiesInbox({ agentId, text });
|
|
304
|
+
return toolResult("OK");
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
{ name: "shared_priorities_append" }
|
|
308
|
+
);
|
|
309
|
+
api.registerTool(
|
|
310
|
+
{
|
|
311
|
+
name: "shared_context_cross_signals_run",
|
|
312
|
+
label: "Run Cross-Signal Synthesis",
|
|
313
|
+
description: "Generate today's shared-context cross-signal markdown + JSON artifacts on demand, without requiring a full roundtable curation pass.",
|
|
314
|
+
parameters: Type.Object({
|
|
315
|
+
date: Type.Optional(Type.String({ description: "YYYY-MM-DD. Defaults to today." }))
|
|
316
|
+
}),
|
|
317
|
+
async execute(_toolCallId, params) {
|
|
318
|
+
if (!orchestrator.sharedContext) {
|
|
319
|
+
return toolResult(
|
|
320
|
+
"Shared context is disabled. Enable `sharedContextEnabled: true` to synthesize cross-signals."
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
const { date } = params;
|
|
324
|
+
const result = await orchestrator.sharedContext.synthesizeCrossSignals({ date });
|
|
325
|
+
return toolResult(
|
|
326
|
+
[
|
|
327
|
+
`Cross-signals markdown: ${result.crossSignalsMarkdownPath}`,
|
|
328
|
+
`Cross-signals JSON: ${result.crossSignalsPath}`,
|
|
329
|
+
`Source outputs analyzed: ${result.report.sourceCount}`,
|
|
330
|
+
`Feedback entries analyzed: ${result.report.feedbackCount}`,
|
|
331
|
+
`Overlap count: ${result.overlapCount}`
|
|
332
|
+
].join("\n")
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
{ name: "shared_context_cross_signals_run" }
|
|
337
|
+
);
|
|
338
|
+
api.registerTool(
|
|
339
|
+
{
|
|
340
|
+
name: "shared_context_curate_daily",
|
|
341
|
+
label: "Curate Daily Roundtable",
|
|
342
|
+
description: "Curator tool: generate today's roundtable summary in shared-context/roundtable (deterministic baseline).",
|
|
343
|
+
parameters: Type.Object({
|
|
344
|
+
date: Type.Optional(Type.String({ description: "YYYY-MM-DD. Defaults to today." }))
|
|
345
|
+
}),
|
|
346
|
+
async execute(_toolCallId, params) {
|
|
347
|
+
if (!orchestrator.sharedContext) {
|
|
348
|
+
return toolResult(
|
|
349
|
+
"Shared context is disabled. Enable `sharedContextEnabled: true` to curate roundtables."
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
const { date } = params;
|
|
353
|
+
const result = await orchestrator.sharedContext.curateDaily({ date });
|
|
354
|
+
return toolResult(
|
|
355
|
+
[
|
|
356
|
+
`Roundtable: ${result.roundtablePath}`,
|
|
357
|
+
`Cross-signals markdown: ${result.crossSignalsMarkdownPath}`,
|
|
358
|
+
`Cross-signals JSON: ${result.crossSignalsPath}`,
|
|
359
|
+
`Overlap count: ${result.overlapCount}`
|
|
360
|
+
].join("\n")
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
{ name: "shared_context_curate_daily" }
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
|
|
226
368
|
// ../../src/tools.ts
|
|
227
369
|
import { WorkStorage } from "@remnic/core/work/storage";
|
|
228
370
|
import { exportWorkBoardMarkdown, exportWorkBoardSnapshot, importWorkBoardSnapshot } from "@remnic/core/work/board";
|
|
229
371
|
import { wrapWorkLayerContext } from "@remnic/core/work/boundary";
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
import {
|
|
233
|
-
formatProfileTraceAscii,
|
|
234
|
-
ProfilingCollector
|
|
235
|
-
} from "@remnic/core/profiling";
|
|
236
|
-
|
|
237
|
-
// ../../src/tools.ts
|
|
372
|
+
import { VALID_MEMORY_CATEGORIES } from "@remnic/core/config";
|
|
373
|
+
import { formatProfileTraceAscii } from "@remnic/core/profiling";
|
|
238
374
|
import { runMemoryGovernance } from "@remnic/core/maintenance/memory-governance";
|
|
239
375
|
|
|
240
376
|
// ../../src/memory-action-target.ts
|
|
@@ -279,15 +415,15 @@ function blocksSupportPassportMutation(action, memory) {
|
|
|
279
415
|
}
|
|
280
416
|
|
|
281
417
|
// ../../src/tools.ts
|
|
282
|
-
function
|
|
418
|
+
function toolResult2(text) {
|
|
283
419
|
return { content: [{ type: "text", text }], details: void 0 };
|
|
284
420
|
}
|
|
285
421
|
function toolJsonResult(value, options) {
|
|
286
422
|
const payload = JSON.stringify(value, null, 2);
|
|
287
|
-
return
|
|
423
|
+
return toolResult2(wrapWorkLayerContext(payload, { linkToMemory: options?.linkToMemory === true }));
|
|
288
424
|
}
|
|
289
425
|
function workLayerTextResult(text, options) {
|
|
290
|
-
return
|
|
426
|
+
return toolResult2(wrapWorkLayerContext(text, { linkToMemory: options?.linkToMemory === true }));
|
|
291
427
|
}
|
|
292
428
|
function asNonEmptyString(value) {
|
|
293
429
|
if (typeof value !== "string") return void 0;
|
|
@@ -468,7 +604,7 @@ function registerTools(api, orchestrator, hostRuntimeAgentId) {
|
|
|
468
604
|
function normalizeMemoryCategory(value, fallback) {
|
|
469
605
|
const normalized = asNonEmptyString(value);
|
|
470
606
|
if (!normalized) return fallback;
|
|
471
|
-
if (!
|
|
607
|
+
if (!VALID_MEMORY_CATEGORIES.has(normalized)) return void 0;
|
|
472
608
|
return normalized;
|
|
473
609
|
}
|
|
474
610
|
function isKnownMemoryActionType(value) {
|
|
@@ -512,21 +648,21 @@ function registerTools(api, orchestrator, hostRuntimeAgentId) {
|
|
|
512
648
|
const result = await persistExplicitCapture(orchestrator, candidate, source);
|
|
513
649
|
if (result.tombstoneBlocked) {
|
|
514
650
|
orchestrator.requestQmdMaintenanceForTool(maintenanceReason);
|
|
515
|
-
return
|
|
651
|
+
return toolResult2(
|
|
516
652
|
`Memory queued for review (tombstone-blocked): ${result.id}${candidate.namespace ? ` (namespace: ${candidate.namespace})` : ""} \u2014 no active copy was created.
|
|
517
653
|
|
|
518
654
|
Content: ${candidate.content}`
|
|
519
655
|
);
|
|
520
656
|
}
|
|
521
|
-
if (!result.duplicateOf && orchestrator.config.queryAwareIndexingEnabled && await
|
|
657
|
+
if (!result.duplicateOf && orchestrator.config.queryAwareIndexingEnabled && await indexesExistAsync2(orchestrator.config.memoryDir)) {
|
|
522
658
|
const storage = await orchestrator.getStorage(candidate.namespace);
|
|
523
659
|
const mem = await storage.getMemoryById(result.id).catch(() => null);
|
|
524
660
|
if (mem?.path && mem.frontmatter?.created) {
|
|
525
|
-
await
|
|
661
|
+
await indexMemoryAsync2(orchestrator.config.memoryDir, mem.path, mem.frontmatter.created, mem.frontmatter.tags ?? []);
|
|
526
662
|
}
|
|
527
663
|
}
|
|
528
664
|
orchestrator.requestQmdMaintenanceForTool(maintenanceReason);
|
|
529
|
-
return
|
|
665
|
+
return toolResult2(
|
|
530
666
|
result.duplicateOf ? `Memory already exists: ${result.duplicateOf}${candidate.namespace ? ` (namespace: ${candidate.namespace})` : ""}
|
|
531
667
|
|
|
532
668
|
Content: ${candidate.content}` : `Memory stored: ${result.id}${candidate.namespace ? ` (namespace: ${candidate.namespace})` : ""}
|
|
@@ -537,7 +673,7 @@ Content: ${candidate.content}`
|
|
|
537
673
|
try {
|
|
538
674
|
const queued = await queueExplicitCaptureForReview(orchestrator, rawInput, source, error);
|
|
539
675
|
orchestrator.requestQmdMaintenanceForTool(`${maintenanceReason}.review`);
|
|
540
|
-
return
|
|
676
|
+
return toolResult2(
|
|
541
677
|
queued.duplicateOf ? `Memory already queued for review: ${queued.duplicateOf}${namespace ? ` (namespace: ${namespace})` : ""}
|
|
542
678
|
|
|
543
679
|
Content: ${content}` : `Memory queued for review: ${queued.id}${namespace ? ` (namespace: ${namespace})` : ""}
|
|
@@ -545,8 +681,8 @@ Content: ${content}` : `Memory queued for review: ${queued.id}${namespace ? ` (n
|
|
|
545
681
|
Content: ${content}`
|
|
546
682
|
);
|
|
547
683
|
} catch (queueError) {
|
|
548
|
-
|
|
549
|
-
return
|
|
684
|
+
log.warn(`explicit tool capture rejected: ${error}; review queue fallback failed: ${queueError}`);
|
|
685
|
+
return toolResult2(`Memory capture failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
550
686
|
}
|
|
551
687
|
}
|
|
552
688
|
}
|
|
@@ -565,24 +701,24 @@ Best for:
|
|
|
565
701
|
- Finding previously learned facts about the user
|
|
566
702
|
- Checking what you know about a topic
|
|
567
703
|
- Locating past decisions or corrections`,
|
|
568
|
-
parameters:
|
|
569
|
-
query:
|
|
704
|
+
parameters: Type2.Object({
|
|
705
|
+
query: Type2.String({
|
|
570
706
|
description: "Search query \u2014 keywords, phrases, or natural language"
|
|
571
707
|
}),
|
|
572
|
-
namespace:
|
|
573
|
-
|
|
708
|
+
namespace: Type2.Optional(
|
|
709
|
+
Type2.String({
|
|
574
710
|
description: "Optional namespace filter. When set, only returns results under memoryDir/namespaces/<namespace>/ (default namespace uses legacy root)."
|
|
575
711
|
})
|
|
576
712
|
),
|
|
577
|
-
maxResults:
|
|
578
|
-
|
|
713
|
+
maxResults: Type2.Optional(
|
|
714
|
+
Type2.Number({
|
|
579
715
|
description: "Maximum results (default: 8)",
|
|
580
716
|
minimum: 1,
|
|
581
717
|
maximum: 50
|
|
582
718
|
})
|
|
583
719
|
),
|
|
584
|
-
collection:
|
|
585
|
-
|
|
720
|
+
collection: Type2.Optional(
|
|
721
|
+
Type2.String({
|
|
586
722
|
description: "QMD collection to search. Omit for memory collection, use 'global' for all collections."
|
|
587
723
|
})
|
|
588
724
|
)
|
|
@@ -625,7 +761,7 @@ Best for:
|
|
|
625
761
|
}
|
|
626
762
|
filtered = filtered.slice(0, resultLimit);
|
|
627
763
|
if (filtered.length === 0) {
|
|
628
|
-
return
|
|
764
|
+
return toolResult2(`No memories found matching: "${query}"`);
|
|
629
765
|
}
|
|
630
766
|
const formatted = filtered.map((r, i) => {
|
|
631
767
|
const snippet = r.snippet ? r.snippet.slice(0, 800) : "(no preview)";
|
|
@@ -636,7 +772,7 @@ Score: ${r.score.toFixed(3)}
|
|
|
636
772
|
${snippet}
|
|
637
773
|
\`\`\``;
|
|
638
774
|
}).join("\n\n");
|
|
639
|
-
return
|
|
775
|
+
return toolResult2(
|
|
640
776
|
`## Memory Search: "${query}"
|
|
641
777
|
|
|
642
778
|
${filtered.length} result(s)
|
|
@@ -653,32 +789,32 @@ ${formatted}`
|
|
|
653
789
|
name: "continuity_audit_generate",
|
|
654
790
|
label: "Generate Continuity Audit",
|
|
655
791
|
description: "Generate a deterministic identity continuity audit report (weekly/monthly) and persist it under identity/audits.",
|
|
656
|
-
parameters:
|
|
657
|
-
period:
|
|
658
|
-
|
|
792
|
+
parameters: Type2.Object({
|
|
793
|
+
period: Type2.Optional(
|
|
794
|
+
Type2.String({
|
|
659
795
|
enum: ["weekly", "monthly"],
|
|
660
796
|
description: "Audit period. Defaults to weekly."
|
|
661
797
|
})
|
|
662
798
|
),
|
|
663
|
-
key:
|
|
664
|
-
|
|
799
|
+
key: Type2.Optional(
|
|
800
|
+
Type2.String({
|
|
665
801
|
description: "Optional period key (weekly: YYYY-Www, monthly: YYYY-MM). Defaults to current period."
|
|
666
802
|
})
|
|
667
803
|
)
|
|
668
804
|
}),
|
|
669
805
|
async execute(_toolCallId, params) {
|
|
670
806
|
if (!orchestrator.config.identityContinuityEnabled) {
|
|
671
|
-
return
|
|
807
|
+
return toolResult2(
|
|
672
808
|
"Identity continuity is disabled. Enable `identityContinuityEnabled: true` to generate continuity audits."
|
|
673
809
|
);
|
|
674
810
|
}
|
|
675
811
|
if (!orchestrator.config.continuityAuditEnabled) {
|
|
676
|
-
return
|
|
812
|
+
return toolResult2(
|
|
677
813
|
"Continuity audits are disabled. Enable `continuityAuditEnabled: true` to generate continuity audits."
|
|
678
814
|
);
|
|
679
815
|
}
|
|
680
816
|
if (!orchestrator.compounding) {
|
|
681
|
-
return
|
|
817
|
+
return toolResult2(
|
|
682
818
|
"Compounding engine is disabled. Enable `compoundingEnabled: true` to generate continuity audits."
|
|
683
819
|
);
|
|
684
820
|
}
|
|
@@ -688,7 +824,7 @@ ${formatted}`
|
|
|
688
824
|
period,
|
|
689
825
|
key
|
|
690
826
|
});
|
|
691
|
-
return
|
|
827
|
+
return toolResult2(
|
|
692
828
|
`OK
|
|
693
829
|
|
|
694
830
|
period: ${audit.period}
|
|
@@ -704,40 +840,40 @@ report: ${audit.reportPath}`
|
|
|
704
840
|
name: "continuity_incident_open",
|
|
705
841
|
label: "Open Continuity Incident",
|
|
706
842
|
description: "Create a new continuity incident record in append-only storage.",
|
|
707
|
-
parameters:
|
|
708
|
-
symptom:
|
|
843
|
+
parameters: Type2.Object({
|
|
844
|
+
symptom: Type2.String({
|
|
709
845
|
description: "Observed continuity failure symptom."
|
|
710
846
|
}),
|
|
711
|
-
namespace:
|
|
712
|
-
|
|
847
|
+
namespace: Type2.Optional(
|
|
848
|
+
Type2.String({
|
|
713
849
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
714
850
|
})
|
|
715
851
|
),
|
|
716
|
-
triggerWindow:
|
|
717
|
-
|
|
852
|
+
triggerWindow: Type2.Optional(
|
|
853
|
+
Type2.String({
|
|
718
854
|
description: "Optional time window when incident occurred."
|
|
719
855
|
})
|
|
720
856
|
),
|
|
721
|
-
suspectedCause:
|
|
722
|
-
|
|
857
|
+
suspectedCause: Type2.Optional(
|
|
858
|
+
Type2.String({
|
|
723
859
|
description: "Optional suspected root cause."
|
|
724
860
|
})
|
|
725
861
|
)
|
|
726
862
|
}),
|
|
727
863
|
async execute(_toolCallId, params) {
|
|
728
864
|
if (!orchestrator.config.identityContinuityEnabled) {
|
|
729
|
-
return
|
|
865
|
+
return toolResult2(
|
|
730
866
|
"Identity continuity is disabled. Enable `identityContinuityEnabled: true` to open incidents."
|
|
731
867
|
);
|
|
732
868
|
}
|
|
733
869
|
if (!orchestrator.config.continuityIncidentLoggingEnabled) {
|
|
734
|
-
return
|
|
870
|
+
return toolResult2(
|
|
735
871
|
"Continuity incident logging is disabled. Enable `continuityIncidentLoggingEnabled: true` to open incidents."
|
|
736
872
|
);
|
|
737
873
|
}
|
|
738
874
|
const symptom = typeof params.symptom === "string" ? params.symptom.trim() : "";
|
|
739
875
|
if (!symptom) {
|
|
740
|
-
return
|
|
876
|
+
return toolResult2("Missing required field: symptom");
|
|
741
877
|
}
|
|
742
878
|
const storage = await orchestrator.getStorageForNamespace(
|
|
743
879
|
normalizeToolNamespace(params.namespace)
|
|
@@ -747,8 +883,8 @@ report: ${audit.reportPath}`
|
|
|
747
883
|
triggerWindow: typeof params.triggerWindow === "string" ? params.triggerWindow : void 0,
|
|
748
884
|
suspectedCause: typeof params.suspectedCause === "string" ? params.suspectedCause : void 0
|
|
749
885
|
});
|
|
750
|
-
|
|
751
|
-
return
|
|
886
|
+
log.info(`continuity-incident open id=${created.id}`);
|
|
887
|
+
return toolResult2(`Continuity incident opened.
|
|
752
888
|
|
|
753
889
|
${formatContinuityIncidentSummary(created)}`);
|
|
754
890
|
}
|
|
@@ -760,35 +896,35 @@ ${formatContinuityIncidentSummary(created)}`);
|
|
|
760
896
|
name: "continuity_incident_close",
|
|
761
897
|
label: "Close Continuity Incident",
|
|
762
898
|
description: "Close an open continuity incident with required verification details.",
|
|
763
|
-
parameters:
|
|
764
|
-
id:
|
|
899
|
+
parameters: Type2.Object({
|
|
900
|
+
id: Type2.String({
|
|
765
901
|
description: "Incident ID to close."
|
|
766
902
|
}),
|
|
767
|
-
namespace:
|
|
768
|
-
|
|
903
|
+
namespace: Type2.Optional(
|
|
904
|
+
Type2.String({
|
|
769
905
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
770
906
|
})
|
|
771
907
|
),
|
|
772
|
-
fixApplied:
|
|
908
|
+
fixApplied: Type2.String({
|
|
773
909
|
description: "What fix was applied."
|
|
774
910
|
}),
|
|
775
|
-
verificationResult:
|
|
911
|
+
verificationResult: Type2.String({
|
|
776
912
|
description: "How closure was verified."
|
|
777
913
|
}),
|
|
778
|
-
preventiveRule:
|
|
779
|
-
|
|
914
|
+
preventiveRule: Type2.Optional(
|
|
915
|
+
Type2.String({
|
|
780
916
|
description: "Optional preventive follow-up rule."
|
|
781
917
|
})
|
|
782
918
|
)
|
|
783
919
|
}),
|
|
784
920
|
async execute(_toolCallId, params) {
|
|
785
921
|
if (!orchestrator.config.identityContinuityEnabled) {
|
|
786
|
-
return
|
|
922
|
+
return toolResult2(
|
|
787
923
|
"Identity continuity is disabled. Enable `identityContinuityEnabled: true` to close incidents."
|
|
788
924
|
);
|
|
789
925
|
}
|
|
790
926
|
if (!orchestrator.config.continuityIncidentLoggingEnabled) {
|
|
791
|
-
return
|
|
927
|
+
return toolResult2(
|
|
792
928
|
"Continuity incident logging is disabled. Enable `continuityIncidentLoggingEnabled: true` to close incidents."
|
|
793
929
|
);
|
|
794
930
|
}
|
|
@@ -796,9 +932,9 @@ ${formatContinuityIncidentSummary(created)}`);
|
|
|
796
932
|
const fixApplied = typeof params.fixApplied === "string" ? params.fixApplied.trim() : "";
|
|
797
933
|
const verificationResult = typeof params.verificationResult === "string" ? params.verificationResult.trim() : "";
|
|
798
934
|
const preventiveRule = typeof params.preventiveRule === "string" ? params.preventiveRule.trim() : void 0;
|
|
799
|
-
if (!id) return
|
|
800
|
-
if (!fixApplied) return
|
|
801
|
-
if (!verificationResult) return
|
|
935
|
+
if (!id) return toolResult2("Missing required field: id");
|
|
936
|
+
if (!fixApplied) return toolResult2("Missing required field: fixApplied");
|
|
937
|
+
if (!verificationResult) return toolResult2("Missing required field: verificationResult");
|
|
802
938
|
const storage = await orchestrator.getStorageForNamespace(
|
|
803
939
|
normalizeToolNamespace(params.namespace)
|
|
804
940
|
);
|
|
@@ -807,9 +943,9 @@ ${formatContinuityIncidentSummary(created)}`);
|
|
|
807
943
|
verificationResult,
|
|
808
944
|
preventiveRule
|
|
809
945
|
});
|
|
810
|
-
if (!closed) return
|
|
811
|
-
|
|
812
|
-
return
|
|
946
|
+
if (!closed) return toolResult2(`Incident not found: ${id}`);
|
|
947
|
+
log.info(`continuity-incident close id=${id}`);
|
|
948
|
+
return toolResult2(`Continuity incident closed.
|
|
813
949
|
|
|
814
950
|
${formatContinuityIncidentSummary(closed)}`);
|
|
815
951
|
}
|
|
@@ -821,20 +957,20 @@ ${formatContinuityIncidentSummary(closed)}`);
|
|
|
821
957
|
name: "continuity_incident_list",
|
|
822
958
|
label: "List Continuity Incidents",
|
|
823
959
|
description: "List continuity incidents and optionally filter by state.",
|
|
824
|
-
parameters:
|
|
825
|
-
state:
|
|
826
|
-
|
|
960
|
+
parameters: Type2.Object({
|
|
961
|
+
state: Type2.Optional(
|
|
962
|
+
Type2.String({
|
|
827
963
|
enum: ["open", "closed", "all"],
|
|
828
964
|
description: "Incident state filter (default: open)."
|
|
829
965
|
})
|
|
830
966
|
),
|
|
831
|
-
namespace:
|
|
832
|
-
|
|
967
|
+
namespace: Type2.Optional(
|
|
968
|
+
Type2.String({
|
|
833
969
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
834
970
|
})
|
|
835
971
|
),
|
|
836
|
-
limit:
|
|
837
|
-
|
|
972
|
+
limit: Type2.Optional(
|
|
973
|
+
Type2.Number({
|
|
838
974
|
description: "Max incidents to return (default: 25, max: 200).",
|
|
839
975
|
minimum: 1,
|
|
840
976
|
maximum: 200
|
|
@@ -843,7 +979,7 @@ ${formatContinuityIncidentSummary(closed)}`);
|
|
|
843
979
|
}),
|
|
844
980
|
async execute(_toolCallId, params) {
|
|
845
981
|
if (!orchestrator.config.identityContinuityEnabled) {
|
|
846
|
-
return
|
|
982
|
+
return toolResult2(
|
|
847
983
|
"Identity continuity is disabled. Enable `identityContinuityEnabled: true` to list incidents."
|
|
848
984
|
);
|
|
849
985
|
}
|
|
@@ -855,10 +991,10 @@ ${formatContinuityIncidentSummary(closed)}`);
|
|
|
855
991
|
);
|
|
856
992
|
const filtered = await storage.readContinuityIncidents(limit, state);
|
|
857
993
|
if (filtered.length === 0) {
|
|
858
|
-
return
|
|
994
|
+
return toolResult2(`No continuity incidents found for state=${state}.`);
|
|
859
995
|
}
|
|
860
996
|
const body = filtered.map((incident, index) => formatContinuityIncidentSummary(incident, index)).join("\n\n");
|
|
861
|
-
return
|
|
997
|
+
return toolResult2(`## Continuity Incidents (${filtered.length}, state=${state})
|
|
862
998
|
|
|
863
999
|
${body}`);
|
|
864
1000
|
}
|
|
@@ -870,43 +1006,43 @@ ${body}`);
|
|
|
870
1006
|
name: "continuity_loop_add_or_update",
|
|
871
1007
|
label: "Add or Update Continuity Loop",
|
|
872
1008
|
description: "Add or update a continuity improvement loop entry in identity/improvement-loops.md.",
|
|
873
|
-
parameters:
|
|
874
|
-
id:
|
|
1009
|
+
parameters: Type2.Object({
|
|
1010
|
+
id: Type2.String({
|
|
875
1011
|
description: "Stable loop identifier."
|
|
876
1012
|
}),
|
|
877
|
-
namespace:
|
|
878
|
-
|
|
1013
|
+
namespace: Type2.Optional(
|
|
1014
|
+
Type2.String({
|
|
879
1015
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
880
1016
|
})
|
|
881
1017
|
),
|
|
882
|
-
cadence:
|
|
1018
|
+
cadence: Type2.String({
|
|
883
1019
|
enum: ["daily", "weekly", "monthly", "quarterly"],
|
|
884
1020
|
description: "Review cadence."
|
|
885
1021
|
}),
|
|
886
|
-
purpose:
|
|
1022
|
+
purpose: Type2.String({
|
|
887
1023
|
description: "What this recurring loop improves."
|
|
888
1024
|
}),
|
|
889
|
-
status:
|
|
1025
|
+
status: Type2.String({
|
|
890
1026
|
enum: ["active", "paused", "retired"],
|
|
891
1027
|
description: "Current lifecycle status for the loop."
|
|
892
1028
|
}),
|
|
893
|
-
killCondition:
|
|
1029
|
+
killCondition: Type2.String({
|
|
894
1030
|
description: "Clear condition for retiring this loop."
|
|
895
1031
|
}),
|
|
896
|
-
lastReviewed:
|
|
897
|
-
|
|
1032
|
+
lastReviewed: Type2.Optional(
|
|
1033
|
+
Type2.String({
|
|
898
1034
|
description: "Optional ISO timestamp for last review. Defaults to now."
|
|
899
1035
|
})
|
|
900
1036
|
),
|
|
901
|
-
notes:
|
|
902
|
-
|
|
1037
|
+
notes: Type2.Optional(
|
|
1038
|
+
Type2.String({
|
|
903
1039
|
description: "Optional operator notes."
|
|
904
1040
|
})
|
|
905
1041
|
)
|
|
906
1042
|
}),
|
|
907
1043
|
async execute(_toolCallId, params) {
|
|
908
1044
|
if (!orchestrator.config.identityContinuityEnabled) {
|
|
909
|
-
return
|
|
1045
|
+
return toolResult2(
|
|
910
1046
|
"Identity continuity is disabled. Enable `identityContinuityEnabled: true` to manage continuity loops."
|
|
911
1047
|
);
|
|
912
1048
|
}
|
|
@@ -923,12 +1059,12 @@ ${body}`);
|
|
|
923
1059
|
lastReviewed: typeof params.lastReviewed === "string" ? params.lastReviewed : void 0,
|
|
924
1060
|
notes: typeof params.notes === "string" ? params.notes : void 0
|
|
925
1061
|
});
|
|
926
|
-
|
|
927
|
-
return
|
|
1062
|
+
log.info(`continuity-loop upsert id=${loop.id} status=${loop.status}`);
|
|
1063
|
+
return toolResult2(`Continuity loop saved.
|
|
928
1064
|
|
|
929
1065
|
${formatContinuityLoopSummary(loop)}`);
|
|
930
1066
|
} catch (err) {
|
|
931
|
-
return
|
|
1067
|
+
return toolResult2(`Failed to save continuity loop: ${String(err)}`);
|
|
932
1068
|
}
|
|
933
1069
|
}
|
|
934
1070
|
},
|
|
@@ -939,40 +1075,40 @@ ${formatContinuityLoopSummary(loop)}`);
|
|
|
939
1075
|
name: "continuity_loop_review",
|
|
940
1076
|
label: "Review Continuity Loop",
|
|
941
1077
|
description: "Update review metadata (lastReviewed/status/notes) for an existing continuity loop.",
|
|
942
|
-
parameters:
|
|
943
|
-
id:
|
|
1078
|
+
parameters: Type2.Object({
|
|
1079
|
+
id: Type2.String({
|
|
944
1080
|
description: "Loop ID to review."
|
|
945
1081
|
}),
|
|
946
|
-
namespace:
|
|
947
|
-
|
|
1082
|
+
namespace: Type2.Optional(
|
|
1083
|
+
Type2.String({
|
|
948
1084
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
949
1085
|
})
|
|
950
1086
|
),
|
|
951
|
-
status:
|
|
952
|
-
|
|
1087
|
+
status: Type2.Optional(
|
|
1088
|
+
Type2.String({
|
|
953
1089
|
enum: ["active", "paused", "retired"],
|
|
954
1090
|
description: "Optional status update."
|
|
955
1091
|
})
|
|
956
1092
|
),
|
|
957
|
-
notes:
|
|
958
|
-
|
|
1093
|
+
notes: Type2.Optional(
|
|
1094
|
+
Type2.String({
|
|
959
1095
|
description: "Optional notes update."
|
|
960
1096
|
})
|
|
961
1097
|
),
|
|
962
|
-
reviewedAt:
|
|
963
|
-
|
|
1098
|
+
reviewedAt: Type2.Optional(
|
|
1099
|
+
Type2.String({
|
|
964
1100
|
description: "Optional ISO timestamp for review event. Defaults to now."
|
|
965
1101
|
})
|
|
966
1102
|
)
|
|
967
1103
|
}),
|
|
968
1104
|
async execute(_toolCallId, params) {
|
|
969
1105
|
if (!orchestrator.config.identityContinuityEnabled) {
|
|
970
|
-
return
|
|
1106
|
+
return toolResult2(
|
|
971
1107
|
"Identity continuity is disabled. Enable `identityContinuityEnabled: true` to manage continuity loops."
|
|
972
1108
|
);
|
|
973
1109
|
}
|
|
974
1110
|
const id = typeof params.id === "string" ? params.id.trim() : "";
|
|
975
|
-
if (!id) return
|
|
1111
|
+
if (!id) return toolResult2("Missing required field: id");
|
|
976
1112
|
try {
|
|
977
1113
|
const storage = await orchestrator.getStorageForNamespace(
|
|
978
1114
|
normalizeToolNamespace(params.namespace)
|
|
@@ -982,13 +1118,13 @@ ${formatContinuityLoopSummary(loop)}`);
|
|
|
982
1118
|
notes: typeof params.notes === "string" ? params.notes : void 0,
|
|
983
1119
|
reviewedAt: typeof params.reviewedAt === "string" ? params.reviewedAt : void 0
|
|
984
1120
|
});
|
|
985
|
-
if (!reviewed) return
|
|
986
|
-
|
|
987
|
-
return
|
|
1121
|
+
if (!reviewed) return toolResult2(`Continuity loop not found: ${id}`);
|
|
1122
|
+
log.info(`continuity-loop review id=${id} status=${reviewed.status}`);
|
|
1123
|
+
return toolResult2(`Continuity loop reviewed.
|
|
988
1124
|
|
|
989
1125
|
${formatContinuityLoopSummary(reviewed)}`);
|
|
990
1126
|
} catch (err) {
|
|
991
|
-
return
|
|
1127
|
+
return toolResult2(`Failed to review continuity loop: ${String(err)}`);
|
|
992
1128
|
}
|
|
993
1129
|
}
|
|
994
1130
|
},
|
|
@@ -999,16 +1135,16 @@ ${formatContinuityLoopSummary(reviewed)}`);
|
|
|
999
1135
|
name: "identity_anchor_get",
|
|
1000
1136
|
label: "Get Identity Anchor",
|
|
1001
1137
|
description: "Read the identity continuity anchor document used for recovery-safe identity context.",
|
|
1002
|
-
parameters:
|
|
1003
|
-
namespace:
|
|
1004
|
-
|
|
1138
|
+
parameters: Type2.Object({
|
|
1139
|
+
namespace: Type2.Optional(
|
|
1140
|
+
Type2.String({
|
|
1005
1141
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
1006
1142
|
})
|
|
1007
1143
|
)
|
|
1008
1144
|
}),
|
|
1009
1145
|
async execute(_toolCallId, params) {
|
|
1010
1146
|
if (!orchestrator.config.identityContinuityEnabled) {
|
|
1011
|
-
return
|
|
1147
|
+
return toolResult2(
|
|
1012
1148
|
"Identity continuity is disabled. Enable `identityContinuityEnabled: true` to use identity anchor tools."
|
|
1013
1149
|
);
|
|
1014
1150
|
}
|
|
@@ -1017,11 +1153,11 @@ ${formatContinuityLoopSummary(reviewed)}`);
|
|
|
1017
1153
|
);
|
|
1018
1154
|
const anchor = await storage.readIdentityAnchor();
|
|
1019
1155
|
if (!anchor) {
|
|
1020
|
-
return
|
|
1156
|
+
return toolResult2(
|
|
1021
1157
|
"No identity anchor found yet. Use `identity_anchor_update` to create one."
|
|
1022
1158
|
);
|
|
1023
1159
|
}
|
|
1024
|
-
return
|
|
1160
|
+
return toolResult2(`## Identity Anchor
|
|
1025
1161
|
|
|
1026
1162
|
${anchor}`);
|
|
1027
1163
|
}
|
|
@@ -1033,36 +1169,36 @@ ${anchor}`);
|
|
|
1033
1169
|
name: "identity_anchor_update",
|
|
1034
1170
|
label: "Update Identity Anchor",
|
|
1035
1171
|
description: "Conservatively update identity anchor sections without overwriting existing material.",
|
|
1036
|
-
parameters:
|
|
1037
|
-
namespace:
|
|
1038
|
-
|
|
1172
|
+
parameters: Type2.Object({
|
|
1173
|
+
namespace: Type2.Optional(
|
|
1174
|
+
Type2.String({
|
|
1039
1175
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
1040
1176
|
})
|
|
1041
1177
|
),
|
|
1042
|
-
identityTraits:
|
|
1043
|
-
|
|
1178
|
+
identityTraits: Type2.Optional(
|
|
1179
|
+
Type2.String({
|
|
1044
1180
|
description: "Updates for the 'Identity Traits' section."
|
|
1045
1181
|
})
|
|
1046
1182
|
),
|
|
1047
|
-
communicationPreferences:
|
|
1048
|
-
|
|
1183
|
+
communicationPreferences: Type2.Optional(
|
|
1184
|
+
Type2.String({
|
|
1049
1185
|
description: "Updates for the 'Communication Preferences' section."
|
|
1050
1186
|
})
|
|
1051
1187
|
),
|
|
1052
|
-
operatingPrinciples:
|
|
1053
|
-
|
|
1188
|
+
operatingPrinciples: Type2.Optional(
|
|
1189
|
+
Type2.String({
|
|
1054
1190
|
description: "Updates for the 'Operating Principles' section."
|
|
1055
1191
|
})
|
|
1056
1192
|
),
|
|
1057
|
-
continuityNotes:
|
|
1058
|
-
|
|
1193
|
+
continuityNotes: Type2.Optional(
|
|
1194
|
+
Type2.String({
|
|
1059
1195
|
description: "Updates for the 'Continuity Notes' section."
|
|
1060
1196
|
})
|
|
1061
1197
|
)
|
|
1062
1198
|
}),
|
|
1063
1199
|
async execute(_toolCallId, params) {
|
|
1064
1200
|
if (!orchestrator.config.identityContinuityEnabled) {
|
|
1065
|
-
return
|
|
1201
|
+
return toolResult2(
|
|
1066
1202
|
"Identity continuity is disabled. Enable `identityContinuityEnabled: true` to use identity anchor tools."
|
|
1067
1203
|
);
|
|
1068
1204
|
}
|
|
@@ -1076,7 +1212,7 @@ ${anchor}`);
|
|
|
1076
1212
|
(value) => typeof value === "string" && value.trim().length > 0
|
|
1077
1213
|
);
|
|
1078
1214
|
if (!hasUpdate) {
|
|
1079
|
-
return
|
|
1215
|
+
return toolResult2(
|
|
1080
1216
|
"No updates provided. Supply at least one section field to update the identity anchor."
|
|
1081
1217
|
);
|
|
1082
1218
|
}
|
|
@@ -1087,10 +1223,10 @@ ${anchor}`);
|
|
|
1087
1223
|
const merged = mergeIdentityAnchor(existing, updates);
|
|
1088
1224
|
await storage.writeIdentityAnchor(merged);
|
|
1089
1225
|
const updatedSections = Object.entries(updates).filter(([, value]) => typeof value === "string" && value.trim().length > 0).map(([name]) => name);
|
|
1090
|
-
|
|
1226
|
+
log.info(
|
|
1091
1227
|
`identity-anchor update sections=${updatedSections.join(",")} chars=${merged.length}`
|
|
1092
1228
|
);
|
|
1093
|
-
return
|
|
1229
|
+
return toolResult2(
|
|
1094
1230
|
`Identity anchor updated (${updatedSections.length} section${updatedSections.length === 1 ? "" : "s"}).
|
|
1095
1231
|
|
|
1096
1232
|
${merged}`
|
|
@@ -1104,16 +1240,16 @@ ${merged}`
|
|
|
1104
1240
|
name: "memory_feedback",
|
|
1105
1241
|
label: "Memory Feedback",
|
|
1106
1242
|
description: "Thumbs up/down a memory's relevance. Stored locally and used as a soft ranking bias when enabled.",
|
|
1107
|
-
parameters:
|
|
1108
|
-
memoryId:
|
|
1243
|
+
parameters: Type2.Object({
|
|
1244
|
+
memoryId: Type2.String({
|
|
1109
1245
|
description: "Memory ID (filename without .md), e.g. fact-123"
|
|
1110
1246
|
}),
|
|
1111
|
-
vote:
|
|
1247
|
+
vote: Type2.String({
|
|
1112
1248
|
enum: ["up", "down"],
|
|
1113
1249
|
description: "up or down"
|
|
1114
1250
|
}),
|
|
1115
|
-
note:
|
|
1116
|
-
|
|
1251
|
+
note: Type2.Optional(
|
|
1252
|
+
Type2.String({
|
|
1117
1253
|
description: "Optional note explaining the feedback (stored locally)."
|
|
1118
1254
|
})
|
|
1119
1255
|
)
|
|
@@ -1121,12 +1257,12 @@ ${merged}`
|
|
|
1121
1257
|
async execute(_toolCallId, params) {
|
|
1122
1258
|
const { memoryId, vote, note } = params;
|
|
1123
1259
|
if (!orchestrator.config.feedbackEnabled) {
|
|
1124
|
-
return
|
|
1260
|
+
return toolResult2(
|
|
1125
1261
|
"Feedback is disabled. Enable `feedbackEnabled: true` in the Engram plugin config to store feedback."
|
|
1126
1262
|
);
|
|
1127
1263
|
}
|
|
1128
1264
|
await orchestrator.recordMemoryFeedback(memoryId, vote, note);
|
|
1129
|
-
return
|
|
1265
|
+
return toolResult2(
|
|
1130
1266
|
`Recorded feedback for ${memoryId}: ${vote}${note ? ` (note: ${note})` : ""}`
|
|
1131
1267
|
);
|
|
1132
1268
|
}
|
|
@@ -1138,9 +1274,9 @@ ${merged}`
|
|
|
1138
1274
|
name: "memory_last_recall",
|
|
1139
1275
|
label: "Last Recall Snapshot",
|
|
1140
1276
|
description: "Fetch the last set of memory IDs that were injected into context for a session. Useful when the user says things like 'why did you say that?' or 'that's not right' and you want to identify which memories may have misled the response.",
|
|
1141
|
-
parameters:
|
|
1142
|
-
sessionKey:
|
|
1143
|
-
|
|
1277
|
+
parameters: Type2.Object({
|
|
1278
|
+
sessionKey: Type2.Optional(
|
|
1279
|
+
Type2.String({
|
|
1144
1280
|
description: "Session key to look up. If omitted, returns the most recent snapshot across all sessions (may be wrong under concurrency)."
|
|
1145
1281
|
})
|
|
1146
1282
|
)
|
|
@@ -1149,12 +1285,12 @@ ${merged}`
|
|
|
1149
1285
|
const { sessionKey } = params;
|
|
1150
1286
|
const snap = sessionKey ? orchestrator.lastRecall.get(sessionKey) : orchestrator.lastRecall.getMostRecent();
|
|
1151
1287
|
if (!snap) {
|
|
1152
|
-
return
|
|
1288
|
+
return toolResult2("No last-recall snapshot found yet.");
|
|
1153
1289
|
}
|
|
1154
1290
|
const prefix = sessionKey ? `## Last Recall (${snap.sessionKey})` : `## Last Recall (most recent: ${snap.sessionKey})
|
|
1155
1291
|
|
|
1156
1292
|
NOTE: You did not provide sessionKey; under concurrency this may not match your current session.`;
|
|
1157
|
-
return
|
|
1293
|
+
return toolResult2(
|
|
1158
1294
|
[
|
|
1159
1295
|
prefix,
|
|
1160
1296
|
"",
|
|
@@ -1174,9 +1310,9 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1174
1310
|
name: "memory_intent_debug",
|
|
1175
1311
|
label: "Inspect Intent Debug",
|
|
1176
1312
|
description: "Inspect the last persisted planner/intent snapshot, including recall mode selection, query intent classification, and graph fallback decisions.",
|
|
1177
|
-
parameters:
|
|
1178
|
-
namespace:
|
|
1179
|
-
|
|
1313
|
+
parameters: Type2.Object({
|
|
1314
|
+
namespace: Type2.Optional(
|
|
1315
|
+
Type2.String({
|
|
1180
1316
|
description: "Optional namespace to inspect. Defaults to defaultNamespace."
|
|
1181
1317
|
})
|
|
1182
1318
|
)
|
|
@@ -1186,7 +1322,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1186
1322
|
const text = await orchestrator.recallIntrospection.explainLastIntent({
|
|
1187
1323
|
namespace
|
|
1188
1324
|
});
|
|
1189
|
-
return
|
|
1325
|
+
return toolResult2(text);
|
|
1190
1326
|
}
|
|
1191
1327
|
},
|
|
1192
1328
|
{ name: "memory_intent_debug" }
|
|
@@ -1196,14 +1332,14 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1196
1332
|
name: "memory_qmd_debug",
|
|
1197
1333
|
label: "Inspect QMD Recall",
|
|
1198
1334
|
description: "Inspect the last persisted QMD recall snapshot, including any intent hint, explain trace capture, and whether hybrid top-up was skipped or used.",
|
|
1199
|
-
parameters:
|
|
1200
|
-
namespace:
|
|
1201
|
-
|
|
1335
|
+
parameters: Type2.Object({
|
|
1336
|
+
namespace: Type2.Optional(
|
|
1337
|
+
Type2.String({
|
|
1202
1338
|
description: "Optional namespace to inspect. Defaults to defaultNamespace."
|
|
1203
1339
|
})
|
|
1204
1340
|
),
|
|
1205
|
-
maxResults:
|
|
1206
|
-
|
|
1341
|
+
maxResults: Type2.Optional(
|
|
1342
|
+
Type2.Number({
|
|
1207
1343
|
description: "Maximum results to show (default: 10, max: 25).",
|
|
1208
1344
|
minimum: 1,
|
|
1209
1345
|
maximum: 25
|
|
@@ -1216,7 +1352,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1216
1352
|
namespace,
|
|
1217
1353
|
maxResults
|
|
1218
1354
|
});
|
|
1219
|
-
return
|
|
1355
|
+
return toolResult2(text);
|
|
1220
1356
|
}
|
|
1221
1357
|
},
|
|
1222
1358
|
{ name: "memory_qmd_debug" }
|
|
@@ -1226,14 +1362,14 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1226
1362
|
name: "memory_graph_explain_last_recall",
|
|
1227
1363
|
label: "Explain Graph Recall",
|
|
1228
1364
|
description: "Inspect the last graph-mode recall expansion snapshot (seed paths + expanded candidates) to explain why graph memories were included.",
|
|
1229
|
-
parameters:
|
|
1230
|
-
namespace:
|
|
1231
|
-
|
|
1365
|
+
parameters: Type2.Object({
|
|
1366
|
+
namespace: Type2.Optional(
|
|
1367
|
+
Type2.String({
|
|
1232
1368
|
description: "Optional namespace to inspect. Defaults to defaultNamespace."
|
|
1233
1369
|
})
|
|
1234
1370
|
),
|
|
1235
|
-
maxExpanded:
|
|
1236
|
-
|
|
1371
|
+
maxExpanded: Type2.Optional(
|
|
1372
|
+
Type2.Number({
|
|
1237
1373
|
description: "Maximum expanded paths to show (default: 10, max: 50).",
|
|
1238
1374
|
minimum: 1,
|
|
1239
1375
|
maximum: 50
|
|
@@ -1246,7 +1382,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1246
1382
|
namespace,
|
|
1247
1383
|
maxExpanded
|
|
1248
1384
|
});
|
|
1249
|
-
return
|
|
1385
|
+
return toolResult2(text);
|
|
1250
1386
|
}
|
|
1251
1387
|
},
|
|
1252
1388
|
{ name: "memory_graph_explain_last_recall" }
|
|
@@ -1256,29 +1392,29 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1256
1392
|
name: "memory_feedback_last_recall",
|
|
1257
1393
|
label: "Feedback Last Recall",
|
|
1258
1394
|
description: "Batch feedback tool for the last recall snapshot. Can mark retrieved memories as 'not useful' (negative examples) so they are softly penalized in future ranking when negative examples are enabled.",
|
|
1259
|
-
parameters:
|
|
1260
|
-
sessionKey:
|
|
1261
|
-
|
|
1395
|
+
parameters: Type2.Object({
|
|
1396
|
+
sessionKey: Type2.Optional(
|
|
1397
|
+
Type2.String({
|
|
1262
1398
|
description: "Session key. If omitted, uses the most recent snapshot across all sessions (may be wrong under concurrency)."
|
|
1263
1399
|
})
|
|
1264
1400
|
),
|
|
1265
|
-
notUsefulMemoryIds:
|
|
1266
|
-
|
|
1401
|
+
notUsefulMemoryIds: Type2.Optional(
|
|
1402
|
+
Type2.Array(Type2.String(), {
|
|
1267
1403
|
description: "Memory IDs to mark as not useful. If omitted, you may use usefulMemoryIds + autoMarkOthersNotUseful to mark the rest as not useful."
|
|
1268
1404
|
})
|
|
1269
1405
|
),
|
|
1270
|
-
usefulMemoryIds:
|
|
1271
|
-
|
|
1406
|
+
usefulMemoryIds: Type2.Optional(
|
|
1407
|
+
Type2.Array(Type2.String(), {
|
|
1272
1408
|
description: "Memory IDs that were useful. Only used when autoMarkOthersNotUseful=true."
|
|
1273
1409
|
})
|
|
1274
1410
|
),
|
|
1275
|
-
autoMarkOthersNotUseful:
|
|
1276
|
-
|
|
1411
|
+
autoMarkOthersNotUseful: Type2.Optional(
|
|
1412
|
+
Type2.Boolean({
|
|
1277
1413
|
description: "If true, marks all last-recall memory IDs not listed in usefulMemoryIds as not useful. Safer than auto-marking without an explicit useful list."
|
|
1278
1414
|
})
|
|
1279
1415
|
),
|
|
1280
|
-
note:
|
|
1281
|
-
|
|
1416
|
+
note: Type2.Optional(
|
|
1417
|
+
Type2.String({
|
|
1282
1418
|
description: "Optional note explaining why these were not useful (stored locally)."
|
|
1283
1419
|
})
|
|
1284
1420
|
)
|
|
@@ -1292,20 +1428,20 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1292
1428
|
note
|
|
1293
1429
|
} = params;
|
|
1294
1430
|
if (!orchestrator.config.negativeExamplesEnabled) {
|
|
1295
|
-
return
|
|
1431
|
+
return toolResult2(
|
|
1296
1432
|
"Negative examples are disabled. Enable `negativeExamplesEnabled: true` in the Engram plugin config to store retrieved-but-not-useful feedback and apply penalties."
|
|
1297
1433
|
);
|
|
1298
1434
|
}
|
|
1299
1435
|
const snap = sessionKey ? orchestrator.lastRecall.get(sessionKey) : orchestrator.lastRecall.getMostRecent();
|
|
1300
1436
|
if (!snap) {
|
|
1301
|
-
return
|
|
1437
|
+
return toolResult2("No last-recall snapshot found yet.");
|
|
1302
1438
|
}
|
|
1303
1439
|
let toMark = null;
|
|
1304
1440
|
if (Array.isArray(notUsefulMemoryIds) && notUsefulMemoryIds.length > 0) {
|
|
1305
1441
|
toMark = notUsefulMemoryIds;
|
|
1306
1442
|
} else if (autoMarkOthersNotUseful) {
|
|
1307
1443
|
if (!Array.isArray(usefulMemoryIds) || usefulMemoryIds.length === 0) {
|
|
1308
|
-
return
|
|
1444
|
+
return toolResult2(
|
|
1309
1445
|
"autoMarkOthersNotUseful=true requires a non-empty usefulMemoryIds list (to avoid accidental mass-negative marking)."
|
|
1310
1446
|
);
|
|
1311
1447
|
}
|
|
@@ -1313,13 +1449,13 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1313
1449
|
toMark = snap.memoryIds.filter((id) => !useful.has(id));
|
|
1314
1450
|
}
|
|
1315
1451
|
if (!toMark || toMark.length === 0) {
|
|
1316
|
-
return
|
|
1452
|
+
return toolResult2(
|
|
1317
1453
|
"Nothing to record. Provide notUsefulMemoryIds, or provide usefulMemoryIds with autoMarkOthersNotUseful=true."
|
|
1318
1454
|
);
|
|
1319
1455
|
}
|
|
1320
1456
|
await orchestrator.recordNotUsefulMemories(toMark, note);
|
|
1321
1457
|
const warn = sessionKey ? "" : "\n\nNOTE: You did not provide sessionKey; under concurrency this may not match your current session.";
|
|
1322
|
-
return
|
|
1458
|
+
return toolResult2(
|
|
1323
1459
|
`Recorded ${toMark.length} not-useful memory ID(s) for last recall (${snap.sessionKey}).${warn}`
|
|
1324
1460
|
);
|
|
1325
1461
|
}
|
|
@@ -1331,50 +1467,50 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1331
1467
|
name: "context_checkpoint",
|
|
1332
1468
|
label: "Context Checkpoint",
|
|
1333
1469
|
description: "Create or validate a transcript checkpoint and record the corresponding context-compression action event (v8.3).",
|
|
1334
|
-
parameters:
|
|
1335
|
-
summary:
|
|
1470
|
+
parameters: Type2.Object({
|
|
1471
|
+
summary: Type2.String({
|
|
1336
1472
|
description: "Short summary of what was checkpointed."
|
|
1337
1473
|
}),
|
|
1338
|
-
sessionKey:
|
|
1339
|
-
|
|
1474
|
+
sessionKey: Type2.Optional(
|
|
1475
|
+
Type2.String({
|
|
1340
1476
|
description: "Session key for the checkpoint source transcript."
|
|
1341
1477
|
})
|
|
1342
1478
|
),
|
|
1343
|
-
turns:
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
timestamp:
|
|
1347
|
-
role:
|
|
1348
|
-
content:
|
|
1349
|
-
sessionKey:
|
|
1350
|
-
turnId:
|
|
1479
|
+
turns: Type2.Optional(
|
|
1480
|
+
Type2.Array(
|
|
1481
|
+
Type2.Object({
|
|
1482
|
+
timestamp: Type2.String(),
|
|
1483
|
+
role: Type2.String({ enum: ["user", "assistant"] }),
|
|
1484
|
+
content: Type2.String(),
|
|
1485
|
+
sessionKey: Type2.String(),
|
|
1486
|
+
turnId: Type2.String()
|
|
1351
1487
|
})
|
|
1352
1488
|
)
|
|
1353
1489
|
),
|
|
1354
|
-
ttlHours:
|
|
1355
|
-
|
|
1490
|
+
ttlHours: Type2.Optional(
|
|
1491
|
+
Type2.Number({
|
|
1356
1492
|
description: "Optional checkpoint TTL in hours."
|
|
1357
1493
|
})
|
|
1358
1494
|
),
|
|
1359
|
-
sourcePrompt:
|
|
1360
|
-
|
|
1495
|
+
sourcePrompt: Type2.Optional(
|
|
1496
|
+
Type2.String({
|
|
1361
1497
|
description: "Optional source prompt text used for hashing in telemetry."
|
|
1362
1498
|
})
|
|
1363
1499
|
),
|
|
1364
|
-
namespace:
|
|
1365
|
-
|
|
1500
|
+
namespace: Type2.Optional(
|
|
1501
|
+
Type2.String({
|
|
1366
1502
|
description: "Optional namespace. Defaults to defaultNamespace."
|
|
1367
1503
|
})
|
|
1368
1504
|
),
|
|
1369
|
-
dryRun:
|
|
1370
|
-
|
|
1505
|
+
dryRun: Type2.Optional(
|
|
1506
|
+
Type2.Boolean({
|
|
1371
1507
|
description: "When true, validate and log without persisting the checkpoint file."
|
|
1372
1508
|
})
|
|
1373
1509
|
)
|
|
1374
1510
|
}),
|
|
1375
1511
|
async execute(_toolCallId, params) {
|
|
1376
1512
|
if (!orchestrator.config.contextCompressionActionsEnabled) {
|
|
1377
|
-
return
|
|
1513
|
+
return toolResult2(
|
|
1378
1514
|
"Context compression actions are disabled. Enable `contextCompressionActionsEnabled: true` to use this tool."
|
|
1379
1515
|
);
|
|
1380
1516
|
}
|
|
@@ -1390,9 +1526,9 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1390
1526
|
promptHash: promptHashForTelemetry(sourcePrompt)
|
|
1391
1527
|
});
|
|
1392
1528
|
if (!wrote2) {
|
|
1393
|
-
return
|
|
1529
|
+
return toolResult2("Checkpoint recorded best-effort failed (fail-open).");
|
|
1394
1530
|
}
|
|
1395
|
-
return
|
|
1531
|
+
return toolResult2(`Recorded context checkpoint telemetry in namespace=${ns}.`);
|
|
1396
1532
|
}
|
|
1397
1533
|
const validationErrors = [];
|
|
1398
1534
|
if (!asNonEmptyString(sessionKey)) validationErrors.push("sessionKey is required");
|
|
@@ -1415,7 +1551,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1415
1551
|
status: "rejected",
|
|
1416
1552
|
reason: `validation: ${validationErrors.join("; ")}`
|
|
1417
1553
|
});
|
|
1418
|
-
return
|
|
1554
|
+
return toolResult2(`Validation failed: ${validationErrors.join("; ")}.`);
|
|
1419
1555
|
}
|
|
1420
1556
|
const structuredEvent = {
|
|
1421
1557
|
...baseEvent,
|
|
@@ -1425,7 +1561,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1425
1561
|
if (preview.policyDecision !== "allow") {
|
|
1426
1562
|
const wrote2 = await orchestrator.appendMemoryActionEvent(structuredEvent);
|
|
1427
1563
|
const suffix2 = wrote2 ? "" : " Telemetry write failed (fail-open).";
|
|
1428
|
-
return
|
|
1564
|
+
return toolResult2(
|
|
1429
1565
|
`Context checkpoint blocked by policy: action=${preview.action}, namespace=${preview.namespace}, policy=${preview.policyDecision}, rationale=${preview.policyRationale}.${suffix2}`
|
|
1430
1566
|
);
|
|
1431
1567
|
}
|
|
@@ -1447,9 +1583,9 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1447
1583
|
});
|
|
1448
1584
|
const suffix = wrote ? "" : " Telemetry write failed (fail-open).";
|
|
1449
1585
|
if (dryRun === true) {
|
|
1450
|
-
return
|
|
1586
|
+
return toolResult2(`Validated context checkpoint for session=${sessionKey} without saving it.${suffix}`);
|
|
1451
1587
|
}
|
|
1452
|
-
return
|
|
1588
|
+
return toolResult2(`Saved context checkpoint for session=${sessionKey} in namespace=${ns}.${suffix}`);
|
|
1453
1589
|
}
|
|
1454
1590
|
},
|
|
1455
1591
|
{ name: "context_checkpoint" }
|
|
@@ -1459,86 +1595,86 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1459
1595
|
name: "memory_action_apply",
|
|
1460
1596
|
label: "Apply Memory Action",
|
|
1461
1597
|
description: "Record a memory-action application event for policy-learning telemetry (v8.3).",
|
|
1462
|
-
parameters:
|
|
1463
|
-
action:
|
|
1598
|
+
parameters: Type2.Object({
|
|
1599
|
+
action: Type2.String({
|
|
1464
1600
|
enum: actionTypes,
|
|
1465
1601
|
description: "Memory action type."
|
|
1466
1602
|
}),
|
|
1467
|
-
category:
|
|
1468
|
-
|
|
1603
|
+
category: Type2.Optional(
|
|
1604
|
+
Type2.String({
|
|
1469
1605
|
description: "Optional memory category for write-style actions."
|
|
1470
1606
|
})
|
|
1471
1607
|
),
|
|
1472
|
-
content:
|
|
1473
|
-
|
|
1608
|
+
content: Type2.Optional(
|
|
1609
|
+
Type2.String({
|
|
1474
1610
|
description: "Content payload for store, update, artifact, or summarize actions."
|
|
1475
1611
|
})
|
|
1476
1612
|
),
|
|
1477
|
-
outcome:
|
|
1478
|
-
|
|
1613
|
+
outcome: Type2.Optional(
|
|
1614
|
+
Type2.String({
|
|
1479
1615
|
enum: ["applied", "skipped", "failed"],
|
|
1480
1616
|
description: "Outcome status (default: applied)."
|
|
1481
1617
|
})
|
|
1482
1618
|
),
|
|
1483
|
-
reason:
|
|
1484
|
-
|
|
1619
|
+
reason: Type2.Optional(
|
|
1620
|
+
Type2.String({
|
|
1485
1621
|
description: "Optional reason/notes for this action outcome."
|
|
1486
1622
|
})
|
|
1487
1623
|
),
|
|
1488
|
-
memoryId:
|
|
1489
|
-
|
|
1624
|
+
memoryId: Type2.Optional(
|
|
1625
|
+
Type2.String({
|
|
1490
1626
|
description: "Optional memory ID targeted by this action."
|
|
1491
1627
|
})
|
|
1492
1628
|
),
|
|
1493
|
-
sessionKey:
|
|
1494
|
-
|
|
1629
|
+
sessionKey: Type2.Optional(
|
|
1630
|
+
Type2.String({
|
|
1495
1631
|
description: "Optional source session key for audit logging."
|
|
1496
1632
|
})
|
|
1497
1633
|
),
|
|
1498
|
-
linkTargetId:
|
|
1499
|
-
|
|
1634
|
+
linkTargetId: Type2.Optional(
|
|
1635
|
+
Type2.String({
|
|
1500
1636
|
description: "Target memory ID for link_graph actions."
|
|
1501
1637
|
})
|
|
1502
1638
|
),
|
|
1503
|
-
linkType:
|
|
1504
|
-
|
|
1639
|
+
linkType: Type2.Optional(
|
|
1640
|
+
Type2.String({
|
|
1505
1641
|
description: "Link type for link_graph actions."
|
|
1506
1642
|
})
|
|
1507
1643
|
),
|
|
1508
|
-
linkStrength:
|
|
1509
|
-
|
|
1644
|
+
linkStrength: Type2.Optional(
|
|
1645
|
+
Type2.Number({
|
|
1510
1646
|
description: "Optional edge strength for link_graph actions."
|
|
1511
1647
|
})
|
|
1512
1648
|
),
|
|
1513
|
-
artifactType:
|
|
1514
|
-
|
|
1649
|
+
artifactType: Type2.Optional(
|
|
1650
|
+
Type2.String({
|
|
1515
1651
|
description: "Optional artifact type for create_artifact."
|
|
1516
1652
|
})
|
|
1517
1653
|
),
|
|
1518
|
-
execute:
|
|
1519
|
-
|
|
1654
|
+
execute: Type2.Optional(
|
|
1655
|
+
Type2.Boolean({
|
|
1520
1656
|
description: "When true, force structured execution mode even for target-only actions like discard."
|
|
1521
1657
|
})
|
|
1522
1658
|
),
|
|
1523
|
-
sourcePrompt:
|
|
1524
|
-
|
|
1659
|
+
sourcePrompt: Type2.Optional(
|
|
1660
|
+
Type2.String({
|
|
1525
1661
|
description: "Optional source prompt text used for hashing in telemetry."
|
|
1526
1662
|
})
|
|
1527
1663
|
),
|
|
1528
|
-
namespace:
|
|
1529
|
-
|
|
1664
|
+
namespace: Type2.Optional(
|
|
1665
|
+
Type2.String({
|
|
1530
1666
|
description: "Optional namespace. Defaults to defaultNamespace."
|
|
1531
1667
|
})
|
|
1532
1668
|
),
|
|
1533
|
-
dryRun:
|
|
1534
|
-
|
|
1669
|
+
dryRun: Type2.Optional(
|
|
1670
|
+
Type2.Boolean({
|
|
1535
1671
|
description: "When true, validate and report without persisting telemetry."
|
|
1536
1672
|
})
|
|
1537
1673
|
)
|
|
1538
1674
|
}),
|
|
1539
1675
|
async execute(_toolCallId, params) {
|
|
1540
1676
|
if (!orchestrator.config.contextCompressionActionsEnabled) {
|
|
1541
|
-
return
|
|
1677
|
+
return toolResult2(
|
|
1542
1678
|
"Context compression actions are disabled. Enable `contextCompressionActionsEnabled: true` to use this tool."
|
|
1543
1679
|
);
|
|
1544
1680
|
}
|
|
@@ -1561,7 +1697,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1561
1697
|
} = params;
|
|
1562
1698
|
const ns = typeof namespace === "string" && namespace.length > 0 ? namespace : orchestrator.config.defaultNamespace;
|
|
1563
1699
|
if (!isKnownMemoryActionType(action)) {
|
|
1564
|
-
return
|
|
1700
|
+
return toolResult2(`Validation failed: invalid action ${String(action)}.`);
|
|
1565
1701
|
}
|
|
1566
1702
|
const validationErrors = [];
|
|
1567
1703
|
const contentValue = asNonEmptyString(content);
|
|
@@ -1587,15 +1723,15 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1587
1723
|
};
|
|
1588
1724
|
const preview2 = orchestrator.previewMemoryActionEvent(event);
|
|
1589
1725
|
if (dryRun === true) {
|
|
1590
|
-
return
|
|
1726
|
+
return toolResult2(
|
|
1591
1727
|
`Dry run: memory action would be recorded with action=${preview2.action}, outcome=${preview2.outcome}, namespace=${preview2.namespace}, policy=${preview2.policyDecision}.`
|
|
1592
1728
|
);
|
|
1593
1729
|
}
|
|
1594
1730
|
const wrote2 = await orchestrator.appendMemoryActionEvent(event);
|
|
1595
1731
|
if (!wrote2) {
|
|
1596
|
-
return
|
|
1732
|
+
return toolResult2("Memory action telemetry write failed (fail-open).");
|
|
1597
1733
|
}
|
|
1598
|
-
return
|
|
1734
|
+
return toolResult2(
|
|
1599
1735
|
`Recorded memory action telemetry: action=${preview2.action}, outcome=${preview2.outcome}, namespace=${preview2.namespace}.`
|
|
1600
1736
|
);
|
|
1601
1737
|
}
|
|
@@ -1631,7 +1767,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1631
1767
|
outputMemoryIds: [],
|
|
1632
1768
|
reason: `validation: ${validationErrors.join("; ")}`
|
|
1633
1769
|
});
|
|
1634
|
-
return
|
|
1770
|
+
return toolResult2(
|
|
1635
1771
|
`Validation failed: ${validationErrors.join("; ")}.`
|
|
1636
1772
|
);
|
|
1637
1773
|
}
|
|
@@ -1646,7 +1782,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1646
1782
|
reason: `validation: invalid category ${String(category)}`
|
|
1647
1783
|
});
|
|
1648
1784
|
const suffix = wrote2 ? "" : " Telemetry write failed (fail-open).";
|
|
1649
|
-
return
|
|
1785
|
+
return toolResult2(`Validation failed: invalid category ${String(category)}.${suffix}`);
|
|
1650
1786
|
}
|
|
1651
1787
|
const storage = typeof orchestrator.getStorage === "function" ? await orchestrator.getStorage(ns) : orchestrator.storage;
|
|
1652
1788
|
const referencedMemory = await readReferencedMemoryForPolicyEligibility(storage, memoryIdValue);
|
|
@@ -1659,7 +1795,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1659
1795
|
outputMemoryIds: [],
|
|
1660
1796
|
reason: "validation: support passport records require the owner surface"
|
|
1661
1797
|
});
|
|
1662
|
-
return
|
|
1798
|
+
return toolResult2(
|
|
1663
1799
|
"Validation failed: support passport records can only be changed through the support passport owner surface."
|
|
1664
1800
|
);
|
|
1665
1801
|
}
|
|
@@ -1675,11 +1811,11 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1675
1811
|
const wrote2 = await orchestrator.appendMemoryActionEvent(structuredEvent);
|
|
1676
1812
|
const suffix = wrote2 ? "" : " Telemetry write failed (fail-open).";
|
|
1677
1813
|
if (preview2.policyDecision !== "allow") {
|
|
1678
|
-
return
|
|
1814
|
+
return toolResult2(
|
|
1679
1815
|
`Memory action blocked by policy during validation: action=${preview2.action}, namespace=${preview2.namespace}, policy=${preview2.policyDecision}, rationale=${preview2.policyRationale}.${suffix}`
|
|
1680
1816
|
);
|
|
1681
1817
|
}
|
|
1682
|
-
return
|
|
1818
|
+
return toolResult2(
|
|
1683
1819
|
`Validated memory action without applying it: action=${preview2.action}, namespace=${preview2.namespace}, policy=${preview2.policyDecision}.${suffix}`
|
|
1684
1820
|
);
|
|
1685
1821
|
}
|
|
@@ -1687,7 +1823,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1687
1823
|
if (preview.policyDecision !== "allow") {
|
|
1688
1824
|
const wrote2 = await orchestrator.appendMemoryActionEvent(structuredEvent);
|
|
1689
1825
|
const suffix = wrote2 ? "" : " Telemetry write failed (fail-open).";
|
|
1690
|
-
return
|
|
1826
|
+
return toolResult2(
|
|
1691
1827
|
`Memory action execution blocked by policy: action=${preview.action}, namespace=${preview.namespace}, policy=${preview.policyDecision}, rationale=${preview.policyRationale}.${suffix}`
|
|
1692
1828
|
);
|
|
1693
1829
|
}
|
|
@@ -1745,7 +1881,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1745
1881
|
reason: `execution: unable to update memory ${memoryIdValue}`
|
|
1746
1882
|
});
|
|
1747
1883
|
const suffix = wrote2 ? "" : " Telemetry write failed (fail-open).";
|
|
1748
|
-
return
|
|
1884
|
+
return toolResult2(`Validation failed: unable to update memory ${memoryIdValue}.${suffix}`);
|
|
1749
1885
|
}
|
|
1750
1886
|
outputMemoryIds.push(memoryIdValue);
|
|
1751
1887
|
appliedMessage = `Applied memory action: action=${action}, memoryId=${memoryIdValue}, namespace=${ns}.`;
|
|
@@ -1766,7 +1902,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1766
1902
|
reason: "execution: unable to create artifact"
|
|
1767
1903
|
});
|
|
1768
1904
|
const suffix = wrote2 ? "" : " Telemetry write failed (fail-open).";
|
|
1769
|
-
return
|
|
1905
|
+
return toolResult2(`Validation failed: unable to create artifact.${suffix}`);
|
|
1770
1906
|
}
|
|
1771
1907
|
outputMemoryIds.push(createdId);
|
|
1772
1908
|
appliedMessage = `Applied memory action: action=${action}, memoryId=${createdId}, namespace=${ns}.`;
|
|
@@ -1802,7 +1938,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1802
1938
|
reason: `execution: unable to find memory ${memoryIdValue}`
|
|
1803
1939
|
});
|
|
1804
1940
|
const suffix = wrote2 ? "" : " Telemetry write failed (fail-open).";
|
|
1805
|
-
return
|
|
1941
|
+
return toolResult2(`Validation failed: unable to find memory ${memoryIdValue}.${suffix}`);
|
|
1806
1942
|
}
|
|
1807
1943
|
await storage.writeMemoryFrontmatter(
|
|
1808
1944
|
target,
|
|
@@ -1845,7 +1981,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1845
1981
|
reason: `execution: unable to link memory ${memoryIdValue}`
|
|
1846
1982
|
});
|
|
1847
1983
|
const suffix = wrote2 ? "" : " Telemetry write failed (fail-open).";
|
|
1848
|
-
return
|
|
1984
|
+
return toolResult2(`Validation failed: unable to link memory ${memoryIdValue}.${suffix}`);
|
|
1849
1985
|
}
|
|
1850
1986
|
outputMemoryIds.push(memoryIdValue);
|
|
1851
1987
|
appliedMessage = `Applied memory action: action=${action}, memoryId=${memoryIdValue}, namespace=${ns}.`;
|
|
@@ -1869,9 +2005,9 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1869
2005
|
...queuedForReview ? { reason: "tombstone-blocked: write landed pending_review, no active copy created" } : {}
|
|
1870
2006
|
});
|
|
1871
2007
|
if (!wrote) {
|
|
1872
|
-
return
|
|
2008
|
+
return toolResult2(`${appliedMessage} Telemetry write failed (fail-open).`);
|
|
1873
2009
|
}
|
|
1874
|
-
return
|
|
2010
|
+
return toolResult2(appliedMessage);
|
|
1875
2011
|
}
|
|
1876
2012
|
},
|
|
1877
2013
|
{ name: "memory_action_apply" }
|
|
@@ -1881,14 +2017,14 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1881
2017
|
name: "compression_guidelines_optimize",
|
|
1882
2018
|
label: "Optimize Compression Guidelines",
|
|
1883
2019
|
description: "Run compression guideline optimizer and optionally persist the new guideline/state (v8.11).",
|
|
1884
|
-
parameters:
|
|
1885
|
-
dryRun:
|
|
1886
|
-
|
|
2020
|
+
parameters: Type2.Object({
|
|
2021
|
+
dryRun: Type2.Optional(
|
|
2022
|
+
Type2.Boolean({
|
|
1887
2023
|
description: "When true, compute candidate/output but do not persist changes."
|
|
1888
2024
|
})
|
|
1889
2025
|
),
|
|
1890
|
-
eventLimit:
|
|
1891
|
-
|
|
2026
|
+
eventLimit: Type2.Optional(
|
|
2027
|
+
Type2.Number({
|
|
1892
2028
|
description: "Max telemetry events to analyze (default: 500)."
|
|
1893
2029
|
})
|
|
1894
2030
|
)
|
|
@@ -1900,11 +2036,11 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1900
2036
|
eventLimit
|
|
1901
2037
|
});
|
|
1902
2038
|
if (!result.enabled) {
|
|
1903
|
-
return
|
|
2039
|
+
return toolResult2(
|
|
1904
2040
|
"Compression guideline learning is disabled. Enable `compressionGuidelineLearningEnabled: true` to run optimizer."
|
|
1905
2041
|
);
|
|
1906
2042
|
}
|
|
1907
|
-
return
|
|
2043
|
+
return toolResult2(
|
|
1908
2044
|
[
|
|
1909
2045
|
"Compression guideline optimization complete.",
|
|
1910
2046
|
`dryRun=${result.dryRun}`,
|
|
@@ -1925,9 +2061,9 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1925
2061
|
name: "compression_guidelines_activate",
|
|
1926
2062
|
label: "Activate Compression Guideline Draft",
|
|
1927
2063
|
description: "Promote the staged compression guideline draft to the active guideline/state after review (v8.11).",
|
|
1928
|
-
parameters:
|
|
1929
|
-
expectedContentHash:
|
|
1930
|
-
expectedGuidelineVersion:
|
|
2064
|
+
parameters: Type2.Object({
|
|
2065
|
+
expectedContentHash: Type2.Optional(Type2.String()),
|
|
2066
|
+
expectedGuidelineVersion: Type2.Optional(Type2.Number())
|
|
1931
2067
|
}),
|
|
1932
2068
|
async execute(_toolCallId, params) {
|
|
1933
2069
|
const expectedContentHash = typeof params.expectedContentHash === "string" ? params.expectedContentHash.trim() : "";
|
|
@@ -1937,32 +2073,32 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
1937
2073
|
...typeof expectedGuidelineVersion === "number" ? { expectedGuidelineVersion } : {}
|
|
1938
2074
|
});
|
|
1939
2075
|
if (!result.enabled) {
|
|
1940
|
-
return
|
|
2076
|
+
return toolResult2(
|
|
1941
2077
|
"Compression guideline learning is disabled. Enable `compressionGuidelineLearningEnabled: true` before activating drafts."
|
|
1942
2078
|
);
|
|
1943
2079
|
}
|
|
1944
2080
|
if (!result.activated) {
|
|
1945
2081
|
if (result.reason === "missing_draft") {
|
|
1946
|
-
return
|
|
2082
|
+
return toolResult2("No staged compression guideline draft is available to activate.");
|
|
1947
2083
|
}
|
|
1948
2084
|
if (result.reason === "expected_revision_required") {
|
|
1949
|
-
return
|
|
2085
|
+
return toolResult2(
|
|
1950
2086
|
"Activation requires `expectedContentHash` or `expectedGuidelineVersion` so the reviewed draft identity is pinned."
|
|
1951
2087
|
);
|
|
1952
2088
|
}
|
|
1953
2089
|
if (result.reason === "content_hash_mismatch" || result.reason === "draft_changed") {
|
|
1954
|
-
return
|
|
2090
|
+
return toolResult2(
|
|
1955
2091
|
"The staged compression guideline draft changed after review. Re-read the current draft and retry activation with its latest identity."
|
|
1956
2092
|
);
|
|
1957
2093
|
}
|
|
1958
2094
|
if (result.reason === "guideline_version_mismatch") {
|
|
1959
|
-
return
|
|
2095
|
+
return toolResult2(
|
|
1960
2096
|
"The staged draft guidelineVersion no longer matches the reviewed revision. Re-read the current draft and retry activation with its latest identity."
|
|
1961
2097
|
);
|
|
1962
2098
|
}
|
|
1963
|
-
return
|
|
2099
|
+
return toolResult2("Compression guideline draft activation was rejected.");
|
|
1964
2100
|
}
|
|
1965
|
-
return
|
|
2101
|
+
return toolResult2(
|
|
1966
2102
|
[
|
|
1967
2103
|
"Compression guideline draft activated.",
|
|
1968
2104
|
`guidelineVersion=${result.guidelineVersion ?? "unknown"}`
|
|
@@ -1985,45 +2121,45 @@ Best for:
|
|
|
1985
2121
|
- User says "remember that..." or "note that..."
|
|
1986
2122
|
- Critical corrections or preferences
|
|
1987
2123
|
- Important decisions or facts`,
|
|
1988
|
-
parameters:
|
|
1989
|
-
content:
|
|
2124
|
+
parameters: Type2.Object({
|
|
2125
|
+
content: Type2.String({
|
|
1990
2126
|
description: "The memory to store \u2014 a clear, standalone statement"
|
|
1991
2127
|
}),
|
|
1992
|
-
namespace:
|
|
1993
|
-
|
|
2128
|
+
namespace: Type2.Optional(
|
|
2129
|
+
Type2.String({
|
|
1994
2130
|
description: "Namespace to store into (v3.0+). Omit to store into defaultNamespace."
|
|
1995
2131
|
})
|
|
1996
2132
|
),
|
|
1997
|
-
category:
|
|
1998
|
-
|
|
2133
|
+
category: Type2.Optional(
|
|
2134
|
+
Type2.String({
|
|
1999
2135
|
description: 'Category: "fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill", "rule", "procedure", "reasoning_trace" (default: "fact")',
|
|
2000
2136
|
enum: ["fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill", "rule", "procedure", "reasoning_trace"]
|
|
2001
2137
|
})
|
|
2002
2138
|
),
|
|
2003
|
-
tags:
|
|
2004
|
-
|
|
2139
|
+
tags: Type2.Optional(
|
|
2140
|
+
Type2.Array(Type2.String(), {
|
|
2005
2141
|
description: "Tags for categorization"
|
|
2006
2142
|
})
|
|
2007
2143
|
),
|
|
2008
|
-
entityRef:
|
|
2009
|
-
|
|
2144
|
+
entityRef: Type2.Optional(
|
|
2145
|
+
Type2.String({
|
|
2010
2146
|
description: "Entity reference (e.g., person-jane-doe, project-my-app)"
|
|
2011
2147
|
})
|
|
2012
2148
|
),
|
|
2013
|
-
confidence:
|
|
2014
|
-
|
|
2149
|
+
confidence: Type2.Optional(
|
|
2150
|
+
Type2.Number({
|
|
2015
2151
|
description: "Explicit capture confidence (0-1). Defaults to 0.95.",
|
|
2016
2152
|
minimum: 0,
|
|
2017
2153
|
maximum: 1
|
|
2018
2154
|
})
|
|
2019
2155
|
),
|
|
2020
|
-
ttl:
|
|
2021
|
-
|
|
2156
|
+
ttl: Type2.Optional(
|
|
2157
|
+
Type2.String({
|
|
2022
2158
|
description: "Optional TTL expression to attach to the stored memory."
|
|
2023
2159
|
})
|
|
2024
2160
|
),
|
|
2025
|
-
sourceReason:
|
|
2026
|
-
|
|
2161
|
+
sourceReason: Type2.Optional(
|
|
2162
|
+
Type2.String({
|
|
2027
2163
|
description: "Optional reason code for audit history."
|
|
2028
2164
|
})
|
|
2029
2165
|
)
|
|
@@ -2043,45 +2179,45 @@ Best for:
|
|
|
2043
2179
|
name: "memory_capture",
|
|
2044
2180
|
label: "Capture Memory",
|
|
2045
2181
|
description: "Store a validated explicit memory note. Preferred tool for explicit capture modes and operator-controlled memory creation.",
|
|
2046
|
-
parameters:
|
|
2047
|
-
content:
|
|
2182
|
+
parameters: Type2.Object({
|
|
2183
|
+
content: Type2.String({
|
|
2048
2184
|
description: "The memory to store \u2014 one standalone validated statement."
|
|
2049
2185
|
}),
|
|
2050
|
-
namespace:
|
|
2051
|
-
|
|
2186
|
+
namespace: Type2.Optional(
|
|
2187
|
+
Type2.String({
|
|
2052
2188
|
description: "Namespace to store into. Omit to store into defaultNamespace."
|
|
2053
2189
|
})
|
|
2054
2190
|
),
|
|
2055
|
-
category:
|
|
2056
|
-
|
|
2191
|
+
category: Type2.Optional(
|
|
2192
|
+
Type2.String({
|
|
2057
2193
|
description: "Memory category.",
|
|
2058
2194
|
enum: ["fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill", "rule", "procedure", "reasoning_trace"]
|
|
2059
2195
|
})
|
|
2060
2196
|
),
|
|
2061
|
-
tags:
|
|
2062
|
-
|
|
2197
|
+
tags: Type2.Optional(
|
|
2198
|
+
Type2.Array(Type2.String(), {
|
|
2063
2199
|
description: "Tags for categorization"
|
|
2064
2200
|
})
|
|
2065
2201
|
),
|
|
2066
|
-
entityRef:
|
|
2067
|
-
|
|
2202
|
+
entityRef: Type2.Optional(
|
|
2203
|
+
Type2.String({
|
|
2068
2204
|
description: "Entity reference (e.g., person-jane-doe, project-my-app)"
|
|
2069
2205
|
})
|
|
2070
2206
|
),
|
|
2071
|
-
confidence:
|
|
2072
|
-
|
|
2207
|
+
confidence: Type2.Optional(
|
|
2208
|
+
Type2.Number({
|
|
2073
2209
|
description: "Explicit capture confidence (0-1). Defaults to 0.95.",
|
|
2074
2210
|
minimum: 0,
|
|
2075
2211
|
maximum: 1
|
|
2076
2212
|
})
|
|
2077
2213
|
),
|
|
2078
|
-
ttl:
|
|
2079
|
-
|
|
2214
|
+
ttl: Type2.Optional(
|
|
2215
|
+
Type2.String({
|
|
2080
2216
|
description: "Optional TTL expression to attach to the stored memory."
|
|
2081
2217
|
})
|
|
2082
2218
|
),
|
|
2083
|
-
sourceReason:
|
|
2084
|
-
|
|
2219
|
+
sourceReason: Type2.Optional(
|
|
2220
|
+
Type2.String({
|
|
2085
2221
|
description: "Optional reason code for audit history."
|
|
2086
2222
|
})
|
|
2087
2223
|
)
|
|
@@ -2101,29 +2237,29 @@ Best for:
|
|
|
2101
2237
|
name: "memory_promote",
|
|
2102
2238
|
label: "Promote Memory To Shared",
|
|
2103
2239
|
description: "Copy a memory into the shared namespace (v3.0+). This is intended for curated promotion of agent-specific learning into a shared brain.",
|
|
2104
|
-
parameters:
|
|
2105
|
-
memoryId:
|
|
2240
|
+
parameters: Type2.Object({
|
|
2241
|
+
memoryId: Type2.String({
|
|
2106
2242
|
description: "Memory ID (filename without .md), e.g. fact-123"
|
|
2107
2243
|
}),
|
|
2108
|
-
fromNamespace:
|
|
2109
|
-
|
|
2244
|
+
fromNamespace: Type2.Optional(
|
|
2245
|
+
Type2.String({
|
|
2110
2246
|
description: "Source namespace (default: defaultNamespace)."
|
|
2111
2247
|
})
|
|
2112
2248
|
),
|
|
2113
|
-
toNamespace:
|
|
2114
|
-
|
|
2249
|
+
toNamespace: Type2.Optional(
|
|
2250
|
+
Type2.String({
|
|
2115
2251
|
description: "Target namespace (default: sharedNamespace)."
|
|
2116
2252
|
})
|
|
2117
2253
|
),
|
|
2118
|
-
note:
|
|
2119
|
-
|
|
2254
|
+
note: Type2.Optional(
|
|
2255
|
+
Type2.String({
|
|
2120
2256
|
description: "Optional note explaining why this should be shared (stored as a tag-like annotation)."
|
|
2121
2257
|
})
|
|
2122
2258
|
)
|
|
2123
2259
|
}),
|
|
2124
2260
|
async execute(_toolCallId, params) {
|
|
2125
2261
|
if (!orchestrator.config.namespacesEnabled) {
|
|
2126
|
-
return
|
|
2262
|
+
return toolResult2(
|
|
2127
2263
|
"Namespaces are disabled. Enable `namespacesEnabled: true` to use memory promotion."
|
|
2128
2264
|
);
|
|
2129
2265
|
}
|
|
@@ -2131,7 +2267,7 @@ Best for:
|
|
|
2131
2267
|
orchestrator,
|
|
2132
2268
|
params
|
|
2133
2269
|
);
|
|
2134
|
-
return
|
|
2270
|
+
return toolResult2(message);
|
|
2135
2271
|
}
|
|
2136
2272
|
},
|
|
2137
2273
|
{ name: "memory_promote" }
|
|
@@ -2149,9 +2285,9 @@ Best for:
|
|
|
2149
2285
|
- Understanding the user holistically
|
|
2150
2286
|
- Checking preferences before making decisions
|
|
2151
2287
|
- "What do you know about me?"`,
|
|
2152
|
-
parameters:
|
|
2153
|
-
namespace:
|
|
2154
|
-
|
|
2288
|
+
parameters: Type2.Object({
|
|
2289
|
+
namespace: Type2.Optional(
|
|
2290
|
+
Type2.String({
|
|
2155
2291
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
2156
2292
|
})
|
|
2157
2293
|
)
|
|
@@ -2161,11 +2297,11 @@ Best for:
|
|
|
2161
2297
|
const storage = await orchestrator.getStorageForNamespace(namespace);
|
|
2162
2298
|
const profile = await storage.readProfile();
|
|
2163
2299
|
if (!profile) {
|
|
2164
|
-
return
|
|
2300
|
+
return toolResult2(
|
|
2165
2301
|
"No profile built yet. The profile builds automatically through conversations."
|
|
2166
2302
|
);
|
|
2167
2303
|
}
|
|
2168
|
-
return
|
|
2304
|
+
return toolResult2(`## User Profile
|
|
2169
2305
|
|
|
2170
2306
|
${profile}`);
|
|
2171
2307
|
}
|
|
@@ -2184,9 +2320,9 @@ Speed: Instant
|
|
|
2184
2320
|
Best for:
|
|
2185
2321
|
- Seeing all known entities
|
|
2186
2322
|
- Looking up facts about a specific entity`,
|
|
2187
|
-
parameters:
|
|
2188
|
-
name:
|
|
2189
|
-
|
|
2323
|
+
parameters: Type2.Object({
|
|
2324
|
+
name: Type2.Optional(
|
|
2325
|
+
Type2.String({
|
|
2190
2326
|
description: "Specific entity to look up (e.g., person-jane-doe)"
|
|
2191
2327
|
})
|
|
2192
2328
|
)
|
|
@@ -2196,17 +2332,17 @@ Best for:
|
|
|
2196
2332
|
if (name) {
|
|
2197
2333
|
const content = await orchestrator.storage.readEntity(name);
|
|
2198
2334
|
if (!content) {
|
|
2199
|
-
return
|
|
2335
|
+
return toolResult2(`Entity "${name}" not found.`);
|
|
2200
2336
|
}
|
|
2201
|
-
return
|
|
2337
|
+
return toolResult2(content);
|
|
2202
2338
|
}
|
|
2203
2339
|
const entities = await orchestrator.storage.readEntities();
|
|
2204
2340
|
if (entities.length === 0) {
|
|
2205
|
-
return
|
|
2341
|
+
return toolResult2(
|
|
2206
2342
|
"No entities tracked yet. Entities build automatically through conversations."
|
|
2207
2343
|
);
|
|
2208
2344
|
}
|
|
2209
|
-
return
|
|
2345
|
+
return toolResult2(
|
|
2210
2346
|
`## Known Entities (${entities.length})
|
|
2211
2347
|
|
|
2212
2348
|
${entities.map((e) => `- ${e}`).join("\n")}`
|
|
@@ -2228,15 +2364,15 @@ Best for:
|
|
|
2228
2364
|
- Seeing what questions have been generated from past conversations
|
|
2229
2365
|
- Resolving questions that have been answered
|
|
2230
2366
|
- "What questions do you have for me?"`,
|
|
2231
|
-
parameters:
|
|
2232
|
-
action:
|
|
2233
|
-
|
|
2367
|
+
parameters: Type2.Object({
|
|
2368
|
+
action: Type2.Optional(
|
|
2369
|
+
Type2.String({
|
|
2234
2370
|
description: '"list" (default) to show unresolved questions, "all" to show all, "resolve" to mark one as answered',
|
|
2235
2371
|
enum: ["list", "all", "resolve"]
|
|
2236
2372
|
})
|
|
2237
2373
|
),
|
|
2238
|
-
questionId:
|
|
2239
|
-
|
|
2374
|
+
questionId: Type2.Optional(
|
|
2375
|
+
Type2.String({
|
|
2240
2376
|
description: "Question ID to resolve (required when action is 'resolve')"
|
|
2241
2377
|
})
|
|
2242
2378
|
)
|
|
@@ -2245,15 +2381,15 @@ Best for:
|
|
|
2245
2381
|
const { action = "list", questionId } = params;
|
|
2246
2382
|
if (action === "resolve") {
|
|
2247
2383
|
if (!questionId) {
|
|
2248
|
-
return
|
|
2384
|
+
return toolResult2("Error: questionId is required when action is 'resolve'");
|
|
2249
2385
|
}
|
|
2250
2386
|
const resolved = await orchestrator.storage.resolveQuestion(questionId);
|
|
2251
|
-
return
|
|
2387
|
+
return toolResult2(resolved ? `Question ${questionId} marked as resolved.` : `Question ${questionId} not found.`);
|
|
2252
2388
|
}
|
|
2253
2389
|
const unresolvedOnly = action !== "all";
|
|
2254
2390
|
const questions = await orchestrator.storage.readQuestions({ unresolvedOnly });
|
|
2255
2391
|
if (questions.length === 0) {
|
|
2256
|
-
return
|
|
2392
|
+
return toolResult2(unresolvedOnly ? "No unresolved questions. Questions are generated automatically during memory extraction." : "No questions found.");
|
|
2257
2393
|
}
|
|
2258
2394
|
const formatted = questions.map(
|
|
2259
2395
|
(q, i) => `### [${i + 1}] ${q.id}
|
|
@@ -2263,7 +2399,7 @@ ${q.question}
|
|
|
2263
2399
|
|
|
2264
2400
|
_Context: ${q.context}_`
|
|
2265
2401
|
).join("\n\n");
|
|
2266
|
-
return
|
|
2402
|
+
return toolResult2(`## Questions (${questions.length})
|
|
2267
2403
|
|
|
2268
2404
|
${formatted}`);
|
|
2269
2405
|
}
|
|
@@ -2283,9 +2419,9 @@ Best for:
|
|
|
2283
2419
|
- Understanding the agent's self-model and growth
|
|
2284
2420
|
- "What have you learned about yourself?"
|
|
2285
2421
|
- Reviewing identity development over time`,
|
|
2286
|
-
parameters:
|
|
2287
|
-
namespace:
|
|
2288
|
-
|
|
2422
|
+
parameters: Type2.Object({
|
|
2423
|
+
namespace: Type2.Optional(
|
|
2424
|
+
Type2.String({
|
|
2289
2425
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
2290
2426
|
})
|
|
2291
2427
|
)
|
|
@@ -2295,9 +2431,9 @@ Best for:
|
|
|
2295
2431
|
const storage = await orchestrator.getStorageForNamespace(namespace);
|
|
2296
2432
|
const identity = await storage.readIdentityReflections();
|
|
2297
2433
|
if (!identity) {
|
|
2298
|
-
return
|
|
2434
|
+
return toolResult2("No identity reflections found. Identity reflections build automatically through conversations when identityEnabled is true.");
|
|
2299
2435
|
}
|
|
2300
|
-
return
|
|
2436
|
+
return toolResult2(`## Agent Identity
|
|
2301
2437
|
|
|
2302
2438
|
${identity}`);
|
|
2303
2439
|
}
|
|
@@ -2317,32 +2453,32 @@ Best for:
|
|
|
2317
2453
|
- Nightly incremental governance sweeps
|
|
2318
2454
|
- Manual shadow runs on recent memory windows
|
|
2319
2455
|
- Small-batch review queue generation without scanning the full corpus at once`,
|
|
2320
|
-
parameters:
|
|
2321
|
-
namespace:
|
|
2322
|
-
|
|
2456
|
+
parameters: Type2.Object({
|
|
2457
|
+
namespace: Type2.Optional(
|
|
2458
|
+
Type2.String({
|
|
2323
2459
|
description: "Optional namespace override. Defaults to the default namespace."
|
|
2324
2460
|
})
|
|
2325
2461
|
),
|
|
2326
|
-
mode:
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2462
|
+
mode: Type2.Optional(
|
|
2463
|
+
Type2.Union([
|
|
2464
|
+
Type2.Literal("shadow"),
|
|
2465
|
+
Type2.Literal("apply")
|
|
2330
2466
|
], {
|
|
2331
2467
|
description: "Governance mode. Defaults to shadow."
|
|
2332
2468
|
})
|
|
2333
2469
|
),
|
|
2334
|
-
recentDays:
|
|
2335
|
-
|
|
2470
|
+
recentDays: Type2.Optional(
|
|
2471
|
+
Type2.Number({
|
|
2336
2472
|
description: "Only scan memories updated within the last N days."
|
|
2337
2473
|
})
|
|
2338
2474
|
),
|
|
2339
|
-
maxMemories:
|
|
2340
|
-
|
|
2475
|
+
maxMemories: Type2.Optional(
|
|
2476
|
+
Type2.Number({
|
|
2341
2477
|
description: "Maximum number of memories to scan in this run."
|
|
2342
2478
|
})
|
|
2343
2479
|
),
|
|
2344
|
-
batchSize:
|
|
2345
|
-
|
|
2480
|
+
batchSize: Type2.Optional(
|
|
2481
|
+
Type2.Number({
|
|
2346
2482
|
description: "File-read batch size for bounded governance runs."
|
|
2347
2483
|
})
|
|
2348
2484
|
)
|
|
@@ -2350,7 +2486,7 @@ Best for:
|
|
|
2350
2486
|
async execute(_toolCallId, params) {
|
|
2351
2487
|
const deepSleep = orchestrator.config.dreamsPhases.deepSleep;
|
|
2352
2488
|
if (deepSleep.enabled === false && deepSleep.enabledExplicitlySet === true) {
|
|
2353
|
-
return
|
|
2489
|
+
return toolResult2(
|
|
2354
2490
|
"Memory governance is disabled by `dreams.phases.deepSleep.enabled=false`."
|
|
2355
2491
|
);
|
|
2356
2492
|
}
|
|
@@ -2394,13 +2530,13 @@ Best for:
|
|
|
2394
2530
|
- Cron job scheduled hourly summarization
|
|
2395
2531
|
- Manual trigger to summarize recent conversations
|
|
2396
2532
|
- Building conversation summaries for context preservation`,
|
|
2397
|
-
parameters:
|
|
2533
|
+
parameters: Type2.Object({}),
|
|
2398
2534
|
async execute() {
|
|
2399
2535
|
try {
|
|
2400
2536
|
await orchestrator.summarizer.runHourly();
|
|
2401
|
-
return
|
|
2537
|
+
return toolResult2("Hourly summarization completed. Check the summaries directory for results.");
|
|
2402
2538
|
} catch (err) {
|
|
2403
|
-
return
|
|
2539
|
+
return toolResult2(`Hourly summarization failed: ${err}`);
|
|
2404
2540
|
}
|
|
2405
2541
|
}
|
|
2406
2542
|
},
|
|
@@ -2417,28 +2553,28 @@ This is optional and default-off (see config: conversationIndexEnabled).
|
|
|
2417
2553
|
Best for:
|
|
2418
2554
|
- Cron jobs to keep the conversation index fresh
|
|
2419
2555
|
- Manual rebuild after changing chunk sizes or retention`,
|
|
2420
|
-
parameters:
|
|
2421
|
-
sessionKey:
|
|
2422
|
-
|
|
2556
|
+
parameters: Type2.Object({
|
|
2557
|
+
sessionKey: Type2.Optional(
|
|
2558
|
+
Type2.String({
|
|
2423
2559
|
description: "Session key to index. If omitted, Engram will best-effort scan transcript storage and index all discovered sessionKeys."
|
|
2424
2560
|
})
|
|
2425
2561
|
),
|
|
2426
|
-
hours:
|
|
2427
|
-
|
|
2562
|
+
hours: Type2.Optional(
|
|
2563
|
+
Type2.Number({
|
|
2428
2564
|
description: "How many hours of transcript history to include (default: 24).",
|
|
2429
2565
|
minimum: 1,
|
|
2430
2566
|
maximum: 24 * 30
|
|
2431
2567
|
})
|
|
2432
2568
|
),
|
|
2433
|
-
embed:
|
|
2434
|
-
|
|
2569
|
+
embed: Type2.Optional(
|
|
2570
|
+
Type2.Boolean({
|
|
2435
2571
|
description: "If true, run QMD embed after update for this invocation. If omitted, uses conversationIndexEmbedOnUpdate config."
|
|
2436
2572
|
})
|
|
2437
2573
|
)
|
|
2438
2574
|
}),
|
|
2439
2575
|
async execute(_toolCallId, params) {
|
|
2440
2576
|
if (!orchestrator.config.conversationIndexEnabled) {
|
|
2441
|
-
return
|
|
2577
|
+
return toolResult2(
|
|
2442
2578
|
"Conversation indexing is disabled. Enable `conversationIndexEnabled: true` in the Engram plugin config to use this tool."
|
|
2443
2579
|
);
|
|
2444
2580
|
}
|
|
@@ -2448,11 +2584,11 @@ Best for:
|
|
|
2448
2584
|
const res = await orchestrator.conversationIndexCoordinator.update(sessionKey, h, { embed });
|
|
2449
2585
|
if (res.skipped && res.reason === "min_interval") {
|
|
2450
2586
|
const retrySec = Math.max(1, Math.ceil((res.retryAfterMs ?? 0) / 1e3));
|
|
2451
|
-
return
|
|
2587
|
+
return toolResult2(
|
|
2452
2588
|
`Skipped for sessionKey=${sessionKey} due to min interval. Retry in ~${retrySec}s or pass a higher interval config.`
|
|
2453
2589
|
);
|
|
2454
2590
|
}
|
|
2455
|
-
return
|
|
2591
|
+
return toolResult2(
|
|
2456
2592
|
`Indexed ${res.chunks} chunk(s) for sessionKey=${sessionKey}.${res.embedded ? " Ran embed." : ""}`
|
|
2457
2593
|
);
|
|
2458
2594
|
}
|
|
@@ -2472,7 +2608,7 @@ Best for:
|
|
|
2472
2608
|
}
|
|
2473
2609
|
const skippedSummary = skipped > 0 ? ` Skipped ${skipped} session(s) due to min-interval gating: ${skippedIds.slice(0, 6).join(", ")}${skippedIds.length > 6 ? "..." : ""}.` : "";
|
|
2474
2610
|
const embedSummary = embeddedRuns > 0 ? ` Ran embed for ${embeddedRuns} session update(s).` : "";
|
|
2475
|
-
return
|
|
2611
|
+
return toolResult2(
|
|
2476
2612
|
`Indexed ${total} total chunk(s) across ${sessions.length} session(s).${skippedSummary}${embedSummary}`
|
|
2477
2613
|
);
|
|
2478
2614
|
}
|
|
@@ -2484,21 +2620,21 @@ Best for:
|
|
|
2484
2620
|
name: "work_task",
|
|
2485
2621
|
label: "Manage Work Tasks",
|
|
2486
2622
|
description: "Manage Engram work-layer tasks (create, get, list, update, transition, delete). Responses are marked as work-layer context and excluded from default memory extraction.",
|
|
2487
|
-
parameters:
|
|
2488
|
-
action:
|
|
2623
|
+
parameters: Type2.Object({
|
|
2624
|
+
action: Type2.String({
|
|
2489
2625
|
enum: ["create", "get", "list", "update", "transition", "delete"],
|
|
2490
2626
|
description: "Task action to run."
|
|
2491
2627
|
}),
|
|
2492
|
-
id:
|
|
2493
|
-
title:
|
|
2494
|
-
description:
|
|
2495
|
-
status:
|
|
2496
|
-
priority:
|
|
2497
|
-
owner:
|
|
2498
|
-
assignee:
|
|
2499
|
-
projectId:
|
|
2500
|
-
tags:
|
|
2501
|
-
dueAt:
|
|
2628
|
+
id: Type2.Optional(Type2.String({ description: "Task ID for get/update/transition/delete." })),
|
|
2629
|
+
title: Type2.Optional(Type2.String({ description: "Task title (create/update)." })),
|
|
2630
|
+
description: Type2.Optional(Type2.String({ description: "Task description (create/update)." })),
|
|
2631
|
+
status: Type2.Optional(Type2.String({ enum: ["todo", "in_progress", "blocked", "done", "cancelled"] })),
|
|
2632
|
+
priority: Type2.Optional(Type2.String({ enum: ["low", "medium", "high"] })),
|
|
2633
|
+
owner: Type2.Optional(Type2.String()),
|
|
2634
|
+
assignee: Type2.Optional(Type2.String()),
|
|
2635
|
+
projectId: Type2.Optional(Type2.String()),
|
|
2636
|
+
tags: Type2.Optional(Type2.Array(Type2.String())),
|
|
2637
|
+
dueAt: Type2.Optional(Type2.String())
|
|
2502
2638
|
}),
|
|
2503
2639
|
async execute(_toolCallId, params) {
|
|
2504
2640
|
const p = params;
|
|
@@ -2606,19 +2742,19 @@ Best for:
|
|
|
2606
2742
|
name: "work_project",
|
|
2607
2743
|
label: "Manage Work Projects",
|
|
2608
2744
|
description: "Manage Engram work-layer projects (create, get, list, update, delete, link_task). Responses are marked as work-layer context and excluded from default memory extraction.",
|
|
2609
|
-
parameters:
|
|
2610
|
-
action:
|
|
2745
|
+
parameters: Type2.Object({
|
|
2746
|
+
action: Type2.String({
|
|
2611
2747
|
enum: ["create", "get", "list", "update", "delete", "link_task"],
|
|
2612
2748
|
description: "Project action to run."
|
|
2613
2749
|
}),
|
|
2614
|
-
id:
|
|
2615
|
-
name:
|
|
2616
|
-
description:
|
|
2617
|
-
status:
|
|
2618
|
-
owner:
|
|
2619
|
-
tags:
|
|
2620
|
-
taskId:
|
|
2621
|
-
projectId:
|
|
2750
|
+
id: Type2.Optional(Type2.String({ description: "Project ID for get/update/delete." })),
|
|
2751
|
+
name: Type2.Optional(Type2.String({ description: "Project name (create/update)." })),
|
|
2752
|
+
description: Type2.Optional(Type2.String({ description: "Project description (create/update)." })),
|
|
2753
|
+
status: Type2.Optional(Type2.String({ enum: ["active", "on_hold", "completed", "archived"] })),
|
|
2754
|
+
owner: Type2.Optional(Type2.String()),
|
|
2755
|
+
tags: Type2.Optional(Type2.Array(Type2.String())),
|
|
2756
|
+
taskId: Type2.Optional(Type2.String({ description: "Task ID for link_task action." })),
|
|
2757
|
+
projectId: Type2.Optional(Type2.String({ description: "Project ID for link_task action." }))
|
|
2622
2758
|
}),
|
|
2623
2759
|
async execute(_toolCallId, params) {
|
|
2624
2760
|
const p = params;
|
|
@@ -2700,15 +2836,15 @@ Best for:
|
|
|
2700
2836
|
name: "work_board",
|
|
2701
2837
|
label: "Work Board Import/Export",
|
|
2702
2838
|
description: "Export/import work-layer board snapshots and markdown. Outputs are marked as work-layer context and excluded from default memory extraction unless explicitly linked.",
|
|
2703
|
-
parameters:
|
|
2704
|
-
action:
|
|
2839
|
+
parameters: Type2.Object({
|
|
2840
|
+
action: Type2.String({
|
|
2705
2841
|
enum: ["export_markdown", "export_snapshot", "import_snapshot"],
|
|
2706
2842
|
description: "Board action to run."
|
|
2707
2843
|
}),
|
|
2708
|
-
projectId:
|
|
2709
|
-
snapshotJson:
|
|
2710
|
-
linkToMemory:
|
|
2711
|
-
|
|
2844
|
+
projectId: Type2.Optional(Type2.String({ description: "Optional project filter/id." })),
|
|
2845
|
+
snapshotJson: Type2.Optional(Type2.String({ description: "Snapshot JSON payload for import_snapshot." })),
|
|
2846
|
+
linkToMemory: Type2.Optional(
|
|
2847
|
+
Type2.Boolean({
|
|
2712
2848
|
description: "If true, wrap output as linkable work context so extraction can retain it as long-term memory."
|
|
2713
2849
|
})
|
|
2714
2850
|
)
|
|
@@ -2722,7 +2858,7 @@ Best for:
|
|
|
2722
2858
|
await new WorkStorage(orchestrator.config.memoryDir).ensureDirectories();
|
|
2723
2859
|
if (action === "export_markdown") {
|
|
2724
2860
|
const markdown = await exportWorkBoardMarkdown({ memoryDir: orchestrator.config.memoryDir, projectId });
|
|
2725
|
-
return
|
|
2861
|
+
return toolResult2(wrapWorkLayerContext(markdown, { linkToMemory }));
|
|
2726
2862
|
}
|
|
2727
2863
|
if (action === "export_snapshot") {
|
|
2728
2864
|
const snapshot = await exportWorkBoardSnapshot({ memoryDir: orchestrator.config.memoryDir, projectId });
|
|
@@ -2750,193 +2886,28 @@ Best for:
|
|
|
2750
2886
|
},
|
|
2751
2887
|
{ name: "work_board" }
|
|
2752
2888
|
);
|
|
2753
|
-
api
|
|
2754
|
-
{
|
|
2755
|
-
name: "shared_context_write_output",
|
|
2756
|
-
label: "Write Shared Agent Output",
|
|
2757
|
-
description: "Write an agent work product into the shared-context directory (v4.0). Other agents can read these files to coordinate without explicit message passing.",
|
|
2758
|
-
parameters: Type.Object({
|
|
2759
|
-
// Provenance is server-derived from the host runtime agent; a
|
|
2760
|
-
// mismatching value here is rejected, never used as the origin.
|
|
2761
|
-
agentId: Type.String({ description: "Agent ID producing this output; must match this host's runtime agent id when the host exposes one." }),
|
|
2762
|
-
title: Type.String({ description: "Short title for the output." }),
|
|
2763
|
-
content: Type.String({ description: "Markdown content to write." })
|
|
2764
|
-
}),
|
|
2765
|
-
async execute(_toolCallId, params) {
|
|
2766
|
-
const { agentId, title, content } = params;
|
|
2767
|
-
if (!orchestrator.sharedContext) {
|
|
2768
|
-
return toolResult(
|
|
2769
|
-
"Shared context is disabled. Enable `sharedContextEnabled: true` to use shared-context tools."
|
|
2770
|
-
);
|
|
2771
|
-
}
|
|
2772
|
-
try {
|
|
2773
|
-
const fp = await orchestrator.sharedContext.writeAgentOutput({
|
|
2774
|
-
title,
|
|
2775
|
-
content,
|
|
2776
|
-
...openClawToolWriteOrigin(hostRuntimeAgentId, agentId)
|
|
2777
|
-
});
|
|
2778
|
-
return toolResult(`Wrote shared agent output: ${fp}`);
|
|
2779
|
-
} catch (err) {
|
|
2780
|
-
return toolResult(`shared_context_write_output error: ${err instanceof Error ? err.message : String(err)}`);
|
|
2781
|
-
}
|
|
2782
|
-
}
|
|
2783
|
-
},
|
|
2784
|
-
{ name: "shared_context_write_output" }
|
|
2785
|
-
);
|
|
2786
|
-
api.registerTool(
|
|
2787
|
-
{
|
|
2788
|
-
name: "shared_feedback_record",
|
|
2789
|
-
label: "Record Shared Feedback",
|
|
2790
|
-
description: "Append an approval/rejection decision into shared-context feedback inbox (v4.0/v5.0). Intended to power compounding learning.",
|
|
2791
|
-
parameters: Type.Object({
|
|
2792
|
-
agent: Type.String({ description: "Agent name that produced the recommendation/output." }),
|
|
2793
|
-
decision: Type.String({
|
|
2794
|
-
enum: ["approved", "approved_with_feedback", "rejected"],
|
|
2795
|
-
description: "Decision outcome."
|
|
2796
|
-
}),
|
|
2797
|
-
reason: Type.String({ description: "Why the decision was made (short but specific)." }),
|
|
2798
|
-
date: Type.Optional(Type.String({ description: "ISO timestamp. Defaults to now." })),
|
|
2799
|
-
learning: Type.Optional(Type.String({ description: "Optional distilled learning/pattern." })),
|
|
2800
|
-
outcome: Type.Optional(Type.String({ description: "Optional downstream outcome (day-one supported; may be empty initially)." })),
|
|
2801
|
-
severity: Type.Optional(Type.String({
|
|
2802
|
-
enum: ["low", "medium", "high"],
|
|
2803
|
-
description: "Optional severity rating for the mistake/outcome."
|
|
2804
|
-
})),
|
|
2805
|
-
confidence: Type.Optional(Type.Number({ description: "Optional confidence score from 0 to 1." })),
|
|
2806
|
-
workflow: Type.Optional(Type.String({ description: "Optional workflow or playbook name associated with the feedback." })),
|
|
2807
|
-
tags: Type.Optional(Type.Array(Type.String(), { description: "Optional tags for rubric grouping and recall matching." })),
|
|
2808
|
-
evidenceWindowStart: Type.Optional(Type.String({ description: "Optional start timestamp for the evidence window." })),
|
|
2809
|
-
evidenceWindowEnd: Type.Optional(Type.String({ description: "Optional end timestamp for the evidence window." })),
|
|
2810
|
-
refs: Type.Optional(Type.Array(Type.String(), { description: "Optional references (URLs, IDs, filenames)." }))
|
|
2811
|
-
}),
|
|
2812
|
-
async execute(_toolCallId, params) {
|
|
2813
|
-
if (!orchestrator.sharedContext) {
|
|
2814
|
-
return toolResult(
|
|
2815
|
-
"Shared context is disabled. Enable `sharedContextEnabled: true` to record shared feedback."
|
|
2816
|
-
);
|
|
2817
|
-
}
|
|
2818
|
-
const p = params;
|
|
2819
|
-
const entry = {
|
|
2820
|
-
agent: String(p.agent ?? ""),
|
|
2821
|
-
decision: p.decision,
|
|
2822
|
-
reason: String(p.reason ?? ""),
|
|
2823
|
-
date: typeof p.date === "string" && p.date.length > 0 ? p.date : (/* @__PURE__ */ new Date()).toISOString(),
|
|
2824
|
-
learning: typeof p.learning === "string" ? p.learning : void 0,
|
|
2825
|
-
outcome: typeof p.outcome === "string" ? p.outcome : void 0,
|
|
2826
|
-
severity: p.severity === "low" || p.severity === "medium" || p.severity === "high" ? p.severity : void 0,
|
|
2827
|
-
confidence: typeof p.confidence === "number" && Number.isFinite(p.confidence) ? p.confidence : void 0,
|
|
2828
|
-
workflow: typeof p.workflow === "string" ? p.workflow : void 0,
|
|
2829
|
-
tags: Array.isArray(p.tags) ? p.tags.map(String) : void 0,
|
|
2830
|
-
evidenceWindowStart: typeof p.evidenceWindowStart === "string" ? p.evidenceWindowStart : void 0,
|
|
2831
|
-
evidenceWindowEnd: typeof p.evidenceWindowEnd === "string" ? p.evidenceWindowEnd : void 0,
|
|
2832
|
-
refs: Array.isArray(p.refs) ? p.refs.map(String) : void 0
|
|
2833
|
-
};
|
|
2834
|
-
await orchestrator.sharedContext.appendFeedback(entry);
|
|
2835
|
-
return toolResult("OK");
|
|
2836
|
-
}
|
|
2837
|
-
},
|
|
2838
|
-
{ name: "shared_feedback_record" }
|
|
2839
|
-
);
|
|
2840
|
-
api.registerTool(
|
|
2841
|
-
{
|
|
2842
|
-
name: "shared_priorities_append",
|
|
2843
|
-
label: "Append Priorities Inbox",
|
|
2844
|
-
description: "Append text into shared-context priorities inbox. A curator run should merge this into priorities.md.",
|
|
2845
|
-
parameters: Type.Object({
|
|
2846
|
-
agentId: Type.String({ description: "Agent ID appending priorities." }),
|
|
2847
|
-
text: Type.String({ description: "Priority notes to append (markdown)." })
|
|
2848
|
-
}),
|
|
2849
|
-
async execute(_toolCallId, params) {
|
|
2850
|
-
if (!orchestrator.sharedContext) {
|
|
2851
|
-
return toolResult(
|
|
2852
|
-
"Shared context is disabled. Enable `sharedContextEnabled: true` to write priorities inbox."
|
|
2853
|
-
);
|
|
2854
|
-
}
|
|
2855
|
-
const { agentId, text } = params;
|
|
2856
|
-
await orchestrator.sharedContext.appendPrioritiesInbox({ agentId, text });
|
|
2857
|
-
return toolResult("OK");
|
|
2858
|
-
}
|
|
2859
|
-
},
|
|
2860
|
-
{ name: "shared_priorities_append" }
|
|
2861
|
-
);
|
|
2862
|
-
api.registerTool(
|
|
2863
|
-
{
|
|
2864
|
-
name: "shared_context_cross_signals_run",
|
|
2865
|
-
label: "Run Cross-Signal Synthesis",
|
|
2866
|
-
description: "Generate today's shared-context cross-signal markdown + JSON artifacts on demand, without requiring a full roundtable curation pass.",
|
|
2867
|
-
parameters: Type.Object({
|
|
2868
|
-
date: Type.Optional(Type.String({ description: "YYYY-MM-DD. Defaults to today." }))
|
|
2869
|
-
}),
|
|
2870
|
-
async execute(_toolCallId, params) {
|
|
2871
|
-
if (!orchestrator.sharedContext) {
|
|
2872
|
-
return toolResult(
|
|
2873
|
-
"Shared context is disabled. Enable `sharedContextEnabled: true` to synthesize cross-signals."
|
|
2874
|
-
);
|
|
2875
|
-
}
|
|
2876
|
-
const { date } = params;
|
|
2877
|
-
const result = await orchestrator.sharedContext.synthesizeCrossSignals({ date });
|
|
2878
|
-
return toolResult(
|
|
2879
|
-
[
|
|
2880
|
-
`Cross-signals markdown: ${result.crossSignalsMarkdownPath}`,
|
|
2881
|
-
`Cross-signals JSON: ${result.crossSignalsPath}`,
|
|
2882
|
-
`Source outputs analyzed: ${result.report.sourceCount}`,
|
|
2883
|
-
`Feedback entries analyzed: ${result.report.feedbackCount}`,
|
|
2884
|
-
`Overlap count: ${result.overlapCount}`
|
|
2885
|
-
].join("\n")
|
|
2886
|
-
);
|
|
2887
|
-
}
|
|
2888
|
-
},
|
|
2889
|
-
{ name: "shared_context_cross_signals_run" }
|
|
2890
|
-
);
|
|
2891
|
-
api.registerTool(
|
|
2892
|
-
{
|
|
2893
|
-
name: "shared_context_curate_daily",
|
|
2894
|
-
label: "Curate Daily Roundtable",
|
|
2895
|
-
description: "Curator tool: generate today's roundtable summary in shared-context/roundtable (deterministic baseline).",
|
|
2896
|
-
parameters: Type.Object({
|
|
2897
|
-
date: Type.Optional(Type.String({ description: "YYYY-MM-DD. Defaults to today." }))
|
|
2898
|
-
}),
|
|
2899
|
-
async execute(_toolCallId, params) {
|
|
2900
|
-
if (!orchestrator.sharedContext) {
|
|
2901
|
-
return toolResult(
|
|
2902
|
-
"Shared context is disabled. Enable `sharedContextEnabled: true` to curate roundtables."
|
|
2903
|
-
);
|
|
2904
|
-
}
|
|
2905
|
-
const { date } = params;
|
|
2906
|
-
const result = await orchestrator.sharedContext.curateDaily({ date });
|
|
2907
|
-
return toolResult(
|
|
2908
|
-
[
|
|
2909
|
-
`Roundtable: ${result.roundtablePath}`,
|
|
2910
|
-
`Cross-signals markdown: ${result.crossSignalsMarkdownPath}`,
|
|
2911
|
-
`Cross-signals JSON: ${result.crossSignalsPath}`,
|
|
2912
|
-
`Overlap count: ${result.overlapCount}`
|
|
2913
|
-
].join("\n")
|
|
2914
|
-
);
|
|
2915
|
-
}
|
|
2916
|
-
},
|
|
2917
|
-
{ name: "shared_context_curate_daily" }
|
|
2918
|
-
);
|
|
2889
|
+
registerSharedContextTools(api, orchestrator, hostRuntimeAgentId);
|
|
2919
2890
|
api.registerTool(
|
|
2920
2891
|
{
|
|
2921
2892
|
name: "compounding_weekly_synthesize",
|
|
2922
2893
|
label: "Synthesize Weekly Learning",
|
|
2923
2894
|
description: "Generate weekly compounding outputs (v5.0): weekly markdown + JSON reports, stable mistake registry, and rubric artifacts. Designed to work from day one (writes even if no feedback exists yet).",
|
|
2924
|
-
parameters:
|
|
2925
|
-
weekId:
|
|
2926
|
-
|
|
2895
|
+
parameters: Type2.Object({
|
|
2896
|
+
weekId: Type2.Optional(
|
|
2897
|
+
Type2.String({
|
|
2927
2898
|
description: "ISO week ID like YYYY-Www. Omit to use current week."
|
|
2928
2899
|
})
|
|
2929
2900
|
)
|
|
2930
2901
|
}),
|
|
2931
2902
|
async execute(_toolCallId, params) {
|
|
2932
2903
|
if (!orchestrator.compounding) {
|
|
2933
|
-
return
|
|
2904
|
+
return toolResult2(
|
|
2934
2905
|
"Compounding engine is disabled. Enable `compoundingEnabled: true` to use this tool."
|
|
2935
2906
|
);
|
|
2936
2907
|
}
|
|
2937
2908
|
const { weekId } = params;
|
|
2938
2909
|
const res = await orchestrator.compounding.synthesizeWeekly({ weekId });
|
|
2939
|
-
return
|
|
2910
|
+
return toolResult2(
|
|
2940
2911
|
`OK
|
|
2941
2912
|
|
|
2942
2913
|
weekId: ${res.weekId}
|
|
@@ -2956,26 +2927,26 @@ promotionCandidates: ${res.promotionCandidateCount}`
|
|
|
2956
2927
|
name: "compounding_promote_candidate",
|
|
2957
2928
|
label: "Promote Compounding Candidate",
|
|
2958
2929
|
description: "Persist one advisory compounding promotion candidate into durable rule/principle memory. Never auto-promotes; this is an explicit operator action.",
|
|
2959
|
-
parameters:
|
|
2960
|
-
weekId:
|
|
2930
|
+
parameters: Type2.Object({
|
|
2931
|
+
weekId: Type2.String({
|
|
2961
2932
|
description: "ISO week ID like YYYY-Www matching the synthesized weekly artifact."
|
|
2962
2933
|
}),
|
|
2963
|
-
candidateId:
|
|
2934
|
+
candidateId: Type2.String({
|
|
2964
2935
|
description: "Promotion candidate id from the weekly compounding report or JSON artifact."
|
|
2965
2936
|
}),
|
|
2966
|
-
dryRun:
|
|
2937
|
+
dryRun: Type2.Optional(Type2.Boolean({
|
|
2967
2938
|
description: "If true, preview the promoted guidance without writing memory."
|
|
2968
2939
|
}))
|
|
2969
2940
|
}),
|
|
2970
2941
|
async execute(_toolCallId, params) {
|
|
2971
2942
|
if (!orchestrator.compounding) {
|
|
2972
|
-
return
|
|
2943
|
+
return toolResult2(
|
|
2973
2944
|
"Compounding engine is disabled. Enable `compoundingEnabled: true` to use this tool."
|
|
2974
2945
|
);
|
|
2975
2946
|
}
|
|
2976
2947
|
const { weekId, candidateId, dryRun } = params;
|
|
2977
2948
|
const result = await orchestrator.compounding.promoteCandidate({ weekId, candidateId, dryRun });
|
|
2978
|
-
return
|
|
2949
|
+
return toolResult2(JSON.stringify(result, null, 2));
|
|
2979
2950
|
}
|
|
2980
2951
|
},
|
|
2981
2952
|
{ name: "compounding_promote_candidate" }
|
|
@@ -2991,14 +2962,14 @@ Requires profilingEnabled: true in plugin config.
|
|
|
2991
2962
|
Shows per-step timing with parallel vs sequential structure, bottleneck identification, and aggregate stats.
|
|
2992
2963
|
|
|
2993
2964
|
Returns: Performance trace data with timing breakdown`,
|
|
2994
|
-
parameters:
|
|
2995
|
-
format:
|
|
2996
|
-
|
|
2965
|
+
parameters: Type2.Object({
|
|
2966
|
+
format: Type2.Optional(
|
|
2967
|
+
Type2.String({
|
|
2997
2968
|
description: 'Output format: "ascii" for human-readable or "json" for structured data'
|
|
2998
2969
|
})
|
|
2999
2970
|
),
|
|
3000
|
-
limit:
|
|
3001
|
-
|
|
2971
|
+
limit: Type2.Optional(
|
|
2972
|
+
Type2.Number({
|
|
3002
2973
|
description: "Number of recent traces to include (1-20, default 5)",
|
|
3003
2974
|
minimum: 1,
|
|
3004
2975
|
maximum: 20
|
|
@@ -3008,7 +2979,7 @@ Returns: Performance trace data with timing breakdown`,
|
|
|
3008
2979
|
async execute(_toolCallId, params) {
|
|
3009
2980
|
const profiler = orchestrator.profiler;
|
|
3010
2981
|
if (!profiler.isEnabled) {
|
|
3011
|
-
return
|
|
2982
|
+
return toolResult2(
|
|
3012
2983
|
"Profiling is disabled. Set profilingEnabled: true in your plugin config to enable."
|
|
3013
2984
|
);
|
|
3014
2985
|
}
|
|
@@ -3018,7 +2989,7 @@ Returns: Performance trace data with timing breakdown`,
|
|
|
3018
2989
|
const stats = profiler.getStats();
|
|
3019
2990
|
const bottleneck = profiler.identifyBottleneck();
|
|
3020
2991
|
if (format === "json") {
|
|
3021
|
-
return
|
|
2992
|
+
return toolResult2(JSON.stringify({ traces, stats, bottleneck }, null, 2));
|
|
3022
2993
|
}
|
|
3023
2994
|
const lines = [];
|
|
3024
2995
|
lines.push("Engram Profiling Report");
|
|
@@ -3052,7 +3023,7 @@ Returns: Performance trace data with timing breakdown`,
|
|
|
3052
3023
|
lines.push("");
|
|
3053
3024
|
}
|
|
3054
3025
|
}
|
|
3055
|
-
return
|
|
3026
|
+
return toolResult2(lines.join("\n"));
|
|
3056
3027
|
}
|
|
3057
3028
|
},
|
|
3058
3029
|
{ name: "remnic_profiling_report" }
|
|
@@ -3062,14 +3033,14 @@ Returns: Performance trace data with timing breakdown`,
|
|
|
3062
3033
|
name: "engram_profiling_report",
|
|
3063
3034
|
label: "Profiling Report",
|
|
3064
3035
|
description: `Legacy alias for remnic_profiling_report.`,
|
|
3065
|
-
parameters:
|
|
3066
|
-
format:
|
|
3067
|
-
|
|
3036
|
+
parameters: Type2.Object({
|
|
3037
|
+
format: Type2.Optional(
|
|
3038
|
+
Type2.String({
|
|
3068
3039
|
description: 'Output format: "ascii" for human-readable or "json" for structured data'
|
|
3069
3040
|
})
|
|
3070
3041
|
),
|
|
3071
|
-
limit:
|
|
3072
|
-
|
|
3042
|
+
limit: Type2.Optional(
|
|
3043
|
+
Type2.Number({
|
|
3073
3044
|
description: "Number of recent traces to include (1-20, default 5)",
|
|
3074
3045
|
minimum: 1,
|
|
3075
3046
|
maximum: 20
|
|
@@ -3079,7 +3050,7 @@ Returns: Performance trace data with timing breakdown`,
|
|
|
3079
3050
|
async execute(_toolCallId, params) {
|
|
3080
3051
|
const profiler = orchestrator.profiler;
|
|
3081
3052
|
if (!profiler.isEnabled) {
|
|
3082
|
-
return
|
|
3053
|
+
return toolResult2(
|
|
3083
3054
|
"Profiling is disabled. Set profilingEnabled: true in your plugin config to enable."
|
|
3084
3055
|
);
|
|
3085
3056
|
}
|
|
@@ -3089,7 +3060,7 @@ Returns: Performance trace data with timing breakdown`,
|
|
|
3089
3060
|
const stats = profiler.getStats();
|
|
3090
3061
|
const bottleneck = profiler.identifyBottleneck();
|
|
3091
3062
|
if (format === "json") {
|
|
3092
|
-
return
|
|
3063
|
+
return toolResult2(JSON.stringify({ traces, stats, bottleneck }, null, 2));
|
|
3093
3064
|
}
|
|
3094
3065
|
const lines = [];
|
|
3095
3066
|
lines.push("Engram Profiling Report");
|
|
@@ -3123,7 +3094,7 @@ Returns: Performance trace data with timing breakdown`,
|
|
|
3123
3094
|
lines.push("");
|
|
3124
3095
|
}
|
|
3125
3096
|
}
|
|
3126
|
-
return
|
|
3097
|
+
return toolResult2(lines.join("\n"));
|
|
3127
3098
|
}
|
|
3128
3099
|
},
|
|
3129
3100
|
{ name: "engram_profiling_report" }
|
|
@@ -3138,16 +3109,8 @@ import {
|
|
|
3138
3109
|
FallbackLlmClient as FallbackLlmClient2,
|
|
3139
3110
|
fallbackLlmRuntimeContextFromConfig as fallbackLlmRuntimeContextFromConfig2
|
|
3140
3111
|
} from "@remnic/core/fallback-llm";
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
var objective_state_exports = {};
|
|
3144
|
-
__reExport(objective_state_exports, objective_state_star);
|
|
3145
|
-
import * as objective_state_star from "@remnic/core/objective-state";
|
|
3146
|
-
|
|
3147
|
-
// ../../src/objective-state-writers.ts
|
|
3148
|
-
var objective_state_writers_exports = {};
|
|
3149
|
-
__reExport(objective_state_writers_exports, objective_state_writers_star);
|
|
3150
|
-
import * as objective_state_writers_star from "@remnic/core/objective-state-writers";
|
|
3112
|
+
import { objectiveStateStoreOverrideForNamespace } from "@remnic/core/objective-state";
|
|
3113
|
+
import { recordObjectiveStateSnapshotsFromAgentMessages } from "@remnic/core/objective-state-writers";
|
|
3151
3114
|
|
|
3152
3115
|
// ../../src/qmd-availability-probe.ts
|
|
3153
3116
|
async function probeQmdAvailability(host) {
|
|
@@ -3196,27 +3159,14 @@ var EngramAccessService = class extends CoreEngramAccessService {
|
|
|
3196
3159
|
}
|
|
3197
3160
|
};
|
|
3198
3161
|
|
|
3199
|
-
// ../../src/access-http.ts
|
|
3200
|
-
var access_http_exports = {};
|
|
3201
|
-
__reExport(access_http_exports, access_http_star);
|
|
3202
|
-
import * as access_http_star from "@remnic/core/access-http";
|
|
3203
|
-
|
|
3204
3162
|
// ../../src/index.ts
|
|
3163
|
+
import { EngramAccessHttpServer } from "@remnic/core/access-http";
|
|
3205
3164
|
import path11 from "path";
|
|
3206
3165
|
import os from "os";
|
|
3207
|
-
|
|
3208
|
-
// ../../src/opik-exporter.ts
|
|
3209
|
-
import { createOpikExporter, OpikExporter } from "@remnic/core/opik-exporter";
|
|
3210
|
-
|
|
3211
|
-
// ../../src/index.ts
|
|
3166
|
+
import { createOpikExporter } from "@remnic/core/opik-exporter";
|
|
3212
3167
|
import { readEnvVar, resolveHomeDir as resolveHomeDir3 } from "@remnic/core/runtime/env";
|
|
3213
3168
|
import { displayErrorDetail as displayErrorDetail2 } from "@remnic/core/runtime/better-sqlite";
|
|
3214
|
-
|
|
3215
|
-
// ../../src/migrate/from-engram.ts
|
|
3216
|
-
import {
|
|
3217
|
-
migrateFromEngram,
|
|
3218
|
-
rollbackFromEngramMigration
|
|
3219
|
-
} from "@remnic/core/migrate/from-engram";
|
|
3169
|
+
import { migrateFromEngram } from "@remnic/core/migrate/from-engram";
|
|
3220
3170
|
|
|
3221
3171
|
// ../../src/user-message-cleaning.ts
|
|
3222
3172
|
import { cleanUserMessageWithPattern } from "@remnic/core/user-message-cleaning";
|
|
@@ -3403,17 +3353,17 @@ import {
|
|
|
3403
3353
|
} from "@remnic/core";
|
|
3404
3354
|
|
|
3405
3355
|
// src/openclaw-tools/shapes.ts
|
|
3406
|
-
import { Type as
|
|
3407
|
-
var MemorySearchInputSchema =
|
|
3408
|
-
query:
|
|
3409
|
-
limit:
|
|
3410
|
-
sessionKey:
|
|
3411
|
-
filters:
|
|
3356
|
+
import { Type as Type3 } from "@sinclair/typebox";
|
|
3357
|
+
var MemorySearchInputSchema = Type3.Object({
|
|
3358
|
+
query: Type3.String(),
|
|
3359
|
+
limit: Type3.Optional(Type3.Number({ minimum: 1, maximum: 50 })),
|
|
3360
|
+
sessionKey: Type3.Optional(Type3.String()),
|
|
3361
|
+
filters: Type3.Optional(Type3.Record(Type3.String(), Type3.Unknown()))
|
|
3412
3362
|
});
|
|
3413
|
-
var MemoryGetInputSchema =
|
|
3414
|
-
id:
|
|
3415
|
-
sessionKey:
|
|
3416
|
-
namespace:
|
|
3363
|
+
var MemoryGetInputSchema = Type3.Object({
|
|
3364
|
+
id: Type3.String(),
|
|
3365
|
+
sessionKey: Type3.Optional(Type3.String()),
|
|
3366
|
+
namespace: Type3.Optional(Type3.String())
|
|
3417
3367
|
});
|
|
3418
3368
|
|
|
3419
3369
|
// src/openclaw-tools/tool-json-result.ts
|
|
@@ -9263,7 +9213,7 @@ async function loadOpenClawProviderAuthRuntimeModule() {
|
|
|
9263
9213
|
if (typeof mod.resolveApiKeyForProvider === "function" || typeof mod.getRuntimeAuthForModel === "function") {
|
|
9264
9214
|
providerAuthRuntimeModule = mod;
|
|
9265
9215
|
providerAuthRuntimeLoaded = true;
|
|
9266
|
-
|
|
9216
|
+
log8.debug("loaded OpenClaw provider auth runtime module");
|
|
9267
9217
|
return providerAuthRuntimeModule;
|
|
9268
9218
|
}
|
|
9269
9219
|
} catch {
|
|
@@ -9272,7 +9222,7 @@ async function loadOpenClawProviderAuthRuntimeModule() {
|
|
|
9272
9222
|
} catch {
|
|
9273
9223
|
}
|
|
9274
9224
|
providerAuthRuntimeNextRetryAt = Date.now() + SECRET_REF_RESOLVER_RETRY_BACKOFF_MS;
|
|
9275
|
-
|
|
9225
|
+
log8.debug(
|
|
9276
9226
|
`OpenClaw provider auth runtime not available \u2014 will retry after ${SECRET_REF_RESOLVER_RETRY_BACKOFF_MS / 1e3}s`
|
|
9277
9227
|
);
|
|
9278
9228
|
return null;
|
|
@@ -9311,7 +9261,7 @@ async function loadOpenClawSecretRefResolver() {
|
|
|
9311
9261
|
if (typeof fn === "function") {
|
|
9312
9262
|
secretRefResolver = fn;
|
|
9313
9263
|
secretRefResolverLoaded = true;
|
|
9314
|
-
|
|
9264
|
+
log8.debug(
|
|
9315
9265
|
`loaded OpenClaw SecretRef resolver "${exportName}" from ${prefix}*.js`
|
|
9316
9266
|
);
|
|
9317
9267
|
return secretRefResolver;
|
|
@@ -9324,7 +9274,7 @@ async function loadOpenClawSecretRefResolver() {
|
|
|
9324
9274
|
} catch {
|
|
9325
9275
|
}
|
|
9326
9276
|
secretRefResolverNextRetryAt = Date.now() + SECRET_REF_RESOLVER_RETRY_BACKOFF_MS;
|
|
9327
|
-
|
|
9277
|
+
log8.debug(
|
|
9328
9278
|
`OpenClaw SecretRef resolver not available \u2014 will retry after ${SECRET_REF_RESOLVER_RETRY_BACKOFF_MS / 1e3}s`
|
|
9329
9279
|
);
|
|
9330
9280
|
return null;
|
|
@@ -9367,7 +9317,7 @@ function loadPluginEntryFromFile(pluginId) {
|
|
|
9367
9317
|
const config = JSON.parse(content);
|
|
9368
9318
|
return resolveRemnicPluginEntry(config, pluginId);
|
|
9369
9319
|
} catch (err) {
|
|
9370
|
-
|
|
9320
|
+
log8.warn(`Failed to load config from file: ${err}`);
|
|
9371
9321
|
return void 0;
|
|
9372
9322
|
}
|
|
9373
9323
|
}
|
|
@@ -9385,7 +9335,7 @@ function loadRawConfigFromFile() {
|
|
|
9385
9335
|
const config = JSON.parse(content);
|
|
9386
9336
|
return config && typeof config === "object" ? config : void 0;
|
|
9387
9337
|
} catch (err) {
|
|
9388
|
-
|
|
9338
|
+
log8.warn(`Failed to load raw OpenClaw config from file: ${err}`);
|
|
9389
9339
|
return void 0;
|
|
9390
9340
|
}
|
|
9391
9341
|
}
|
|
@@ -9400,7 +9350,7 @@ async function maybeRegisterLiveConnectorCron(orchestrator) {
|
|
|
9400
9350
|
const jobsPath = path11.join(resolveHomeDir3(), ".openclaw", "cron", "jobs.json");
|
|
9401
9351
|
try {
|
|
9402
9352
|
if (!fileExistsNow(jobsPath)) {
|
|
9403
|
-
|
|
9353
|
+
log8.debug("live connectors cron: jobs.json not found, skipping auto-register");
|
|
9404
9354
|
return;
|
|
9405
9355
|
}
|
|
9406
9356
|
const result = await ensureLiveConnectorCron(jobsPath, {
|
|
@@ -9408,12 +9358,12 @@ async function maybeRegisterLiveConnectorCron(orchestrator) {
|
|
|
9408
9358
|
connectors: orchestrator.config.connectors
|
|
9409
9359
|
});
|
|
9410
9360
|
if (result.created || result.updated) {
|
|
9411
|
-
|
|
9361
|
+
log8.info(`live connectors cron ${result.created ? "auto-registered" : "reconciled"} (${result.jobId})`);
|
|
9412
9362
|
} else {
|
|
9413
|
-
|
|
9363
|
+
log8.debug("live connectors cron already exists, skipping auto-register");
|
|
9414
9364
|
}
|
|
9415
9365
|
} catch (err) {
|
|
9416
|
-
|
|
9366
|
+
log8.debug(`live connectors cron auto-register error: ${err}`);
|
|
9417
9367
|
}
|
|
9418
9368
|
}
|
|
9419
9369
|
function isBundledActiveMemoryEnabledForAgent(runtimeConfig, fileBackedRuntimeConfig, agentId) {
|
|
@@ -9582,13 +9532,13 @@ function registerOpenClawHostEmbeddingProvider(params) {
|
|
|
9582
9532
|
}).then((result) => {
|
|
9583
9533
|
providerInstance = result && typeof result === "object" ? result.provider ?? null : null;
|
|
9584
9534
|
if (!providerInstance) {
|
|
9585
|
-
|
|
9535
|
+
log8.debug(
|
|
9586
9536
|
`OpenClaw host embedding provider ${selected.adapter.id} did not create a provider; using Remnic fallback embeddings`
|
|
9587
9537
|
);
|
|
9588
9538
|
}
|
|
9589
9539
|
return providerInstance;
|
|
9590
9540
|
}).catch((error) => {
|
|
9591
|
-
|
|
9541
|
+
log8.debug(
|
|
9592
9542
|
`OpenClaw host embedding provider ${selected.adapter.id} unavailable: ${error}`
|
|
9593
9543
|
);
|
|
9594
9544
|
return null;
|
|
@@ -9620,7 +9570,7 @@ function registerOpenClawHostEmbeddingProvider(params) {
|
|
|
9620
9570
|
}
|
|
9621
9571
|
};
|
|
9622
9572
|
const unregister = registerHostEmbeddingProvider(cfg.memoryDir, hostProvider);
|
|
9623
|
-
|
|
9573
|
+
log8.info(
|
|
9624
9574
|
`registered OpenClaw host embedding provider bridge (${selected.adapter.id}) for ${serviceId}`
|
|
9625
9575
|
);
|
|
9626
9576
|
return unregister;
|
|
@@ -9773,13 +9723,13 @@ var pluginDefinition = {
|
|
|
9773
9723
|
const registerThis = typeof this === "object" && this !== null ? this : void 0;
|
|
9774
9724
|
const serviceId = typeof registerThis?.id === "string" && registerThis.id.trim().length > 0 ? registerThis.id : REMNIC_OPENCLAW_PLUGIN_ID;
|
|
9775
9725
|
const keys = buildServiceKeys(serviceId);
|
|
9776
|
-
|
|
9726
|
+
initLogger(api.logger, false);
|
|
9777
9727
|
sdkCaps = detectSdkCapabilities(api);
|
|
9778
|
-
|
|
9728
|
+
log8.info(
|
|
9779
9729
|
`SDK detection: version=${sdkCaps.sdkVersion}, beforePromptBuild=${sdkCaps.hasBeforePromptBuild}, memoryPromptSection=${sdkCaps.hasRegisterMemoryPromptSection}, memoryCapability=${sdkCaps.hasRegisterMemoryCapability}, typedHooks=${sdkCaps.hasTypedHooks}`
|
|
9780
9730
|
);
|
|
9781
9731
|
if (isNonRuntimeRegistrationMode(sdkCaps.registrationMode)) {
|
|
9782
|
-
|
|
9732
|
+
log8.info(
|
|
9783
9733
|
`registrationMode=${sdkCaps.registrationMode} \u2014 skipping runtime initialization`
|
|
9784
9734
|
);
|
|
9785
9735
|
return;
|
|
@@ -9788,9 +9738,9 @@ var pluginDefinition = {
|
|
|
9788
9738
|
if (!disableRegisterMigration) {
|
|
9789
9739
|
const migrationPromise = globalThis[ENGRAM_MIGRATION_PROMISE] ??= migrateFromEngram({
|
|
9790
9740
|
quiet: true,
|
|
9791
|
-
logger: (message) =>
|
|
9741
|
+
logger: (message) => log8.info(message)
|
|
9792
9742
|
}).catch((error) => {
|
|
9793
|
-
|
|
9743
|
+
log8.warn(`register migration failed: ${error}`);
|
|
9794
9744
|
});
|
|
9795
9745
|
void migrationPromise;
|
|
9796
9746
|
}
|
|
@@ -9801,7 +9751,7 @@ var pluginDefinition = {
|
|
|
9801
9751
|
...fileConfig,
|
|
9802
9752
|
...api.pluginConfig
|
|
9803
9753
|
};
|
|
9804
|
-
const cfg =
|
|
9754
|
+
const cfg = parseConfig(
|
|
9805
9755
|
{
|
|
9806
9756
|
...rawPluginConfig,
|
|
9807
9757
|
gatewayConfig: api.config
|
|
@@ -9823,11 +9773,11 @@ var pluginDefinition = {
|
|
|
9823
9773
|
);
|
|
9824
9774
|
cfg.providerApiKeyResolver = resolveOpenClawProviderApiKey;
|
|
9825
9775
|
cfg.runtimeAuthForModelResolver = getOpenClawRuntimeAuthForModel;
|
|
9826
|
-
|
|
9827
|
-
|
|
9776
|
+
initLogger(api.logger, cfg.debug);
|
|
9777
|
+
log8.info(
|
|
9828
9778
|
`initialized (debug=${cfg.debug}, qmdEnabled=${cfg.qmdEnabled}, transcriptEnabled=${cfg.transcriptEnabled}, hourlySummariesEnabled=${cfg.hourlySummariesEnabled})`
|
|
9829
9779
|
);
|
|
9830
|
-
|
|
9780
|
+
log8.debug(
|
|
9831
9781
|
`init llm routing (modelSource=${cfg.modelSource}, localLlmEnabled=${cfg.localLlmEnabled}${cfg.localLlmFastEnabled ? `, fastLlm=${cfg.localLlmFastModel || "(primary)"}` : ""})`
|
|
9832
9782
|
);
|
|
9833
9783
|
const fileBackedRawRuntimeConfig = loadRawConfigFromFile();
|
|
@@ -9841,7 +9791,7 @@ var pluginDefinition = {
|
|
|
9841
9791
|
});
|
|
9842
9792
|
const passiveMode = slotValidationMode === "passive";
|
|
9843
9793
|
if (passiveMode) {
|
|
9844
|
-
|
|
9794
|
+
log8.info(
|
|
9845
9795
|
`[remnic] memory slot not assigned to ${serviceId}; running passively`
|
|
9846
9796
|
);
|
|
9847
9797
|
}
|
|
@@ -9923,14 +9873,14 @@ var pluginDefinition = {
|
|
|
9923
9873
|
}
|
|
9924
9874
|
const hookApis = globalThis[keys.HOOK_APIS] ??= /* @__PURE__ */ new WeakSet();
|
|
9925
9875
|
if (hookApis.has(api)) {
|
|
9926
|
-
|
|
9876
|
+
log8.debug(
|
|
9927
9877
|
"register: this api already has hooks bound \u2014 skipping duplicate hook registration"
|
|
9928
9878
|
);
|
|
9929
9879
|
return;
|
|
9930
9880
|
}
|
|
9931
9881
|
hookApis.add(api);
|
|
9932
9882
|
if (!isFirstRegistration) {
|
|
9933
|
-
|
|
9883
|
+
log8.debug(
|
|
9934
9884
|
"register called again (new registry); re-registering hooks with shared orchestrator"
|
|
9935
9885
|
);
|
|
9936
9886
|
}
|
|
@@ -9951,7 +9901,7 @@ var pluginDefinition = {
|
|
|
9951
9901
|
};
|
|
9952
9902
|
const authTokensFromSecretRef = () => accessHttpAuthState.resolvedSecretRefAuthToken ? [accessHttpAuthState.resolvedSecretRefAuthToken] : [];
|
|
9953
9903
|
const existingAccessHttpServer = globalThis[keys.ACCESS_HTTP_SERVER];
|
|
9954
|
-
const accessHttpServer = existingAccessHttpServer && existingAccessHttpServer ? existingAccessHttpServer : new
|
|
9904
|
+
const accessHttpServer = existingAccessHttpServer && existingAccessHttpServer ? existingAccessHttpServer : new EngramAccessHttpServer({
|
|
9955
9905
|
service: accessService,
|
|
9956
9906
|
host: cfg.agentAccessHttp.host,
|
|
9957
9907
|
port: cfg.agentAccessHttp.port,
|
|
@@ -10014,7 +9964,7 @@ var pluginDefinition = {
|
|
|
10014
9964
|
}
|
|
10015
9965
|
const remainingMs = Math.max(0, deadlineMs - Date.now());
|
|
10016
9966
|
if (remainingMs === 0) {
|
|
10017
|
-
|
|
9967
|
+
log8.warn(
|
|
10018
9968
|
`OpenClaw flush-plan processing timed out before queue wait for ${reason}`
|
|
10019
9969
|
);
|
|
10020
9970
|
return Promise.resolve();
|
|
@@ -10024,7 +9974,7 @@ var pluginDefinition = {
|
|
|
10024
9974
|
task,
|
|
10025
9975
|
new Promise((resolve) => {
|
|
10026
9976
|
timeout = setTimeout(() => {
|
|
10027
|
-
|
|
9977
|
+
log8.warn(
|
|
10028
9978
|
`OpenClaw flush-plan processing timed out while waiting for ${reason}; current drain remains fenced until it settles`
|
|
10029
9979
|
);
|
|
10030
9980
|
resolve();
|
|
@@ -10036,7 +9986,7 @@ var pluginDefinition = {
|
|
|
10036
9986
|
}
|
|
10037
9987
|
async function runOpenClawFlushPlanProcessing(reason, workspaceRoot, deadlineMs) {
|
|
10038
9988
|
if (typeof deadlineMs === "number" && Date.now() >= deadlineMs) {
|
|
10039
|
-
|
|
9989
|
+
log8.warn(
|
|
10040
9990
|
`OpenClaw flush-plan processing timed out before starting for ${reason}`
|
|
10041
9991
|
);
|
|
10042
9992
|
return;
|
|
@@ -10048,26 +9998,26 @@ var pluginDefinition = {
|
|
|
10048
9998
|
serviceId,
|
|
10049
9999
|
ingestor: orchestrator,
|
|
10050
10000
|
logger: {
|
|
10051
|
-
debug: (message) =>
|
|
10052
|
-
info: (message) =>
|
|
10053
|
-
warn: (message) =>
|
|
10001
|
+
debug: (message) => log8.debug(message),
|
|
10002
|
+
info: (message) => log8.info(message),
|
|
10003
|
+
warn: (message) => log8.warn(message)
|
|
10054
10004
|
},
|
|
10055
10005
|
reason,
|
|
10056
10006
|
deadlineMs,
|
|
10057
10007
|
maxTurnChars: cfg.extractionMaxTurnChars
|
|
10058
10008
|
});
|
|
10059
10009
|
if (result.status === "processed" || result.status === "processed_preserved_tail" || result.status === "processed_marker_recovered" || result.status === "processed_marker_recovered_tail" || result.status === "processed_cleanup_deferred") {
|
|
10060
|
-
|
|
10010
|
+
log8.info(
|
|
10061
10011
|
`OpenClaw flush-plan ${result.status}: ${result.bytesProcessed ?? 0} bytes` + (result.preservedBytes ? ` (${result.preservedBytes} bytes preserved)` : "")
|
|
10062
10012
|
);
|
|
10063
10013
|
} else if (result.status === "skipped") {
|
|
10064
|
-
|
|
10014
|
+
log8.warn(
|
|
10065
10015
|
`OpenClaw flush-plan processing skipped: ${result.reason ?? "unknown reason"}`
|
|
10066
10016
|
);
|
|
10067
10017
|
}
|
|
10068
10018
|
} catch (error) {
|
|
10069
10019
|
const detail = displayErrorDetail2(error) || "unknown error";
|
|
10070
|
-
|
|
10020
|
+
log8.warn(`OpenClaw flush-plan processing failed: ${detail}`);
|
|
10071
10021
|
}
|
|
10072
10022
|
}
|
|
10073
10023
|
async function queueOpenClawFlushPlanProcessing(reason, runtimeWorkspaceDir, options = {}) {
|
|
@@ -10148,7 +10098,7 @@ var pluginDefinition = {
|
|
|
10148
10098
|
});
|
|
10149
10099
|
},
|
|
10150
10100
|
logger: {
|
|
10151
|
-
debug: (message) =>
|
|
10101
|
+
debug: (message) => log8.debug(message)
|
|
10152
10102
|
}
|
|
10153
10103
|
});
|
|
10154
10104
|
}
|
|
@@ -10160,7 +10110,7 @@ var pluginDefinition = {
|
|
|
10160
10110
|
if (!cfg.dreaming.enabled) return;
|
|
10161
10111
|
const route = resolveDreamNarrativeRoute(cfg, !!dreamNarrativeClient);
|
|
10162
10112
|
if (route.kind === "skip") {
|
|
10163
|
-
|
|
10113
|
+
log8.debug(
|
|
10164
10114
|
"dreaming narrative skipped: no LLM available (set openaiApiKey or use modelSource=gateway)"
|
|
10165
10115
|
);
|
|
10166
10116
|
return;
|
|
@@ -10191,7 +10141,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10191
10141
|
fallbackLlmRuntimeContextFromConfig2(cfg)
|
|
10192
10142
|
);
|
|
10193
10143
|
if (!route.hasExplicitModel && !llm.isAvailable(route.options)) {
|
|
10194
|
-
|
|
10144
|
+
log8.debug(
|
|
10195
10145
|
"dreaming narrative skipped: no gateway model configured (set dreaming.narrativeModel or taskModelChain)"
|
|
10196
10146
|
);
|
|
10197
10147
|
return;
|
|
@@ -10215,7 +10165,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10215
10165
|
rawNarrative = typeof response.output_text === "string" ? response.output_text : JSON.stringify(response.output_text ?? "");
|
|
10216
10166
|
}
|
|
10217
10167
|
} catch (error) {
|
|
10218
|
-
|
|
10168
|
+
log8.warn(`dreaming narrative generation failed: ${String(error)}`);
|
|
10219
10169
|
return;
|
|
10220
10170
|
}
|
|
10221
10171
|
const parsed = parseDreamNarrativeResponse(
|
|
@@ -10235,7 +10185,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10235
10185
|
recallAuditDir,
|
|
10236
10186
|
cfg.recallTranscriptRetentionDays
|
|
10237
10187
|
).catch((error) => {
|
|
10238
|
-
|
|
10188
|
+
log8.debug(`recall audit prune failed: ${String(error)}`);
|
|
10239
10189
|
});
|
|
10240
10190
|
const sessionCommandDescriptors = buildSessionCommandDescriptors(serviceId, {
|
|
10241
10191
|
toggles: sessionToggleStore,
|
|
@@ -10682,7 +10632,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10682
10632
|
return;
|
|
10683
10633
|
}
|
|
10684
10634
|
if (typeof orchestrator.flushSession !== "function") {
|
|
10685
|
-
|
|
10635
|
+
log8.warn("codexCompat provider-switch flush unavailable; preserving binding");
|
|
10686
10636
|
return;
|
|
10687
10637
|
}
|
|
10688
10638
|
try {
|
|
@@ -10692,7 +10642,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10692
10642
|
});
|
|
10693
10643
|
forgetCodexThread2(sessionKey, sessionIdentity.previousCodexThreadId);
|
|
10694
10644
|
} catch (error) {
|
|
10695
|
-
|
|
10645
|
+
log8.warn(`codexCompat provider-switch flush failed: ${String(error)}`);
|
|
10696
10646
|
}
|
|
10697
10647
|
}
|
|
10698
10648
|
async function flushAndForgetRememberedCodexThreadOnMetadataLoss(sessionKey, sessionIdentity) {
|
|
@@ -10710,7 +10660,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10710
10660
|
return;
|
|
10711
10661
|
}
|
|
10712
10662
|
if (typeof orchestrator.flushSession !== "function") {
|
|
10713
|
-
|
|
10663
|
+
log8.warn("codexCompat metadata-loss flush unavailable; preserving binding");
|
|
10714
10664
|
return;
|
|
10715
10665
|
}
|
|
10716
10666
|
try {
|
|
@@ -10720,7 +10670,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10720
10670
|
});
|
|
10721
10671
|
forgetCodexThread2(sessionKey, rememberedThreadId);
|
|
10722
10672
|
} catch (error) {
|
|
10723
|
-
|
|
10673
|
+
log8.warn(`codexCompat metadata-loss flush failed: ${String(error)}`);
|
|
10724
10674
|
}
|
|
10725
10675
|
}
|
|
10726
10676
|
async function resolveBeforeResetBufferKeys(sessionKey, sessionIdentity) {
|
|
@@ -10848,7 +10798,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10848
10798
|
rememberCodexThread2(sessionKey, sessionIdentity.providerThreadId);
|
|
10849
10799
|
if (sessionIdentity.isCodex && !codexCompactionModeLogged) {
|
|
10850
10800
|
const mode = cfg.codexCompat.compactionFlushMode === "auto" ? "auto compaction flush mode (signal + heuristic)" : `${cfg.codexCompat.compactionFlushMode} compaction flush mode`;
|
|
10851
|
-
|
|
10801
|
+
log8.info(
|
|
10852
10802
|
`codexCompat enabled: using ${mode} for bundled Codex sessions`
|
|
10853
10803
|
);
|
|
10854
10804
|
codexCompactionModeLogged = true;
|
|
@@ -10872,12 +10822,12 @@ Keep the reflection grounded in the evidence below.
|
|
|
10872
10822
|
});
|
|
10873
10823
|
clearCodexCompatCaches2(sessionKey, sessionIdentity.providerThreadId);
|
|
10874
10824
|
rememberCodexThread2(sessionKey, sessionIdentity.providerThreadId);
|
|
10875
|
-
|
|
10825
|
+
log8.info(
|
|
10876
10826
|
`codexCompat heuristic flush: thread=${sessionIdentity.providerThreadId} messages ${previousCount} -> ${currentCount}`
|
|
10877
10827
|
);
|
|
10878
10828
|
} catch (error) {
|
|
10879
10829
|
shouldPersistMessageCount = false;
|
|
10880
|
-
|
|
10830
|
+
log8.warn(`codexCompat heuristic flush failed: ${String(error)}`);
|
|
10881
10831
|
}
|
|
10882
10832
|
}
|
|
10883
10833
|
if (typeof currentCount === "number" && shouldPersistMessageCount && codexBaselineKey) {
|
|
@@ -10888,10 +10838,10 @@ Keep the reflection grounded in the evidence below.
|
|
|
10888
10838
|
const runtimeAgent = ctx.runtime?.agent;
|
|
10889
10839
|
const agentId = ctx?.agentId ?? runtimeAgent?.id ?? "main";
|
|
10890
10840
|
const verboseRequested = cfg.verboseRecallVisibility !== false && isVerboseRecallRequested(event, ctx);
|
|
10891
|
-
|
|
10841
|
+
log8.debug(
|
|
10892
10842
|
`${hookLabel}: sessionKey=${sessionKey}, promptLen=${prompt.length}`
|
|
10893
10843
|
);
|
|
10894
|
-
|
|
10844
|
+
log8.debug(
|
|
10895
10845
|
`${hookLabel}: cronRecallMode=${cfg.cronRecallMode}, allowlistCount=${cfg.cronRecallAllowlist.length}`
|
|
10896
10846
|
);
|
|
10897
10847
|
if (sessionKey.includes(":cron:") && cfg.cronRecallMode === "allowlist") {
|
|
@@ -10899,12 +10849,12 @@ Keep the reflection grounded in the evidence below.
|
|
|
10899
10849
|
const re = wildcardToRegExp(pattern);
|
|
10900
10850
|
return re.test(sessionKey);
|
|
10901
10851
|
});
|
|
10902
|
-
|
|
10852
|
+
log8.debug(
|
|
10903
10853
|
`${hookLabel}: cron allowlist match=${matchedPattern ? "yes" : "no"} pattern=${matchedPattern ?? "none"}`
|
|
10904
10854
|
);
|
|
10905
10855
|
}
|
|
10906
10856
|
if (shouldSkipRecallForSession(sessionKey, cfg)) {
|
|
10907
|
-
|
|
10857
|
+
log8.debug(
|
|
10908
10858
|
`${hookLabel}: skip recall for cron session ${sessionKey} (mode=${cfg.cronRecallMode})`
|
|
10909
10859
|
);
|
|
10910
10860
|
return;
|
|
@@ -10928,7 +10878,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10928
10878
|
injectedChars: 0,
|
|
10929
10879
|
toggleState: auditToggleState
|
|
10930
10880
|
}).catch((error) => {
|
|
10931
|
-
|
|
10881
|
+
log8.debug(`recall audit append failed: ${String(error)}`);
|
|
10932
10882
|
});
|
|
10933
10883
|
}
|
|
10934
10884
|
if (!verboseRequested) return;
|
|
@@ -10982,7 +10932,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10982
10932
|
const shouldWarnAndSuppressBundledActiveMemoryCollision = cfg.activeRecallEnabled && !cfg.activeRecallAllowChainedActiveMemory && bundledActiveMemoryEnabledForAgent;
|
|
10983
10933
|
if (shouldWarnAndSuppressBundledActiveMemoryCollision && !warnedBundledActiveMemoryCollisionAgents.has(agentId)) {
|
|
10984
10934
|
warnedBundledActiveMemoryCollisionAgents.add(agentId);
|
|
10985
|
-
|
|
10935
|
+
log8.warn(
|
|
10986
10936
|
`active recall suppressed because bundled active-memory plugin is enabled for agent "${agentId}" while activeRecallAllowChainedActiveMemory=false`
|
|
10987
10937
|
);
|
|
10988
10938
|
}
|
|
@@ -10996,7 +10946,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10996
10946
|
),
|
|
10997
10947
|
currentMessage: prompt
|
|
10998
10948
|
}).catch((error) => {
|
|
10999
|
-
|
|
10949
|
+
log8.debug(`active recall fallback failed: ${String(error)}`);
|
|
11000
10950
|
return null;
|
|
11001
10951
|
});
|
|
11002
10952
|
const activeRecallLines = activeRecallResult?.summary && activeRecallResult.summary.length > 0 ? ["## Active Recall (Remnic)", "", activeRecallResult.summary, ""] : [];
|
|
@@ -11011,7 +10961,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11011
10961
|
}
|
|
11012
10962
|
});
|
|
11013
10963
|
recallComposition ??= { context };
|
|
11014
|
-
|
|
10964
|
+
log8.debug(
|
|
11015
10965
|
`${hookLabel}: recall returned ${context?.length ?? 0} chars`
|
|
11016
10966
|
);
|
|
11017
10967
|
const lastRecall = orchestrator.getLastRecall(sessionKey);
|
|
@@ -11058,7 +11008,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11058
11008
|
requestedMode: lastRecall?.requestedMode,
|
|
11059
11009
|
fallbackUsed: lastRecall?.fallbackUsed
|
|
11060
11010
|
}).catch((error) => {
|
|
11061
|
-
|
|
11011
|
+
log8.debug(`recall audit append failed: ${String(error)}`);
|
|
11062
11012
|
});
|
|
11063
11013
|
}
|
|
11064
11014
|
if (mergedLines.length === 0) return;
|
|
@@ -11085,7 +11035,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11085
11035
|
requestedMode: lastRecall?.requestedMode,
|
|
11086
11036
|
fallbackUsed: lastRecall?.fallbackUsed
|
|
11087
11037
|
}).catch((error) => {
|
|
11088
|
-
|
|
11038
|
+
log8.debug(`recall audit append failed: ${String(error)}`);
|
|
11089
11039
|
});
|
|
11090
11040
|
}
|
|
11091
11041
|
const verboseLines = verboseRequested ? buildVerboseRecallHeader({
|
|
@@ -11105,12 +11055,12 @@ Keep the reflection grounded in the evidence below.
|
|
|
11105
11055
|
const memorySectionLines = memoryContext.lines;
|
|
11106
11056
|
const memoryLines = useMemoryPromptSection ? memorySectionLines : [...auxiliaryLines, ...memorySectionLines];
|
|
11107
11057
|
const promptWithVerbose = useMemoryPromptSection ? auxiliaryLines.length > 0 ? auxiliaryLines.join("\n").replace(/\n$/, "") : void 0 : auxiliaryLines.length > 0 ? [...auxiliaryLines, ...memorySectionLines].join("\n").replace(/\n$/, "") : memoryContext.prompt;
|
|
11108
|
-
|
|
11058
|
+
log8.debug(
|
|
11109
11059
|
`${hookLabel}: returning memory context with ${trimmed.length} chars`
|
|
11110
11060
|
);
|
|
11111
11061
|
return promptWithVerbose ? { prependSystemContext: promptWithVerbose, memoryLines } : { memoryLines };
|
|
11112
11062
|
} catch (err) {
|
|
11113
|
-
|
|
11063
|
+
log8.error("recall failed", err);
|
|
11114
11064
|
lastRecallSummaryBySession.set(sessionKey, null);
|
|
11115
11065
|
clearCodexCompatCaches2(sessionKey, void 0, {
|
|
11116
11066
|
preserveMessageCount: true,
|
|
@@ -11161,7 +11111,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11161
11111
|
if (useMemoryPromptSection && api.registerMemoryPromptSection) {
|
|
11162
11112
|
if (cfg.activeRecallEnabled && !globalThis[ACTIVE_RECALL_OVERLAP_WARNED]) {
|
|
11163
11113
|
globalThis[ACTIVE_RECALL_OVERLAP_WARNED] = true;
|
|
11164
|
-
|
|
11114
|
+
log8.warn(
|
|
11165
11115
|
"activeRecallEnabled=true while memory-slot prompt injection is active (registerMemoryPromptSection). Prompt injection does NOT require active recall; this runs a second blocking retrieval per turn. Disable activeRecallEnabled unless the secondary pre-reply summary block is intentional (issue #1550)."
|
|
11166
11116
|
);
|
|
11167
11117
|
}
|
|
@@ -11372,7 +11322,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11372
11322
|
agentIds: capabilityAgentIds
|
|
11373
11323
|
});
|
|
11374
11324
|
} catch (err) {
|
|
11375
|
-
|
|
11325
|
+
log8.error("publicArtifacts.listArtifacts failed", err);
|
|
11376
11326
|
return [];
|
|
11377
11327
|
}
|
|
11378
11328
|
}
|
|
@@ -11389,14 +11339,14 @@ Keep the reflection grounded in the evidence below.
|
|
|
11389
11339
|
}
|
|
11390
11340
|
const builderDesc = !promptInjectionAllowed ? " (promptBuilder omitted \u2014 injection disabled by policy)" : memoryPromptBuilder ? " and promptBuilder (from registerMemoryPromptSection)" : " and promptBuilder (capability-only fallback)";
|
|
11391
11341
|
const capabilityDesc = typeof api.registerMemoryCapability === "function" ? `memory capability with publicArtifacts provider${builderDesc}` : "split memory runtime/flush-plan surfaces";
|
|
11392
|
-
|
|
11342
|
+
log8.info(`registered ${capabilityDesc}`);
|
|
11393
11343
|
}
|
|
11394
11344
|
if (cfg.openclawMessageReceivedCaptureEnabled) {
|
|
11395
11345
|
api.on(
|
|
11396
11346
|
"message_received",
|
|
11397
11347
|
async (event, ctx) => {
|
|
11398
11348
|
if (cfg.heartbeat.enabled && cfg.heartbeat.gateExtractionDuringHeartbeat && isHeartbeatTrigger2(event, ctx)) {
|
|
11399
|
-
|
|
11349
|
+
log8.debug(
|
|
11400
11350
|
`message_received: skipping transcript capture during heartbeat run for ${ctx?.sessionKey ?? "default"}`
|
|
11401
11351
|
);
|
|
11402
11352
|
return;
|
|
@@ -11484,7 +11434,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11484
11434
|
rememberPendingSparseInboundContentFingerprint2(sparseInboundContentFingerprint);
|
|
11485
11435
|
}
|
|
11486
11436
|
} catch (err) {
|
|
11487
|
-
|
|
11437
|
+
log8.debug(`message_received transcript append failed: ${err}`);
|
|
11488
11438
|
}
|
|
11489
11439
|
}
|
|
11490
11440
|
);
|
|
@@ -11495,7 +11445,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11495
11445
|
if (!event.success || !Array.isArray(event.messages)) return;
|
|
11496
11446
|
if (event.messages.length === 0) return;
|
|
11497
11447
|
if (cfg.heartbeat.enabled && cfg.heartbeat.gateExtractionDuringHeartbeat && isHeartbeatTrigger2(event, ctx)) {
|
|
11498
|
-
|
|
11448
|
+
log8.debug(
|
|
11499
11449
|
`agent_end: skipping transcript/extraction buffering during heartbeat run for ${ctx?.sessionKey ?? "default"}`
|
|
11500
11450
|
);
|
|
11501
11451
|
return;
|
|
@@ -11543,9 +11493,9 @@ Keep the reflection grounded in the evidence below.
|
|
|
11543
11493
|
try {
|
|
11544
11494
|
const objectiveStateNamespace = orchestrator.config.namespacesEnabled && typeof orchestrator.resolveSelfNamespace === "function" ? orchestrator.resolveSelfNamespace(sessionKey) : orchestrator.config.defaultNamespace;
|
|
11545
11495
|
const objectiveStateStorage = orchestrator.config.namespacesEnabled && typeof orchestrator.getStorageForNamespace === "function" ? await orchestrator.getStorageForNamespace(objectiveStateNamespace) : null;
|
|
11546
|
-
await
|
|
11496
|
+
await recordObjectiveStateSnapshotsFromAgentMessages({
|
|
11547
11497
|
memoryDir: objectiveStateStorage?.dir ?? orchestrator.config.memoryDir,
|
|
11548
|
-
objectiveStateStoreDir:
|
|
11498
|
+
objectiveStateStoreDir: objectiveStateStoreOverrideForNamespace({
|
|
11549
11499
|
memoryDir: orchestrator.config.memoryDir,
|
|
11550
11500
|
configuredStoreDir: orchestrator.config.objectiveStateStoreDir,
|
|
11551
11501
|
namespacesEnabled: orchestrator.config.namespacesEnabled,
|
|
@@ -11558,7 +11508,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11558
11508
|
messages
|
|
11559
11509
|
});
|
|
11560
11510
|
} catch (error) {
|
|
11561
|
-
|
|
11511
|
+
log8.debug(
|
|
11562
11512
|
`agent_end objective-state writer skipped due to error: ${error}`
|
|
11563
11513
|
);
|
|
11564
11514
|
}
|
|
@@ -11676,11 +11626,11 @@ Keep the reflection grounded in the evidence below.
|
|
|
11676
11626
|
);
|
|
11677
11627
|
}
|
|
11678
11628
|
} catch (lcmErr) {
|
|
11679
|
-
|
|
11629
|
+
log8.debug(`LCM agent_end indexing error: ${lcmErr}`);
|
|
11680
11630
|
}
|
|
11681
11631
|
}
|
|
11682
11632
|
} catch (err) {
|
|
11683
|
-
|
|
11633
|
+
log8.error("agent_end processing failed", err);
|
|
11684
11634
|
}
|
|
11685
11635
|
}
|
|
11686
11636
|
);
|
|
@@ -11706,7 +11656,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11706
11656
|
clearCodexCompatCaches2(sessionKey, signalThreadId);
|
|
11707
11657
|
rememberCodexThread2(sessionKey, signalThreadId);
|
|
11708
11658
|
} catch (error) {
|
|
11709
|
-
|
|
11659
|
+
log8.warn(`codexCompat signal flush failed: ${String(error)}`);
|
|
11710
11660
|
}
|
|
11711
11661
|
}
|
|
11712
11662
|
if (orchestrator.lcmEngine?.enabled) {
|
|
@@ -11734,7 +11684,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11734
11684
|
);
|
|
11735
11685
|
await orchestrator.lcmEngine.preCompactionFlush(sessionKey);
|
|
11736
11686
|
} catch (lcmErr) {
|
|
11737
|
-
|
|
11687
|
+
log8.debug(`LCM before_compaction error: ${lcmErr}`);
|
|
11738
11688
|
}
|
|
11739
11689
|
}
|
|
11740
11690
|
if (!orchestrator.config.checkpointEnabled) {
|
|
@@ -11754,10 +11704,10 @@ Keep the reflection grounded in the evidence below.
|
|
|
11754
11704
|
turns: checkpointTurns,
|
|
11755
11705
|
ttl: new Date(Date.now() + 24 * 60 * 60 * 1e3).toISOString()
|
|
11756
11706
|
});
|
|
11757
|
-
|
|
11707
|
+
log8.info(`saved checkpoint for ${sessionKey} before compaction`);
|
|
11758
11708
|
}
|
|
11759
11709
|
} catch (err) {
|
|
11760
|
-
|
|
11710
|
+
log8.error("before_compaction hook failed", err);
|
|
11761
11711
|
}
|
|
11762
11712
|
}
|
|
11763
11713
|
);
|
|
@@ -11797,24 +11747,24 @@ Keep the reflection grounded in the evidence below.
|
|
|
11797
11747
|
);
|
|
11798
11748
|
await orchestrator.lcmEngine.verifyPostCompaction(sessionKey);
|
|
11799
11749
|
} catch (lcmErr) {
|
|
11800
|
-
|
|
11750
|
+
log8.debug(`LCM after_compaction error: ${lcmErr}`);
|
|
11801
11751
|
}
|
|
11802
11752
|
}
|
|
11803
11753
|
void queueOpenClawFlushPlanProcessing("after_compaction", workspaceDir);
|
|
11804
11754
|
if (!orchestrator.config.compactionResetEnabled) {
|
|
11805
|
-
|
|
11755
|
+
log8.debug(
|
|
11806
11756
|
`compaction completed for ${sessionKey}, reset disabled \u2014 skipping`
|
|
11807
11757
|
);
|
|
11808
11758
|
return;
|
|
11809
11759
|
}
|
|
11810
|
-
|
|
11760
|
+
log8.info(
|
|
11811
11761
|
`compaction completed for ${sessionKey}, triggering session reset`
|
|
11812
11762
|
);
|
|
11813
11763
|
const apiAny = api;
|
|
11814
11764
|
if (typeof apiAny.resetSession === "function") {
|
|
11815
11765
|
const result = await apiAny.resetSession(sessionKey, "new");
|
|
11816
11766
|
if (result?.ok === true) {
|
|
11817
|
-
|
|
11767
|
+
log8.info(
|
|
11818
11768
|
`session reset via API for ${sessionKey}, new sessionId=${result.sessionId}`
|
|
11819
11769
|
);
|
|
11820
11770
|
const safeSessionKey = sanitizeSessionKeyForFilename(sessionKey);
|
|
@@ -11834,17 +11784,17 @@ Keep the reflection grounded in the evidence below.
|
|
|
11834
11784
|
const errorDetail = result && typeof result === "object" && "error" in result ? String(
|
|
11835
11785
|
result.error ?? "unknown error"
|
|
11836
11786
|
) : `invalid result: ${JSON.stringify(result)}`;
|
|
11837
|
-
|
|
11787
|
+
log8.error(
|
|
11838
11788
|
`api.resetSession failed for ${sessionKey}: ${errorDetail}`
|
|
11839
11789
|
);
|
|
11840
11790
|
}
|
|
11841
11791
|
} else {
|
|
11842
|
-
|
|
11792
|
+
log8.error(
|
|
11843
11793
|
`api.resetSession not available \u2014 compaction reset requires OC fork with PR #29985. Session ${sessionKey} will continue without reset.`
|
|
11844
11794
|
);
|
|
11845
11795
|
}
|
|
11846
11796
|
} catch (err) {
|
|
11847
|
-
|
|
11797
|
+
log8.error("after_compaction reset failed", err);
|
|
11848
11798
|
}
|
|
11849
11799
|
}
|
|
11850
11800
|
);
|
|
@@ -11877,7 +11827,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11877
11827
|
).catch((error) => {
|
|
11878
11828
|
if (!flushAbort.signal.aborted) {
|
|
11879
11829
|
flushFailed = true;
|
|
11880
|
-
|
|
11830
|
+
log8.warn(
|
|
11881
11831
|
`before_reset flush failed for ${bufferKey}: ${String(error)}`
|
|
11882
11832
|
);
|
|
11883
11833
|
}
|
|
@@ -11910,7 +11860,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11910
11860
|
);
|
|
11911
11861
|
}
|
|
11912
11862
|
if (flushTimedOut) {
|
|
11913
|
-
|
|
11863
|
+
log8.warn(
|
|
11914
11864
|
`before_reset flush timed out after ${cfg.beforeResetTimeoutMs}ms`
|
|
11915
11865
|
);
|
|
11916
11866
|
}
|
|
@@ -11925,18 +11875,18 @@ Keep the reflection grounded in the evidence below.
|
|
|
11925
11875
|
}
|
|
11926
11876
|
);
|
|
11927
11877
|
} catch (error) {
|
|
11928
|
-
|
|
11878
|
+
log8.debug(`before_reset hook unavailable on this runtime: ${String(error)}`);
|
|
11929
11879
|
}
|
|
11930
11880
|
if (!passiveMode && sdkCaps.hasBeforePromptBuild) {
|
|
11931
11881
|
api.on(
|
|
11932
11882
|
"session_start",
|
|
11933
11883
|
async (event, ctx) => {
|
|
11934
11884
|
const sessionKey = event.sessionKey ?? "default";
|
|
11935
|
-
|
|
11885
|
+
log8.debug(`session_start: ${sessionKey}`);
|
|
11936
11886
|
try {
|
|
11937
11887
|
await orchestrator.maybeRunFileHygiene().catch(() => void 0);
|
|
11938
11888
|
} catch (err) {
|
|
11939
|
-
|
|
11889
|
+
log8.debug(`session_start file hygiene failed: ${err}`);
|
|
11940
11890
|
}
|
|
11941
11891
|
void queueOpenClawFlushPlanProcessing(
|
|
11942
11892
|
"session_start",
|
|
@@ -11949,7 +11899,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11949
11899
|
"session_end",
|
|
11950
11900
|
async (event, ctx) => {
|
|
11951
11901
|
const sessionKey = event.sessionKey ?? ctx.sessionKey ?? "default";
|
|
11952
|
-
|
|
11902
|
+
log8.debug(`session_end: ${sessionKey}`);
|
|
11953
11903
|
const sessionIdentity = resolveSessionIdentity2(sessionKey, event, ctx);
|
|
11954
11904
|
const rememberedThreadId = sessionIdentity.providerThreadId ?? resolveStoredCodexThreadId2(sessionKey);
|
|
11955
11905
|
const bufferKeys = await resolveBeforeResetBufferKeys(sessionKey, {
|
|
@@ -11967,7 +11917,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11967
11917
|
});
|
|
11968
11918
|
} catch (error) {
|
|
11969
11919
|
flushFailed = true;
|
|
11970
|
-
|
|
11920
|
+
log8.warn(
|
|
11971
11921
|
`session_end flush failed for ${bufferKey}: ${String(error)}`
|
|
11972
11922
|
);
|
|
11973
11923
|
}
|
|
@@ -11992,7 +11942,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11992
11942
|
"before_tool_call",
|
|
11993
11943
|
async (event, _ctx) => {
|
|
11994
11944
|
if (event.toolName) {
|
|
11995
|
-
|
|
11945
|
+
log8.debug(`before_tool_call: ${event.toolName}`);
|
|
11996
11946
|
}
|
|
11997
11947
|
}
|
|
11998
11948
|
);
|
|
@@ -12000,7 +11950,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12000
11950
|
"after_tool_call",
|
|
12001
11951
|
async (event, _ctx) => {
|
|
12002
11952
|
if (event.toolName) {
|
|
12003
|
-
|
|
11953
|
+
log8.debug(
|
|
12004
11954
|
`after_tool_call: ${event.toolName} (${event.durationMs ?? "?"}ms)`
|
|
12005
11955
|
);
|
|
12006
11956
|
}
|
|
@@ -12011,7 +11961,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12011
11961
|
async (event, ctx) => {
|
|
12012
11962
|
const sessionKey = ctx?.sessionKey ?? "default";
|
|
12013
11963
|
if (event.tokenUsage) {
|
|
12014
|
-
|
|
11964
|
+
log8.debug(
|
|
12015
11965
|
`llm_output: model=${event.model ?? "?"}, tokens=${event.tokenUsage.input ?? 0}/${event.tokenUsage.output ?? 0}, ${event.durationMs ?? "?"}ms, session=${sessionKey}`
|
|
12016
11966
|
);
|
|
12017
11967
|
}
|
|
@@ -12020,7 +11970,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12020
11970
|
api.on(
|
|
12021
11971
|
"subagent_spawned",
|
|
12022
11972
|
async (event, _ctx) => {
|
|
12023
|
-
|
|
11973
|
+
log8.debug(
|
|
12024
11974
|
`subagent_spawned: ${event.subagentId ?? "?"} purpose=${event.purpose ?? "?"} parent=${event.parentSessionKey ?? "?"}`
|
|
12025
11975
|
);
|
|
12026
11976
|
}
|
|
@@ -12028,7 +11978,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12028
11978
|
api.on(
|
|
12029
11979
|
"subagent_ended",
|
|
12030
11980
|
async (event, _ctx) => {
|
|
12031
|
-
|
|
11981
|
+
log8.debug(
|
|
12032
11982
|
`subagent_ended: ${event.subagentId ?? "?"} success=${event.success ?? "?"} ${event.durationMs ?? "?"}ms`
|
|
12033
11983
|
);
|
|
12034
11984
|
}
|
|
@@ -12046,7 +11996,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12046
11996
|
try {
|
|
12047
11997
|
const loadedJobs = await loadHourlySummaryCronJobsData(cronFilePath);
|
|
12048
11998
|
if (loadedJobs.status === "invalid") {
|
|
12049
|
-
|
|
11999
|
+
log8.error(
|
|
12050
12000
|
`hourly summary cron auto-registration skipped: existing jobs file is invalid at ${cronFilePath}`,
|
|
12051
12001
|
loadedJobs.error
|
|
12052
12002
|
);
|
|
@@ -12061,7 +12011,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12061
12011
|
{ nowMs: Date.now() }
|
|
12062
12012
|
);
|
|
12063
12013
|
if (!changed) {
|
|
12064
|
-
|
|
12014
|
+
log8.debug("hourly summary cron job already up to date");
|
|
12065
12015
|
return;
|
|
12066
12016
|
}
|
|
12067
12017
|
jobsData.jobs[existingIndex] = job;
|
|
@@ -12069,7 +12019,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12069
12019
|
cronFilePath,
|
|
12070
12020
|
JSON.stringify(jobsData, null, 2)
|
|
12071
12021
|
);
|
|
12072
|
-
|
|
12022
|
+
log8.info("reconciled hourly summary cron job routing to configured task model");
|
|
12073
12023
|
return;
|
|
12074
12024
|
}
|
|
12075
12025
|
const randomMinute = Math.floor(Math.random() * 59) + 1;
|
|
@@ -12083,9 +12033,9 @@ Keep the reflection grounded in the evidence below.
|
|
|
12083
12033
|
cronFilePath,
|
|
12084
12034
|
JSON.stringify(jobsData, null, 2)
|
|
12085
12035
|
);
|
|
12086
|
-
|
|
12036
|
+
log8.info("auto-registered hourly summary cron job");
|
|
12087
12037
|
} catch (err) {
|
|
12088
|
-
|
|
12038
|
+
log8.error("failed to auto-register hourly summary cron job:", err);
|
|
12089
12039
|
}
|
|
12090
12040
|
}
|
|
12091
12041
|
if (typeof api.registerMemoryCorpusSupplement === "function") {
|
|
@@ -12195,7 +12145,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12195
12145
|
};
|
|
12196
12146
|
});
|
|
12197
12147
|
} catch (err) {
|
|
12198
|
-
|
|
12148
|
+
log8.warn(`memory corpus search failed: ${err}`);
|
|
12199
12149
|
throw corpusBackendError("search", err);
|
|
12200
12150
|
}
|
|
12201
12151
|
},
|
|
@@ -12231,7 +12181,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12231
12181
|
updatedAt: memory.frontmatter.updated
|
|
12232
12182
|
};
|
|
12233
12183
|
} catch (err) {
|
|
12234
|
-
|
|
12184
|
+
log8.warn(`memory corpus get failed: ${err}`);
|
|
12235
12185
|
throw corpusBackendError("get", err);
|
|
12236
12186
|
}
|
|
12237
12187
|
}
|
|
@@ -12254,7 +12204,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12254
12204
|
commandApi.registerCommand(descriptor);
|
|
12255
12205
|
}
|
|
12256
12206
|
} else if (typeof commandApi.registerCommand !== "function") {
|
|
12257
|
-
|
|
12207
|
+
log8.debug(
|
|
12258
12208
|
"registerCommand unavailable on this runtime; skipping Remnic session command descriptors because commands.list is a gateway RPC surface, not a typed plugin hook"
|
|
12259
12209
|
);
|
|
12260
12210
|
}
|
|
@@ -12293,7 +12243,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12293
12243
|
if (globalThis[keys.SERVICE_STARTED]) return;
|
|
12294
12244
|
}
|
|
12295
12245
|
if (globalThis[keys.SERVICE_STARTED]) {
|
|
12296
|
-
|
|
12246
|
+
log8.debug(
|
|
12297
12247
|
`${serviceId}: service.start() called again \u2014 skipping duplicate init`
|
|
12298
12248
|
);
|
|
12299
12249
|
return;
|
|
@@ -12306,10 +12256,10 @@ Keep the reflection grounded in the evidence below.
|
|
|
12306
12256
|
globalThis[keys.ORCHESTRATOR] = orchestrator;
|
|
12307
12257
|
const initPromise = (async () => {
|
|
12308
12258
|
try {
|
|
12309
|
-
|
|
12259
|
+
log8.info("initializing engram memory system...");
|
|
12310
12260
|
await orchestrator.initialize();
|
|
12311
12261
|
if (!didCountStart) return;
|
|
12312
|
-
activeOpikExporter = createOpikExporter({},
|
|
12262
|
+
activeOpikExporter = createOpikExporter({}, log8);
|
|
12313
12263
|
if (activeOpikExporter) activeOpikExporter.subscribe();
|
|
12314
12264
|
if (orchestrator.config.transcriptEnabled) {
|
|
12315
12265
|
await orchestrator.transcript.cleanup(
|
|
@@ -12321,7 +12271,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12321
12271
|
await ensureHourlySummaryCron(api);
|
|
12322
12272
|
if (!didCountStart) return;
|
|
12323
12273
|
} else if (orchestrator.config.hourlySummariesEnabled) {
|
|
12324
|
-
|
|
12274
|
+
log8.info(
|
|
12325
12275
|
"hourly summaries enabled; cron auto-register is disabled. To schedule summaries, create an isolated/agentTurn cron job that calls `memory_summarize_hourly`."
|
|
12326
12276
|
);
|
|
12327
12277
|
}
|
|
@@ -12337,7 +12287,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12337
12287
|
resolveDreamJournalPath(),
|
|
12338
12288
|
() => {
|
|
12339
12289
|
void queueDreamSurfaceSync().catch((error) => {
|
|
12340
|
-
|
|
12290
|
+
log8.debug(`dream surface watch sync failed: ${String(error)}`);
|
|
12341
12291
|
});
|
|
12342
12292
|
}
|
|
12343
12293
|
);
|
|
@@ -12357,7 +12307,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12357
12307
|
resolveHeartbeatJournalPath(),
|
|
12358
12308
|
() => {
|
|
12359
12309
|
void queueHeartbeatSurfaceSync().catch((error) => {
|
|
12360
|
-
|
|
12310
|
+
log8.debug(`heartbeat surface watch sync failed: ${String(error)}`);
|
|
12361
12311
|
});
|
|
12362
12312
|
}
|
|
12363
12313
|
);
|
|
@@ -12378,17 +12328,17 @@ Keep the reflection grounded in the evidence below.
|
|
|
12378
12328
|
}
|
|
12379
12329
|
try {
|
|
12380
12330
|
const status = await accessHttpServer.start();
|
|
12381
|
-
|
|
12331
|
+
log8.info(
|
|
12382
12332
|
`engram access HTTP ready at http://${status.host}:${status.port}`
|
|
12383
12333
|
);
|
|
12384
12334
|
} catch (err) {
|
|
12385
|
-
|
|
12335
|
+
log8.error("failed to start engram access HTTP server", err);
|
|
12386
12336
|
}
|
|
12387
12337
|
}
|
|
12388
12338
|
if (!didCountStart) return;
|
|
12389
12339
|
globalThis[keys.SERVICE_STARTED] = true;
|
|
12390
|
-
|
|
12391
|
-
|
|
12340
|
+
log8.info("engram memory system ready");
|
|
12341
|
+
log8.info(
|
|
12392
12342
|
`gateway_start fired \u2014 Remnic memory plugin is active (id=${pluginDefinition.id}, memoryDir=${cfg.memoryDir})`
|
|
12393
12343
|
);
|
|
12394
12344
|
void queueOpenClawFlushPlanProcessing(
|
|
@@ -12462,7 +12412,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12462
12412
|
try {
|
|
12463
12413
|
activeOpikExporter?.unsubscribe();
|
|
12464
12414
|
} catch (err) {
|
|
12465
|
-
|
|
12415
|
+
log8.debug(`engram opik exporter unsubscribe failed: ${err}`);
|
|
12466
12416
|
}
|
|
12467
12417
|
activeOpikExporter = null;
|
|
12468
12418
|
const finishCodex = beginCodexSubscriptionShutdown(getCodexSubscriptionRunnerForOwner(cfg));
|
|
@@ -12470,7 +12420,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12470
12420
|
try {
|
|
12471
12421
|
await accessHttpServer.stop();
|
|
12472
12422
|
} catch (err) {
|
|
12473
|
-
|
|
12423
|
+
log8.debug(`engram access HTTP stop failed: ${err}`);
|
|
12474
12424
|
}
|
|
12475
12425
|
stopDreamWatcher?.();
|
|
12476
12426
|
stopDreamWatcher = null;
|
|
@@ -12481,11 +12431,12 @@ Keep the reflection grounded in the evidence below.
|
|
|
12481
12431
|
try {
|
|
12482
12432
|
await orchestrator.destroy();
|
|
12483
12433
|
} catch (err) {
|
|
12484
|
-
|
|
12434
|
+
log8.debug(`engram orchestrator destroy on stop failed: ${err}`);
|
|
12485
12435
|
}
|
|
12486
12436
|
} finally {
|
|
12487
12437
|
finishCodex();
|
|
12488
12438
|
}
|
|
12439
|
+
terminateActiveCodexSubscriptionChildren("SIGKILL", getCodexSubscriptionRunnerForOwner(cfg));
|
|
12489
12440
|
if (globalThis[keys.ORCHESTRATOR] === orchestrator) {
|
|
12490
12441
|
delete globalThis[keys.ORCHESTRATOR];
|
|
12491
12442
|
}
|
|
@@ -12506,7 +12457,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
12506
12457
|
if (!secondaryTookOver) {
|
|
12507
12458
|
globalThis[keys.SERVICE_STARTED] = false;
|
|
12508
12459
|
}
|
|
12509
|
-
|
|
12460
|
+
log8.info("stopped");
|
|
12510
12461
|
}
|
|
12511
12462
|
});
|
|
12512
12463
|
}
|
|
@@ -12649,7 +12600,6 @@ async function resolveFlushPlanProcessingChainKey(workspaceRoot) {
|
|
|
12649
12600
|
return lexicalRoot;
|
|
12650
12601
|
}
|
|
12651
12602
|
}
|
|
12652
|
-
var export_loadDaySummaryPrompt = day_summary_exports.loadDaySummaryPrompt;
|
|
12653
12603
|
export {
|
|
12654
12604
|
buildHourlySummaryCronJob,
|
|
12655
12605
|
checkDaemonHealth,
|
|
@@ -12659,7 +12609,7 @@ export {
|
|
|
12659
12609
|
detectDaemonBridgeMode,
|
|
12660
12610
|
embedWithOpenClawProvider,
|
|
12661
12611
|
listRemnicPublicArtifacts,
|
|
12662
|
-
|
|
12612
|
+
loadDaySummaryPrompt,
|
|
12663
12613
|
loadHourlySummaryCronJobsData,
|
|
12664
12614
|
loadOpenClawMemoryEmbeddingSdk,
|
|
12665
12615
|
parseHourlySummaryCronJobsData,
|