@agenr/agenr-plugin 1.9.3 → 2.0.0
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/{chunk-I6A6DPNF.js → chunk-XD3446YW.js} +2 -2
- package/dist/{chunk-EMRMV2QR.js → chunk-Y2BC7RCE.js} +1347 -110
- package/dist/chunk-ZYADFKX3.js +115 -0
- package/dist/index.js +132 -10
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/chunk-ETQPUJGS.js +0 -0
- package/dist/{chunk-GUDCFFRV.js → chunk-MEHOGUZE.js} +175 -175
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// src/core/procedures/hashing.ts
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
function computeProcedureSourceHash(sourceText) {
|
|
4
|
+
return createHash("sha256").update(sourceText).digest("hex");
|
|
5
|
+
}
|
|
6
|
+
function computeProcedureRevisionHash(procedure) {
|
|
7
|
+
return createHash("sha256").update(stringifyCanonical(procedure)).digest("hex");
|
|
8
|
+
}
|
|
9
|
+
function stringifyCanonical(value) {
|
|
10
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
11
|
+
return JSON.stringify(value);
|
|
12
|
+
}
|
|
13
|
+
if (Array.isArray(value)) {
|
|
14
|
+
return `[${value.map((item) => stringifyCanonical(item)).join(",")}]`;
|
|
15
|
+
}
|
|
16
|
+
const keys = Object.keys(value).sort((left, right) => left.localeCompare(right));
|
|
17
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${stringifyCanonical(value[key])}`).join(",")}}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/core/procedures/recall-text.ts
|
|
21
|
+
function composeProcedureRecallText(procedure) {
|
|
22
|
+
const lines = [
|
|
23
|
+
`procedure_key: ${procedure.procedure_key}`,
|
|
24
|
+
`title: ${procedure.title}`,
|
|
25
|
+
`goal: ${procedure.goal}`,
|
|
26
|
+
...formatSection("when_to_use", procedure.when_to_use),
|
|
27
|
+
...formatSection("when_not_to_use", procedure.when_not_to_use),
|
|
28
|
+
...formatSection("prerequisites", procedure.prerequisites),
|
|
29
|
+
"steps:",
|
|
30
|
+
...procedure.steps.flatMap((step, index) => formatStep(step, index)),
|
|
31
|
+
...formatSection("verification", procedure.verification),
|
|
32
|
+
...formatSection("failure_modes", procedure.failure_modes),
|
|
33
|
+
"sources:",
|
|
34
|
+
...procedure.sources.map((source, index) => ` ${index + 1}. ${formatSource(source)}`)
|
|
35
|
+
];
|
|
36
|
+
return lines.join("\n");
|
|
37
|
+
}
|
|
38
|
+
function formatSection(label, values) {
|
|
39
|
+
if (values.length === 0) {
|
|
40
|
+
return [`${label}: none`];
|
|
41
|
+
}
|
|
42
|
+
return [`${label}:`, ...values.map((value, index) => ` ${index + 1}. ${value}`)];
|
|
43
|
+
}
|
|
44
|
+
function formatStep(step, index) {
|
|
45
|
+
const lines = [` ${index + 1}. [${step.kind}] ${step.id} - ${step.instruction}`];
|
|
46
|
+
switch (step.kind) {
|
|
47
|
+
case "run_command":
|
|
48
|
+
lines.push(` command: ${step.command}`);
|
|
49
|
+
break;
|
|
50
|
+
case "read_reference":
|
|
51
|
+
lines.push(` ref: ${formatSource(step.ref)}`);
|
|
52
|
+
break;
|
|
53
|
+
case "inspect_state":
|
|
54
|
+
if (step.target) {
|
|
55
|
+
lines.push(` target: ${step.target}`);
|
|
56
|
+
}
|
|
57
|
+
if (step.query) {
|
|
58
|
+
lines.push(` query: ${step.query}`);
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
case "edit_file":
|
|
62
|
+
lines.push(` path: ${step.path}`);
|
|
63
|
+
lines.push(` edit: ${step.edit}`);
|
|
64
|
+
break;
|
|
65
|
+
case "ask_user":
|
|
66
|
+
lines.push(` prompt: ${step.prompt}`);
|
|
67
|
+
break;
|
|
68
|
+
case "invoke_tool":
|
|
69
|
+
lines.push(` tool: ${step.tool}`);
|
|
70
|
+
if (step.arguments) {
|
|
71
|
+
lines.push(` arguments: ${JSON.stringify(step.arguments)}`);
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
case "verify":
|
|
75
|
+
lines.push(...step.checks.map((check, checkIndex) => ` check ${checkIndex + 1}: ${check}`));
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
if (step.conditions?.length) {
|
|
79
|
+
lines.push(` conditions: ${step.conditions.map((condition) => formatCondition(condition)).join("; ")}`);
|
|
80
|
+
}
|
|
81
|
+
if (step.stop_if?.length) {
|
|
82
|
+
lines.push(` stop_if: ${step.stop_if.map((condition) => formatCondition(condition)).join("; ")}`);
|
|
83
|
+
}
|
|
84
|
+
return lines;
|
|
85
|
+
}
|
|
86
|
+
function formatCondition(condition) {
|
|
87
|
+
switch (condition.kind) {
|
|
88
|
+
case "file_exists":
|
|
89
|
+
case "path_exists":
|
|
90
|
+
return `${condition.kind}=${condition.path}`;
|
|
91
|
+
case "env_flag":
|
|
92
|
+
return condition.value ? `${condition.kind}=${condition.name}:${condition.value}` : `${condition.kind}=${condition.name}`;
|
|
93
|
+
default:
|
|
94
|
+
return `${condition.kind}=${condition.value}`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function formatSource(source) {
|
|
98
|
+
const parts = [source.kind];
|
|
99
|
+
if (source.path) {
|
|
100
|
+
parts.push(`path=${source.path}`);
|
|
101
|
+
}
|
|
102
|
+
if (source.locator) {
|
|
103
|
+
parts.push(`locator=${source.locator}`);
|
|
104
|
+
}
|
|
105
|
+
if (source.label) {
|
|
106
|
+
parts.push(`label=${source.label}`);
|
|
107
|
+
}
|
|
108
|
+
return parts.join(" ");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export {
|
|
112
|
+
computeProcedureSourceHash,
|
|
113
|
+
computeProcedureRevisionHash,
|
|
114
|
+
composeProcedureRecallText
|
|
115
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
parseTuiSessionKey,
|
|
8
8
|
readOpenClawSessionsStore,
|
|
9
9
|
storeEntriesDetailed
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XD3446YW.js";
|
|
11
11
|
import {
|
|
12
12
|
EMBEDDING_DIMENSIONS,
|
|
13
13
|
ENTRY_TYPES,
|
|
@@ -24,10 +24,10 @@ import {
|
|
|
24
24
|
resolveEmbeddingModel,
|
|
25
25
|
runUnifiedRecall,
|
|
26
26
|
validateTemporalValidityRange
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-Y2BC7RCE.js";
|
|
28
28
|
import {
|
|
29
29
|
resolveClaimSlotPolicy
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-MEHOGUZE.js";
|
|
31
31
|
|
|
32
32
|
// src/adapters/openclaw/index.ts
|
|
33
33
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
@@ -41,7 +41,7 @@ var ENTRY_TYPE_DESCRIPTION = "Knowledge type to store. Use fact for durable trut
|
|
|
41
41
|
var EXPIRY_DESCRIPTION = "Lifetime bucket: core (always injected at session start, use sparingly), permanent (durable and recalled on demand), or temporary (short-horizon).";
|
|
42
42
|
var UPDATE_EXPIRY_DESCRIPTION = `${EXPIRY_DESCRIPTION} Accepted values: ${EXPIRY_LEVELS.join(", ")}.`;
|
|
43
43
|
var DEFAULT_RECALL_LIMIT = 10;
|
|
44
|
-
var RECALL_MODES = ["auto", "entries", "episodes"];
|
|
44
|
+
var RECALL_MODES = ["auto", "entries", "episodes", "procedures"];
|
|
45
45
|
var RESULT_SUBJECT_LOG_LIMIT = 5;
|
|
46
46
|
async function resolveTargetEntry(services, params, options = {}) {
|
|
47
47
|
const id = readStringParam(params, "id");
|
|
@@ -89,7 +89,7 @@ function parseRecallMode(value) {
|
|
|
89
89
|
if (value === void 0) {
|
|
90
90
|
return void 0;
|
|
91
91
|
}
|
|
92
|
-
if (value === "auto" || value === "entries" || value === "episodes") {
|
|
92
|
+
if (value === "auto" || value === "entries" || value === "episodes" || value === "procedures") {
|
|
93
93
|
return value;
|
|
94
94
|
}
|
|
95
95
|
throw new Error(`Unsupported recall mode "${value}".`);
|
|
@@ -233,6 +233,10 @@ function formatUnifiedRecallResults(result) {
|
|
|
233
233
|
lines.push(result.asOf);
|
|
234
234
|
lines.push("");
|
|
235
235
|
}
|
|
236
|
+
if (result.routing.queried.includes("procedures") || result.procedure || result.procedureCandidates.length > 0 || result.procedureNotices.length > 0) {
|
|
237
|
+
appendProcedureMatches(lines, result);
|
|
238
|
+
lines.push("");
|
|
239
|
+
}
|
|
236
240
|
const renderEntriesFirst = result.routing.detectedIntent === "historical_state";
|
|
237
241
|
if (renderEntriesFirst) {
|
|
238
242
|
appendEntryMatches(lines, result);
|
|
@@ -256,6 +260,33 @@ function formatUnifiedRecallResults(result) {
|
|
|
256
260
|
}
|
|
257
261
|
return lines.join("\n");
|
|
258
262
|
}
|
|
263
|
+
function appendProcedureMatches(lines, result) {
|
|
264
|
+
lines.push("Procedure Matches");
|
|
265
|
+
if (!result.procedure && result.procedureCandidates.length === 0) {
|
|
266
|
+
lines.push("None.");
|
|
267
|
+
} else {
|
|
268
|
+
if (result.procedure) {
|
|
269
|
+
appendCanonicalProcedure(lines, result.procedure, result.procedureCandidates);
|
|
270
|
+
} else {
|
|
271
|
+
lines.push("Canonical procedure: none.");
|
|
272
|
+
}
|
|
273
|
+
const additionalCandidates = result.procedureCandidates.filter((candidate) => candidate.procedure.id !== result.procedure?.id);
|
|
274
|
+
if (additionalCandidates.length > 0) {
|
|
275
|
+
lines.push("Other Candidates");
|
|
276
|
+
for (const [index, candidate] of additionalCandidates.entries()) {
|
|
277
|
+
lines.push(
|
|
278
|
+
`${index + 1}. ${candidate.procedure.procedure_key} | ${candidate.procedure.title} | score ${candidate.score.toFixed(2)} | lexical=${candidate.scores.lexical.toFixed(2)} | vector=${candidate.scores.vector.toFixed(2)}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (result.procedureNotices.length > 0) {
|
|
284
|
+
lines.push("Procedure Notices");
|
|
285
|
+
for (const notice of result.procedureNotices) {
|
|
286
|
+
lines.push(`- ${notice}`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
259
290
|
function appendEntryMatches(lines, result) {
|
|
260
291
|
lines.push("Entry Matches");
|
|
261
292
|
if (result.projectedEntries.length === 0) {
|
|
@@ -294,6 +325,32 @@ function appendEpisodeMatches(lines, result) {
|
|
|
294
325
|
lines.push(` why_matched=${describeEpisodeMatch(episode)}`);
|
|
295
326
|
}
|
|
296
327
|
}
|
|
328
|
+
function appendCanonicalProcedure(lines, procedure, candidates) {
|
|
329
|
+
const leadCandidate = candidates.find((candidate) => candidate.procedure.id === procedure.id);
|
|
330
|
+
lines.push(
|
|
331
|
+
leadCandidate ? `Canonical Procedure. ${procedure.procedure_key} | ${procedure.title} | score ${leadCandidate.score.toFixed(2)}` : `Canonical Procedure. ${procedure.procedure_key} | ${procedure.title}`
|
|
332
|
+
);
|
|
333
|
+
lines.push(` goal=${procedure.goal}`);
|
|
334
|
+
appendLabeledList(lines, "when_to_use", procedure.when_to_use);
|
|
335
|
+
appendLabeledList(lines, "when_not_to_use", procedure.when_not_to_use);
|
|
336
|
+
appendLabeledList(lines, "prerequisites", procedure.prerequisites);
|
|
337
|
+
lines.push(" steps");
|
|
338
|
+
for (const [index, step] of procedure.steps.entries()) {
|
|
339
|
+
lines.push(` ${index + 1}. [${step.kind}] ${step.instruction}`);
|
|
340
|
+
const stepDetails = formatProcedureStepDetails(step);
|
|
341
|
+
if (stepDetails.length > 0) {
|
|
342
|
+
for (const detail of stepDetails) {
|
|
343
|
+
lines.push(` ${detail}`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
appendLabeledList(lines, "verification", procedure.verification);
|
|
348
|
+
appendLabeledList(lines, "failure_modes", procedure.failure_modes);
|
|
349
|
+
lines.push(" sources");
|
|
350
|
+
for (const source of procedure.sources) {
|
|
351
|
+
lines.push(` - ${formatProcedureSource(source)}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
297
354
|
function appendClaimTransitions(lines, result) {
|
|
298
355
|
lines.push("Claim Transitions");
|
|
299
356
|
if (result.claimTransitions.length === 0) {
|
|
@@ -314,11 +371,55 @@ function appendClaimTransitions(lines, result) {
|
|
|
314
371
|
}
|
|
315
372
|
}
|
|
316
373
|
function formatUnifiedRecallLogSummary(result) {
|
|
374
|
+
const procedureCount = result.procedureCandidates.length;
|
|
375
|
+
const procedureSummary = result.procedure ? ` [procedure: ${JSON.stringify(truncate(result.procedure.title, 80))}]` : "";
|
|
317
376
|
const entrySubjects = result.entries.map((entry) => entry.entry.subject.trim()).filter((subject) => subject.length > 0);
|
|
318
377
|
const displayed = entrySubjects.slice(0, RESULT_SUBJECT_LOG_LIMIT).map((subject) => JSON.stringify(truncate(subject, 80)));
|
|
319
378
|
const remaining = entrySubjects.length - RESULT_SUBJECT_LOG_LIMIT;
|
|
320
379
|
const suffix = displayed.length === 0 ? "" : ` [entry subjects: ${displayed.join(", ")}${remaining > 0 ? `, ... and ${remaining} more` : ""}]`;
|
|
321
|
-
|
|
380
|
+
const entryEpisodeSummary = `${result.episodes.length} episode${result.episodes.length === 1 ? "" : "s"}, ${result.entries.length} entr${result.entries.length === 1 ? "y" : "ies"}`;
|
|
381
|
+
if (procedureCount === 0 && !result.procedure) {
|
|
382
|
+
return `${entryEpisodeSummary}${suffix}`;
|
|
383
|
+
}
|
|
384
|
+
return `${procedureCount} procedure candidate${procedureCount === 1 ? "" : "s"}, ${entryEpisodeSummary}${procedureSummary}${suffix}`;
|
|
385
|
+
}
|
|
386
|
+
function appendLabeledList(lines, label, values) {
|
|
387
|
+
lines.push(` ${label}`);
|
|
388
|
+
if (values.length === 0) {
|
|
389
|
+
lines.push(" - none");
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
for (const value of values) {
|
|
393
|
+
lines.push(` - ${value}`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function formatProcedureStepDetails(step) {
|
|
397
|
+
switch (step.kind) {
|
|
398
|
+
case "run_command":
|
|
399
|
+
return [`command=${step.command}`];
|
|
400
|
+
case "read_reference":
|
|
401
|
+
return [`ref=${formatProcedureSource(step.ref)}`];
|
|
402
|
+
case "inspect_state":
|
|
403
|
+
return [step.target ? `target=${step.target}` : void 0, step.query ? `query=${step.query}` : void 0].filter(
|
|
404
|
+
(value) => value !== void 0
|
|
405
|
+
);
|
|
406
|
+
case "edit_file":
|
|
407
|
+
return [`path=${step.path}`, `edit=${step.edit}`];
|
|
408
|
+
case "ask_user":
|
|
409
|
+
return [`prompt=${step.prompt}`];
|
|
410
|
+
case "invoke_tool":
|
|
411
|
+
return [step.tool ? `tool=${step.tool}` : void 0, step.arguments ? `arguments=${JSON.stringify(step.arguments)}` : void 0].filter(
|
|
412
|
+
(value) => value !== void 0
|
|
413
|
+
);
|
|
414
|
+
case "verify":
|
|
415
|
+
return step.checks.map((check) => `check=${check}`);
|
|
416
|
+
default:
|
|
417
|
+
return [];
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
function formatProcedureSource(source) {
|
|
421
|
+
const parts = [source.kind, source.label, source.path, source.locator].filter((value) => Boolean(value && value.length > 0));
|
|
422
|
+
return parts.join(" | ");
|
|
322
423
|
}
|
|
323
424
|
function formatTrace(entry, supersededBy, supersedes, claimFamily, recallEvents) {
|
|
324
425
|
const slotPolicy = entry.claim_key ? claimFamily ? {
|
|
@@ -469,12 +570,12 @@ var RECALL_TOOL_PARAMETERS = {
|
|
|
469
570
|
properties: {
|
|
470
571
|
query: {
|
|
471
572
|
type: "string",
|
|
472
|
-
description: "What you need to remember. Use a focused natural-language query rather than a broad 'everything' search. Phrase prior-state asks directly, for example 'what was the previous approach' or 'what changed from X to Y'."
|
|
573
|
+
description: "What you need to remember. Use a focused natural-language query rather than a broad 'everything' search. Phrase prior-state asks directly, for example 'what was the previous approach' or 'what changed from X to Y'. Phrase procedural asks directly, for example 'how do I rotate credentials' or 'what steps should I follow'."
|
|
473
574
|
},
|
|
474
575
|
mode: {
|
|
475
576
|
type: "string",
|
|
476
577
|
enum: [...RECALL_MODES],
|
|
477
|
-
description: "Recall mode: auto routes between exact entry recall, historical-state recall, and episodes; entries forces semantic recall; episodes forces temporal or semantic session recall."
|
|
578
|
+
description: "Recall mode: auto routes between exact entry recall, historical-state recall, procedural recall, and episodes; entries forces semantic recall; episodes forces temporal or semantic session recall; procedures forces procedural recall."
|
|
478
579
|
},
|
|
479
580
|
limit: {
|
|
480
581
|
type: "integer",
|
|
@@ -512,7 +613,7 @@ function createAgenrRecallTool(ctx, servicesPromise, logger) {
|
|
|
512
613
|
return {
|
|
513
614
|
name: "agenr_recall",
|
|
514
615
|
label: "Agenr Recall",
|
|
515
|
-
description: "Retrieve knowledge from agenr long-term memory. Use mode=auto for the normal path, including historical-state questions like what was the previous approach or what changed from X to Y; use mode=entries for exact facts and decisions; use mode=episodes for time-bounded 'what happened' questions. Time periods are parsed from the query text. Session-start recall is already handled automatically.",
|
|
616
|
+
description: "Retrieve knowledge from agenr long-term memory. Use mode=auto for the normal path, including historical-state questions like what was the previous approach or what changed from X to Y and procedural questions like how to do something or what steps to follow; use mode=entries for exact facts and decisions; use mode=episodes for time-bounded 'what happened' questions; use mode=procedures for canonical methods and checklists. Time periods are parsed from the query text. Session-start recall is already handled automatically.",
|
|
516
617
|
parameters: RECALL_TOOL_PARAMETERS,
|
|
517
618
|
async execute(_toolCallId, rawParams) {
|
|
518
619
|
try {
|
|
@@ -559,6 +660,7 @@ function createAgenrRecallTool(ctx, servicesPromise, logger) {
|
|
|
559
660
|
);
|
|
560
661
|
const result = await runUnifiedRecall(request, {
|
|
561
662
|
database: services.episodes,
|
|
663
|
+
procedures: services.procedures,
|
|
562
664
|
recall: services.recall,
|
|
563
665
|
embeddingAvailable: services.embeddingStatus.available,
|
|
564
666
|
embeddingError: services.embeddingStatus.error,
|
|
@@ -588,6 +690,24 @@ function createAgenrRecallTool(ctx, servicesPromise, logger) {
|
|
|
588
690
|
},
|
|
589
691
|
...result.asOf ? { asOf: result.asOf } : {},
|
|
590
692
|
...result.timeWindow ? { timeWindow: result.timeWindow } : {},
|
|
693
|
+
...result.procedure ? {
|
|
694
|
+
procedure: {
|
|
695
|
+
id: result.procedure.id,
|
|
696
|
+
procedureKey: result.procedure.procedure_key,
|
|
697
|
+
title: result.procedure.title,
|
|
698
|
+
goal: result.procedure.goal
|
|
699
|
+
}
|
|
700
|
+
} : {},
|
|
701
|
+
procedures: result.procedureCandidates.map((candidate) => ({
|
|
702
|
+
id: candidate.procedure.id,
|
|
703
|
+
procedureKey: candidate.procedure.procedure_key,
|
|
704
|
+
title: candidate.procedure.title,
|
|
705
|
+
goal: candidate.procedure.goal,
|
|
706
|
+
score: candidate.score,
|
|
707
|
+
lexicalScore: candidate.scores.lexical,
|
|
708
|
+
vectorScore: candidate.scores.vector
|
|
709
|
+
})),
|
|
710
|
+
procedureNotices: result.procedureNotices,
|
|
591
711
|
episodes: result.episodes.map((episode) => ({
|
|
592
712
|
id: episode.episode.id,
|
|
593
713
|
source: episode.episode.source,
|
|
@@ -1055,7 +1175,7 @@ function registerAgenrOpenClawTools(api, servicesPromise, logger) {
|
|
|
1055
1175
|
var openclaw_plugin_default = {
|
|
1056
1176
|
id: "agenr",
|
|
1057
1177
|
name: "agenr",
|
|
1058
|
-
version: "
|
|
1178
|
+
version: "2.0.0",
|
|
1059
1179
|
description: "agenr memory plugin for OpenClaw",
|
|
1060
1180
|
kind: "memory",
|
|
1061
1181
|
contracts: {
|
|
@@ -3193,6 +3313,7 @@ async function createAgenrOpenClawServices(config, options) {
|
|
|
3193
3313
|
dbPath: resolvedConfig.dbPath,
|
|
3194
3314
|
entries: runtimeServices.entries,
|
|
3195
3315
|
episodes: runtimeServices.episodes,
|
|
3316
|
+
procedures: runtimeServices.procedures,
|
|
3196
3317
|
memory: runtimeServices.memory,
|
|
3197
3318
|
embedding: runtimeServices.embedding,
|
|
3198
3319
|
recall: runtimeServices.recall,
|
|
@@ -3229,6 +3350,7 @@ async function createRuntimeServices(dbPath, config, embeddingStatus, openClawCo
|
|
|
3229
3350
|
return {
|
|
3230
3351
|
entries: database,
|
|
3231
3352
|
episodes: database,
|
|
3353
|
+
procedures: database,
|
|
3232
3354
|
memory: createOpenClawRepository(database, {
|
|
3233
3355
|
claimSlotPolicyConfig: openClawContext.pluginConfig.memoryPolicy?.slotPolicies
|
|
3234
3356
|
}),
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/dist/chunk-ETQPUJGS.js
DELETED
|
File without changes
|