@vainplex/openclaw-cortex 0.3.0 → 0.4.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.
Files changed (151) hide show
  1. package/README.md +89 -55
  2. package/dist/src/config.d.ts.map +1 -1
  3. package/dist/src/config.js +3 -0
  4. package/dist/src/config.js.map +1 -1
  5. package/dist/src/hooks.d.ts.map +1 -1
  6. package/dist/src/hooks.js +13 -1
  7. package/dist/src/hooks.js.map +1 -1
  8. package/dist/src/trace-analyzer/analyzer.d.ts +59 -0
  9. package/dist/src/trace-analyzer/analyzer.d.ts.map +1 -0
  10. package/dist/src/trace-analyzer/analyzer.js +175 -0
  11. package/dist/src/trace-analyzer/analyzer.js.map +1 -0
  12. package/dist/src/trace-analyzer/chain-reconstructor.d.ts +52 -0
  13. package/dist/src/trace-analyzer/chain-reconstructor.d.ts.map +1 -0
  14. package/dist/src/trace-analyzer/chain-reconstructor.js +190 -0
  15. package/dist/src/trace-analyzer/chain-reconstructor.js.map +1 -0
  16. package/dist/src/trace-analyzer/classifier.d.ts +28 -0
  17. package/dist/src/trace-analyzer/classifier.d.ts.map +1 -0
  18. package/dist/src/trace-analyzer/classifier.js +271 -0
  19. package/dist/src/trace-analyzer/classifier.js.map +1 -0
  20. package/dist/src/trace-analyzer/config.d.ts +78 -0
  21. package/dist/src/trace-analyzer/config.d.ts.map +1 -0
  22. package/dist/src/trace-analyzer/config.js +161 -0
  23. package/dist/src/trace-analyzer/config.js.map +1 -0
  24. package/dist/src/trace-analyzer/events.d.ts +70 -0
  25. package/dist/src/trace-analyzer/events.d.ts.map +1 -0
  26. package/dist/src/trace-analyzer/events.js +228 -0
  27. package/dist/src/trace-analyzer/events.js.map +1 -0
  28. package/dist/src/trace-analyzer/hooks.d.ts +22 -0
  29. package/dist/src/trace-analyzer/hooks.d.ts.map +1 -0
  30. package/dist/src/trace-analyzer/hooks.js +151 -0
  31. package/dist/src/trace-analyzer/hooks.js.map +1 -0
  32. package/dist/src/trace-analyzer/index.d.ts +32 -0
  33. package/dist/src/trace-analyzer/index.d.ts.map +1 -0
  34. package/dist/src/trace-analyzer/index.js +30 -0
  35. package/dist/src/trace-analyzer/index.js.map +1 -0
  36. package/dist/src/trace-analyzer/nats-trace-source.d.ts +10 -0
  37. package/dist/src/trace-analyzer/nats-trace-source.d.ts.map +1 -0
  38. package/dist/src/trace-analyzer/nats-trace-source.js +151 -0
  39. package/dist/src/trace-analyzer/nats-trace-source.js.map +1 -0
  40. package/dist/src/trace-analyzer/output-generator.d.ts +29 -0
  41. package/dist/src/trace-analyzer/output-generator.d.ts.map +1 -0
  42. package/dist/src/trace-analyzer/output-generator.js +142 -0
  43. package/dist/src/trace-analyzer/output-generator.js.map +1 -0
  44. package/dist/src/trace-analyzer/redactor.d.ts +14 -0
  45. package/dist/src/trace-analyzer/redactor.d.ts.map +1 -0
  46. package/dist/src/trace-analyzer/redactor.js +137 -0
  47. package/dist/src/trace-analyzer/redactor.js.map +1 -0
  48. package/dist/src/trace-analyzer/report.d.ts +93 -0
  49. package/dist/src/trace-analyzer/report.d.ts.map +1 -0
  50. package/dist/src/trace-analyzer/report.js +108 -0
  51. package/dist/src/trace-analyzer/report.js.map +1 -0
  52. package/dist/src/trace-analyzer/signals/correction.d.ts +11 -0
  53. package/dist/src/trace-analyzer/signals/correction.d.ts.map +1 -0
  54. package/dist/src/trace-analyzer/signals/correction.js +54 -0
  55. package/dist/src/trace-analyzer/signals/correction.js.map +1 -0
  56. package/dist/src/trace-analyzer/signals/dissatisfied.d.ts +11 -0
  57. package/dist/src/trace-analyzer/signals/dissatisfied.d.ts.map +1 -0
  58. package/dist/src/trace-analyzer/signals/dissatisfied.js +60 -0
  59. package/dist/src/trace-analyzer/signals/dissatisfied.js.map +1 -0
  60. package/dist/src/trace-analyzer/signals/doom-loop.d.ts +13 -0
  61. package/dist/src/trace-analyzer/signals/doom-loop.d.ts.map +1 -0
  62. package/dist/src/trace-analyzer/signals/doom-loop.js +156 -0
  63. package/dist/src/trace-analyzer/signals/doom-loop.js.map +1 -0
  64. package/dist/src/trace-analyzer/signals/hallucination.d.ts +11 -0
  65. package/dist/src/trace-analyzer/signals/hallucination.d.ts.map +1 -0
  66. package/dist/src/trace-analyzer/signals/hallucination.js +67 -0
  67. package/dist/src/trace-analyzer/signals/hallucination.js.map +1 -0
  68. package/dist/src/trace-analyzer/signals/index.d.ts +16 -0
  69. package/dist/src/trace-analyzer/signals/index.d.ts.map +1 -0
  70. package/dist/src/trace-analyzer/signals/index.js +92 -0
  71. package/dist/src/trace-analyzer/signals/index.js.map +1 -0
  72. package/dist/src/trace-analyzer/signals/lang/index.d.ts +4 -0
  73. package/dist/src/trace-analyzer/signals/lang/index.d.ts.map +1 -0
  74. package/dist/src/trace-analyzer/signals/lang/index.js +2 -0
  75. package/dist/src/trace-analyzer/signals/lang/index.js.map +1 -0
  76. package/dist/src/trace-analyzer/signals/lang/registry.d.ts +41 -0
  77. package/dist/src/trace-analyzer/signals/lang/registry.d.ts.map +1 -0
  78. package/dist/src/trace-analyzer/signals/lang/registry.js +111 -0
  79. package/dist/src/trace-analyzer/signals/lang/registry.js.map +1 -0
  80. package/dist/src/trace-analyzer/signals/lang/signal-lang-de.d.ts +10 -0
  81. package/dist/src/trace-analyzer/signals/lang/signal-lang-de.d.ts.map +1 -0
  82. package/dist/src/trace-analyzer/signals/lang/signal-lang-de.js +60 -0
  83. package/dist/src/trace-analyzer/signals/lang/signal-lang-de.js.map +1 -0
  84. package/dist/src/trace-analyzer/signals/lang/signal-lang-en.d.ts +4 -0
  85. package/dist/src/trace-analyzer/signals/lang/signal-lang-en.d.ts.map +1 -0
  86. package/dist/src/trace-analyzer/signals/lang/signal-lang-en.js +55 -0
  87. package/dist/src/trace-analyzer/signals/lang/signal-lang-en.js.map +1 -0
  88. package/dist/src/trace-analyzer/signals/lang/signal-lang-es.d.ts +9 -0
  89. package/dist/src/trace-analyzer/signals/lang/signal-lang-es.d.ts.map +1 -0
  90. package/dist/src/trace-analyzer/signals/lang/signal-lang-es.js +59 -0
  91. package/dist/src/trace-analyzer/signals/lang/signal-lang-es.js.map +1 -0
  92. package/dist/src/trace-analyzer/signals/lang/signal-lang-fr.d.ts +10 -0
  93. package/dist/src/trace-analyzer/signals/lang/signal-lang-fr.d.ts.map +1 -0
  94. package/dist/src/trace-analyzer/signals/lang/signal-lang-fr.js +60 -0
  95. package/dist/src/trace-analyzer/signals/lang/signal-lang-fr.js.map +1 -0
  96. package/dist/src/trace-analyzer/signals/lang/signal-lang-it.d.ts +9 -0
  97. package/dist/src/trace-analyzer/signals/lang/signal-lang-it.d.ts.map +1 -0
  98. package/dist/src/trace-analyzer/signals/lang/signal-lang-it.js +59 -0
  99. package/dist/src/trace-analyzer/signals/lang/signal-lang-it.js.map +1 -0
  100. package/dist/src/trace-analyzer/signals/lang/signal-lang-ja.d.ts +9 -0
  101. package/dist/src/trace-analyzer/signals/lang/signal-lang-ja.d.ts.map +1 -0
  102. package/dist/src/trace-analyzer/signals/lang/signal-lang-ja.js +59 -0
  103. package/dist/src/trace-analyzer/signals/lang/signal-lang-ja.js.map +1 -0
  104. package/dist/src/trace-analyzer/signals/lang/signal-lang-ko.d.ts +9 -0
  105. package/dist/src/trace-analyzer/signals/lang/signal-lang-ko.d.ts.map +1 -0
  106. package/dist/src/trace-analyzer/signals/lang/signal-lang-ko.js +59 -0
  107. package/dist/src/trace-analyzer/signals/lang/signal-lang-ko.js.map +1 -0
  108. package/dist/src/trace-analyzer/signals/lang/signal-lang-pt.d.ts +9 -0
  109. package/dist/src/trace-analyzer/signals/lang/signal-lang-pt.d.ts.map +1 -0
  110. package/dist/src/trace-analyzer/signals/lang/signal-lang-pt.js +59 -0
  111. package/dist/src/trace-analyzer/signals/lang/signal-lang-pt.js.map +1 -0
  112. package/dist/src/trace-analyzer/signals/lang/signal-lang-ru.d.ts +9 -0
  113. package/dist/src/trace-analyzer/signals/lang/signal-lang-ru.d.ts.map +1 -0
  114. package/dist/src/trace-analyzer/signals/lang/signal-lang-ru.js +59 -0
  115. package/dist/src/trace-analyzer/signals/lang/signal-lang-ru.js.map +1 -0
  116. package/dist/src/trace-analyzer/signals/lang/signal-lang-zh.d.ts +8 -0
  117. package/dist/src/trace-analyzer/signals/lang/signal-lang-zh.d.ts.map +1 -0
  118. package/dist/src/trace-analyzer/signals/lang/signal-lang-zh.js +58 -0
  119. package/dist/src/trace-analyzer/signals/lang/signal-lang-zh.js.map +1 -0
  120. package/dist/src/trace-analyzer/signals/lang/types.d.ts +76 -0
  121. package/dist/src/trace-analyzer/signals/lang/types.d.ts.map +1 -0
  122. package/dist/src/trace-analyzer/signals/lang/types.js +12 -0
  123. package/dist/src/trace-analyzer/signals/lang/types.js.map +1 -0
  124. package/dist/src/trace-analyzer/signals/repeat-fail.d.ts +24 -0
  125. package/dist/src/trace-analyzer/signals/repeat-fail.d.ts.map +1 -0
  126. package/dist/src/trace-analyzer/signals/repeat-fail.js +112 -0
  127. package/dist/src/trace-analyzer/signals/repeat-fail.js.map +1 -0
  128. package/dist/src/trace-analyzer/signals/tool-fail.d.ts +10 -0
  129. package/dist/src/trace-analyzer/signals/tool-fail.d.ts.map +1 -0
  130. package/dist/src/trace-analyzer/signals/tool-fail.js +99 -0
  131. package/dist/src/trace-analyzer/signals/tool-fail.js.map +1 -0
  132. package/dist/src/trace-analyzer/signals/types.d.ts +54 -0
  133. package/dist/src/trace-analyzer/signals/types.d.ts.map +1 -0
  134. package/dist/src/trace-analyzer/signals/types.js +9 -0
  135. package/dist/src/trace-analyzer/signals/types.js.map +1 -0
  136. package/dist/src/trace-analyzer/signals/unverified-claim.d.ts +11 -0
  137. package/dist/src/trace-analyzer/signals/unverified-claim.d.ts.map +1 -0
  138. package/dist/src/trace-analyzer/signals/unverified-claim.js +84 -0
  139. package/dist/src/trace-analyzer/signals/unverified-claim.js.map +1 -0
  140. package/dist/src/trace-analyzer/trace-source.d.ts +31 -0
  141. package/dist/src/trace-analyzer/trace-source.d.ts.map +1 -0
  142. package/dist/src/trace-analyzer/trace-source.js +5 -0
  143. package/dist/src/trace-analyzer/trace-source.js.map +1 -0
  144. package/dist/src/trace-analyzer/util.d.ts +17 -0
  145. package/dist/src/trace-analyzer/util.d.ts.map +1 -0
  146. package/dist/src/trace-analyzer/util.js +26 -0
  147. package/dist/src/trace-analyzer/util.js.map +1 -0
  148. package/dist/src/types.d.ts +2 -0
  149. package/dist/src/types.d.ts.map +1 -1
  150. package/dist/src/types.js.map +1 -1
  151. package/package.json +1 -1
@@ -0,0 +1,190 @@
1
+ // ============================================================
2
+ // Trace Analyzer — Chain Reconstructor
3
+ // ============================================================
4
+ //
5
+ // Reconstructs conversation chains from a stream of NormalizedEvents.
6
+ // Groups by (session, agent), splits on lifecycle boundaries and
7
+ // inactivity gaps, deduplicates across Schema A/B events, and
8
+ // uses a sliding window for memory management.
9
+ // ============================================================
10
+ import { createHash } from "node:crypto";
11
+ const DEFAULT_OPTS = {
12
+ gapMinutes: 30,
13
+ maxEventsPerChain: 1000,
14
+ };
15
+ /** Phase 1: Bucket events by (session, agent). */
16
+ async function bucketEvents(events) {
17
+ const buckets = new Map();
18
+ for await (const event of events) {
19
+ const key = `${event.session}::${event.agent}`;
20
+ let bucket = buckets.get(key);
21
+ if (!bucket) {
22
+ bucket = [];
23
+ buckets.set(key, bucket);
24
+ }
25
+ bucket.push(event);
26
+ }
27
+ return buckets;
28
+ }
29
+ /** Convert a segment of events into a ConversationChain. */
30
+ function segmentToChain(segment) {
31
+ const first = segment[0];
32
+ const last = segment[segment.length - 1];
33
+ const typeCounts = {};
34
+ for (const e of segment) {
35
+ typeCounts[e.type] = (typeCounts[e.type] ?? 0) + 1;
36
+ }
37
+ return {
38
+ id: computeChainId(first.session, first.agent, first.ts),
39
+ agent: first.agent,
40
+ session: first.session,
41
+ startTs: first.ts,
42
+ endTs: last.ts,
43
+ events: segment,
44
+ typeCounts,
45
+ boundaryType: determineBoundaryType(segment),
46
+ };
47
+ }
48
+ /**
49
+ * Reconstruct conversation chains from a stream of normalized events.
50
+ *
51
+ * Two-pass algorithm:
52
+ * 1. Accumulate events into (session, agent) buckets
53
+ * 2. Split each bucket into chains by boundaries, deduplicate, emit
54
+ */
55
+ export async function reconstructChains(events, opts) {
56
+ const config = { ...DEFAULT_OPTS, ...opts };
57
+ const buckets = await bucketEvents(events);
58
+ const chains = [];
59
+ for (const bucket of buckets.values()) {
60
+ bucket.sort((a, b) => a.ts - b.ts);
61
+ const deduped = deduplicateEvents(bucket);
62
+ const segments = splitOnBoundaries(deduped, config);
63
+ for (const segment of segments) {
64
+ if (segment.length >= 2)
65
+ chains.push(segmentToChain(segment));
66
+ }
67
+ }
68
+ return chains;
69
+ }
70
+ /**
71
+ * Determine if a chain boundary should be inserted between prev and curr.
72
+ * Checks lifecycle events and inactivity gaps.
73
+ */
74
+ function isBoundary(prev, curr, gapMs) {
75
+ if (curr.type === "session.start")
76
+ return true;
77
+ if (prev.type === "session.end")
78
+ return true;
79
+ if (prev.type === "run.end" && curr.type === "run.start" && curr.ts - prev.ts > 5 * 60 * 1000)
80
+ return true;
81
+ if (curr.ts - prev.ts > gapMs)
82
+ return true;
83
+ return false;
84
+ }
85
+ /**
86
+ * Split a sorted, deduplicated event list into chain segments based on
87
+ * lifecycle boundaries, inactivity gaps, and memory caps.
88
+ */
89
+ function splitOnBoundaries(events, opts) {
90
+ if (events.length === 0)
91
+ return [];
92
+ const gapMs = opts.gapMinutes * 60 * 1000;
93
+ const chains = [];
94
+ let current = [events[0]];
95
+ for (let i = 1; i < events.length; i++) {
96
+ if (isBoundary(events[i - 1], events[i], gapMs)) {
97
+ if (current.length > 0)
98
+ chains.push(current);
99
+ current = [events[i]];
100
+ }
101
+ else {
102
+ current.push(events[i]);
103
+ if (current.length >= opts.maxEventsPerChain) {
104
+ chains.push(current);
105
+ current = [];
106
+ }
107
+ }
108
+ }
109
+ if (current.length > 0)
110
+ chains.push(current);
111
+ return chains;
112
+ }
113
+ /**
114
+ * Deduplicate events within a sorted event list.
115
+ * When two events share the same fingerprint (same type, agent, time window,
116
+ * and content/params), keep the one with the higher sequence number.
117
+ */
118
+ export function deduplicateEvents(events) {
119
+ const seen = new Map();
120
+ for (const event of events) {
121
+ const fp = eventFingerprint(event);
122
+ const existing = seen.get(fp);
123
+ if (!existing) {
124
+ seen.set(fp, event);
125
+ }
126
+ else {
127
+ // Keep the event with the higher sequence number (prefer Schema A)
128
+ if (event.seq > existing.seq) {
129
+ seen.set(fp, event);
130
+ }
131
+ }
132
+ }
133
+ // Return in timestamp order
134
+ return [...seen.values()].sort((a, b) => a.ts - b.ts);
135
+ }
136
+ /**
137
+ * Compute a fingerprint for deduplication.
138
+ * Uses a 1-second time window to match events from both schemas
139
+ * that represent the same underlying action.
140
+ */
141
+ export function eventFingerprint(event) {
142
+ const tsWindow = Math.floor(event.ts / 1000); // 1-second window
143
+ switch (event.type) {
144
+ case "msg.in":
145
+ case "msg.out": {
146
+ const contentHash = simpleHash(event.payload.content ?? "");
147
+ return `${event.type}:${event.agent}:${tsWindow}:${contentHash}`;
148
+ }
149
+ case "tool.call": {
150
+ const paramsHash = simpleHash(JSON.stringify(event.payload.toolParams ?? {}));
151
+ return `${event.type}:${event.agent}:${event.payload.toolName ?? ""}:${tsWindow}:${paramsHash}`;
152
+ }
153
+ case "tool.result": {
154
+ const toolName = event.payload.toolName ?? "";
155
+ return `tool.result:${event.agent}:${toolName}:${tsWindow}`;
156
+ }
157
+ default:
158
+ // Session/run lifecycle events — use exact type + timestamp
159
+ return `${event.type}:${event.agent}:${event.ts}`;
160
+ }
161
+ }
162
+ /** Fast non-crypto hash for dedup fingerprinting. */
163
+ export function simpleHash(str) {
164
+ let hash = 5381;
165
+ for (let i = 0; i < Math.min(str.length, 200); i++) {
166
+ hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;
167
+ }
168
+ return hash >>> 0;
169
+ }
170
+ /** Compute a deterministic chain ID. */
171
+ export function computeChainId(session, agent, firstTs) {
172
+ const input = `${session}:${agent}:${firstTs}`;
173
+ return createHash("sha256").update(input).digest("hex").slice(0, 16);
174
+ }
175
+ /** Determine the boundary type of a chain segment based on its events. */
176
+ function determineBoundaryType(events) {
177
+ if (events.length === 0)
178
+ return "gap";
179
+ const first = events[0];
180
+ const last = events[events.length - 1];
181
+ // If the chain starts with a lifecycle event, it's lifecycle-bounded
182
+ if (first.type === "session.start" ||
183
+ first.type === "run.start" ||
184
+ last.type === "session.end" ||
185
+ last.type === "run.end") {
186
+ return "lifecycle";
187
+ }
188
+ return "gap";
189
+ }
190
+ //# sourceMappingURL=chain-reconstructor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-reconstructor.js","sourceRoot":"","sources":["../../../src/trace-analyzer/chain-reconstructor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { PluginLogger } from "../types.js";
2
+ import type { LlmConfig } from "../llm-enhance.js";
3
+ import type { TraceAnalyzerConfig } from "./config.js";
4
+ import type { ConversationChain } from "./chain-reconstructor.js";
5
+ import type { Finding } from "./signals/types.js";
6
+ type ResolvedLlmConfig = {
7
+ enabled: boolean;
8
+ endpoint: string;
9
+ model: string;
10
+ apiKey: string;
11
+ timeoutMs: number;
12
+ };
13
+ /**
14
+ * Merge analyzer-specific LLM overrides with top-level config.
15
+ * Per-field merge, not full replace (R-031).
16
+ */
17
+ export declare function resolveAnalyzerLlmConfig(topLevel: LlmConfig, override: TraceAnalyzerConfig["llm"]): ResolvedLlmConfig;
18
+ export declare function formatChainAsTranscript(chain: ConversationChain): string;
19
+ /**
20
+ * Classify findings using LLM analysis (Stage 2).
21
+ *
22
+ * If LLM is disabled, returns findings unchanged (classification=null).
23
+ * If triage model configured, filters false positives first.
24
+ * Graceful degradation: invalid JSON → classification=null, timeout → skip.
25
+ */
26
+ export declare function classifyFindings(findings: Finding[], chains: Map<string, ConversationChain>, config: TraceAnalyzerConfig, topLevelLlm: LlmConfig, logger: PluginLogger): Promise<Finding[]>;
27
+ export {};
28
+ //# sourceMappingURL=classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../../src/trace-analyzer/classifier.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,oBAAoB,CAAC;AAMzE,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,mBAAmB,CAAC,KAAK,CAAC,GACnC,iBAAiB,CAWnB;AAoCD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAmCxE;AAoMD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACtC,MAAM,EAAE,mBAAmB,EAC3B,WAAW,EAAE,SAAS,EACtB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,OAAO,EAAE,CAAC,CAgCpB"}
@@ -0,0 +1,271 @@
1
+ // ============================================================
2
+ // Trace Analyzer — LLM Classifier (Stage 2)
3
+ // ============================================================
4
+ //
5
+ // Takes Finding[] from signal detection, optionally triages them
6
+ // with a fast/local model, then classifies remaining findings
7
+ // with a capable analysis model. Implements R-015, R-017, R-018,
8
+ // R-031, R-046, R-047.
9
+ // ============================================================
10
+ import { redactChain } from "./redactor.js";
11
+ import { truncate } from "./util.js";
12
+ /**
13
+ * Merge analyzer-specific LLM overrides with top-level config.
14
+ * Per-field merge, not full replace (R-031).
15
+ */
16
+ export function resolveAnalyzerLlmConfig(topLevel, override) {
17
+ if (!override.enabled) {
18
+ return { enabled: false, endpoint: "", model: "", apiKey: "", timeoutMs: 15000 };
19
+ }
20
+ return {
21
+ enabled: true,
22
+ endpoint: override.endpoint ?? topLevel.endpoint,
23
+ model: override.model ?? topLevel.model,
24
+ apiKey: override.apiKey ?? topLevel.apiKey,
25
+ timeoutMs: override.timeoutMs ?? topLevel.timeoutMs,
26
+ };
27
+ }
28
+ // ---- Prompts ----
29
+ const TRIAGE_SYSTEM_PROMPT = `You are a signal triage system. Given a failure detection summary, decide:
30
+ 1. Is this a TRUE positive (real failure) or FALSE positive (benign/expected behavior)?
31
+ 2. If true positive, what severity? (low/medium/high/critical)
32
+
33
+ Respond ONLY with JSON: {"keep": true|false, "severity": "low|medium|high|critical", "reason": "one sentence"}
34
+
35
+ Common false positives to watch for:
36
+ - User saying "nein" to a question (not a correction)
37
+ - Tool errors that the agent intentionally provoked for testing
38
+ - Session endings due to timeout, not dissatisfaction
39
+ - Tool calls to check status (no claim made, just checking)`;
40
+ const DEEP_ANALYSIS_SYSTEM_PROMPT = `You are analyzing an agent failure trace. Given the full conversation chain and failure signal, produce:
41
+
42
+ 1. **rootCause**: Why did the failure happen? Be specific.
43
+ 2. **actionType**: What kind of fix prevents recurrence?
44
+ - "soul_rule": A behavioral directive for the agent's system prompt
45
+ - "governance_policy": A machine-enforced policy rule
46
+ - "cortex_pattern": A regex pattern for real-time detection
47
+ - "manual_review": Requires human judgment
48
+ 3. **actionText**: The specific rule/policy/pattern text. Be concrete.
49
+ - For soul_rule: "NIEMALS X — stattdessen Y. [Grund: Z]" or "NEVER X — instead Y. [Reason: Z]"
50
+ - For governance_policy: The condition and effect as a sentence.
51
+ - For cortex_pattern: A regex string.
52
+ - For manual_review: Describe what to investigate.
53
+ 4. **confidence**: How confident are you (0.0–1.0)?
54
+
55
+ Respond ONLY with valid JSON:
56
+ {"rootCause": "...", "actionType": "soul_rule|governance_policy|cortex_pattern|manual_review", "actionText": "...", "confidence": 0.85}`;
57
+ // ---- Chain-to-Transcript Formatter ----
58
+ export function formatChainAsTranscript(chain) {
59
+ const lines = [];
60
+ for (const event of chain.events) {
61
+ const ts = new Date(event.ts).toISOString();
62
+ switch (event.type) {
63
+ case "msg.in":
64
+ lines.push(`[${ts}] USER: ${truncate(event.payload.content ?? "", 500)}`);
65
+ break;
66
+ case "msg.out":
67
+ lines.push(`[${ts}] AGENT: ${truncate(event.payload.content ?? "", 500)}`);
68
+ break;
69
+ case "tool.call":
70
+ lines.push(`[${ts}] TOOL_CALL: ${event.payload.toolName ?? "unknown"}(${truncate(JSON.stringify(event.payload.toolParams ?? {}), 300)})`);
71
+ break;
72
+ case "tool.result":
73
+ if (event.payload.toolError) {
74
+ lines.push(`[${ts}] TOOL_ERROR: ${event.payload.toolName ?? "unknown"} → ${truncate(String(event.payload.toolError), 300)}`);
75
+ }
76
+ else {
77
+ const resultStr = typeof event.payload.toolResult === "object"
78
+ ? JSON.stringify(event.payload.toolResult)
79
+ : String(event.payload.toolResult ?? "");
80
+ lines.push(`[${ts}] TOOL_OK: ${event.payload.toolName ?? "unknown"} → ${truncate(resultStr, 300)}`);
81
+ }
82
+ break;
83
+ case "session.start":
84
+ lines.push(`[${ts}] SESSION_START`);
85
+ break;
86
+ case "session.end":
87
+ lines.push(`[${ts}] SESSION_END`);
88
+ break;
89
+ default:
90
+ lines.push(`[${ts}] ${event.type.toUpperCase()}`);
91
+ }
92
+ }
93
+ return lines.join("\n");
94
+ }
95
+ // ---- HTTP Call (uses node built-in fetch — Node 22) ----
96
+ /** Resolve config fields that may come from ResolvedLlmConfig or TriageLlmConfig. */
97
+ function resolveLlmCallConfig(config) {
98
+ return {
99
+ endpoint: "endpoint" in config ? config.endpoint : "",
100
+ model: "model" in config ? config.model : "",
101
+ apiKey: "apiKey" in config && config.apiKey ? config.apiKey : "",
102
+ timeoutMs: "timeoutMs" in config && config.timeoutMs ? config.timeoutMs : 15000,
103
+ };
104
+ }
105
+ /** Extract the assistant message content from an OpenAI-compatible response. */
106
+ function parseLlmResponse(data) {
107
+ const choices = data.choices;
108
+ return choices?.[0]?.message?.content ?? null;
109
+ }
110
+ async function callLlmChat(config, messages, logger) {
111
+ const { endpoint, model, apiKey, timeoutMs } = resolveLlmCallConfig(config);
112
+ if (!endpoint || !model)
113
+ return null;
114
+ const url = `${endpoint}/chat/completions`;
115
+ const body = JSON.stringify({
116
+ model, messages, temperature: 0.1,
117
+ max_tokens: 1000, response_format: { type: "json_object" },
118
+ });
119
+ const headers = { "Content-Type": "application/json" };
120
+ if (apiKey)
121
+ headers["Authorization"] = `Bearer ${apiKey}`;
122
+ try {
123
+ const controller = new AbortController();
124
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
125
+ const response = await fetch(url, { method: "POST", headers, body, signal: controller.signal });
126
+ clearTimeout(timer);
127
+ if (!response.ok) {
128
+ logger.warn(`[trace-analyzer] LLM HTTP ${response.status}: ${response.statusText}`);
129
+ return null;
130
+ }
131
+ return parseLlmResponse(await response.json());
132
+ }
133
+ catch (err) {
134
+ if (err instanceof Error && err.name === "AbortError") {
135
+ logger.warn(`[trace-analyzer] LLM request timed out (${timeoutMs}ms)`);
136
+ }
137
+ else {
138
+ logger.warn(`[trace-analyzer] LLM request failed: ${err instanceof Error ? err.message : String(err)}`);
139
+ }
140
+ return null;
141
+ }
142
+ }
143
+ // ---- Response Parsing (Graceful Degradation) ----
144
+ const VALID_ACTION_TYPES = ["soul_rule", "governance_policy", "cortex_pattern", "manual_review"];
145
+ function parseClassification(raw, model, logger) {
146
+ if (!raw)
147
+ return null;
148
+ try {
149
+ // Try to extract JSON from response (may have markdown fences)
150
+ let jsonStr = raw.trim();
151
+ const fenceMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)```/);
152
+ if (fenceMatch) {
153
+ jsonStr = fenceMatch[1].trim();
154
+ }
155
+ const parsed = JSON.parse(jsonStr);
156
+ if (typeof parsed.rootCause !== "string" || typeof parsed.actionText !== "string") {
157
+ logger.warn("[trace-analyzer] LLM response missing required fields");
158
+ return null;
159
+ }
160
+ let actionType = String(parsed.actionType ?? "manual_review");
161
+ if (!VALID_ACTION_TYPES.includes(actionType)) {
162
+ logger.warn(`[trace-analyzer] LLM returned unknown actionType: ${actionType}`);
163
+ actionType = "manual_review";
164
+ }
165
+ return {
166
+ rootCause: parsed.rootCause,
167
+ actionType: actionType,
168
+ actionText: parsed.actionText,
169
+ confidence: typeof parsed.confidence === "number" ? parsed.confidence : 0.5,
170
+ model,
171
+ };
172
+ }
173
+ catch {
174
+ logger.warn("[trace-analyzer] Failed to parse LLM classification response as JSON");
175
+ return null;
176
+ }
177
+ }
178
+ function parseTriageResponse(raw, logger) {
179
+ if (!raw)
180
+ return null;
181
+ try {
182
+ let jsonStr = raw.trim();
183
+ const fenceMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)```/);
184
+ if (fenceMatch) {
185
+ jsonStr = fenceMatch[1].trim();
186
+ }
187
+ const parsed = JSON.parse(jsonStr);
188
+ if (typeof parsed.keep !== "boolean")
189
+ return null;
190
+ return {
191
+ keep: parsed.keep,
192
+ severity: typeof parsed.severity === "string" ? parsed.severity : undefined,
193
+ };
194
+ }
195
+ catch {
196
+ logger.warn("[trace-analyzer] Failed to parse triage response");
197
+ return null;
198
+ }
199
+ }
200
+ async function triageFinding(finding, triageConfig, logger) {
201
+ const userPrompt = `Signal: ${finding.signal.signal}
202
+ Detected severity: ${finding.signal.severity}
203
+ Summary: ${finding.signal.summary}
204
+ Agent: ${finding.agent}
205
+ Evidence: ${JSON.stringify(finding.signal.evidence, null, 2)}`;
206
+ const raw = await callLlmChat(triageConfig, [
207
+ { role: "system", content: TRIAGE_SYSTEM_PROMPT },
208
+ { role: "user", content: userPrompt },
209
+ ], logger);
210
+ const result = parseTriageResponse(raw, logger);
211
+ if (!result)
212
+ return true; // On failure, keep the finding (conservative)
213
+ return result.keep;
214
+ }
215
+ // ---- Deep Analysis ----
216
+ async function deepAnalyze(finding, chain, config, logger) {
217
+ const transcript = formatChainAsTranscript(chain);
218
+ const userPrompt = `## Failure Signal
219
+ Type: ${finding.signal.signal}
220
+ Severity: ${finding.signal.severity}
221
+ Summary: ${finding.signal.summary}
222
+
223
+ ## Evidence
224
+ ${JSON.stringify(finding.signal.evidence, null, 2)}
225
+
226
+ ## Full Conversation Chain (${chain.events.length} events, ${chain.agent}@${chain.session})
227
+ ${transcript}`;
228
+ const raw = await callLlmChat(config, [
229
+ { role: "system", content: DEEP_ANALYSIS_SYSTEM_PROMPT },
230
+ { role: "user", content: userPrompt },
231
+ ], logger);
232
+ return parseClassification(raw, config.model, logger);
233
+ }
234
+ // ---- Main Classification Pipeline ----
235
+ /**
236
+ * Classify findings using LLM analysis (Stage 2).
237
+ *
238
+ * If LLM is disabled, returns findings unchanged (classification=null).
239
+ * If triage model configured, filters false positives first.
240
+ * Graceful degradation: invalid JSON → classification=null, timeout → skip.
241
+ */
242
+ export async function classifyFindings(findings, chains, config, topLevelLlm, logger) {
243
+ const llmConfig = resolveAnalyzerLlmConfig(topLevelLlm, config.llm);
244
+ if (!llmConfig.enabled)
245
+ return findings;
246
+ const result = [];
247
+ for (const finding of findings) {
248
+ // Step 1: Triage (optional)
249
+ if (config.llm.triage) {
250
+ const keep = await triageFinding(finding, config.llm.triage, logger);
251
+ if (!keep) {
252
+ logger.debug(`[trace-analyzer] Triage filtered finding ${finding.id}`);
253
+ continue;
254
+ }
255
+ }
256
+ // Step 2: Deep analysis
257
+ const chain = chains.get(finding.chainId);
258
+ if (!chain) {
259
+ result.push(finding); // No chain context — skip classification
260
+ continue;
261
+ }
262
+ const redactedChain = redactChain(chain, config.redactPatterns);
263
+ const classification = await deepAnalyze(finding, redactedChain, llmConfig, logger);
264
+ result.push({
265
+ ...finding,
266
+ classification,
267
+ });
268
+ }
269
+ return result;
270
+ }
271
+ //# sourceMappingURL=classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../../src/trace-analyzer/classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /** Signal identifiers for the failure signal taxonomy. */
2
+ export type SignalId = "SIG-CORRECTION" | "SIG-TOOL-FAIL" | "SIG-DOOM-LOOP" | "SIG-DISSATISFIED" | "SIG-REPEAT-FAIL" | "SIG-HALLUCINATION" | "SIG-UNVERIFIED-CLAIM";
3
+ /** Severity levels for failure signals. */
4
+ export type Severity = "low" | "medium" | "high" | "critical";
5
+ /** Triage LLM configuration (fast/local model for filtering). */
6
+ export type TriageLlmConfig = {
7
+ endpoint: string;
8
+ model: string;
9
+ apiKey?: string;
10
+ timeoutMs?: number;
11
+ };
12
+ /** Trace analyzer configuration. */
13
+ export type TraceAnalyzerConfig = {
14
+ /** Master switch. Default: false. */
15
+ enabled: boolean;
16
+ /** NATS connection for the trace source. */
17
+ nats: {
18
+ /** NATS server URL (e.g., "nats://localhost:4222"). */
19
+ url: string;
20
+ /** JetStream stream name (e.g., "openclaw-events"). */
21
+ stream: string;
22
+ /** NATS subject prefix (e.g., "openclaw.events"). */
23
+ subjectPrefix: string;
24
+ /** Optional credentials file path. */
25
+ credentials?: string;
26
+ /** Optional user. */
27
+ user?: string;
28
+ /** Optional password. */
29
+ password?: string;
30
+ };
31
+ /** Scheduled analysis runs. */
32
+ schedule: {
33
+ /** Enable scheduled runs. Default: false. */
34
+ enabled: boolean;
35
+ /** Hours between runs. Default: 24. */
36
+ intervalHours: number;
37
+ };
38
+ /** Inactivity gap in minutes for chain boundary detection. Default: 30. */
39
+ chainGapMinutes: number;
40
+ /** Per-signal toggles and severity overrides. */
41
+ signals: Partial<Record<SignalId, {
42
+ enabled: boolean;
43
+ severity?: Severity;
44
+ }>>;
45
+ /** LLM config overrides for trace analysis. */
46
+ llm: {
47
+ enabled: boolean;
48
+ endpoint?: string;
49
+ model?: string;
50
+ apiKey?: string;
51
+ timeoutMs?: number;
52
+ /** Optional triage model (fast, local). */
53
+ triage?: TriageLlmConfig;
54
+ };
55
+ /** Output configuration. */
56
+ output: {
57
+ /** Maximum findings in a single report. Default: 200. */
58
+ maxFindings: number;
59
+ /** Custom report output path. */
60
+ reportPath?: string;
61
+ };
62
+ /** Redaction patterns (regex strings) applied before LLM/disk writes. */
63
+ redactPatterns: string[];
64
+ /** Context window size for incremental processing. Default: 500. */
65
+ incrementalContextWindow: number;
66
+ /** NATS consumer batch size for fetching events. Default: 500. */
67
+ fetchBatchSize: number;
68
+ /** Maximum events to process per run. Default: 100000. */
69
+ maxEventsPerRun: number;
70
+ };
71
+ /** Default trace analyzer configuration. */
72
+ export declare const TRACE_ANALYZER_DEFAULTS: TraceAnalyzerConfig;
73
+ /**
74
+ * Resolve a raw config object into a fully-typed TraceAnalyzerConfig.
75
+ * Missing values are filled from TRACE_ANALYZER_DEFAULTS.
76
+ */
77
+ export declare function resolveTraceAnalyzerConfig(raw?: Record<string, unknown>): TraceAnalyzerConfig;
78
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/trace-analyzer/config.ts"],"names":[],"mappings":"AAQA,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAChB,gBAAgB,GAChB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,iBAAiB,GACjB,mBAAmB,GACnB,sBAAsB,CAAC;AAE3B,2CAA2C;AAC3C,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAE9D,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,oCAAoC;AACpC,MAAM,MAAM,mBAAmB,GAAG;IAChC,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IAEjB,4CAA4C;IAC5C,IAAI,EAAE;QACJ,uDAAuD;QACvD,GAAG,EAAE,MAAM,CAAC;QACZ,uDAAuD;QACvD,MAAM,EAAE,MAAM,CAAC;QACf,qDAAqD;QACrD,aAAa,EAAE,MAAM,CAAC;QACtB,sCAAsC;QACtC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,qBAAqB;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,yBAAyB;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF,+BAA+B;IAC/B,QAAQ,EAAE;QACR,6CAA6C;QAC7C,OAAO,EAAE,OAAO,CAAC;QACjB,uCAAuC;QACvC,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IAEF,2EAA2E;IAC3E,eAAe,EAAE,MAAM,CAAC;IAExB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC,CAAC;IAE9E,+CAA+C;IAC/C,GAAG,EAAE;QACH,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,2CAA2C;QAC3C,MAAM,CAAC,EAAE,eAAe,CAAC;KAC1B,CAAC;IAEF,4BAA4B;IAC5B,MAAM,EAAE;QACN,yDAAyD;QACzD,WAAW,EAAE,MAAM,CAAC;QACpB,iCAAiC;QACjC,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,yEAAyE;IACzE,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB,oEAAoE;IACpE,wBAAwB,EAAE,MAAM,CAAC;IAEjC,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC;IAEvB,0DAA0D;IAC1D,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,EAAE,mBA+BrC,CAAC;AA4GF;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,mBAAmB,CA4BrB"}