smart-claude-memory-mcp 2.1.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 (104) hide show
  1. package/.claude-plugin/plugin.json +38 -0
  2. package/CHANGELOG.md +52 -0
  3. package/LICENSE +21 -0
  4. package/README.md +790 -0
  5. package/dist/chunker.js +33 -0
  6. package/dist/chunker.js.map +1 -0
  7. package/dist/config.js +23 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/curriculum/daemon.js +190 -0
  10. package/dist/curriculum/daemon.js.map +1 -0
  11. package/dist/curriculum/scanner.js +237 -0
  12. package/dist/curriculum/scanner.js.map +1 -0
  13. package/dist/index.js +429 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lib/migrations.js +128 -0
  16. package/dist/lib/migrations.js.map +1 -0
  17. package/dist/ollama.js +59 -0
  18. package/dist/ollama.js.map +1 -0
  19. package/dist/project-detect.js +102 -0
  20. package/dist/project-detect.js.map +1 -0
  21. package/dist/project.js +26 -0
  22. package/dist/project.js.map +1 -0
  23. package/dist/sleep/daemon.js +215 -0
  24. package/dist/sleep/daemon.js.map +1 -0
  25. package/dist/sleep/miner.js +285 -0
  26. package/dist/sleep/miner.js.map +1 -0
  27. package/dist/supabase.js +405 -0
  28. package/dist/supabase.js.map +1 -0
  29. package/dist/telemetry/emit.js +19 -0
  30. package/dist/telemetry/emit.js.map +1 -0
  31. package/dist/telemetry/pruner.js +141 -0
  32. package/dist/telemetry/pruner.js.map +1 -0
  33. package/dist/telemetry/types.js +2 -0
  34. package/dist/telemetry/types.js.map +1 -0
  35. package/dist/tools/backlog.js +599 -0
  36. package/dist/tools/backlog.js.map +1 -0
  37. package/dist/tools/batch-freeze-patterns.js +243 -0
  38. package/dist/tools/batch-freeze-patterns.js.map +1 -0
  39. package/dist/tools/bloat-audit.js +101 -0
  40. package/dist/tools/bloat-audit.js.map +1 -0
  41. package/dist/tools/checkpoint.js +259 -0
  42. package/dist/tools/checkpoint.js.map +1 -0
  43. package/dist/tools/compact.js +60 -0
  44. package/dist/tools/compact.js.map +1 -0
  45. package/dist/tools/conflict.js +102 -0
  46. package/dist/tools/conflict.js.map +1 -0
  47. package/dist/tools/curriculum.js +225 -0
  48. package/dist/tools/curriculum.js.map +1 -0
  49. package/dist/tools/frozen-cache.js +106 -0
  50. package/dist/tools/frozen-cache.js.map +1 -0
  51. package/dist/tools/health.js +368 -0
  52. package/dist/tools/health.js.map +1 -0
  53. package/dist/tools/hygiene.js +309 -0
  54. package/dist/tools/hygiene.js.map +1 -0
  55. package/dist/tools/image.js +107 -0
  56. package/dist/tools/image.js.map +1 -0
  57. package/dist/tools/list-global-patterns.js +101 -0
  58. package/dist/tools/list-global-patterns.js.map +1 -0
  59. package/dist/tools/orchestrator.js +113 -0
  60. package/dist/tools/orchestrator.js.map +1 -0
  61. package/dist/tools/policy.js +90 -0
  62. package/dist/tools/policy.js.map +1 -0
  63. package/dist/tools/refactor.js +220 -0
  64. package/dist/tools/refactor.js.map +1 -0
  65. package/dist/tools/save.js +42 -0
  66. package/dist/tools/save.js.map +1 -0
  67. package/dist/tools/search.js +189 -0
  68. package/dist/tools/search.js.map +1 -0
  69. package/dist/tools/setup.js +868 -0
  70. package/dist/tools/setup.js.map +1 -0
  71. package/dist/tools/shared-schemas.js +24 -0
  72. package/dist/tools/shared-schemas.js.map +1 -0
  73. package/dist/tools/skills.js +174 -0
  74. package/dist/tools/skills.js.map +1 -0
  75. package/dist/tools/sleep.js +239 -0
  76. package/dist/tools/sleep.js.map +1 -0
  77. package/dist/tools/sovereign-constitution.js +319 -0
  78. package/dist/tools/sovereign-constitution.js.map +1 -0
  79. package/dist/tools/summarize.js +55 -0
  80. package/dist/tools/summarize.js.map +1 -0
  81. package/dist/tools/sync.js +255 -0
  82. package/dist/tools/sync.js.map +1 -0
  83. package/dist/tools/system_dashboard.js +181 -0
  84. package/dist/tools/system_dashboard.js.map +1 -0
  85. package/dist/tools/update-rule.js +15 -0
  86. package/dist/tools/update-rule.js.map +1 -0
  87. package/dist/tools/verification.js +333 -0
  88. package/dist/tools/verification.js.map +1 -0
  89. package/dist/trajectory/daemon.js +270 -0
  90. package/dist/trajectory/daemon.js.map +1 -0
  91. package/dist/trajectory/stripper.js +124 -0
  92. package/dist/trajectory/stripper.js.map +1 -0
  93. package/dist/trajectory/summarizer.js +77 -0
  94. package/dist/trajectory/summarizer.js.map +1 -0
  95. package/dist/transactions/checkpoint.js +272 -0
  96. package/dist/transactions/checkpoint.js.map +1 -0
  97. package/dist/verification-gate.js +43 -0
  98. package/dist/verification-gate.js.map +1 -0
  99. package/dist/version.js +16 -0
  100. package/dist/version.js.map +1 -0
  101. package/hooks/README.md +54 -0
  102. package/hooks/md-policy.py +497 -0
  103. package/marketplace.json +13 -0
  104. package/package.json +66 -0
@@ -0,0 +1,270 @@
1
+ // Trajectory Compaction Daemon (Agentic OS 2026 — Mission 2 / AgentDiet).
2
+ // Idle compactor: every TRAJECTORY_COMPACTOR_INTERVAL_MS, pulls bloated
3
+ // memory_chunks rows (no matching trajectory_summaries row) and compresses
4
+ // each via stripTrajectory → summarizeTrajectory → optional embed → INSERT.
5
+ // Mirrors the keepAlive pattern in supabase.ts:74-135 — module-level state,
6
+ // idempotent start/stop, .unref()'d interval, re-entrancy guard.
7
+ import { embed } from "../ollama.js";
8
+ import { supabase } from "../supabase.js";
9
+ import { emit } from "../telemetry/emit.js";
10
+ import { stripTrajectory } from "./stripper.js";
11
+ import { summarizeTrajectory } from "./summarizer.js";
12
+ const DEFAULT_INTERVAL_MS = 600_000;
13
+ const DEFAULT_BATCH = 25;
14
+ const DEFAULT_MIN_BYTES = 16_000;
15
+ const MIN_STRIPPED_TOKENS = 250;
16
+ const state = {
17
+ enabled: false,
18
+ intervalMs: DEFAULT_INTERVAL_MS,
19
+ batch: DEFAULT_BATCH,
20
+ minBytes: DEFAULT_MIN_BYTES,
21
+ lastRunAt: null,
22
+ lastRunCompacted: 0,
23
+ lastRunSkipped: 0,
24
+ lastRunErrored: 0,
25
+ lastRunDurationMs: 0,
26
+ // Backlog #125 — per-tick token aggregates summed from CompactOneResult.
27
+ // Reset to 0 at the top of every runCompactionOnce; emitted in run_ended.
28
+ lastRunSourceTokens: 0,
29
+ lastRunSummaryTokens: 0,
30
+ timer: null,
31
+ running: false,
32
+ };
33
+ function readIntEnv(name, fallback) {
34
+ const raw = process.env[name];
35
+ if (!raw)
36
+ return fallback;
37
+ const n = Number.parseInt(raw, 10);
38
+ return Number.isFinite(n) && n > 0 ? n : fallback;
39
+ }
40
+ function resolveConfig() {
41
+ return {
42
+ intervalMs: readIntEnv("TRAJECTORY_COMPACTOR_INTERVAL_MS", DEFAULT_INTERVAL_MS),
43
+ batch: readIntEnv("TRAJECTORY_COMPACTOR_BATCH", DEFAULT_BATCH),
44
+ minBytes: readIntEnv("TRAJECTORY_COMPACTOR_MIN_BYTES", DEFAULT_MIN_BYTES),
45
+ };
46
+ }
47
+ // PostgREST cannot filter by octet_length directly: we exclude already-
48
+ // summarized rows via a Set and filter byte length in code. Over-fetch
49
+ // headroom absorbs rows that don't clear the byte threshold.
50
+ async function fetchCandidates(limit, minBytes) {
51
+ const summarized = new Set();
52
+ const pageSize = 1000;
53
+ for (let from = 0;; from += pageSize) {
54
+ const { data, error } = await supabase
55
+ .from("trajectory_summaries")
56
+ .select("source_chunk_id")
57
+ .range(from, from + pageSize - 1);
58
+ if (error)
59
+ throw new Error(`fetchCandidates: scan failed: ${error.message}`);
60
+ if (!data || data.length === 0)
61
+ break;
62
+ for (const row of data) {
63
+ if (typeof row.source_chunk_id === "number")
64
+ summarized.add(row.source_chunk_id);
65
+ }
66
+ if (data.length < pageSize)
67
+ break;
68
+ }
69
+ const overFetch = Math.max(limit * 4, limit + 50);
70
+ const { data, error } = await supabase
71
+ .from("memory_chunks")
72
+ .select("id, project_id, content")
73
+ .order("id", { ascending: true })
74
+ .limit(overFetch);
75
+ if (error)
76
+ throw new Error(`fetchCandidates: memory_chunks scan failed: ${error.message}`);
77
+ const candidates = [];
78
+ for (const row of data ?? []) {
79
+ if (candidates.length >= limit)
80
+ break;
81
+ if (typeof row.id !== "number" || typeof row.content !== "string")
82
+ continue;
83
+ if (summarized.has(row.id))
84
+ continue;
85
+ if (Buffer.byteLength(row.content, "utf8") <= minBytes)
86
+ continue;
87
+ candidates.push({ id: row.id, project_id: row.project_id, content: row.content });
88
+ }
89
+ return candidates;
90
+ }
91
+ function result(ok, source, summaryTokens, summary, reason) {
92
+ const r = {
93
+ ok,
94
+ source_tokens: source,
95
+ summary_tokens: summaryTokens,
96
+ compression_ratio: source > 0 ? summaryTokens / source : 0,
97
+ summary,
98
+ };
99
+ if (reason)
100
+ r.reason = reason;
101
+ return r;
102
+ }
103
+ export async function compactOneChunk(chunkId, opts = {}) {
104
+ const { data, error } = await supabase
105
+ .from("memory_chunks")
106
+ .select("id, project_id, content")
107
+ .eq("id", chunkId)
108
+ .maybeSingle();
109
+ if (error)
110
+ return result(false, 0, 0, null, `lookup_failed: ${error.message}`);
111
+ if (!data || typeof data.content !== "string")
112
+ return result(false, 0, 0, null, "not_found");
113
+ const { stripped, sourceTokens, strippedTokens } = stripTrajectory(data.content);
114
+ if (strippedTokens < MIN_STRIPPED_TOKENS) {
115
+ return result(false, sourceTokens, 0, null, "too_small_after_strip");
116
+ }
117
+ const { summary, summaryTokens, model } = await summarizeTrajectory(stripped);
118
+ // Best-effort embedding (summary_embedding is nullable in
119
+ // scripts/011_trajectory_compaction.sql) — embed failures do not abort.
120
+ let summaryEmbedding = null;
121
+ try {
122
+ const [vec] = await embed([summary]);
123
+ if (Array.isArray(vec) && vec.length > 0)
124
+ summaryEmbedding = vec;
125
+ }
126
+ catch {
127
+ summaryEmbedding = null;
128
+ }
129
+ if (opts.dryRun)
130
+ return result(true, sourceTokens, summaryTokens, summary);
131
+ const { error: insertError } = await supabase.from("trajectory_summaries").upsert({
132
+ project_id: data.project_id,
133
+ source_chunk_id: chunkId,
134
+ summary,
135
+ summary_embedding: summaryEmbedding,
136
+ source_tokens: sourceTokens,
137
+ summary_tokens: summaryTokens,
138
+ strategy: "heuristic+llm",
139
+ model,
140
+ }, { onConflict: "project_id,source_chunk_id" });
141
+ if (insertError) {
142
+ return result(false, sourceTokens, summaryTokens, summary, `insert_failed: ${insertError.message}`);
143
+ }
144
+ return result(true, sourceTokens, summaryTokens, summary);
145
+ }
146
+ export async function runCompactionOnce(opts = {}) {
147
+ const t0 = Date.now();
148
+ const cfg = resolveConfig();
149
+ const limit = opts.limit ?? cfg.batch;
150
+ let compacted = 0;
151
+ let skipped = 0;
152
+ let errored = 0;
153
+ // Backlog #125 — per-tick token accumulators. Sum unconditionally: failed
154
+ // chunks contribute summary_tokens=0 (per `result()` builder), so summing
155
+ // them is a no-op edge-case-free.
156
+ let sourceTokens = 0;
157
+ let summaryTokens = 0;
158
+ try {
159
+ const candidates = await fetchCandidates(limit, cfg.minBytes);
160
+ for (const row of candidates) {
161
+ try {
162
+ const r = await compactOneChunk(row.id, { dryRun: opts.dryRun });
163
+ sourceTokens += r.source_tokens;
164
+ summaryTokens += r.summary_tokens;
165
+ if (r.ok)
166
+ compacted++;
167
+ else
168
+ skipped++;
169
+ }
170
+ catch {
171
+ errored++;
172
+ }
173
+ }
174
+ }
175
+ catch {
176
+ errored++;
177
+ }
178
+ return {
179
+ compacted,
180
+ skipped,
181
+ errored,
182
+ duration_ms: Date.now() - t0,
183
+ source_tokens: sourceTokens,
184
+ summary_tokens: summaryTokens,
185
+ };
186
+ }
187
+ // Daemon tick — wrapped in try/finally so the loop NEVER throws.
188
+ async function tick() {
189
+ if (state.running)
190
+ return;
191
+ state.running = true;
192
+ const __tStart = Date.now();
193
+ void emit({ daemon: "trajectory_compactor", event: "run_started" });
194
+ try {
195
+ const result = await runCompactionOnce({ limit: state.batch });
196
+ state.lastRunCompacted = result.compacted;
197
+ state.lastRunSkipped = result.skipped;
198
+ state.lastRunErrored = result.errored;
199
+ state.lastRunDurationMs = result.duration_ms;
200
+ state.lastRunSourceTokens = result.source_tokens;
201
+ state.lastRunSummaryTokens = result.summary_tokens;
202
+ state.lastRunAt = new Date().toISOString();
203
+ // Backlog #125 — emit per-tick token aggregates via TrajectoryEndedPayload's
204
+ // `[extra: string]: unknown` slot. No types.ts change required.
205
+ void emit({
206
+ daemon: "trajectory_compactor",
207
+ event: "run_ended",
208
+ payload: {
209
+ compacted: state.lastRunCompacted,
210
+ skipped: state.lastRunSkipped,
211
+ errored: state.lastRunErrored,
212
+ duration_ms: Date.now() - __tStart,
213
+ source_tokens: state.lastRunSourceTokens,
214
+ summary_tokens: state.lastRunSummaryTokens,
215
+ compression_ratio: state.lastRunSourceTokens > 0
216
+ ? state.lastRunSummaryTokens / state.lastRunSourceTokens
217
+ : 0,
218
+ },
219
+ });
220
+ }
221
+ catch (err) {
222
+ state.lastRunErrored++;
223
+ state.lastRunAt = new Date().toISOString();
224
+ void emit({
225
+ daemon: "trajectory_compactor",
226
+ event: "run_errored",
227
+ payload: {
228
+ error_message: err instanceof Error ? err.message : String(err),
229
+ duration_ms: Date.now() - __tStart,
230
+ },
231
+ });
232
+ }
233
+ finally {
234
+ state.running = false;
235
+ }
236
+ }
237
+ // Public alias for one-shot invocation (smoke tests, Task 6 dashboard probe).
238
+ // Keeps the internal `tick` name stable while exposing a stable external name.
239
+ export const runTrajectoryCompactorOnce = tick;
240
+ export function startCompactor() {
241
+ if (state.timer)
242
+ return;
243
+ const cfg = resolveConfig();
244
+ state.intervalMs = cfg.intervalMs;
245
+ state.batch = cfg.batch;
246
+ state.minBytes = cfg.minBytes;
247
+ state.enabled = true;
248
+ state.timer = setInterval(() => void tick(), state.intervalMs);
249
+ state.timer.unref();
250
+ }
251
+ export function stopCompactor() {
252
+ if (state.timer)
253
+ clearInterval(state.timer);
254
+ state.timer = null;
255
+ state.enabled = false;
256
+ }
257
+ export function getCompactorStatus() {
258
+ return {
259
+ enabled: state.enabled,
260
+ interval_ms: state.intervalMs,
261
+ last_run_at: state.lastRunAt,
262
+ last_run_compacted: state.lastRunCompacted,
263
+ last_run_skipped: state.lastRunSkipped,
264
+ last_run_errored: state.lastRunErrored,
265
+ last_run_duration_ms: state.lastRunDurationMs,
266
+ last_run_source_tokens: state.lastRunSourceTokens,
267
+ last_run_summary_tokens: state.lastRunSummaryTokens,
268
+ };
269
+ }
270
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/trajectory/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ // Heuristic noise-stripper for M2 AgentDiet (pre-LLM trajectory compression stage).
2
+ // Pure function: no I/O, no logging, no side effects. Regex + string ops only.
3
+ const ANSI_RE = /\x1b\[[0-9;]*m/g;
4
+ const STACK_FRAME_RE = /^\s+at\s/;
5
+ const NOISE_LEVEL_RE = /^(DEBUG|TRACE|VERBOSE):\s/;
6
+ const BLANK_RE = /^\s*$/;
7
+ const JSON_MIN_LEN = 500;
8
+ const STACK_KEEP = 5;
9
+ const MAX_CHARS = 100_000;
10
+ const TRUNC_SUFFIX = "[... source truncated at 100k chars]";
11
+ function estimateTokens(text) {
12
+ return Math.ceil(text.length / 4);
13
+ }
14
+ function isJsonShaped(line) {
15
+ if (line.length <= JSON_MIN_LEN)
16
+ return false;
17
+ const trimmed = line.trim();
18
+ if (trimmed.length <= JSON_MIN_LEN)
19
+ return false;
20
+ const first = trimmed.charAt(0);
21
+ const last = trimmed.charAt(trimmed.length - 1);
22
+ const opensObject = first === "{" && last === "}";
23
+ const opensArray = first === "[" && last === "]";
24
+ if (!opensObject && !opensArray)
25
+ return false;
26
+ return trimmed.includes(":");
27
+ }
28
+ function collapseJsonBlobs(lines) {
29
+ const out = [];
30
+ for (const line of lines) {
31
+ if (isJsonShaped(line)) {
32
+ out.push(`[json blob ${line.length} chars elided]`);
33
+ }
34
+ else {
35
+ out.push(line);
36
+ }
37
+ }
38
+ return out;
39
+ }
40
+ function truncateStackTraces(lines) {
41
+ const out = [];
42
+ let i = 0;
43
+ while (i < lines.length) {
44
+ if (STACK_FRAME_RE.test(lines[i])) {
45
+ let j = i;
46
+ while (j < lines.length && STACK_FRAME_RE.test(lines[j]))
47
+ j++;
48
+ const run = j - i;
49
+ if (run > STACK_KEEP) {
50
+ for (let k = i; k < i + STACK_KEEP; k++)
51
+ out.push(lines[k]);
52
+ out.push(`... [${run - STACK_KEEP} more frames elided]`);
53
+ }
54
+ else {
55
+ for (let k = i; k < j; k++)
56
+ out.push(lines[k]);
57
+ }
58
+ i = j;
59
+ }
60
+ else {
61
+ out.push(lines[i]);
62
+ i++;
63
+ }
64
+ }
65
+ return out;
66
+ }
67
+ function dedupeConsecutive(lines) {
68
+ const out = [];
69
+ let i = 0;
70
+ while (i < lines.length) {
71
+ const current = lines[i];
72
+ let j = i + 1;
73
+ while (j < lines.length && lines[j] === current)
74
+ j++;
75
+ const run = j - i;
76
+ out.push(current);
77
+ if (run > 1)
78
+ out.push(`[× ${run} repeats]`);
79
+ i = j;
80
+ }
81
+ return out;
82
+ }
83
+ function stripNoiseLines(lines) {
84
+ const filtered = lines.filter((l) => !NOISE_LEVEL_RE.test(l));
85
+ const out = [];
86
+ let prevBlank = false;
87
+ for (const line of filtered) {
88
+ const isBlank = BLANK_RE.test(line);
89
+ if (isBlank) {
90
+ if (!prevBlank)
91
+ out.push("");
92
+ prevBlank = true;
93
+ }
94
+ else {
95
+ out.push(line);
96
+ prevBlank = false;
97
+ }
98
+ }
99
+ return out;
100
+ }
101
+ function capLength(text) {
102
+ if (text.length <= MAX_CHARS)
103
+ return text;
104
+ const room = MAX_CHARS - TRUNC_SUFFIX.length;
105
+ const head = room > 0 ? text.slice(0, room) : "";
106
+ return `${head}${TRUNC_SUFFIX}`;
107
+ }
108
+ export function stripTrajectory(raw) {
109
+ const sourceTokens = estimateTokens(raw);
110
+ if (raw.length === 0) {
111
+ return { stripped: "", sourceTokens: 0, strippedTokens: 0 };
112
+ }
113
+ const noAnsi = raw.replace(ANSI_RE, "");
114
+ const lines = noAnsi.split(/\r?\n/);
115
+ const afterJson = collapseJsonBlobs(lines);
116
+ const afterStack = truncateStackTraces(afterJson);
117
+ const afterDedupe = dedupeConsecutive(afterStack);
118
+ const afterNoise = stripNoiseLines(afterDedupe);
119
+ const joined = afterNoise.join("\n");
120
+ const stripped = capLength(joined);
121
+ const strippedTokens = estimateTokens(stripped);
122
+ return { stripped, sourceTokens, strippedTokens };
123
+ }
124
+ //# sourceMappingURL=stripper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripper.js","sourceRoot":"","sources":["../../src/trajectory/stripper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { chat } from "../ollama.js";
2
+ const DEFAULT_MODEL = process.env.OLLAMA_TRAJECTORY_MODEL ?? "gemma3:e2b";
3
+ const SYSTEM_PROMPT = "You are a log compression engine. Produce a dense ~50-token semantic summary of the operational trajectory log provided. " +
4
+ "Emphasize: WHAT happened (the action taken), WHAT FOR (intent or outcome), and KEY identifiers (file paths, error codes, IDs, function names). " +
5
+ "Strip all chat-style filler, greetings, and meta-commentary. Output exactly one paragraph, single line, no bullets, no preamble, no quotes. " +
6
+ "Do not introduce your output. Begin directly with the summary content.";
7
+ const USER_PREFIX = "Compress the following trajectory log into a dense ~50-token semantic summary:\n\n";
8
+ const PREAMBLE_REGEX = /^(?:summary|compressed|here(?:'s| is)(?:\s+(?:the|a))?(?:\s+(?:summary|compressed\s+log|dense\s+summary))?|the\s+log)\s*[:\-—]\s*/i;
9
+ const MAX_CHARS = 400;
10
+ export async function summarizeTrajectory(stripped, opts = {}) {
11
+ if (stripped.trim().length === 0) {
12
+ throw new Error("summarizeTrajectory: empty input");
13
+ }
14
+ const model = opts.model ?? DEFAULT_MODEL;
15
+ const chatPromise = chat([
16
+ { role: "system", content: SYSTEM_PROMPT },
17
+ { role: "user", content: `${USER_PREFIX}${stripped}` },
18
+ ], {
19
+ model,
20
+ temperature: 0.2,
21
+ timeoutMs: 60_000,
22
+ });
23
+ const raw = opts.signal ? await raceAbort(chatPromise, opts.signal) : await chatPromise;
24
+ const summary = postProcess(raw);
25
+ const summaryTokens = Math.ceil(summary.length / 4);
26
+ return { summary, summaryTokens, model };
27
+ }
28
+ function postProcess(raw) {
29
+ let s = raw.trim();
30
+ s = s.replace(/\s*[\r\n]+\s*/g, " ");
31
+ s = s.replace(/\s{2,}/g, " ");
32
+ // Strip leading preambles up to 3 times in case the model stacks them.
33
+ for (let i = 0; i < 3; i++) {
34
+ const next = s.replace(PREAMBLE_REGEX, "").trim();
35
+ if (next === s)
36
+ break;
37
+ s = next;
38
+ }
39
+ if (s.length > MAX_CHARS) {
40
+ s = truncateAtSentence(s, MAX_CHARS);
41
+ }
42
+ return s;
43
+ }
44
+ function truncateAtSentence(s, max) {
45
+ const slice = s.slice(0, max);
46
+ let cut = -1;
47
+ for (const punct of [". ", "! ", "? "]) {
48
+ const idx = slice.lastIndexOf(punct);
49
+ if (idx > cut)
50
+ cut = idx + 1;
51
+ }
52
+ if (cut > 0)
53
+ return slice.slice(0, cut).trim();
54
+ // No sentence boundary found within window — clean cut at last word boundary.
55
+ const lastSpace = slice.lastIndexOf(" ");
56
+ return (lastSpace > 0 ? slice.slice(0, lastSpace) : slice).trim();
57
+ }
58
+ function raceAbort(p, signal) {
59
+ if (signal.aborted) {
60
+ return Promise.reject(new Error("summarizeTrajectory: aborted"));
61
+ }
62
+ return new Promise((resolve, reject) => {
63
+ const onAbort = () => {
64
+ signal.removeEventListener("abort", onAbort);
65
+ reject(new Error("summarizeTrajectory: aborted"));
66
+ };
67
+ signal.addEventListener("abort", onAbort, { once: true });
68
+ p.then((v) => {
69
+ signal.removeEventListener("abort", onAbort);
70
+ resolve(v);
71
+ }, (e) => {
72
+ signal.removeEventListener("abort", onAbort);
73
+ reject(e);
74
+ });
75
+ });
76
+ }
77
+ //# sourceMappingURL=summarizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../src/trajectory/summarizer.ts"],"names":[],"mappings":"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"}