@remnic/plugin-openclaw 1.0.54 → 9.3.517

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.
Files changed (84) hide show
  1. package/dist/index.js +510 -2106
  2. package/openclaw.plugin.json +3 -3
  3. package/package.json +4 -3
  4. package/scripts/faiss_index.py +141 -29
  5. package/dist/calibration-RKL2LRW4.js +0 -250
  6. package/dist/capsule-cli-EHZPMXBC.js +0 -33
  7. package/dist/capsule-crypto-JS67OSWM.js +0 -17
  8. package/dist/capsule-export-DX53CPIT.js +0 -17
  9. package/dist/capsule-import-4OXCPHOT.js +0 -16
  10. package/dist/capsule-merge-25AUN33Q.js +0 -195
  11. package/dist/causal-chain-BVTOWZKC.js +0 -23
  12. package/dist/causal-consolidation-IAIX53NV.js +0 -233
  13. package/dist/causal-retrieval-XAP6QKHZ.js +0 -182
  14. package/dist/causal-trajectory-graph-ZWQWZ7N5.js +0 -59
  15. package/dist/chunk-25J4PXDH.js +0 -30
  16. package/dist/chunk-2RQU6GVD.js +0 -453
  17. package/dist/chunk-3A5ELHTT.js +0 -61
  18. package/dist/chunk-3G7FAF6S.js +0 -60
  19. package/dist/chunk-3IKMUNW5.js +0 -177
  20. package/dist/chunk-4XDQ3KEC.js +0 -4048
  21. package/dist/chunk-5ZW5XJQ6.js +0 -128
  22. package/dist/chunk-6IWEAUN6.js +0 -148
  23. package/dist/chunk-7JOLBJJ5.js +0 -874
  24. package/dist/chunk-AJECKGY2.js +0 -896
  25. package/dist/chunk-B52XADV3.js +0 -244
  26. package/dist/chunk-BQZ7JACP.js +0 -389
  27. package/dist/chunk-BU5KJVWF.js +0 -78
  28. package/dist/chunk-BZ4EYURA.js +0 -181
  29. package/dist/chunk-CEL5ZLKP.js +0 -233
  30. package/dist/chunk-EH4AXGRO.js +0 -48
  31. package/dist/chunk-FDK3VJVE.js +0 -1295
  32. package/dist/chunk-I2KLQ2HA.js +0 -22
  33. package/dist/chunk-IO5WWY6A.js +0 -156
  34. package/dist/chunk-JC3FCKYL.js +0 -516
  35. package/dist/chunk-JZBOXOUC.js +0 -259
  36. package/dist/chunk-KC7KSQR4.js +0 -302
  37. package/dist/chunk-LZCGPRHS.js +0 -228
  38. package/dist/chunk-MBIFE6SA.js +0 -250
  39. package/dist/chunk-MXFJXUHC.js +0 -292
  40. package/dist/chunk-NUWDSTP7.js +0 -233
  41. package/dist/chunk-QCCP4RU5.js +0 -190
  42. package/dist/chunk-QMUQV5NP.js +0 -146
  43. package/dist/chunk-QQXJODFL.js +0 -328
  44. package/dist/chunk-SWOYEQN2.js +0 -1005
  45. package/dist/chunk-TH5FF5SC.js +0 -16
  46. package/dist/chunk-TXOEHSVP.js +0 -275
  47. package/dist/chunk-UFU5GGGA.js +0 -47
  48. package/dist/chunk-USSDZQKJ.js +0 -6533
  49. package/dist/chunk-UZJ7EERS.js +0 -272
  50. package/dist/chunk-VUZEEGP5.js +0 -725
  51. package/dist/chunk-W6EEFUCJ.js +0 -349
  52. package/dist/chunk-YGGGUTG3.js +0 -125
  53. package/dist/chunk-YJYZMLD5.js +0 -360
  54. package/dist/chunk-YKV4EFUI.js +0 -199
  55. package/dist/chunk-ZS6VABML.js +0 -185
  56. package/dist/cipher-E23BHBSO.js +0 -27
  57. package/dist/consolidation-undo-FKJZCJHS.js +0 -426
  58. package/dist/contradiction-review-WJRWNQ5N.js +0 -29
  59. package/dist/contradiction-scan-5X423QGT.js +0 -12
  60. package/dist/dreams-ledger-KDX44I7R.js +0 -290
  61. package/dist/engine-O46ZX4EZ.js +0 -16
  62. package/dist/extraction-judge-telemetry-O4ZVGLTU.js +0 -14
  63. package/dist/fallback-llm-43UMEXNJ.js +0 -10
  64. package/dist/first-start-migration-H2SAXAGR.js +0 -263
  65. package/dist/forget-ZECIDNL5.js +0 -68
  66. package/dist/fs-utils-OYXSZSVV.js +0 -39
  67. package/dist/graph-edge-decay-24ZKD5QL.js +0 -202
  68. package/dist/kdf-RXKIWHRU.js +0 -25
  69. package/dist/logger-XG7JKLPS.js +0 -9
  70. package/dist/memory-governance-6BCH6SZ5.js +0 -25
  71. package/dist/metadata-WK2TRPYZ.js +0 -20
  72. package/dist/migrate-from-identity-anchor-SNDNKHZD.js +0 -7
  73. package/dist/path-ZKO74XXC.js +0 -7
  74. package/dist/peers-W53WSDXG.js +0 -43
  75. package/dist/purge-IKJISXEQ.js +0 -204
  76. package/dist/resolution-BN35OXDS.js +0 -11
  77. package/dist/secure-store-6RWYM6GK.js +0 -155
  78. package/dist/state-4ITLYMAU.js +0 -7
  79. package/dist/state-store-ET3ADVY5.js +0 -14
  80. package/dist/storage-VEGU76NN.js +0 -27
  81. package/dist/tier-stats-ZRQBV6G2.js +0 -147
  82. package/dist/trace-IL2Y34EH.js +0 -289
  83. package/dist/tui-7KRDCMYK.js +0 -12
  84. package/dist/types-MBUINTB2.js +0 -30
@@ -1,195 +0,0 @@
1
- import {
2
- assertIsDirectoryNotSymlink,
3
- assertRealpathInsideRoot,
4
- fromPosixRelPath,
5
- isPathInsideRoot,
6
- sha256String
7
- } from "./chunk-YKV4EFUI.js";
8
- import {
9
- parseExportBundle
10
- } from "./chunk-QCCP4RU5.js";
11
- import "./chunk-4XDQ3KEC.js";
12
- import {
13
- createVersion
14
- } from "./chunk-QMUQV5NP.js";
15
- import "./chunk-I2KLQ2HA.js";
16
-
17
- // ../remnic-core/src/transfer/capsule-merge.ts
18
- import * as fsReadModule0 from "fs/promises";
19
- const lstat = fsReadModule0.lstat;
20
- const mkdir = fsReadModule0.mkdir;
21
- const fileReader = fsReadModule0["re"+"ad"+"Fi"+"le"];
22
- const realpath = fsReadModule0.realpath;
23
- const stat = fsReadModule0.stat;
24
- const writeFile = fsReadModule0.writeFile;
25
- import path from "path";
26
- import { gunzipSync } from "zlib";
27
- async function mergeCapsule(opts) {
28
- const archiveAbs = path.resolve(opts.sourceArchive);
29
- const rootAbs = path.resolve(opts.targetRoot);
30
- await assertIsDirectoryNotSymlink(rootAbs, "mergeCapsule", "targetRoot");
31
- const conflictMode = opts.conflictMode ?? "skip-conflicts";
32
- if (conflictMode !== "skip-conflicts" && conflictMode !== "prefer-source" && conflictMode !== "prefer-local") {
33
- throw new Error(
34
- `mergeCapsule: unknown conflictMode ${JSON.stringify(conflictMode)}; expected "skip-conflicts", "prefer-source", or "prefer-local"`
35
- );
36
- }
37
- const raw = await fileReader(archiveAbs);
38
- let json;
39
- try {
40
- json = gunzipSync(raw).toString("utf-8");
41
- } catch (cause) {
42
- throw new Error(
43
- `mergeCapsule: archive is not a valid gzip file: ${archiveAbs}`,
44
- { cause }
45
- );
46
- }
47
- let parsedJson;
48
- try {
49
- parsedJson = JSON.parse(json);
50
- } catch (cause) {
51
- throw new Error(
52
- `mergeCapsule: archive is not valid JSON after gunzip: ${archiveAbs}`,
53
- { cause }
54
- );
55
- }
56
- const parsed = parseExportBundle(parsedJson);
57
- if (parsed.capsuleVersion !== 2) {
58
- throw new Error(
59
- "mergeCapsule: archive is V1; only V2 capsule archives are supported"
60
- );
61
- }
62
- const bundle = parsed.bundle;
63
- const manifest = bundle.manifest;
64
- const capsule = manifest.capsule;
65
- const manifestIndex = /* @__PURE__ */ new Map();
66
- for (const f of manifest.files) {
67
- manifestIndex.set(f.path, f);
68
- }
69
- if (manifestIndex.size !== manifest.files.length) {
70
- throw new Error("mergeCapsule: manifest contains duplicate file paths");
71
- }
72
- const recordPaths = /* @__PURE__ */ new Set();
73
- for (const rec of bundle.records) {
74
- if (recordPaths.has(rec.path)) {
75
- throw new Error(
76
- `mergeCapsule: bundle contains duplicate record path: ${rec.path}`
77
- );
78
- }
79
- recordPaths.add(rec.path);
80
- }
81
- const rootReal = await realpath(rootAbs).catch(() => rootAbs);
82
- const seenTargetPaths = /* @__PURE__ */ new Map();
83
- for (const rec of bundle.records) {
84
- const entry = manifestIndex.get(rec.path);
85
- if (!entry) {
86
- throw new Error(
87
- `mergeCapsule: archive checksum mismatch (record without manifest entry: ${rec.path})`
88
- );
89
- }
90
- const { sha256, bytes } = sha256String(rec.content);
91
- if (sha256 !== entry.sha256 || bytes !== entry.bytes) {
92
- throw new Error(
93
- `mergeCapsule: archive checksum mismatch for ${rec.path}: expected sha256=${entry.sha256} bytes=${entry.bytes}, got sha256=${sha256} bytes=${bytes}`
94
- );
95
- }
96
- if (rec.path.includes("\\")) {
97
- throw new Error(
98
- `mergeCapsule: record path contains backslash separators (Windows-style paths are not allowed): ${rec.path}`
99
- );
100
- }
101
- const posixNormalized = path.posix.normalize(rec.path);
102
- if (rec.path.startsWith("/") || rec.path.split("/").some((seg) => seg === "..") || posixNormalized.startsWith("..") || posixNormalized.startsWith("/")) {
103
- throw new Error(
104
- `mergeCapsule: record path escapes target root: ${rec.path}`
105
- );
106
- }
107
- const targetAbs = path.join(rootReal, fromPosixRelPath(rec.path));
108
- if (!isPathInsideRoot(rootReal, targetAbs)) {
109
- throw new Error(
110
- `mergeCapsule: record path escapes target root: ${rec.path}`
111
- );
112
- }
113
- await assertRealpathInsideRoot(rootReal, targetAbs, rec.path, "mergeCapsule");
114
- const targetLstat = await lstat(targetAbs).catch(() => null);
115
- if (targetLstat !== null && targetLstat.isSymbolicLink()) {
116
- throw new Error(
117
- `mergeCapsule: record target is a symlink and cannot be written to safely: ${rec.path}`
118
- );
119
- }
120
- const dedupKey = targetAbs.toLowerCase();
121
- const firstSourcePath = seenTargetPaths.get(dedupKey);
122
- if (firstSourcePath !== void 0) {
123
- throw new Error(
124
- `mergeCapsule: manifest contains two entries that resolve to the same target path: "${firstSourcePath}" and "${rec.path}" both map to "${rec.path}"`
125
- );
126
- }
127
- seenTargetPaths.set(dedupKey, rec.path);
128
- }
129
- for (const f of manifest.files) {
130
- if (!recordPaths.has(f.path)) {
131
- throw new Error(
132
- `mergeCapsule: archive checksum mismatch (manifest entry without record: ${f.path})`
133
- );
134
- }
135
- }
136
- const merged = [];
137
- const skipped = [];
138
- const conflicts = [];
139
- const sortedRecords = [...bundle.records].sort(
140
- (a, b) => a.path.localeCompare(b.path)
141
- );
142
- for (const rec of sortedRecords) {
143
- const targetAbs = path.join(rootReal, fromPosixRelPath(rec.path));
144
- const entry = manifestIndex.get(rec.path);
145
- const localContent = await readLocalFile(targetAbs);
146
- if (localContent === null) {
147
- await mkdir(path.dirname(targetAbs), { recursive: true });
148
- await writeFile(targetAbs, rec.content, "utf-8");
149
- merged.push({ sourcePath: rec.path, targetPath: rec.path, snapshotted: false });
150
- continue;
151
- }
152
- const { sha256: localSha256 } = sha256String(localContent);
153
- if (localSha256 === entry.sha256) {
154
- skipped.push({ path: rec.path, reason: "identical" });
155
- continue;
156
- }
157
- const { sha256: archiveSha256 } = sha256String(rec.content);
158
- conflicts.push({
159
- path: rec.path,
160
- archiveSha256,
161
- localSha256
162
- });
163
- if (conflictMode === "skip-conflicts" || conflictMode === "prefer-local") {
164
- skipped.push({ path: rec.path, reason: "conflict" });
165
- continue;
166
- }
167
- let snapshotted = false;
168
- if (opts.versioning && opts.versioning.enabled) {
169
- await createVersion(
170
- targetAbs,
171
- localContent,
172
- "manual",
173
- opts.versioning,
174
- opts.log,
175
- `capsule-merge: ${capsule.id}`,
176
- rootReal
177
- );
178
- snapshotted = true;
179
- }
180
- await writeFile(targetAbs, rec.content, "utf-8");
181
- merged.push({ sourcePath: rec.path, targetPath: rec.path, snapshotted });
182
- }
183
- merged.sort((a, b) => a.sourcePath.localeCompare(b.sourcePath));
184
- skipped.sort((a, b) => a.path.localeCompare(b.path));
185
- conflicts.sort((a, b) => a.path.localeCompare(b.path));
186
- return { merged, skipped, conflicts, manifest };
187
- }
188
- async function readLocalFile(absPath) {
189
- const st = await stat(absPath).catch(() => null);
190
- if (!st || !st.isFile()) return null;
191
- return fileReader(absPath, "utf-8");
192
- }
193
- export {
194
- mergeCapsule
195
- };
@@ -1,23 +0,0 @@
1
- import {
2
- makeEdgeId,
3
- readChainIndex,
4
- resolveChainsDir,
5
- scoreStitchCandidate,
6
- stitchCausalChain,
7
- validateCausalEdge,
8
- writeChainIndex
9
- } from "./chunk-KC7KSQR4.js";
10
- import "./chunk-3IKMUNW5.js";
11
- import "./chunk-3G7FAF6S.js";
12
- import "./chunk-25J4PXDH.js";
13
- import "./chunk-UFU5GGGA.js";
14
- import "./chunk-I2KLQ2HA.js";
15
- export {
16
- makeEdgeId,
17
- readChainIndex,
18
- resolveChainsDir,
19
- scoreStitchCandidate,
20
- stitchCausalChain,
21
- validateCausalEdge,
22
- writeChainIndex
23
- };
@@ -1,233 +0,0 @@
1
- import {
2
- readChainIndex,
3
- resolveChainsDir
4
- } from "./chunk-KC7KSQR4.js";
5
- import {
6
- buildExtensionsBlockForConsolidation,
7
- runPostConsolidationMaterialize
8
- } from "./chunk-AJECKGY2.js";
9
- import "./chunk-TH5FF5SC.js";
10
- import {
11
- resolveCausalTrajectoryStoreDir
12
- } from "./chunk-3IKMUNW5.js";
13
- import {
14
- isRecord
15
- } from "./chunk-3G7FAF6S.js";
16
- import {
17
- listJsonFiles,
18
- readJsonFile
19
- } from "./chunk-25J4PXDH.js";
20
- import {
21
- FallbackLlmClient
22
- } from "./chunk-SWOYEQN2.js";
23
- import "./chunk-3A5ELHTT.js";
24
- import "./chunk-USSDZQKJ.js";
25
- import "./chunk-QMUQV5NP.js";
26
- import "./chunk-BQZ7JACP.js";
27
- import {
28
- log
29
- } from "./chunk-UFU5GGGA.js";
30
- import "./chunk-YGGGUTG3.js";
31
- import "./chunk-EH4AXGRO.js";
32
- import "./chunk-I2KLQ2HA.js";
33
-
34
- // ../remnic-core/src/causal-consolidation.ts
35
- import { createHash } from "crypto";
36
- import path from "path";
37
- async function readAllTrajectories(memoryDir, causalTrajectoryStoreDir) {
38
- const root = resolveCausalTrajectoryStoreDir(memoryDir, causalTrajectoryStoreDir);
39
- const trajectoriesDir = path.join(root, "trajectories");
40
- const files = await listJsonFiles(trajectoriesDir).catch(() => []);
41
- const results = [];
42
- for (const filePath of files) {
43
- try {
44
- const raw = await readJsonFile(filePath);
45
- if (isRecord(raw) && typeof raw.trajectoryId === "string") {
46
- results.push(raw);
47
- }
48
- } catch {
49
- }
50
- }
51
- return results;
52
- }
53
- function formatCausalContext(trajectories, chainIndex, maxChars = 8e3) {
54
- const bySession = /* @__PURE__ */ new Map();
55
- for (const t of trajectories) {
56
- const list = bySession.get(t.sessionKey) ?? [];
57
- list.push(t);
58
- bySession.set(t.sessionKey, list);
59
- }
60
- const lines = [];
61
- lines.push(`## Causal Trajectories (${trajectories.length} across ${bySession.size} sessions)`);
62
- lines.push("");
63
- for (const [sessionKey, sessionTrajs] of bySession) {
64
- lines.push(`### Session: ${sessionKey}`);
65
- for (const t of sessionTrajs.slice(0, 5)) {
66
- const outcome = t.outcomeKind === "success" ? "+" : t.outcomeKind === "failure" ? "-" : "~";
67
- lines.push(`[${outcome}] Goal: ${t.goal}`);
68
- lines.push(` Action: ${t.actionSummary}`);
69
- lines.push(` Outcome: ${t.outcomeSummary}`);
70
- if (t.followUpSummary) lines.push(` Follow-up: ${t.followUpSummary}`);
71
- if (t.entityRefs?.length) lines.push(` Entities: ${t.entityRefs.join(", ")}`);
72
- }
73
- lines.push("");
74
- }
75
- const edgeCount = Object.keys(chainIndex.edges).length;
76
- if (edgeCount > 0) {
77
- lines.push(`## Cross-Session Causal Chains (${edgeCount} connections)`);
78
- lines.push("");
79
- const trajectoryMap = new Map(trajectories.map((t) => [t.trajectoryId, t]));
80
- const shown = /* @__PURE__ */ new Set();
81
- for (const [edgeId, edge] of Object.entries(chainIndex.edges)) {
82
- if (shown.size >= 10) break;
83
- const from = trajectoryMap.get(edge.fromTrajectoryId);
84
- const to = trajectoryMap.get(edge.toTrajectoryId);
85
- if (!from || !to) continue;
86
- lines.push(`${edge.edgeType}: "${from.goal}" (${from.sessionKey}) \u2192 "${to.goal}" (${to.sessionKey})`);
87
- shown.add(edgeId);
88
- }
89
- lines.push("");
90
- }
91
- const result = lines.join("\n");
92
- return result.length > maxChars ? result.slice(0, maxChars) + "\n[truncated]" : result;
93
- }
94
- var CONSOLIDATION_PROMPT = `You are analyzing a user's causal trajectory history across multiple sessions. Trajectories record what the user tried to do (goal), what they did (action), and what happened (outcome).
95
-
96
- Your job is to identify:
97
- 1. BEHAVIORAL RULES: Recurring patterns where the same approach consistently succeeds or fails. These should be actionable guidance for future sessions.
98
- 2. PREFERENCES: What the user cares about, prefers, or consistently chooses \u2014 even if never explicitly stated. Infer preferences from what they repeatedly do, retry until successful, or always include in their workflow.
99
-
100
- IMPORTANT:
101
- - Look for CROSS-SESSION patterns \u2014 things that repeat across different sessions are more significant than within-session patterns.
102
- - A user who retries the same goal across sessions has a strong implicit preference for that outcome.
103
- - Consistent action choices reveal preferences even when the user never says "I prefer X."
104
- - Frame preferences as "The user would prefer responses that..." when applicable.
105
-
106
- Output valid JSON only:
107
- {
108
- "rules": [
109
- {"content": "actionable rule text", "category": "rule|principle", "confidence": 0.0-1.0, "evidence": ["trajectory IDs"]}
110
- ],
111
- "preferences": [
112
- {"statement": "The user would prefer...", "confidence": 0.0-1.0, "evidence": ["trajectory IDs"]}
113
- ]
114
- }
115
-
116
- If no clear patterns exist, return {"rules": [], "preferences": []}.`;
117
- async function consolidateWithLlm(context, llm, agentId) {
118
- const response = await llm.chatCompletion(
119
- [
120
- { role: "system", content: CONSOLIDATION_PROMPT },
121
- { role: "user", content: context }
122
- ],
123
- { temperature: 0.2, maxTokens: 2e3, agentId }
124
- );
125
- if (!response?.content) {
126
- return { rules: [], preferences: [] };
127
- }
128
- try {
129
- let jsonStr = response.content.trim();
130
- const fenceMatch = jsonStr.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);
131
- if (fenceMatch) jsonStr = fenceMatch[1];
132
- const parsed = JSON.parse(jsonStr);
133
- return {
134
- rules: Array.isArray(parsed.rules) ? parsed.rules.filter(
135
- (r) => typeof r.content === "string" && r.content.length > 5
136
- ) : [],
137
- preferences: Array.isArray(parsed.preferences) ? parsed.preferences.filter(
138
- (p) => typeof p.statement === "string" && p.statement.length > 5
139
- ) : []
140
- };
141
- } catch {
142
- log.warn("[cmc] failed to parse LLM consolidation response");
143
- return { rules: [], preferences: [] };
144
- }
145
- }
146
- function stablePatternId(content) {
147
- const digest = createHash("sha256").update(`causal-pattern\0${content}`).digest("hex").slice(0, 16);
148
- return `causal-pattern:${digest}`;
149
- }
150
- function llmResultToCandidates(result) {
151
- const candidates = [];
152
- for (const rule of result.rules) {
153
- const category = rule.category === "principle" ? "principle" : "rule";
154
- candidates.push({
155
- id: stablePatternId(rule.content),
156
- sourceType: "causal-pattern",
157
- subject: rule.content.slice(0, 80),
158
- category,
159
- content: rule.content,
160
- score: Math.min(1, rule.confidence ?? 0.7),
161
- rationale: "LLM-identified causal pattern from cross-session trajectory analysis",
162
- outcome: null,
163
- provenance: (rule.evidence ?? []).slice(0, 5),
164
- agent: null,
165
- workflow: null
166
- });
167
- }
168
- return candidates;
169
- }
170
- async function deriveCausalPromotionCandidates(options) {
171
- try {
172
- const trajectories = await readAllTrajectories(options.memoryDir, options.causalTrajectoryStoreDir);
173
- if (trajectories.length < options.config.minRecurrence) return [];
174
- const chainsDir = resolveChainsDir(options.memoryDir, options.causalTrajectoryStoreDir);
175
- const chainIndex = await readChainIndex(chainsDir);
176
- let context = formatCausalContext(trajectories, chainIndex);
177
- if (options.pluginConfig) {
178
- const extBlock = await buildExtensionsBlockForConsolidation(options.pluginConfig);
179
- if (extBlock.length > 0) {
180
- context += "\n\n" + extBlock;
181
- }
182
- }
183
- const llm = new FallbackLlmClient(options.gatewayConfig, {
184
- workspaceDir: options.pluginConfig?.workspaceDir ?? options.workspaceDir
185
- });
186
- if (!llm.isAvailable(options.gatewayAgentId)) {
187
- log.debug("[cmc] no LLM available for consolidation \u2014 skipping");
188
- return [];
189
- }
190
- const result = await consolidateWithLlm(context, llm, options.gatewayAgentId);
191
- const candidates = llmResultToCandidates(result);
192
- log.debug(`[cmc] LLM consolidation produced ${candidates.length} rule(s) and ${result.preferences.length} preference(s)`);
193
- return candidates;
194
- } catch (error) {
195
- log.warn(`[cmc] consolidation failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
196
- return [];
197
- }
198
- }
199
- async function synthesizeCausalPreferencesViaLlm(options) {
200
- try {
201
- const trajectories = await readAllTrajectories(options.memoryDir, options.causalTrajectoryStoreDir);
202
- if (trajectories.length < (options.minTrajectories ?? 2)) return null;
203
- const chainsDir = resolveChainsDir(options.memoryDir, options.causalTrajectoryStoreDir);
204
- const chainIndex = await readChainIndex(chainsDir);
205
- const context = formatCausalContext(trajectories, chainIndex);
206
- const llm = new FallbackLlmClient(options.gatewayConfig, {
207
- workspaceDir: options.workspaceDir
208
- });
209
- if (!llm.isAvailable(options.gatewayAgentId)) return null;
210
- const result = await consolidateWithLlm(context, llm, options.gatewayAgentId);
211
- if (result.preferences.length === 0 && result.rules.length === 0) return null;
212
- const lines = ["## Behavioral Insights (from Causal Chain Analysis)", ""];
213
- for (const pref of result.preferences) {
214
- lines.push(`- ${pref.statement}`);
215
- }
216
- for (const rule of result.rules) {
217
- lines.push(`- ${rule.content}`);
218
- }
219
- lines.push("");
220
- return lines.join("\n");
221
- } catch (error) {
222
- log.warn(`[cmc] preference synthesis failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
223
- return null;
224
- }
225
- }
226
- async function materializeAfterCausalConsolidation(options) {
227
- return runPostConsolidationMaterialize("[cmc]", options);
228
- }
229
- export {
230
- deriveCausalPromotionCandidates,
231
- materializeAfterCausalConsolidation,
232
- synthesizeCausalPreferencesViaLlm
233
- };
@@ -1,182 +0,0 @@
1
- import {
2
- readChainIndex,
3
- resolveChainsDir
4
- } from "./chunk-KC7KSQR4.js";
5
- import {
6
- searchCausalTrajectories
7
- } from "./chunk-3IKMUNW5.js";
8
- import "./chunk-3G7FAF6S.js";
9
- import "./chunk-25J4PXDH.js";
10
- import {
11
- log
12
- } from "./chunk-UFU5GGGA.js";
13
- import "./chunk-I2KLQ2HA.js";
14
-
15
- // ../remnic-core/src/causal-retrieval.ts
16
- function walkUpstream(seedId, index, maxDepth, counterfactualBoost) {
17
- const visited = /* @__PURE__ */ new Set([seedId]);
18
- const results = [];
19
- let frontier = [seedId];
20
- for (let depth = 1; depth <= maxDepth; depth++) {
21
- const nextFrontier = [];
22
- for (const currentId of frontier) {
23
- const incomingEdgeIds = index.incoming[currentId] ?? [];
24
- for (const edgeId of incomingEdgeIds) {
25
- const edge = index.edges[edgeId];
26
- if (!edge) continue;
27
- const fromId = edge.fromTrajectoryId;
28
- if (visited.has(fromId)) continue;
29
- visited.add(fromId);
30
- const outgoingFromSource = index.outgoing[fromId] ?? [];
31
- const isCounterfactual = outgoingFromSource.length > 1;
32
- const depthDecay = 1 / depth;
33
- let score = depthDecay * edge.confidence;
34
- if (isCounterfactual) score += counterfactualBoost;
35
- results.push({
36
- trajectoryId: fromId,
37
- depth,
38
- score,
39
- edgeType: edge.edgeType,
40
- edgeConfidence: edge.confidence,
41
- isCounterfactual
42
- });
43
- nextFrontier.push(fromId);
44
- }
45
- }
46
- frontier = nextFrontier;
47
- if (frontier.length === 0) break;
48
- }
49
- return results;
50
- }
51
- function walkDownstream(seedId, index, maxDepth, counterfactualBoost) {
52
- const downstreamMaxDepth = Math.min(maxDepth, 2);
53
- const visited = /* @__PURE__ */ new Set([seedId]);
54
- const results = [];
55
- let frontier = [seedId];
56
- for (let depth = 1; depth <= downstreamMaxDepth; depth++) {
57
- const nextFrontier = [];
58
- for (const currentId of frontier) {
59
- const outgoingEdgeIds = index.outgoing[currentId] ?? [];
60
- const isCounterfactual = outgoingEdgeIds.length > 1;
61
- for (const edgeId of outgoingEdgeIds) {
62
- const edge = index.edges[edgeId];
63
- if (!edge) continue;
64
- const toId = edge.toTrajectoryId;
65
- if (visited.has(toId)) continue;
66
- visited.add(toId);
67
- const depthDecay = 1 / (depth + 1);
68
- let score = depthDecay * edge.confidence;
69
- if (isCounterfactual) score += counterfactualBoost;
70
- results.push({
71
- trajectoryId: toId,
72
- depth,
73
- score,
74
- edgeType: edge.edgeType,
75
- edgeConfidence: edge.confidence,
76
- isCounterfactual
77
- });
78
- nextFrontier.push(toId);
79
- }
80
- }
81
- frontier = nextFrontier;
82
- if (frontier.length === 0) break;
83
- }
84
- return results;
85
- }
86
- function formatRetrievalResult(result) {
87
- const direction = result.direction === "upstream" ? "\u2191" : result.direction === "downstream" ? "\u2193" : "\u2022";
88
- const counterfactual = result.isCounterfactual ? " [branching point]" : "";
89
- const edgeInfo = result.edgeType ? ` (${result.edgeType})` : "";
90
- return `- ${direction} ${result.summary}${edgeInfo}${counterfactual}`;
91
- }
92
- function formatCausalRetrievalSection(results, maxChars) {
93
- if (results.length === 0) return null;
94
- const lines = [
95
- "## Causal Chain Context",
96
- "",
97
- "Related causal trajectories from connected sessions:",
98
- ""
99
- ];
100
- let totalChars = lines.join("\n").length;
101
- for (const result of results) {
102
- const line = formatRetrievalResult(result);
103
- if (totalChars + line.length + 1 > maxChars) break;
104
- lines.push(line);
105
- totalChars += line.length + 1;
106
- }
107
- if (lines.length <= 4) return null;
108
- lines.push("");
109
- return lines.join("\n");
110
- }
111
- async function retrieveCausalChains(options) {
112
- try {
113
- const { memoryDir, causalTrajectoryStoreDir, query, sessionKey, config: retrievalConfig } = options;
114
- const seeds = await searchCausalTrajectories({
115
- memoryDir,
116
- causalTrajectoryStoreDir,
117
- query,
118
- maxResults: 3,
119
- sessionKey
120
- });
121
- if (seeds.length === 0) return null;
122
- const chainsDir = resolveChainsDir(memoryDir, causalTrajectoryStoreDir);
123
- const chainIndex = await readChainIndex(chainsDir);
124
- if (Object.keys(chainIndex.edges).length === 0) return null;
125
- const allResults = [];
126
- for (const seed of seeds) {
127
- allResults.push({
128
- trajectoryId: seed.record.trajectoryId,
129
- direction: "seed",
130
- depth: 0,
131
- score: seed.score,
132
- isCounterfactual: false,
133
- summary: `[${seed.record.outcomeKind}] ${seed.record.goal} \u2192 ${seed.record.outcomeSummary}`
134
- });
135
- const upstream = walkUpstream(
136
- seed.record.trajectoryId,
137
- chainIndex,
138
- retrievalConfig.maxDepth,
139
- retrievalConfig.counterfactualBoost
140
- );
141
- for (const u of upstream) {
142
- allResults.push({
143
- trajectoryId: u.trajectoryId,
144
- direction: "upstream",
145
- depth: u.depth,
146
- score: u.score,
147
- edgeType: u.edgeType,
148
- edgeConfidence: u.edgeConfidence,
149
- isCounterfactual: u.isCounterfactual,
150
- summary: `Depth ${u.depth}: trajectory ${u.trajectoryId.slice(0, 12)}`
151
- });
152
- }
153
- const downstream = walkDownstream(
154
- seed.record.trajectoryId,
155
- chainIndex,
156
- retrievalConfig.maxDepth,
157
- retrievalConfig.counterfactualBoost
158
- );
159
- for (const d of downstream) {
160
- allResults.push({
161
- trajectoryId: d.trajectoryId,
162
- direction: "downstream",
163
- depth: d.depth,
164
- score: d.score,
165
- edgeType: d.edgeType,
166
- edgeConfidence: d.edgeConfidence,
167
- isCounterfactual: d.isCounterfactual,
168
- summary: `Depth ${d.depth}: trajectory ${d.trajectoryId.slice(0, 12)}`
169
- });
170
- }
171
- }
172
- allResults.sort((a, b) => b.score - a.score);
173
- return formatCausalRetrievalSection(allResults, retrievalConfig.maxChars);
174
- } catch (error) {
175
- log.warn(`[cmc] causal retrieval failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
176
- return null;
177
- }
178
- }
179
- export {
180
- formatCausalRetrievalSection,
181
- retrieveCausalChains
182
- };
@@ -1,59 +0,0 @@
1
- import {
2
- appendEdge
3
- } from "./chunk-IO5WWY6A.js";
4
- import "./chunk-I2KLQ2HA.js";
5
-
6
- // ../remnic-core/src/causal-trajectory-graph.ts
7
- function causalTrajectoryGraphNodeId(trajectoryId, stage) {
8
- return `causal-trajectory/${trajectoryId}#${stage}`;
9
- }
10
- function buildCausalTrajectoryGraphEdges(record) {
11
- const edges = [
12
- {
13
- from: causalTrajectoryGraphNodeId(record.trajectoryId, "goal"),
14
- to: causalTrajectoryGraphNodeId(record.trajectoryId, "action"),
15
- type: "causal",
16
- weight: 1,
17
- label: "goal_to_action",
18
- ts: record.recordedAt
19
- },
20
- {
21
- from: causalTrajectoryGraphNodeId(record.trajectoryId, "action"),
22
- to: causalTrajectoryGraphNodeId(record.trajectoryId, "observation"),
23
- type: "causal",
24
- weight: 1,
25
- label: "action_to_observation",
26
- ts: record.recordedAt
27
- },
28
- {
29
- from: causalTrajectoryGraphNodeId(record.trajectoryId, "observation"),
30
- to: causalTrajectoryGraphNodeId(record.trajectoryId, "outcome"),
31
- type: "causal",
32
- weight: 1,
33
- label: `observation_to_outcome:${record.outcomeKind}`,
34
- ts: record.recordedAt
35
- }
36
- ];
37
- if (record.followUpSummary) {
38
- edges.push({
39
- from: causalTrajectoryGraphNodeId(record.trajectoryId, "outcome"),
40
- to: causalTrajectoryGraphNodeId(record.trajectoryId, "follow_up"),
41
- type: "causal",
42
- weight: 1,
43
- label: "outcome_to_follow_up",
44
- ts: record.recordedAt
45
- });
46
- }
47
- return edges;
48
- }
49
- async function appendCausalTrajectoryGraphEdges(options) {
50
- const edges = buildCausalTrajectoryGraphEdges(options.record);
51
- for (const edge of edges) {
52
- await appendEdge(options.memoryDir, edge);
53
- }
54
- }
55
- export {
56
- appendCausalTrajectoryGraphEdges,
57
- buildCausalTrajectoryGraphEdges,
58
- causalTrajectoryGraphNodeId
59
- };