@wrongstack/core 0.310.1 → 0.313.1
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/chronicle/index.js +84 -6391
- package/dist/chronicle/project-server.js +84 -4868
- package/dist/chunk-2BUUIMQB.js +225 -0
- package/dist/chunk-2FK4WTFF.js +207 -0
- package/dist/chunk-2FQL4PDC.js +292 -0
- package/dist/chunk-2KKODIQU.js +2256 -0
- package/dist/chunk-2YU4WVBW.js +134 -0
- package/dist/chunk-3E244UDA.js +356 -0
- package/dist/chunk-3XPVB7BA.js +135 -0
- package/dist/chunk-4LJJYBAU.js +388 -0
- package/dist/chunk-4VWO3ZXL.js +342 -0
- package/dist/chunk-4XV6IR37.js +187 -0
- package/dist/chunk-4ZHTKJHM.js +183 -0
- package/dist/chunk-52RTVH4M.js +361 -0
- package/dist/chunk-57GEWK5X.js +26 -0
- package/dist/chunk-5DSMEVA4.js +931 -0
- package/dist/chunk-5RP3QTRL.js +1223 -0
- package/dist/chunk-5S437PRC.js +50 -0
- package/dist/chunk-5XDUGTKN.js +511 -0
- package/dist/chunk-62V2AFVG.js +422 -0
- package/dist/chunk-65RDIOR2.js +2470 -0
- package/dist/chunk-6AKOTGLM.js +597 -0
- package/dist/chunk-7ZHZE5EO.js +28 -0
- package/dist/chunk-A455ATZB.js +140 -0
- package/dist/chunk-AD7ZFZCS.js +46 -0
- package/dist/chunk-AI4LLQ2U.js +856 -0
- package/dist/chunk-ASX6AW36.js +789 -0
- package/dist/chunk-AT4V4XGI.js +3522 -0
- package/dist/chunk-AWNQ6ED6.js +311 -0
- package/dist/chunk-B4AMLZPB.js +9 -0
- package/dist/chunk-BAKVJLEV.js +417 -0
- package/dist/chunk-BJHVULHO.js +55 -0
- package/dist/chunk-CB2HFKTP.js +9 -0
- package/dist/chunk-CE4ZOCOI.js +1640 -0
- package/dist/chunk-CQQL4ZOQ.js +151 -0
- package/dist/chunk-DEIQMBD2.js +65 -0
- package/dist/chunk-E6I5RXVK.js +58 -0
- package/dist/chunk-EFEHDQGY.js +1589 -0
- package/dist/chunk-EODDVJBM.js +82 -0
- package/dist/chunk-EPC3GZD4.js +308 -0
- package/dist/chunk-FAYRX2AD.js +13 -0
- package/dist/chunk-FFSX2QDQ.js +362 -0
- package/dist/chunk-FHAMQS7Q.js +5856 -0
- package/dist/chunk-FIV4IJL7.js +2263 -0
- package/dist/chunk-FNXVT7HF.js +52 -0
- package/dist/chunk-FSWCWSTS.js +395 -0
- package/dist/chunk-FW5LDDMJ.js +16464 -0
- package/dist/chunk-FXQLIX3K.js +211 -0
- package/dist/chunk-G5AAKEEZ.js +228 -0
- package/dist/chunk-G5S3S5ZN.js +38 -0
- package/dist/chunk-GAZEWQEZ.js +231 -0
- package/dist/chunk-GFJOMSHG.js +125 -0
- package/dist/chunk-GFXZTHNI.js +158 -0
- package/dist/chunk-GM54GJBU.js +960 -0
- package/dist/chunk-GPQ3NJPR.js +900 -0
- package/dist/chunk-GTCU6DZ3.js +1 -0
- package/dist/chunk-H5E77KUJ.js +15 -0
- package/dist/chunk-H72H4XDU.js +1023 -0
- package/dist/chunk-HA4ZYA6T.js +178 -0
- package/dist/chunk-I45KAW2N.js +5020 -0
- package/dist/chunk-IQ35HMQL.js +1396 -0
- package/dist/chunk-IYFBFX34.js +86 -0
- package/dist/chunk-JJPMWPB6.js +109 -0
- package/dist/chunk-JTHKOYWU.js +663 -0
- package/dist/chunk-JVGPR3TS.js +365 -0
- package/dist/chunk-JVKB2TBL.js +48 -0
- package/dist/chunk-JX7VBZDK.js +31 -0
- package/dist/chunk-K3G6JBUC.js +5232 -0
- package/dist/chunk-K4YUNKU7.js +589 -0
- package/dist/chunk-KBZGE6LN.js +710 -0
- package/dist/chunk-KDQJCT2J.js +45 -0
- package/dist/chunk-KI4L2DUL.js +560 -0
- package/dist/chunk-KJ2ZTQSL.js +47 -0
- package/dist/chunk-KSJ5UTP7.js +154 -0
- package/dist/chunk-LHOA5DWA.js +28 -0
- package/dist/chunk-LX5QWLBL.js +27 -0
- package/dist/chunk-LZDDLNCZ.js +279 -0
- package/dist/chunk-M2WF6AXG.js +115 -0
- package/dist/chunk-M7BS2K6U.js +1 -0
- package/dist/chunk-NDBIPFNY.js +102 -0
- package/dist/chunk-NEMIWEXC.js +1199 -0
- package/dist/chunk-NFAYHPRH.js +323 -0
- package/dist/chunk-O37BQ65S.js +21 -0
- package/dist/chunk-O74MJHXU.js +187 -0
- package/dist/chunk-OJZEX73F.js +112 -0
- package/dist/chunk-PAAWLLZX.js +74 -0
- package/dist/chunk-PFXFQQRT.js +339 -0
- package/dist/chunk-PFZO3C6H.js +14 -0
- package/dist/chunk-PHH7LD45.js +113 -0
- package/dist/chunk-QRTG4XTI.js +188 -0
- package/dist/chunk-QVOVMXJR.js +1351 -0
- package/dist/chunk-RCQYT2I4.js +757 -0
- package/dist/chunk-RD6DEE36.js +1178 -0
- package/dist/chunk-RJIZEJ42.js +30 -0
- package/dist/chunk-RPOA7IAE.js +150 -0
- package/dist/chunk-SN2DQRL6.js +1172 -0
- package/dist/chunk-SQJVFEBV.js +41 -0
- package/dist/chunk-SQP64RCS.js +5391 -0
- package/dist/chunk-SVT4RNTR.js +49 -0
- package/dist/chunk-SWUFN7XM.js +43 -0
- package/dist/chunk-SXMVYC5H.js +174 -0
- package/dist/chunk-SZ6AYUIZ.js +23 -0
- package/dist/chunk-T3KGZBU5.js +3171 -0
- package/dist/chunk-TBRL2RCC.js +9 -0
- package/dist/chunk-TRT2HRWZ.js +18 -0
- package/dist/chunk-TYW2GI5I.js +1077 -0
- package/dist/chunk-UIWONWVG.js +4959 -0
- package/dist/chunk-VB3H5WWB.js +151 -0
- package/dist/chunk-W4A6QA3D.js +258 -0
- package/dist/chunk-WBPVKEEE.js +227 -0
- package/dist/chunk-WEBMSQP2.js +123 -0
- package/dist/chunk-WOEZV3Q4.js +333 -0
- package/dist/chunk-WQQON3SV.js +473 -0
- package/dist/chunk-WQTOVMGV.js +119 -0
- package/dist/chunk-WZO23AWO.js +2779 -0
- package/dist/chunk-XBDP4QPW.js +7 -0
- package/dist/chunk-XEBHSJLT.js +103 -0
- package/dist/chunk-XQ2ECNK3.js +1 -0
- package/dist/chunk-XQ2XGIBF.js +2086 -0
- package/dist/chunk-Y2GE5TSI.js +355 -0
- package/dist/chunk-YBUJCZ57.js +351 -0
- package/dist/chunk-YNCVSFGF.js +149 -0
- package/dist/chunk-YUPMXOGP.js +282 -0
- package/dist/chunk-YY6APYUM.js +49 -0
- package/dist/chunk-Z2IJUO45.js +691 -0
- package/dist/chunk-ZEHUCJHY.js +129 -0
- package/dist/chunk-ZYU2YOJ6.js +1496 -0
- package/dist/chunk-ZZ4V3WIZ.js +163 -0
- package/dist/coordination/agents/index.js +145 -6260
- package/dist/coordination/index.js +365 -34323
- package/dist/coordination/mailbox-project-server.js +48 -3220
- package/dist/coordination/mailbox-types.d.ts +13 -1
- package/dist/coordination/provider-status-tracker.d.ts +4 -0
- package/dist/coordination/sqlite-mailbox.d.ts +2 -1
- package/dist/core/agent.d.ts +14 -1
- package/dist/core/index.js +267 -12479
- package/dist/core/model-ref.js +5 -23
- package/dist/core/provider-runner.d.ts +36 -1
- package/dist/design/index.js +50 -1087
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +1599 -21887
- package/dist/execution/prompt-enhancer.js +16 -535
- package/dist/execution/retry-policy.d.ts +31 -1
- package/dist/extension/index.js +7 -311
- package/dist/goal/index.js +33 -3435
- package/dist/hooks/index.js +14 -1138
- package/dist/hq/index.js +112 -5139
- package/dist/hq/protocol.js +21 -668
- package/dist/index.js +1410 -92655
- package/dist/infrastructure/index.js +64 -4811
- package/dist/kernel/events/provider-events.d.ts +15 -0
- package/dist/kernel/events/wrongtrace-events.d.ts +26 -0
- package/dist/kernel/events.d.ts +16 -7
- package/dist/kernel/index.js +14 -992
- package/dist/models/index.js +40 -1117
- package/dist/notifications/index.js +3 -108
- package/dist/observability/index.js +17 -279
- package/dist/plugin/index.js +584 -14835
- package/dist/prompts/index.js +14 -948
- package/dist/registry/index.js +9 -822
- package/dist/registry-R23UBE7H.js +14 -0
- package/dist/replay/index.js +6 -84
- package/dist/review-finding-store-DKAV3AS6.js +21 -0
- package/dist/review-report-store-OWY3EC3N.js +19 -0
- package/dist/security/index.js +114 -2202
- package/dist/session-catalog/index.js +36 -2103
- package/dist/session-catalog/project-server.js +42 -1435
- package/dist/skills/index.js +35 -1578
- package/dist/storage/index.js +182 -15600
- package/dist/tasking/index.js +10 -676
- package/dist/tools/index.js +52 -9589
- package/dist/types/config/autonomy.d.ts +5 -0
- package/dist/types/config/tools.d.ts +2 -2
- package/dist/types/config/ui.d.ts +1 -1
- package/dist/types/errors.d.ts +18 -0
- package/dist/types/index.js +121 -1341
- package/dist/types/provider-runner.d.ts +8 -0
- package/dist/types/session-markers.js +8 -144
- package/dist/utils/error.js +3 -4
- package/dist/utils/expect-defined.js +3 -9
- package/dist/utils/heap-watchdog.js +6 -706
- package/dist/utils/index.js +269 -5685
- package/dist/utils/sage-output-block.js +5 -42
- package/dist/wiring/proxy-rewrite.d.ts +92 -4
- package/dist/wiring/proxy-rewrite.js +20 -61
- package/dist/worktree/index.js +6 -887
- package/package.json +4 -4
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import {
|
|
2
|
+
noOpLogger
|
|
3
|
+
} from "./chunk-WBPVKEEE.js";
|
|
4
|
+
import {
|
|
5
|
+
readBundledInstructionText
|
|
6
|
+
} from "./chunk-5S437PRC.js";
|
|
7
|
+
import {
|
|
8
|
+
estimateMessageTokens,
|
|
9
|
+
estimateTextTokens
|
|
10
|
+
} from "./chunk-FSWCWSTS.js";
|
|
11
|
+
import {
|
|
12
|
+
isTextBlock
|
|
13
|
+
} from "./chunk-O37BQ65S.js";
|
|
14
|
+
import {
|
|
15
|
+
expectDefined
|
|
16
|
+
} from "./chunk-PFZO3C6H.js";
|
|
17
|
+
|
|
18
|
+
// src/utils/compaction-preview.ts
|
|
19
|
+
var PATH_HINT_PATTERN = /(?:(?:[A-Za-z]:)?[./\\]?[\w@.-]+(?:[\\/][\w@(). -]+)+\.[A-Za-z0-9]{1,12})/g;
|
|
20
|
+
var PATH_BACKSLASH_PATTERN = /\\/g;
|
|
21
|
+
var PATH_TRIM_PATTERN = /^["'`]+|["'`),;:]+$/g;
|
|
22
|
+
var ERROR_LINE_PATTERN = /\b(error|exception|failed|failure|fatal|panic|timeout|denied|enoent|eacces|eperm)\b/i;
|
|
23
|
+
var NEWLINE_SPLIT_PATTERN = /\r?\n/;
|
|
24
|
+
var WHITESPACE_COLLAPSE_PATTERN = /\s+/g;
|
|
25
|
+
function buildCompactionPreview(message, maxChars = 600) {
|
|
26
|
+
if (maxChars <= 0) return "";
|
|
27
|
+
if (typeof message.content === "string") {
|
|
28
|
+
return truncatePreview(message.content, maxChars);
|
|
29
|
+
}
|
|
30
|
+
const parts = [];
|
|
31
|
+
for (const block of message.content) {
|
|
32
|
+
if (isTextBlock(block)) {
|
|
33
|
+
const text = truncatePreview(block.text, maxChars);
|
|
34
|
+
if (text) parts.push(text);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (block.type === "tool_use") {
|
|
38
|
+
const input = truncatePreview(safePreviewString(block.input), 220);
|
|
39
|
+
parts.push(`[tool_use: ${block.name}${input ? `; input=${input}` : ""}]`);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (block.type === "tool_result") {
|
|
43
|
+
const raw = safePreviewString(block.content);
|
|
44
|
+
const details = [block.is_error ? "error" : "ok"];
|
|
45
|
+
if (block.name) details.push(`tool=${block.name}`);
|
|
46
|
+
const files = extractPathHints(raw).slice(0, 5);
|
|
47
|
+
if (files.length > 0) details.push(`files=${files.join(", ")}`);
|
|
48
|
+
const error = firstErrorLine(raw);
|
|
49
|
+
if (error) details.push(`error=${error}`);
|
|
50
|
+
const sample = truncatePreview(raw, 260);
|
|
51
|
+
if (sample) details.push(`sample=${sample}`);
|
|
52
|
+
parts.push(`[tool_result: ${details.join("; ")}]`);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
parts.push(`[${block.type}]`);
|
|
56
|
+
}
|
|
57
|
+
return truncatePreview(parts.join(" "), maxChars);
|
|
58
|
+
}
|
|
59
|
+
function safePreviewString(value) {
|
|
60
|
+
if (typeof value === "string") return value;
|
|
61
|
+
try {
|
|
62
|
+
return JSON.stringify(value);
|
|
63
|
+
} catch {
|
|
64
|
+
return String(value);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function truncatePreview(value, maxChars) {
|
|
68
|
+
const compact = value.replace(WHITESPACE_COLLAPSE_PATTERN, " ").trim();
|
|
69
|
+
if (compact.length <= maxChars) return compact;
|
|
70
|
+
return `${compact.slice(0, Math.max(0, maxChars - 1))}\u2026`;
|
|
71
|
+
}
|
|
72
|
+
function extractPathHints(content) {
|
|
73
|
+
const text = safePreviewString(content);
|
|
74
|
+
const out = /* @__PURE__ */ new Set();
|
|
75
|
+
for (const match of text.matchAll(PATH_HINT_PATTERN)) {
|
|
76
|
+
const clean = match[0]?.replace(PATH_BACKSLASH_PATTERN, "/").replace(PATH_TRIM_PATTERN, "");
|
|
77
|
+
if (clean) out.add(clean);
|
|
78
|
+
}
|
|
79
|
+
return [...out];
|
|
80
|
+
}
|
|
81
|
+
function firstErrorLine(content) {
|
|
82
|
+
const text = safePreviewString(content);
|
|
83
|
+
for (const line of text.split(NEWLINE_SPLIT_PATTERN)) {
|
|
84
|
+
if (!ERROR_LINE_PATTERN.test(line)) continue;
|
|
85
|
+
const trimmed = line.replace(WHITESPACE_COLLAPSE_PATTERN, " ").trim();
|
|
86
|
+
if (trimmed) return truncatePreview(trimmed, 220);
|
|
87
|
+
}
|
|
88
|
+
return void 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/models/llm-selector.ts
|
|
92
|
+
var DEFAULT_SYSTEM_PROMPT = readBundledInstructionText("llm/llm-selector.md");
|
|
93
|
+
function formatMessages(messages, maxTokens = 2048) {
|
|
94
|
+
const previewChars = Math.max(
|
|
95
|
+
120,
|
|
96
|
+
Math.min(600, Math.floor(maxTokens * 3.2 / Math.max(1, messages.length)))
|
|
97
|
+
);
|
|
98
|
+
const lines = [];
|
|
99
|
+
for (let i = 0; i < messages.length; i++) {
|
|
100
|
+
const m = expectDefined(messages[i]);
|
|
101
|
+
const role = m.role.padEnd(10, " ");
|
|
102
|
+
const line = `[${i}][${role}]: ${buildCompactionPreview(m, previewChars)}`;
|
|
103
|
+
lines.push({ index: i, text: line, tokens: estimateTextTokens(line) });
|
|
104
|
+
}
|
|
105
|
+
const total = lines.reduce((sum, line) => sum + line.tokens, 0);
|
|
106
|
+
if (total <= maxTokens) return lines.map((line) => line.text).join("\n");
|
|
107
|
+
const recentCount = Math.min(8, lines.length);
|
|
108
|
+
const recentStart = lines.length - recentCount;
|
|
109
|
+
const tail = [];
|
|
110
|
+
let usedTokens = 0;
|
|
111
|
+
for (let i = lines.length - 1; i >= recentStart; i--) {
|
|
112
|
+
const line = expectDefined(lines[i]);
|
|
113
|
+
if (tail.length >= 2 && usedTokens + line.tokens > Math.floor(maxTokens * 0.45)) continue;
|
|
114
|
+
tail.unshift(line);
|
|
115
|
+
usedTokens += line.tokens;
|
|
116
|
+
}
|
|
117
|
+
const head = [];
|
|
118
|
+
for (let i = 0; i < recentStart; i++) {
|
|
119
|
+
const line = expectDefined(lines[i]);
|
|
120
|
+
if (usedTokens + line.tokens > maxTokens) break;
|
|
121
|
+
head.push(line);
|
|
122
|
+
usedTokens += line.tokens;
|
|
123
|
+
}
|
|
124
|
+
const omitted = Math.max(0, recentStart - head.length);
|
|
125
|
+
const marker = omitted > 0 ? [`[\u2026 ${omitted} middle message(s) omitted from selector preview \u2026]`] : [];
|
|
126
|
+
return [...head.map((line) => line.text), ...marker, ...tail.map((line) => line.text)].join("\n");
|
|
127
|
+
}
|
|
128
|
+
var LLMSelector = class {
|
|
129
|
+
provider;
|
|
130
|
+
model;
|
|
131
|
+
maxContextTokens;
|
|
132
|
+
systemPrompt;
|
|
133
|
+
maxOutputTokens;
|
|
134
|
+
oneShotOrchestrator;
|
|
135
|
+
logger;
|
|
136
|
+
constructor(opts) {
|
|
137
|
+
this.provider = opts.provider;
|
|
138
|
+
this.model = opts.model ?? "unknown";
|
|
139
|
+
this.logger = opts.logger ?? noOpLogger;
|
|
140
|
+
if (this.model === "unknown" && (process.env["NODE_ENV"] === "development" || process.env["WRONGSTACK_DEBUG"] === "1")) {
|
|
141
|
+
this.logger.warn(
|
|
142
|
+
"[LLMSelector] model not set \u2014 selector will use the provider default. Set `model` explicitly in LLMSelectorOptions to silence this warning."
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
this.maxContextTokens = opts.maxContextTokens ?? 4e4;
|
|
146
|
+
this.systemPrompt = opts.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
147
|
+
this.maxOutputTokens = opts.maxOutputTokens ?? 1024;
|
|
148
|
+
this.oneShotOrchestrator = opts.oneShotOrchestrator;
|
|
149
|
+
}
|
|
150
|
+
async select(messages, maxToKeep) {
|
|
151
|
+
const effectiveBudget = Math.min(maxToKeep, this.maxContextTokens);
|
|
152
|
+
const totalTokens = estimateMessageTokens(messages);
|
|
153
|
+
const systemText = `${this.systemPrompt}
|
|
154
|
+
|
|
155
|
+
Conversation (${messages.length} messages, ~${totalTokens} tokens, budget: ${effectiveBudget}):
|
|
156
|
+
`;
|
|
157
|
+
const systemTokens = estimateTextTokens(systemText);
|
|
158
|
+
const historyBudget = Math.max(512, effectiveBudget - systemTokens - this.maxOutputTokens);
|
|
159
|
+
const historyText = formatMessages(messages, historyBudget);
|
|
160
|
+
const budgetInstruction = totalTokens > effectiveBudget ? `
|
|
161
|
+
|
|
162
|
+
IMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiveBudget}). You MUST collapse enough to fit. Prefer collapsing older/lower-importance ranges.` : "";
|
|
163
|
+
const req = {
|
|
164
|
+
model: this.model,
|
|
165
|
+
system: [{ type: "text", text: systemText + budgetInstruction }],
|
|
166
|
+
messages: [{ role: "user", content: historyText }],
|
|
167
|
+
maxTokens: this.maxOutputTokens
|
|
168
|
+
};
|
|
169
|
+
let raw;
|
|
170
|
+
const ac = new AbortController();
|
|
171
|
+
try {
|
|
172
|
+
if (this.oneShotOrchestrator) {
|
|
173
|
+
const result = await this.oneShotOrchestrator.call({
|
|
174
|
+
system: systemText + budgetInstruction,
|
|
175
|
+
userPrompt: historyText,
|
|
176
|
+
maxTokens: this.maxOutputTokens,
|
|
177
|
+
timeoutMs: 3e4
|
|
178
|
+
});
|
|
179
|
+
if (result.error) throw new Error(result.error);
|
|
180
|
+
raw = result.text;
|
|
181
|
+
} else {
|
|
182
|
+
const timeoutSignal = AbortSignal.timeout(3e4);
|
|
183
|
+
const res = await this.provider.complete(req, {
|
|
184
|
+
signal: AbortSignal.any([ac.signal, timeoutSignal])
|
|
185
|
+
});
|
|
186
|
+
const textBlocks = res.content.filter(isTextBlock);
|
|
187
|
+
raw = textBlocks.map((b) => b.text).join("\n").trim();
|
|
188
|
+
}
|
|
189
|
+
} catch (err) {
|
|
190
|
+
if (err instanceof Error) {
|
|
191
|
+
this.logger.warn(`selector call failed, using recency fallback: ${err.message}`, {
|
|
192
|
+
event: "llm_selector.call_failed"
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
return this.fallbackSelect(messages, effectiveBudget);
|
|
196
|
+
} finally {
|
|
197
|
+
ac.abort();
|
|
198
|
+
}
|
|
199
|
+
return this.parseSelectorOutput(raw, messages);
|
|
200
|
+
}
|
|
201
|
+
fallbackSelect(messages, budget) {
|
|
202
|
+
const toKeep = [];
|
|
203
|
+
const toCollapse = [];
|
|
204
|
+
let tokenCount = 0;
|
|
205
|
+
let startIdx = 0;
|
|
206
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
207
|
+
const m = expectDefined(messages[i]);
|
|
208
|
+
const cost = estimateMessageTokens([m]);
|
|
209
|
+
if (tokenCount + cost <= budget) {
|
|
210
|
+
tokenCount += cost;
|
|
211
|
+
} else {
|
|
212
|
+
startIdx = i + 1;
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (startIdx > 0) {
|
|
217
|
+
toCollapse.push({ from: 0, to: startIdx - 1 });
|
|
218
|
+
}
|
|
219
|
+
toKeep.push({ from: startIdx, to: messages.length - 1, importance: "high" });
|
|
220
|
+
return {
|
|
221
|
+
kept: toKeep,
|
|
222
|
+
collapsed: toCollapse,
|
|
223
|
+
reasoning: `Fallback: kept last ${messages.length - startIdx} messages within ${budget} token budget`
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Parse and validate the raw LLM output into a SelectorResult.
|
|
228
|
+
* Falls back to recency-based selection if the LLM output is malformed,
|
|
229
|
+
* out-of-bounds, or internally inconsistent.
|
|
230
|
+
*/
|
|
231
|
+
parseSelectorOutput(raw, messages) {
|
|
232
|
+
const messageCount = messages.length;
|
|
233
|
+
if (messageCount === 0) {
|
|
234
|
+
return { kept: [], collapsed: [], reasoning: "empty session" };
|
|
235
|
+
}
|
|
236
|
+
const jsonStart = raw.indexOf("{");
|
|
237
|
+
const jsonEnd = raw.lastIndexOf("}");
|
|
238
|
+
if (jsonStart === -1 || jsonEnd === -1) {
|
|
239
|
+
return this.fallbackSelect(messages, this.maxContextTokens);
|
|
240
|
+
}
|
|
241
|
+
let parsed;
|
|
242
|
+
try {
|
|
243
|
+
parsed = JSON.parse(raw.slice(jsonStart, jsonEnd + 1));
|
|
244
|
+
} catch {
|
|
245
|
+
return this.fallbackSelect(messages, this.maxContextTokens);
|
|
246
|
+
}
|
|
247
|
+
const obj = parsed;
|
|
248
|
+
const keptRaw = obj.kept ?? [];
|
|
249
|
+
const collapsedRaw = obj.collapsed ?? [];
|
|
250
|
+
const kept = [];
|
|
251
|
+
for (const k of keptRaw) {
|
|
252
|
+
if (typeof k.from !== "number" || typeof k.to !== "number" || k.from < 0 || k.to >= messageCount || k.from > k.to) {
|
|
253
|
+
return this.fallbackSelect(messages, this.maxContextTokens);
|
|
254
|
+
}
|
|
255
|
+
kept.push({
|
|
256
|
+
from: k.from,
|
|
257
|
+
to: k.to,
|
|
258
|
+
importance: k.importance ?? "medium"
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
const collapsed = [];
|
|
262
|
+
for (const c of collapsedRaw) {
|
|
263
|
+
if (typeof c.from !== "number" || typeof c.to !== "number" || c.from < 0 || c.to >= messageCount || c.from > c.to) {
|
|
264
|
+
return this.fallbackSelect(messages, this.maxContextTokens);
|
|
265
|
+
}
|
|
266
|
+
collapsed.push({ from: c.from, to: c.to, summary: c.summary });
|
|
267
|
+
}
|
|
268
|
+
const allRanges = [...kept, ...collapsed];
|
|
269
|
+
for (let i = 0; i < allRanges.length; i++) {
|
|
270
|
+
const a = allRanges[i];
|
|
271
|
+
if (!a) continue;
|
|
272
|
+
for (let j = i + 1; j < allRanges.length; j++) {
|
|
273
|
+
const b = allRanges[j];
|
|
274
|
+
if (!b) continue;
|
|
275
|
+
if (a.from <= b.to && a.to >= b.from) {
|
|
276
|
+
return this.fallbackSelect(messages, this.maxContextTokens);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
kept,
|
|
282
|
+
collapsed,
|
|
283
|
+
reasoning: typeof obj.reasoning === "string" ? obj.reasoning : ""
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
export {
|
|
289
|
+
buildCompactionPreview,
|
|
290
|
+
LLMSelector
|
|
291
|
+
};
|
|
292
|
+
//# sourceMappingURL=chunk-2FQL4PDC.js.map
|