@joshuaswarren/openclaw-engram 8.3.64 → 8.3.66
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 +121 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1604,6 +1604,21 @@ var FallbackLlmClient = class {
|
|
|
1604
1604
|
|
|
1605
1605
|
// src/schemas.ts
|
|
1606
1606
|
import { z } from "zod";
|
|
1607
|
+
var MemoryActionTypeSchema = z.enum([
|
|
1608
|
+
"store_episode",
|
|
1609
|
+
"store_note",
|
|
1610
|
+
"update_note",
|
|
1611
|
+
"create_artifact",
|
|
1612
|
+
"summarize_node",
|
|
1613
|
+
"discard",
|
|
1614
|
+
"link_graph"
|
|
1615
|
+
]);
|
|
1616
|
+
var MemoryActionEligibilityContextSchema = z.object({
|
|
1617
|
+
confidence: z.number().min(0).max(1),
|
|
1618
|
+
lifecycleState: z.enum(["active", "validated", "candidate", "stale", "archived"]),
|
|
1619
|
+
importance: z.number().min(0).max(1),
|
|
1620
|
+
source: z.enum(["extraction", "consolidation", "replay", "manual", "unknown"])
|
|
1621
|
+
}).strict();
|
|
1607
1622
|
var ExtractedFactSchema = z.object({
|
|
1608
1623
|
category: z.enum(["fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill"]),
|
|
1609
1624
|
content: z.string().describe("The memory content \u2014 a clear, standalone statement"),
|
|
@@ -10919,6 +10934,92 @@ async function readAllEdges(memoryDir, config) {
|
|
|
10919
10934
|
]);
|
|
10920
10935
|
return parts.flat();
|
|
10921
10936
|
}
|
|
10937
|
+
function isValidGraphEdge(raw, expectedType) {
|
|
10938
|
+
if (!raw || typeof raw !== "object") return false;
|
|
10939
|
+
const edge = raw;
|
|
10940
|
+
return edge.type === expectedType && typeof edge.from === "string" && edge.from.length > 0 && typeof edge.to === "string" && edge.to.length > 0 && typeof edge.weight === "number" && Number.isFinite(edge.weight) && typeof edge.label === "string" && typeof edge.ts === "string";
|
|
10941
|
+
}
|
|
10942
|
+
async function analyzeGraphHealth(memoryDir, options) {
|
|
10943
|
+
const enabledTypes = [];
|
|
10944
|
+
if (options?.entityGraphEnabled !== false) enabledTypes.push("entity");
|
|
10945
|
+
if (options?.timeGraphEnabled !== false) enabledTypes.push("time");
|
|
10946
|
+
if (options?.causalGraphEnabled !== false) enabledTypes.push("causal");
|
|
10947
|
+
const files = [];
|
|
10948
|
+
const globalNodes = /* @__PURE__ */ new Set();
|
|
10949
|
+
for (const type of enabledTypes) {
|
|
10950
|
+
const filePath = graphFilePath(memoryDir, type);
|
|
10951
|
+
let exists3 = true;
|
|
10952
|
+
let totalLines = 0;
|
|
10953
|
+
let validEdges = 0;
|
|
10954
|
+
let corruptLines = 0;
|
|
10955
|
+
const nodes = /* @__PURE__ */ new Set();
|
|
10956
|
+
try {
|
|
10957
|
+
const raw = await readFile14(filePath, "utf8");
|
|
10958
|
+
for (const line of raw.split("\n")) {
|
|
10959
|
+
const trimmed = line.trim();
|
|
10960
|
+
if (!trimmed) continue;
|
|
10961
|
+
totalLines += 1;
|
|
10962
|
+
try {
|
|
10963
|
+
const parsed = JSON.parse(trimmed);
|
|
10964
|
+
if (!isValidGraphEdge(parsed, type)) {
|
|
10965
|
+
corruptLines += 1;
|
|
10966
|
+
continue;
|
|
10967
|
+
}
|
|
10968
|
+
validEdges += 1;
|
|
10969
|
+
nodes.add(parsed.from);
|
|
10970
|
+
nodes.add(parsed.to);
|
|
10971
|
+
globalNodes.add(parsed.from);
|
|
10972
|
+
globalNodes.add(parsed.to);
|
|
10973
|
+
} catch {
|
|
10974
|
+
corruptLines += 1;
|
|
10975
|
+
}
|
|
10976
|
+
}
|
|
10977
|
+
} catch {
|
|
10978
|
+
exists3 = false;
|
|
10979
|
+
}
|
|
10980
|
+
files.push({
|
|
10981
|
+
type,
|
|
10982
|
+
filePath,
|
|
10983
|
+
exists: exists3,
|
|
10984
|
+
totalLines,
|
|
10985
|
+
validEdges,
|
|
10986
|
+
corruptLines,
|
|
10987
|
+
uniqueNodes: nodes.size
|
|
10988
|
+
});
|
|
10989
|
+
}
|
|
10990
|
+
const totals = files.reduce(
|
|
10991
|
+
(acc, item) => {
|
|
10992
|
+
acc.totalLines += item.totalLines;
|
|
10993
|
+
acc.validEdges += item.validEdges;
|
|
10994
|
+
acc.corruptLines += item.corruptLines;
|
|
10995
|
+
return acc;
|
|
10996
|
+
},
|
|
10997
|
+
{
|
|
10998
|
+
totalLines: 0,
|
|
10999
|
+
validEdges: 0,
|
|
11000
|
+
corruptLines: 0,
|
|
11001
|
+
uniqueNodes: globalNodes.size
|
|
11002
|
+
}
|
|
11003
|
+
);
|
|
11004
|
+
totals.uniqueNodes = globalNodes.size;
|
|
11005
|
+
const report = {
|
|
11006
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11007
|
+
enabledTypes,
|
|
11008
|
+
totals,
|
|
11009
|
+
files
|
|
11010
|
+
};
|
|
11011
|
+
if (options?.includeRepairGuidance === true) {
|
|
11012
|
+
const guidance = [];
|
|
11013
|
+
if (totals.corruptLines > 0) {
|
|
11014
|
+
guidance.push("Corrupt graph lines detected: back up memory/state/graphs, then rebuild graphs from clean memory replay/extraction runs.");
|
|
11015
|
+
}
|
|
11016
|
+
if (totals.validEdges === 0) {
|
|
11017
|
+
guidance.push("No valid edges detected yet: run normal extraction traffic (or replay ingestion) to seed graph files.");
|
|
11018
|
+
}
|
|
11019
|
+
if (guidance.length > 0) report.repairGuidance = guidance;
|
|
11020
|
+
}
|
|
11021
|
+
return report;
|
|
11022
|
+
}
|
|
10922
11023
|
function detectCausalPhrase(text) {
|
|
10923
11024
|
const lower = text.toLowerCase();
|
|
10924
11025
|
for (const phrase of CAUSAL_PHRASES) {
|
|
@@ -20823,6 +20924,14 @@ async function runMigrateObservationsCliCommand(options) {
|
|
|
20823
20924
|
async function runConversationIndexHealthCliCommand(orchestrator) {
|
|
20824
20925
|
return orchestrator.getConversationIndexHealth();
|
|
20825
20926
|
}
|
|
20927
|
+
async function runGraphHealthCliCommand(options) {
|
|
20928
|
+
return analyzeGraphHealth(options.memoryDir, {
|
|
20929
|
+
entityGraphEnabled: options.entityGraphEnabled,
|
|
20930
|
+
timeGraphEnabled: options.timeGraphEnabled,
|
|
20931
|
+
causalGraphEnabled: options.causalGraphEnabled,
|
|
20932
|
+
includeRepairGuidance: options.includeRepairGuidance
|
|
20933
|
+
});
|
|
20934
|
+
}
|
|
20826
20935
|
async function runTailscaleStatusCliCommand(options = {}) {
|
|
20827
20936
|
const helper = options.helper ?? new TailscaleHelper({ timeoutMs: options.timeoutMs });
|
|
20828
20937
|
return helper.status();
|
|
@@ -21454,6 +21563,18 @@ function registerCli(api, orchestrator) {
|
|
|
21454
21563
|
console.log(JSON.stringify(health, null, 2));
|
|
21455
21564
|
console.log("OK");
|
|
21456
21565
|
});
|
|
21566
|
+
cmd.command("graph-health").description("Show graph edge-file integrity, node coverage, and corruption counts").option("--repair-guidance", "Include non-destructive repair guidance").action(async (...args) => {
|
|
21567
|
+
const options = args[0] ?? {};
|
|
21568
|
+
const report = await runGraphHealthCliCommand({
|
|
21569
|
+
memoryDir: orchestrator.config.memoryDir,
|
|
21570
|
+
entityGraphEnabled: orchestrator.config.entityGraphEnabled,
|
|
21571
|
+
timeGraphEnabled: orchestrator.config.timeGraphEnabled,
|
|
21572
|
+
causalGraphEnabled: orchestrator.config.causalGraphEnabled,
|
|
21573
|
+
includeRepairGuidance: options.repairGuidance === true
|
|
21574
|
+
});
|
|
21575
|
+
console.log(JSON.stringify(report, null, 2));
|
|
21576
|
+
console.log("OK");
|
|
21577
|
+
});
|
|
21457
21578
|
cmd.command("tailscale-status").description("Show Tailscale availability and daemon status").option("--timeout-ms <n>", "Command timeout in milliseconds", "10000").action(async (...args) => {
|
|
21458
21579
|
const options = args[0] ?? {};
|
|
21459
21580
|
const timeoutMsRaw = parseInt(String(options.timeoutMs ?? "10000"), 10);
|