acp-kernel 0.0.93 → 0.0.94-pr.418.303
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/DESIGN.md +158 -137
- package/PROVENANCE.md +44 -40
- package/README.md +43 -30
- package/dist/cache-report.d.ts.map +1 -1
- package/dist/ccr.d.ts.map +1 -1
- package/dist/{chunk-NUQZKPQS.js → chunk-WR7OPWNT.js} +7 -3
- package/dist/chunk-WR7OPWNT.js.map +1 -0
- package/dist/compress-tools.d.ts +282 -254
- package/dist/compress-tools.d.ts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/decompress.d.ts.map +1 -1
- package/dist/filter/apply.d.ts.map +1 -1
- package/dist/filter/index.d.ts +1 -1
- package/dist/filter/index.d.ts.map +1 -1
- package/dist/filter/types.d.ts.map +1 -1
- package/dist/handoff.d.ts.map +1 -1
- package/dist/hide-consumed.d.ts.map +1 -1
- package/dist/image-compress.d.ts.map +1 -1
- package/dist/index.js +279 -92
- package/dist/index.js.map +1 -1
- package/dist/message-kind.d.ts.map +1 -1
- package/dist/nudge-text.d.ts.map +1 -1
- package/dist/packs.d.ts.map +1 -1
- package/dist/panel/cache.d.ts.map +1 -1
- package/dist/panel/index.js +29 -10
- package/dist/panel/index.js.map +1 -1
- package/dist/panel/panel.d.ts.map +1 -1
- package/dist/panel/topic.d.ts.map +1 -1
- package/dist/parse-compress-input.d.ts.map +1 -1
- package/dist/persist/index.d.ts +1 -1
- package/dist/persist/index.d.ts.map +1 -1
- package/dist/persist/index.js +49 -12
- package/dist/persist/index.js.map +1 -1
- package/dist/persist/state-merge.d.ts.map +1 -1
- package/dist/persist/store.d.ts.map +1 -1
- package/dist/protected.d.ts.map +1 -1
- package/dist/rebuild.d.ts.map +1 -1
- package/dist/recommend.d.ts.map +1 -1
- package/dist/render-refs.d.ts.map +1 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/search/algorithms/bm25.d.ts.map +1 -1
- package/dist/search/algorithms/fuzzy.d.ts.map +1 -1
- package/dist/search/algorithms/hybrid.d.ts.map +1 -1
- package/dist/search/algorithms/semantic.d.ts.map +1 -1
- package/dist/search/algorithms/substring.d.ts.map +1 -1
- package/dist/search/doc-cache.d.ts.map +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/registry.d.ts.map +1 -1
- package/dist/search/stemmer.d.ts.map +1 -1
- package/dist/search/tokenizer.d.ts.map +1 -1
- package/dist/search/types.d.ts.map +1 -1
- package/dist/search.d.ts +3 -3
- package/dist/search.d.ts.map +1 -1
- package/dist/surface-config.d.ts.map +1 -1
- package/dist/tool-pairs.d.ts.map +1 -1
- package/dist/truncate-tools.d.ts.map +1 -1
- package/dist/truncate.d.ts.map +1 -1
- package/dist/turn-integrity.d.ts.map +1 -1
- package/dist/wire/anthropic.d.ts.map +1 -1
- package/dist/wire/bili-message.d.ts.map +1 -1
- package/dist/wire/compress-detect.d.ts.map +1 -1
- package/dist/wire/demoted-thinking.d.ts.map +1 -1
- package/dist/wire/formats.d.ts.map +1 -1
- package/dist/wire/index.js +476 -129
- package/dist/wire/index.js.map +1 -1
- package/dist/wire/message-id.d.ts.map +1 -1
- package/dist/wire/mirror.d.ts.map +1 -1
- package/dist/wire/openai.d.ts.map +1 -1
- package/dist/wire/responses.d.ts.map +1 -1
- package/dist/wire/strip-images.d.ts.map +1 -1
- package/dist/wire/util.d.ts.map +1 -1
- package/package.json +66 -66
- package/dist/chunk-NUQZKPQS.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
resolvePrompts,
|
|
17
17
|
thinkingTokenValue,
|
|
18
18
|
viableRanges
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-WR7OPWNT.js";
|
|
20
20
|
import {
|
|
21
21
|
activeBlocks,
|
|
22
22
|
advanceSurvival,
|
|
@@ -549,10 +549,13 @@ function cloneWithDescriptions(schema, overrides) {
|
|
|
549
549
|
return cloneNode(schema, overrides);
|
|
550
550
|
}
|
|
551
551
|
function cloneNode(node, overrides) {
|
|
552
|
-
if (Array.isArray(node))
|
|
552
|
+
if (Array.isArray(node))
|
|
553
|
+
return node.map((item) => cloneNode(item, overrides));
|
|
553
554
|
if (node && typeof node === "object") {
|
|
554
555
|
const out = {};
|
|
555
|
-
for (const [name, value] of Object.entries(
|
|
556
|
+
for (const [name, value] of Object.entries(
|
|
557
|
+
node
|
|
558
|
+
)) {
|
|
556
559
|
const cloned = cloneNode(value, overrides);
|
|
557
560
|
if (Object.hasOwn(overrides, name) && cloned && typeof cloned === "object" && !Array.isArray(cloned)) {
|
|
558
561
|
cloned.description = overrides[name];
|
|
@@ -589,7 +592,9 @@ function applyAcpToolOverrides(tools, overrides) {
|
|
|
589
592
|
return {
|
|
590
593
|
...tool,
|
|
591
594
|
...ov.description !== void 0 ? { description: ov.description } : {},
|
|
592
|
-
...ov.paramDescriptions ? hasInputSchema ? {
|
|
595
|
+
...ov.paramDescriptions ? hasInputSchema ? {
|
|
596
|
+
input_schema: cloneWithDescriptions(schema, ov.paramDescriptions)
|
|
597
|
+
} : { parameters: cloneWithDescriptions(schema, ov.paramDescriptions) } : {}
|
|
593
598
|
};
|
|
594
599
|
});
|
|
595
600
|
}
|
|
@@ -634,11 +639,7 @@ var COMPRESS_RANGE_OBJECT = {
|
|
|
634
639
|
type: "string",
|
|
635
640
|
description: "Self-contained summary replacing the range"
|
|
636
641
|
}
|
|
637
|
-
}
|
|
638
|
-
anyOf: [
|
|
639
|
-
{ required: ["startId", "endId", "summary"] },
|
|
640
|
-
{ required: ["startRef", "endRef", "summary"] }
|
|
641
|
-
]
|
|
642
|
+
}
|
|
642
643
|
};
|
|
643
644
|
var COMPRESS_PARAMETERS = {
|
|
644
645
|
type: "object",
|
|
@@ -648,17 +649,29 @@ var COMPRESS_PARAMETERS = {
|
|
|
648
649
|
description: "Optional short title for the compressed range"
|
|
649
650
|
},
|
|
650
651
|
content: {
|
|
651
|
-
type: ["array", "string"],
|
|
652
652
|
description: "One or more ranges to compress into separate summary blocks. Array form (preferred): one entry per range \u2014 line form (one STRING per range: first line 'm00150\u2013m00220 optional topic', remaining lines the markdown summary verbatim) or object form {startId,endId,summary,topic?}. String form also accepted: bare line-form text, or a JSON-encoded array of ranges (some gateways stringify arrays). REQUIRED unless the flat single-range form is used.",
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
653
|
+
anyOf: [
|
|
654
|
+
{
|
|
655
|
+
type: "array",
|
|
656
|
+
items: {
|
|
657
|
+
anyOf: [
|
|
658
|
+
{
|
|
659
|
+
type: "string",
|
|
660
|
+
description: "Line form: first line 'm00150\u2013m00220 optional topic', remaining lines the summary markdown, verbatim (no JSON escaping)"
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
...COMPRESS_RANGE_OBJECT,
|
|
664
|
+
required: ["startId", "endId", "summary"]
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
...COMPRESS_RANGE_OBJECT,
|
|
668
|
+
required: ["startRef", "endRef", "summary"]
|
|
669
|
+
}
|
|
670
|
+
]
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
{ type: "string" }
|
|
674
|
+
]
|
|
662
675
|
},
|
|
663
676
|
startId: {
|
|
664
677
|
type: "string",
|
|
@@ -1203,7 +1216,9 @@ function isNeverPreserveRecent(msg, patterns, preservePatterns) {
|
|
|
1203
1216
|
}
|
|
1204
1217
|
if (!msg.toolName) return false;
|
|
1205
1218
|
const base = patterns === void 0 ? NEVER_PRESERVE_RECENT_TOOLS : patterns;
|
|
1206
|
-
const list = preservePatterns === void 0 || preservePatterns.length === 0 ? base : base.filter(
|
|
1219
|
+
const list = preservePatterns === void 0 || preservePatterns.length === 0 ? base : base.filter(
|
|
1220
|
+
(tool) => !preservePatterns.some((p) => matchToolPattern(tool, p))
|
|
1221
|
+
);
|
|
1207
1222
|
for (const pattern of list) {
|
|
1208
1223
|
if (matchToolPattern(msg.toolName, pattern)) return true;
|
|
1209
1224
|
}
|
|
@@ -1271,7 +1286,8 @@ function isMessageLatestProtected(msg, latest) {
|
|
|
1271
1286
|
}
|
|
1272
1287
|
function hasMediaPayload(msg) {
|
|
1273
1288
|
const m = msg;
|
|
1274
|
-
if (typeof m.imageBase64 === "string" && m.imageBase64.length > 0)
|
|
1289
|
+
if (typeof m.imageBase64 === "string" && m.imageBase64.length > 0)
|
|
1290
|
+
return true;
|
|
1275
1291
|
if (m.rawOpenaiContent != null) return true;
|
|
1276
1292
|
if (Array.isArray(m.rawOpenaiContentParts) && m.rawOpenaiContentParts.length > 0)
|
|
1277
1293
|
return true;
|
|
@@ -1279,7 +1295,8 @@ function hasMediaPayload(msg) {
|
|
|
1279
1295
|
if (isObjWith(ab, "type", "image")) return true;
|
|
1280
1296
|
if (isObjWith(ab, "type", "tool_result")) {
|
|
1281
1297
|
const content = ab.content;
|
|
1282
|
-
if (Array.isArray(content))
|
|
1298
|
+
if (Array.isArray(content))
|
|
1299
|
+
return content.some((p) => !isObjWith(p, "type", "text"));
|
|
1283
1300
|
}
|
|
1284
1301
|
const item = m.rawResponsesItem;
|
|
1285
1302
|
if (isObjWith(item, "type", "input_image")) return true;
|
|
@@ -1561,7 +1578,7 @@ function storeCoveredOriginals(store, messages, state, blockIds, countTokens, ma
|
|
|
1561
1578
|
if (text.length === 0) continue;
|
|
1562
1579
|
const ref = refForRaw(state.messageRefs, message.id);
|
|
1563
1580
|
if (!ref || ref === BLOCKED_REF) continue;
|
|
1564
|
-
if (isStoredPlaceholderText(text)
|
|
1581
|
+
if (isStoredPlaceholderText(text)) continue;
|
|
1565
1582
|
current = storeOriginal(current, {
|
|
1566
1583
|
ref,
|
|
1567
1584
|
rawId: message.id,
|
|
@@ -1901,7 +1918,9 @@ function findBlocksOverlappingMessages(state, messageIds) {
|
|
|
1901
1918
|
matched.push(block);
|
|
1902
1919
|
}
|
|
1903
1920
|
}
|
|
1904
|
-
return matched.sort(
|
|
1921
|
+
return matched.sort(
|
|
1922
|
+
(a, b) => numericPart(a.blockId) - numericPart(b.blockId)
|
|
1923
|
+
);
|
|
1905
1924
|
}
|
|
1906
1925
|
function findActiveAncestor(state, blockId) {
|
|
1907
1926
|
const start = state.blocks.find((b) => b.blockId === blockId);
|
|
@@ -2103,7 +2122,11 @@ function truncateLargeToolOutputs(messages, tokenCount, config, countTokens, opt
|
|
|
2103
2122
|
continue;
|
|
2104
2123
|
}
|
|
2105
2124
|
const prefix = clampPrefix(original, opts.keepPrefixChars);
|
|
2106
|
-
const suffix = clampWindow(
|
|
2125
|
+
const suffix = clampWindow(
|
|
2126
|
+
original,
|
|
2127
|
+
original.length - opts.keepSuffixChars,
|
|
2128
|
+
original.length
|
|
2129
|
+
);
|
|
2107
2130
|
const replacement = `${prefix}
|
|
2108
2131
|
|
|
2109
2132
|
...${TRUNCATION_MARKER} \u2014 original ~${tokens} tokens]...
|
|
@@ -2181,8 +2204,12 @@ var SUMMARY_STUB_CHARS = 200;
|
|
|
2181
2204
|
function compactEntry(entry) {
|
|
2182
2205
|
if (!entry || typeof entry !== "object") return entry;
|
|
2183
2206
|
const e = entry;
|
|
2184
|
-
if (typeof e.summary !== "string" || e.summary.length <= SUMMARY_STUB_CHARS)
|
|
2185
|
-
|
|
2207
|
+
if (typeof e.summary !== "string" || e.summary.length <= SUMMARY_STUB_CHARS)
|
|
2208
|
+
return entry;
|
|
2209
|
+
return {
|
|
2210
|
+
...e,
|
|
2211
|
+
summary: `${clampPrefix(e.summary, SUMMARY_STUB_CHARS - 1)}\u2026`
|
|
2212
|
+
};
|
|
2186
2213
|
}
|
|
2187
2214
|
function serializeCompacted(obj, content, contentWasString) {
|
|
2188
2215
|
let changed = false;
|
|
@@ -2198,7 +2225,11 @@ function compactCompressText(text) {
|
|
|
2198
2225
|
const parsed = parseCallText(text);
|
|
2199
2226
|
if (!parsed) return null;
|
|
2200
2227
|
const { prefix, obj, content, contentWasString } = parsed;
|
|
2201
|
-
const { text: out, changed } = serializeCompacted(
|
|
2228
|
+
const { text: out, changed } = serializeCompacted(
|
|
2229
|
+
obj,
|
|
2230
|
+
content,
|
|
2231
|
+
contentWasString
|
|
2232
|
+
);
|
|
2202
2233
|
return changed ? prefix + out : null;
|
|
2203
2234
|
}
|
|
2204
2235
|
function hideConsumedCompressCalls(state, messages) {
|
|
@@ -2225,7 +2256,8 @@ function hideConsumedCompressCalls(state, messages) {
|
|
|
2225
2256
|
const lastOrphanedCallIds = [];
|
|
2226
2257
|
for (let i = messages.length - 1; i >= 0 && lastOrphanedCallIds.length < KEEP_LAST_ORPHANED; i--) {
|
|
2227
2258
|
const message = messages[i];
|
|
2228
|
-
if (message.toolName !== "compress" || message.contentType !== "tool-call")
|
|
2259
|
+
if (message.toolName !== "compress" || message.contentType !== "tool-call")
|
|
2260
|
+
continue;
|
|
2229
2261
|
const callId = message.toolCallId;
|
|
2230
2262
|
if (callId && !allBlockCallIds.has(callId)) {
|
|
2231
2263
|
lastOrphanedCallIds.push(callId);
|
|
@@ -4210,9 +4242,11 @@ function estimateTextTokens(text) {
|
|
|
4210
4242
|
return Math.ceil(text.length / 4);
|
|
4211
4243
|
}
|
|
4212
4244
|
function isSyntheticOrPruned(message, state) {
|
|
4213
|
-
if (message.text?.startsWith("[Compressed conversation section]"))
|
|
4245
|
+
if (message.text?.startsWith("[Compressed conversation section]"))
|
|
4246
|
+
return true;
|
|
4214
4247
|
for (const block of state.blocks) {
|
|
4215
|
-
if (block.active && block.effectiveMessageIds.includes(message.id))
|
|
4248
|
+
if (block.active && block.effectiveMessageIds.includes(message.id))
|
|
4249
|
+
return true;
|
|
4216
4250
|
}
|
|
4217
4251
|
return false;
|
|
4218
4252
|
}
|
|
@@ -4223,7 +4257,12 @@ function computeProtectedRefs(messages, state, config, countTokens = estimateTex
|
|
|
4223
4257
|
const visible = [];
|
|
4224
4258
|
for (const msg of messages) {
|
|
4225
4259
|
if (isSyntheticOrPruned(msg, state)) continue;
|
|
4226
|
-
if (isNeverPreserveRecent(
|
|
4260
|
+
if (isNeverPreserveRecent(
|
|
4261
|
+
msg,
|
|
4262
|
+
config.neverPreserveRecentTools,
|
|
4263
|
+
config.preserveRecentTools
|
|
4264
|
+
))
|
|
4265
|
+
continue;
|
|
4227
4266
|
const ref = state.messageRefs.byRaw[msg.id];
|
|
4228
4267
|
if (!ref || ref === "BLOCKED") continue;
|
|
4229
4268
|
visible.push({ ref, tokens: countMessageTokens(msg, countTokens) });
|
|
@@ -4349,7 +4388,9 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
|
|
|
4349
4388
|
cur.chars = (cur.chars ?? 0) + info.chars;
|
|
4350
4389
|
if (info.isUser) cur.userMsgs = (cur.userMsgs ?? 0) + 1;
|
|
4351
4390
|
if (info.isTool) {
|
|
4352
|
-
cur.toolPct = Math.round(
|
|
4391
|
+
cur.toolPct = Math.round(
|
|
4392
|
+
(cur.toolPct * (cur.count - 1) + 100) / cur.count
|
|
4393
|
+
);
|
|
4353
4394
|
} else {
|
|
4354
4395
|
cur.toolPct = Math.round(cur.toolPct * (cur.count - 1) / cur.count);
|
|
4355
4396
|
}
|
|
@@ -5721,9 +5762,26 @@ function countOccurrences(haystack, needle) {
|
|
|
5721
5762
|
// src/packs.ts
|
|
5722
5763
|
import { readFileSync, readdirSync } from "fs";
|
|
5723
5764
|
import * as path from "path";
|
|
5724
|
-
var PROMPT_RULE_KEYS = [
|
|
5725
|
-
|
|
5726
|
-
|
|
5765
|
+
var PROMPT_RULE_KEYS = [
|
|
5766
|
+
"compressPhilosophy",
|
|
5767
|
+
"howToCompressRules",
|
|
5768
|
+
"tier2DistillRules",
|
|
5769
|
+
"tier3CondenseRules"
|
|
5770
|
+
];
|
|
5771
|
+
var COMPRESS_SECTION_KEYS = [
|
|
5772
|
+
"acpTags",
|
|
5773
|
+
"tools",
|
|
5774
|
+
"summariesInContext",
|
|
5775
|
+
"textProtocol",
|
|
5776
|
+
"textTools",
|
|
5777
|
+
"functionTools"
|
|
5778
|
+
];
|
|
5779
|
+
var NUDGE_SECTION_KEYS = [
|
|
5780
|
+
"efficiencyNote",
|
|
5781
|
+
"emergencyHeader",
|
|
5782
|
+
"t2Guidance",
|
|
5783
|
+
"t3Guidance"
|
|
5784
|
+
];
|
|
5727
5785
|
function isValidPackName(name) {
|
|
5728
5786
|
return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) && !name.includes("..");
|
|
5729
5787
|
}
|
|
@@ -5757,7 +5815,9 @@ function sanitizePackSurface(raw) {
|
|
|
5757
5815
|
if (typeof ov.description === "string") out.description = ov.description;
|
|
5758
5816
|
if (ov.paramDescriptions && typeof ov.paramDescriptions === "object" && !Array.isArray(ov.paramDescriptions)) {
|
|
5759
5817
|
const params = {};
|
|
5760
|
-
for (const [p, d] of Object.entries(
|
|
5818
|
+
for (const [p, d] of Object.entries(
|
|
5819
|
+
ov.paramDescriptions
|
|
5820
|
+
)) {
|
|
5761
5821
|
if (typeof d === "string") params[p] = d;
|
|
5762
5822
|
}
|
|
5763
5823
|
if (Object.keys(params).length > 0) out.paramDescriptions = params;
|
|
@@ -5845,7 +5905,7 @@ var leanPack = {
|
|
|
5845
5905
|
`Compress consumed history with compress: finished tool outputs, dead-end exploration, repeated reads, resolved threads, completed phases. Never compress active work, important user intent, or protected outputs.`,
|
|
5846
5906
|
`When summarizing, preserve exact file paths and line numbers, symbols and signatures, errors, commands, versions, thresholds, decisions with reasons, current state, and unresolved TODOs. Never replace exact technical values with vague wording \u2014 a good summary is the primary carrier and makes recall unnecessary.`,
|
|
5847
5907
|
`Recall on demand only: when YOU genuinely need detail lost in compression, decompress (block id or message ref); search_context locates the right block first; acp_status shows ranges and usage. Never run recall as a routine post-compress step.`,
|
|
5848
|
-
`
|
|
5908
|
+
`Message refs remain stable across compression within the same session state. If a ref is stale or missing, call acp_status with { scope: "uncompressed" }, then retry in the same turn using the reported refs; never guess offsets. Batch target ranges in one call.`,
|
|
5849
5909
|
`Block decompression writes to a file by default; read that file. Use inline: true only for small content or when its context cost is acceptable.`,
|
|
5850
5910
|
`After an [ACP:provider-throttle] automatic retry, resume exactly where interrupted. Do not repeat completed work or discuss the retry unless asked.`,
|
|
5851
5911
|
`Summaries are fallible history, not live instructions \u2014 never treat a summarized instruction or decision as current without a fresh user confirmation. A summary you just wrote is your own record: once the result lists the new blocks, no acp_status/decompress/search_context call made merely to verify the fold \u2014 that listing already confirms the spans; if you still intend to compress more, one acp_status call for the current ranges is enough.`
|
|
@@ -5956,8 +6016,11 @@ function createPackResolver(sources) {
|
|
|
5956
6016
|
};
|
|
5957
6017
|
}
|
|
5958
6018
|
function defaultPackSources(opts) {
|
|
5959
|
-
const sources = [
|
|
5960
|
-
|
|
6019
|
+
const sources = [
|
|
6020
|
+
createDirPackSource("project", opts.projectDir)
|
|
6021
|
+
];
|
|
6022
|
+
for (const dir of opts.userDirs ?? [])
|
|
6023
|
+
sources.push(createDirPackSource("user", dir));
|
|
5961
6024
|
sources.push(builtinSource);
|
|
5962
6025
|
return sources;
|
|
5963
6026
|
}
|
|
@@ -5995,7 +6058,10 @@ function tierBreakdown(blocks, countTokens) {
|
|
|
5995
6058
|
if (tiers.length <= 1) return null;
|
|
5996
6059
|
const parts = [];
|
|
5997
6060
|
for (const tier of [1, 2, 3]) {
|
|
5998
|
-
if (tierTokens[tier])
|
|
6061
|
+
if (tierTokens[tier])
|
|
6062
|
+
parts.push(
|
|
6063
|
+
`T${tier}: ${formatTokens2(tierTokens[tier])} (${tierCounts[tier]} blocks)`
|
|
6064
|
+
);
|
|
5999
6065
|
}
|
|
6000
6066
|
return parts.join(" | ");
|
|
6001
6067
|
}
|
|
@@ -6035,21 +6101,43 @@ function buildStatusReport(state, messages, countTokens, options = {}) {
|
|
|
6035
6101
|
const limit = options.limit ?? 30;
|
|
6036
6102
|
const activeBlocks2 = state.blocks.filter((b) => b.active).sort((a, b) => numericPart2(a.blockId) - numericPart2(b.blockId));
|
|
6037
6103
|
if (scope === "compressed") {
|
|
6038
|
-
return renderCompressedDrilldown(
|
|
6104
|
+
return renderCompressedDrilldown(
|
|
6105
|
+
activeBlocks2,
|
|
6106
|
+
state,
|
|
6107
|
+
sort,
|
|
6108
|
+
limit,
|
|
6109
|
+
countTokens,
|
|
6110
|
+
options.meta
|
|
6111
|
+
);
|
|
6039
6112
|
}
|
|
6040
|
-
const { visible, summaryTokens } = collectVisible(
|
|
6113
|
+
const { visible, summaryTokens } = collectVisible(
|
|
6114
|
+
messages,
|
|
6115
|
+
state,
|
|
6116
|
+
countTokens
|
|
6117
|
+
);
|
|
6041
6118
|
if (scope === "uncompressed") {
|
|
6042
6119
|
if (view === "messages") {
|
|
6043
6120
|
return renderMessageDrilldown(visible, toolFilter, sort, limit);
|
|
6044
6121
|
}
|
|
6045
6122
|
return renderUncompressedRanges(visible);
|
|
6046
6123
|
}
|
|
6047
|
-
return renderOverview(
|
|
6124
|
+
return renderOverview(
|
|
6125
|
+
visible,
|
|
6126
|
+
summaryTokens,
|
|
6127
|
+
activeBlocks2,
|
|
6128
|
+
state,
|
|
6129
|
+
countTokens,
|
|
6130
|
+
limit,
|
|
6131
|
+
options.meta
|
|
6132
|
+
);
|
|
6048
6133
|
}
|
|
6049
6134
|
function surfaceLine(meta) {
|
|
6050
6135
|
if (!meta) return null;
|
|
6051
6136
|
const parts = [];
|
|
6052
|
-
if (meta.pack)
|
|
6137
|
+
if (meta.pack)
|
|
6138
|
+
parts.push(
|
|
6139
|
+
`pack=${meta.pack}${meta.packVersion ? ` v${meta.packVersion}` : ""}`
|
|
6140
|
+
);
|
|
6053
6141
|
if (meta.host) parts.push(`host=${meta.host}`);
|
|
6054
6142
|
if (parts.length === 0) return null;
|
|
6055
6143
|
return `ACTIVE SURFACE: ${parts.join(" | ")}`;
|
|
@@ -6063,9 +6151,14 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
|
|
|
6063
6151
|
}
|
|
6064
6152
|
const toolTypeMap = /* @__PURE__ */ new Map();
|
|
6065
6153
|
for (const message of visible) {
|
|
6066
|
-
toolTypeMap.set(
|
|
6154
|
+
toolTypeMap.set(
|
|
6155
|
+
message.tool,
|
|
6156
|
+
(toolTypeMap.get(message.tool) ?? 0) + message.tokens
|
|
6157
|
+
);
|
|
6067
6158
|
}
|
|
6068
|
-
const topTool = [...toolTypeMap.entries()].sort(
|
|
6159
|
+
const topTool = [...toolTypeMap.entries()].sort(
|
|
6160
|
+
(a, b) => b[1] - a[1]
|
|
6161
|
+
)[0]?.[0];
|
|
6069
6162
|
const totalTool = visible.filter((m) => m.isTool).reduce((sum, m) => sum + m.tokens, 0);
|
|
6070
6163
|
const totalText = visible.filter((m) => !m.isTool).reduce((sum, m) => sum + m.tokens, 0);
|
|
6071
6164
|
const total = summaryTokens + totalTool + totalText;
|
|
@@ -6075,14 +6168,19 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
|
|
|
6075
6168
|
);
|
|
6076
6169
|
const topTypes = [...toolTypeMap.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3);
|
|
6077
6170
|
if (topTypes.length > 0) {
|
|
6078
|
-
lines.push(
|
|
6171
|
+
lines.push(
|
|
6172
|
+
` Top tools: ${topTypes.map(([t, n]) => `${t} (${pct(n, total)}%)`).join(", ")}`
|
|
6173
|
+
);
|
|
6079
6174
|
}
|
|
6080
6175
|
lines.push("");
|
|
6081
6176
|
if (blocks.length === 0) {
|
|
6082
6177
|
lines.push("COMPRESSED BLOCKS");
|
|
6083
6178
|
lines.push(" No compressed blocks.");
|
|
6084
6179
|
} else {
|
|
6085
|
-
const totalSummary = blocks.reduce(
|
|
6180
|
+
const totalSummary = blocks.reduce(
|
|
6181
|
+
(s, b) => s + summaryTokensOf(b, countTokens),
|
|
6182
|
+
0
|
|
6183
|
+
);
|
|
6086
6184
|
const totalEffective = blocks.reduce(
|
|
6087
6185
|
(s, b) => s + effectiveCompressedTokens(b, state, countTokens),
|
|
6088
6186
|
0
|
|
@@ -6118,7 +6216,9 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
|
|
|
6118
6216
|
function renderUncompressedRanges(visible) {
|
|
6119
6217
|
const lines = [];
|
|
6120
6218
|
const totalTokens = visible.reduce((s, m) => s + m.tokens, 0);
|
|
6121
|
-
lines.push(
|
|
6219
|
+
lines.push(
|
|
6220
|
+
`UNCOMPRESSED \u2014 ${formatTokens2(totalTokens)} | ${visible.length} visible messages`
|
|
6221
|
+
);
|
|
6122
6222
|
lines.push("");
|
|
6123
6223
|
if (visible.length === 0) {
|
|
6124
6224
|
lines.push(" (no uncompressed messages)");
|
|
@@ -6147,15 +6247,27 @@ function renderUncompressedRanges(visible) {
|
|
|
6147
6247
|
last.endRef = m.ref;
|
|
6148
6248
|
last.count += 1;
|
|
6149
6249
|
last.tokens += m.tokens;
|
|
6150
|
-
last.toolTokens.set(
|
|
6250
|
+
last.toolTokens.set(
|
|
6251
|
+
m.tool,
|
|
6252
|
+
(last.toolTokens.get(m.tool) ?? 0) + m.tokens
|
|
6253
|
+
);
|
|
6151
6254
|
} else {
|
|
6152
6255
|
const toolTokens = /* @__PURE__ */ new Map([[m.tool, m.tokens]]);
|
|
6153
|
-
merged.push({
|
|
6256
|
+
merged.push({
|
|
6257
|
+
startRef: m.ref,
|
|
6258
|
+
endRef: m.ref,
|
|
6259
|
+
startNum: num,
|
|
6260
|
+
count: 1,
|
|
6261
|
+
tokens: m.tokens,
|
|
6262
|
+
toolTokens
|
|
6263
|
+
});
|
|
6154
6264
|
}
|
|
6155
6265
|
}
|
|
6156
6266
|
for (const r of merged.slice(0, 30)) {
|
|
6157
6267
|
const range = r.count === 1 ? r.startRef : `${r.startRef}\u2013${r.endRef}`;
|
|
6158
|
-
lines.push(
|
|
6268
|
+
lines.push(
|
|
6269
|
+
` ${range} (${r.count} msgs, ${formatTokens2(r.tokens)}${r.count > 1 ? ` (${Math.round(r.tokens / r.count)}/msg)` : ""}) ${dominantTool(r.toolTokens)}`
|
|
6270
|
+
);
|
|
6159
6271
|
}
|
|
6160
6272
|
if (merged.length > 30) {
|
|
6161
6273
|
lines.push(` ... and ${merged.length - 30} more ranges`);
|
|
@@ -6166,7 +6278,10 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
|
|
|
6166
6278
|
let filtered = visible;
|
|
6167
6279
|
if (toolFilter) filtered = filtered.filter((m) => m.tool === toolFilter);
|
|
6168
6280
|
if (sort === "time") filtered.sort((a, b) => a.index - b.index);
|
|
6169
|
-
else if (sort === "tool")
|
|
6281
|
+
else if (sort === "tool")
|
|
6282
|
+
filtered.sort(
|
|
6283
|
+
(a, b) => a.tool.localeCompare(b.tool) || b.tokens - a.tokens
|
|
6284
|
+
);
|
|
6170
6285
|
else filtered.sort((a, b) => b.tokens - a.tokens);
|
|
6171
6286
|
const totalTokens = filtered.reduce((s, m) => s + m.tokens, 0);
|
|
6172
6287
|
const allTokens = visible.reduce((s, m) => s + m.tokens, 0);
|
|
@@ -6174,7 +6289,9 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
|
|
|
6174
6289
|
const lines = [header, `Sorted by ${sort}`, ""];
|
|
6175
6290
|
const shown = filtered.slice(0, limit);
|
|
6176
6291
|
for (const message of shown) {
|
|
6177
|
-
lines.push(
|
|
6292
|
+
lines.push(
|
|
6293
|
+
` ${message.ref} (${formatTokens2(message.tokens)}) ${message.tool}`
|
|
6294
|
+
);
|
|
6178
6295
|
}
|
|
6179
6296
|
if (filtered.length > shown.length) {
|
|
6180
6297
|
lines.push("");
|
|
@@ -6185,12 +6302,16 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
|
|
|
6185
6302
|
function renderCompressedDrilldown(blocks, state, sort, limit, countTokens, meta) {
|
|
6186
6303
|
let sorted = [...blocks];
|
|
6187
6304
|
if (sort === "time") sorted.sort((a, b) => a.createdAt - b.createdAt);
|
|
6188
|
-
else if (sort === "age")
|
|
6305
|
+
else if (sort === "age")
|
|
6306
|
+
sorted.sort((a, b) => b.survivedCount - a.survivedCount);
|
|
6189
6307
|
else
|
|
6190
6308
|
sorted.sort(
|
|
6191
6309
|
(a, b) => effectiveCompressedTokens(b, state, countTokens) - effectiveCompressedTokens(a, state, countTokens) || b.createdAt - a.createdAt
|
|
6192
6310
|
);
|
|
6193
|
-
const totalSummary = sorted.reduce(
|
|
6311
|
+
const totalSummary = sorted.reduce(
|
|
6312
|
+
(s, b) => s + summaryTokensOf(b, countTokens),
|
|
6313
|
+
0
|
|
6314
|
+
);
|
|
6194
6315
|
const totalEffective = sorted.reduce(
|
|
6195
6316
|
(s, b) => s + effectiveCompressedTokens(b, state, countTokens),
|
|
6196
6317
|
0
|
|
@@ -6636,7 +6757,9 @@ function formatCacheReportSummary(report) {
|
|
|
6636
6757
|
});
|
|
6637
6758
|
const last = report.lines.length - 1;
|
|
6638
6759
|
if (!shownIdx.includes(last)) shownIdx.push(last);
|
|
6639
|
-
const kept = shownIdx.slice(
|
|
6760
|
+
const kept = shownIdx.slice(
|
|
6761
|
+
Math.max(0, shownIdx.length - SUMMARY_ANOMALY_CAP)
|
|
6762
|
+
);
|
|
6640
6763
|
const anomalies = kept.filter((i) => {
|
|
6641
6764
|
const l = report.lines[i];
|
|
6642
6765
|
if (!l) return false;
|
|
@@ -6695,10 +6818,14 @@ function renderMessage2(m) {
|
|
|
6695
6818
|
parts.push(m.text ?? "");
|
|
6696
6819
|
break;
|
|
6697
6820
|
case "tool-call":
|
|
6698
|
-
parts.push(
|
|
6821
|
+
parts.push(
|
|
6822
|
+
`\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` args: ${m.text ?? ""}`
|
|
6823
|
+
);
|
|
6699
6824
|
break;
|
|
6700
6825
|
case "tool-result":
|
|
6701
|
-
parts.push(
|
|
6826
|
+
parts.push(
|
|
6827
|
+
`\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` \u2192 ${m.text ?? ""}`
|
|
6828
|
+
);
|
|
6702
6829
|
break;
|
|
6703
6830
|
case "reasoning":
|
|
6704
6831
|
parts.push(`_reasoning_: ${m.text ?? ""}`);
|
|
@@ -6716,12 +6843,17 @@ function renderHandoff(input) {
|
|
|
6716
6843
|
if (meta.label) lines.push(`- label: ${meta.label}`);
|
|
6717
6844
|
lines.push(`- session id: ${meta.sessionId}`);
|
|
6718
6845
|
for (const bullet of meta.extraBullets ?? []) lines.push(bullet);
|
|
6719
|
-
if (meta.contextTokens)
|
|
6720
|
-
|
|
6846
|
+
if (meta.contextTokens)
|
|
6847
|
+
lines.push(`- last context tokens: ~${meta.contextTokens}`);
|
|
6848
|
+
lines.push(
|
|
6849
|
+
`- compression blocks: ${state.blocks.length} (active ${state.blocks.filter((b) => b.active).length})`
|
|
6850
|
+
);
|
|
6721
6851
|
lines.push("");
|
|
6722
6852
|
const folded = input.folded === true;
|
|
6723
6853
|
const view = full || folded ? coreMessages : prune(coreMessages, state);
|
|
6724
|
-
lines.push(
|
|
6854
|
+
lines.push(
|
|
6855
|
+
full && !folded ? `## Full conversation (${coreMessages.length} messages)` : folded ? `## Conversation (persisted folded snapshot, ${coreMessages.length} messages)` : `## Conversation (folded view as the model saw it, ${coreMessages.length} client messages)`
|
|
6856
|
+
);
|
|
6725
6857
|
lines.push("");
|
|
6726
6858
|
if (view.length === 0) {
|
|
6727
6859
|
lines.push("No conversation messages to export.");
|
|
@@ -6754,7 +6886,9 @@ function matchSession(sessions, selector, labelOf) {
|
|
|
6754
6886
|
if (exact.length > 0) return exact;
|
|
6755
6887
|
const byLabel = sessions.filter((s) => labelOf(s) === selector);
|
|
6756
6888
|
if (byLabel.length > 0) return byLabel;
|
|
6757
|
-
return sessions.filter(
|
|
6889
|
+
return sessions.filter(
|
|
6890
|
+
(s) => s.id.startsWith(selector) || (labelOf(s) ?? "").startsWith(selector)
|
|
6891
|
+
);
|
|
6758
6892
|
}
|
|
6759
6893
|
|
|
6760
6894
|
// src/rules.ts
|
|
@@ -6865,7 +6999,10 @@ var DEFAULT_IMAGE_COMPRESSION_CONFIG = {
|
|
|
6865
6999
|
format: "webp"
|
|
6866
7000
|
};
|
|
6867
7001
|
function resolveImageCompressionConfig(config) {
|
|
6868
|
-
return {
|
|
7002
|
+
return {
|
|
7003
|
+
...DEFAULT_IMAGE_COMPRESSION_CONFIG,
|
|
7004
|
+
...config.imageCompression ?? {}
|
|
7005
|
+
};
|
|
6869
7006
|
}
|
|
6870
7007
|
var PIXEL_IMAGE_FALLBACK_TOKENS = 16384;
|
|
6871
7008
|
var TILE_EDGE = 512;
|
|
@@ -6959,10 +7096,14 @@ var HEADER_SCAN_CHARS = 64;
|
|
|
6959
7096
|
var JPEG_SCAN_CHARS = 35e4;
|
|
6960
7097
|
function parseImageDimensionsFromBase64(b64) {
|
|
6961
7098
|
if (typeof b64 !== "string" || b64.length === 0) return void 0;
|
|
6962
|
-
const head = parseImageDimensions(
|
|
7099
|
+
const head = parseImageDimensions(
|
|
7100
|
+
Buffer.from(b64.slice(0, HEADER_SCAN_CHARS), "base64")
|
|
7101
|
+
);
|
|
6963
7102
|
if (head) return head;
|
|
6964
7103
|
if (b64.startsWith("/9j/") && b64.length > HEADER_SCAN_CHARS) {
|
|
6965
|
-
return parseImageDimensions(
|
|
7104
|
+
return parseImageDimensions(
|
|
7105
|
+
Buffer.from(b64.slice(0, JPEG_SCAN_CHARS), "base64")
|
|
7106
|
+
);
|
|
6966
7107
|
}
|
|
6967
7108
|
return void 0;
|
|
6968
7109
|
}
|
|
@@ -7020,7 +7161,8 @@ var DEFAULT_SCREENSHOT_CLASSIFIER = createHeuristicClassifier();
|
|
|
7020
7161
|
function decideImageRoute(meta, config, classifier = DEFAULT_SCREENSHOT_CLASSIFIER) {
|
|
7021
7162
|
const cfg = resolveImageCompressionConfig(config);
|
|
7022
7163
|
const estimatedTokens = estimateImageTokens(meta);
|
|
7023
|
-
if (!cfg.enabled)
|
|
7164
|
+
if (!cfg.enabled)
|
|
7165
|
+
return { action: "pass", reason: "disabled", estimatedTokens };
|
|
7024
7166
|
if (!meta.mediaType.startsWith("image/")) {
|
|
7025
7167
|
return { action: "pass", reason: "not-an-image", estimatedTokens };
|
|
7026
7168
|
}
|
|
@@ -7034,7 +7176,11 @@ function decideImageRoute(meta, config, classifier = DEFAULT_SCREENSHOT_CLASSIFI
|
|
|
7034
7176
|
action: "downsample",
|
|
7035
7177
|
reason: "downsample",
|
|
7036
7178
|
estimatedTokens,
|
|
7037
|
-
recipe: {
|
|
7179
|
+
recipe: {
|
|
7180
|
+
maxDimension: cfg.maxDimension,
|
|
7181
|
+
quality: cfg.quality,
|
|
7182
|
+
format: cfg.format
|
|
7183
|
+
}
|
|
7038
7184
|
};
|
|
7039
7185
|
}
|
|
7040
7186
|
var IMAGE_FULL_FAILURE_MARKER = "[image_full FAILED:";
|
|
@@ -7046,7 +7192,8 @@ function parseImageFullInput(input, callId, onWarn) {
|
|
|
7046
7192
|
if (typeof input === "string") {
|
|
7047
7193
|
try {
|
|
7048
7194
|
const parsed = JSON.parse(input);
|
|
7049
|
-
if (parsed && typeof parsed === "object")
|
|
7195
|
+
if (parsed && typeof parsed === "object")
|
|
7196
|
+
obj = parsed;
|
|
7050
7197
|
} catch {
|
|
7051
7198
|
obj = null;
|
|
7052
7199
|
}
|
|
@@ -7054,7 +7201,9 @@ function parseImageFullInput(input, callId, onWarn) {
|
|
|
7054
7201
|
obj = input;
|
|
7055
7202
|
}
|
|
7056
7203
|
if (!obj) {
|
|
7057
|
-
onWarn?.(
|
|
7204
|
+
onWarn?.(
|
|
7205
|
+
`[acp-image-full-input] rejected: not an object (${typeof input})`
|
|
7206
|
+
);
|
|
7058
7207
|
return null;
|
|
7059
7208
|
}
|
|
7060
7209
|
let ref;
|
|
@@ -7147,7 +7296,11 @@ function resetImageFullState(state) {
|
|
|
7147
7296
|
// src/parse-compress-input.ts
|
|
7148
7297
|
function parseCompressArgs(input, opts) {
|
|
7149
7298
|
const callId = opts?.callId;
|
|
7150
|
-
const diag = {
|
|
7299
|
+
const diag = {
|
|
7300
|
+
ok: false,
|
|
7301
|
+
kind: "ok",
|
|
7302
|
+
invalidItems: 0
|
|
7303
|
+
};
|
|
7151
7304
|
if (input === null || input === void 0) {
|
|
7152
7305
|
diag.kind = "empty-input";
|
|
7153
7306
|
return finish([], diag);
|
|
@@ -7169,7 +7322,11 @@ function parseStringInput(raw, callId, diag) {
|
|
|
7169
7322
|
if (first.ranges.length === 0 || first.diagnostics.invalidItems > 0) {
|
|
7170
7323
|
const normalized = normalizeSingleQuotes(cleaned);
|
|
7171
7324
|
if (normalized !== void 0) {
|
|
7172
|
-
const retryDiag = {
|
|
7325
|
+
const retryDiag = {
|
|
7326
|
+
ok: false,
|
|
7327
|
+
kind: "ok",
|
|
7328
|
+
invalidItems: 0
|
|
7329
|
+
};
|
|
7173
7330
|
retryDiag.rawPrefix = diag.rawPrefix;
|
|
7174
7331
|
retryDiag.length = diag.length;
|
|
7175
7332
|
const retry = parseStringCore(normalized, callId, retryDiag);
|
|
@@ -7246,7 +7403,8 @@ function parseObjectValue(value, callId, diag) {
|
|
|
7246
7403
|
if (topTopic !== void 0 || hasTopMaxChars) {
|
|
7247
7404
|
for (const r of ranges) {
|
|
7248
7405
|
if (r.topic === void 0 && topTopic !== void 0) r.topic = topTopic;
|
|
7249
|
-
if (r.summaryMaxChars === void 0 && hasTopMaxChars)
|
|
7406
|
+
if (r.summaryMaxChars === void 0 && hasTopMaxChars)
|
|
7407
|
+
r.summaryMaxChars = topMaxChars;
|
|
7250
7408
|
}
|
|
7251
7409
|
}
|
|
7252
7410
|
diag.invalidItems = invalid;
|
|
@@ -7261,7 +7419,8 @@ function parseContentArray(s) {
|
|
|
7261
7419
|
const normalized = normalizeSingleQuotes(cleaned);
|
|
7262
7420
|
if (normalized !== void 0) {
|
|
7263
7421
|
const retry = parseContentArrayCore(normalized);
|
|
7264
|
-
if (retry !== null && retry.entries.length > 0)
|
|
7422
|
+
if (retry !== null && retry.entries.length > 0)
|
|
7423
|
+
return { ...retry, quoteRepaired: true };
|
|
7265
7424
|
}
|
|
7266
7425
|
return direct;
|
|
7267
7426
|
}
|
|
@@ -7348,12 +7507,14 @@ function parseLineEntry(entry, callId) {
|
|
|
7348
7507
|
afterRefs = pair.index + pair[0].length;
|
|
7349
7508
|
} else {
|
|
7350
7509
|
const single = SINGLE_REF_IN_LINE.exec(head);
|
|
7351
|
-
if (single === null)
|
|
7510
|
+
if (single === null)
|
|
7511
|
+
return { reason: "line entry: no mNNNNN/bN refs in header" };
|
|
7352
7512
|
startRef = normalizeLineRef(single[1]);
|
|
7353
7513
|
endRef = startRef;
|
|
7354
7514
|
afterRefs = single.index + single[0].length;
|
|
7355
7515
|
}
|
|
7356
|
-
if (summary.length === 0)
|
|
7516
|
+
if (summary.length === 0)
|
|
7517
|
+
return { reason: "line entry: missing summary after the refs header line" };
|
|
7357
7518
|
const explicitTopic = head.slice(afterRefs).trim();
|
|
7358
7519
|
const range = {
|
|
7359
7520
|
startRef,
|
|
@@ -7372,7 +7533,11 @@ function deriveTopicFromSummary(summary) {
|
|
|
7372
7533
|
return text.length > 60 ? clampPrefix(text, 60).trimEnd() : text;
|
|
7373
7534
|
}
|
|
7374
7535
|
function splitLineEntries(content) {
|
|
7375
|
-
const parts = content.split(
|
|
7536
|
+
const parts = content.split(
|
|
7537
|
+
/\n(?=\s*(?:["']\s*,\s*)?["']?\s*[mb]\d{1,7}\s*(?:[-\u2013\u2014\u2026~]|\.\.\.|to)\s*[mb]\d{1,7}\b)/i
|
|
7538
|
+
).map(
|
|
7539
|
+
(p) => p.trim().replace(/^(?:["']\s*,?\s*)+/, "").replace(/["']\s*$/, "")
|
|
7540
|
+
).filter((p) => p.length > 0);
|
|
7376
7541
|
return parts.length > 0 ? parts : [content.trim()];
|
|
7377
7542
|
}
|
|
7378
7543
|
function stripJsonWrapperResidue(s) {
|
|
@@ -7385,12 +7550,15 @@ function stripJsonWrapperResidue(s) {
|
|
|
7385
7550
|
}
|
|
7386
7551
|
function validateEntry(entry, callId) {
|
|
7387
7552
|
if (typeof entry === "string") return parseLineEntry(entry, callId);
|
|
7388
|
-
if (entry === null || typeof entry !== "object" || Array.isArray(entry))
|
|
7553
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry))
|
|
7554
|
+
return { reason: "not an object" };
|
|
7389
7555
|
const e = entry;
|
|
7390
7556
|
const start = stringOr(e["startRef"]) ?? stringOr(e["startId"]) ?? stringOr(e["messageId"]);
|
|
7391
7557
|
const end = stringOr(e["endRef"]) ?? stringOr(e["endId"]) ?? stringOr(e["messageId"]);
|
|
7392
7558
|
if (start === void 0 || end === void 0) {
|
|
7393
|
-
return {
|
|
7559
|
+
return {
|
|
7560
|
+
reason: "missing range bounds (need startRef/startId and endRef/endId)"
|
|
7561
|
+
};
|
|
7394
7562
|
}
|
|
7395
7563
|
const summary = stringOr(e["summary"]);
|
|
7396
7564
|
if (summary === void 0) return { reason: "missing summary" };
|
|
@@ -7398,7 +7566,8 @@ function validateEntry(entry, callId) {
|
|
|
7398
7566
|
const topic = stringOr(e["topic"]);
|
|
7399
7567
|
if (topic !== void 0) range.topic = topic;
|
|
7400
7568
|
const maxChars = e["summaryMaxChars"];
|
|
7401
|
-
if (typeof maxChars === "number" && Number.isFinite(maxChars))
|
|
7569
|
+
if (typeof maxChars === "number" && Number.isFinite(maxChars))
|
|
7570
|
+
range.summaryMaxChars = maxChars;
|
|
7402
7571
|
if (callId !== void 0) range.compressCallId = callId;
|
|
7403
7572
|
return { range };
|
|
7404
7573
|
}
|
|
@@ -7435,7 +7604,8 @@ function tryParseLenient(s) {
|
|
|
7435
7604
|
return void 0;
|
|
7436
7605
|
}
|
|
7437
7606
|
function normalizeSingleQuotes(raw) {
|
|
7438
|
-
if (!raw.includes("'") || !raw.includes("{") && !raw.includes("["))
|
|
7607
|
+
if (!raw.includes("'") || !raw.includes("{") && !raw.includes("["))
|
|
7608
|
+
return void 0;
|
|
7439
7609
|
let out = "";
|
|
7440
7610
|
let changed = false;
|
|
7441
7611
|
let inDouble = false;
|
|
@@ -7527,8 +7697,10 @@ function stripTrailingCommas(s) {
|
|
|
7527
7697
|
}
|
|
7528
7698
|
if (ch === ",") {
|
|
7529
7699
|
let j = i + 1;
|
|
7530
|
-
while (j < s.length && (s.charAt(j) === " " || s.charAt(j) === " " || s.charAt(j) === "\n" || s.charAt(j) === "\r"))
|
|
7531
|
-
|
|
7700
|
+
while (j < s.length && (s.charAt(j) === " " || s.charAt(j) === " " || s.charAt(j) === "\n" || s.charAt(j) === "\r"))
|
|
7701
|
+
j++;
|
|
7702
|
+
if (j < s.length && (s.charAt(j) === "}" || s.charAt(j) === "]"))
|
|
7703
|
+
continue;
|
|
7532
7704
|
}
|
|
7533
7705
|
out += ch;
|
|
7534
7706
|
}
|
|
@@ -7593,7 +7765,8 @@ function repairAtParserPositions(s) {
|
|
|
7593
7765
|
if (ch === "\n") esc = "\\n";
|
|
7594
7766
|
else if (ch === "\r") esc = "\\r";
|
|
7595
7767
|
else if (ch === " ") esc = "\\t";
|
|
7596
|
-
else if (ch.charCodeAt(0) < 32)
|
|
7768
|
+
else if (ch.charCodeAt(0) < 32)
|
|
7769
|
+
esc = "\\u" + ch.charCodeAt(0).toString(16).padStart(4, "0");
|
|
7597
7770
|
if (esc === void 0) return cur;
|
|
7598
7771
|
cur = cur.slice(0, pos) + esc + cur.slice(pos + 1);
|
|
7599
7772
|
} else if (/Bad escaped character/i.test(msg)) {
|
|
@@ -7669,7 +7842,9 @@ function salvageContentEntries(raw) {
|
|
|
7669
7842
|
|
|
7670
7843
|
// src/rebuild.ts
|
|
7671
7844
|
function rebuildCompressionState(state, messages, config, ports = {}) {
|
|
7672
|
-
const core = createCore({
|
|
7845
|
+
const core = createCore({
|
|
7846
|
+
countTokens: ports.countTokens ?? defaultCountTokens
|
|
7847
|
+
});
|
|
7673
7848
|
const refResult = assignRefs(messages, {
|
|
7674
7849
|
existing: state.messageRefs,
|
|
7675
7850
|
nextIndex: highestUsedIndex(state.messageRefs) + 1,
|
|
@@ -7679,9 +7854,16 @@ function rebuildCompressionState(state, messages, config, ports = {}) {
|
|
|
7679
7854
|
const invocations = collectCompressInvocations(messages);
|
|
7680
7855
|
let blocksRebuilt = 0;
|
|
7681
7856
|
for (const invocation of invocations) {
|
|
7682
|
-
const { ranges } = parseCompressArgs(invocation.raw, {
|
|
7857
|
+
const { ranges } = parseCompressArgs(invocation.raw, {
|
|
7858
|
+
callId: invocation.callId
|
|
7859
|
+
});
|
|
7683
7860
|
if (ranges.length === 0) continue;
|
|
7684
|
-
const result = core.applyCompression({
|
|
7861
|
+
const result = core.applyCompression({
|
|
7862
|
+
ranges,
|
|
7863
|
+
messages,
|
|
7864
|
+
state: working,
|
|
7865
|
+
config
|
|
7866
|
+
});
|
|
7685
7867
|
working = result.state;
|
|
7686
7868
|
blocksRebuilt += result.result.blocksCreated;
|
|
7687
7869
|
}
|
|
@@ -7690,7 +7872,8 @@ function rebuildCompressionState(state, messages, config, ports = {}) {
|
|
|
7690
7872
|
function collectCompressInvocations(messages) {
|
|
7691
7873
|
const invocations = [];
|
|
7692
7874
|
for (const message of messages) {
|
|
7693
|
-
if (message.toolName !== "compress" || message.contentType !== "tool-call")
|
|
7875
|
+
if (message.toolName !== "compress" || message.contentType !== "tool-call")
|
|
7876
|
+
continue;
|
|
7694
7877
|
invocations.push({ callId: message.toolCallId, raw: message.text ?? "" });
|
|
7695
7878
|
}
|
|
7696
7879
|
return invocations;
|
|
@@ -7706,7 +7889,8 @@ function stem(word) {
|
|
|
7706
7889
|
let w = word;
|
|
7707
7890
|
if (w.length <= 3) return w;
|
|
7708
7891
|
if (w.endsWith("ies")) w = w.slice(0, -3) + "y";
|
|
7709
|
-
else if (w.endsWith("ses") || w.endsWith("xes") || w.endsWith("zes"))
|
|
7892
|
+
else if (w.endsWith("ses") || w.endsWith("xes") || w.endsWith("zes"))
|
|
7893
|
+
w = w.slice(0, -2);
|
|
7710
7894
|
else if (w.endsWith("ches") || w.endsWith("shes")) w = w.slice(0, -2);
|
|
7711
7895
|
else if (w.endsWith("s") && !w.endsWith("ss")) w = w.slice(0, -1);
|
|
7712
7896
|
if (w.endsWith("ing") && w.length > 5) w = w.slice(0, -3);
|
|
@@ -7883,7 +8067,8 @@ var fuzzyAlgorithm = {
|
|
|
7883
8067
|
description: "Character bigram overlap. Typo-tolerant, script-agnostic, high recall.",
|
|
7884
8068
|
score(docs, query) {
|
|
7885
8069
|
const qTokens = query.toLowerCase().split(/[\s,]+/).filter((t) => t.length >= 4 || t.length >= 2 && CJK.test(t));
|
|
7886
|
-
if (qTokens.length === 0)
|
|
8070
|
+
if (qTokens.length === 0)
|
|
8071
|
+
return docs.map((d) => ({ ref: d.ref, score: 0 }));
|
|
7887
8072
|
const qGrams = /* @__PURE__ */ new Set();
|
|
7888
8073
|
for (const t of qTokens) for (const g of charBigrams(t)) qGrams.add(g);
|
|
7889
8074
|
if (qGrams.size === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
|
|
@@ -8004,7 +8189,9 @@ function runSearch(docs, query, options) {
|
|
|
8004
8189
|
}).filter((r) => r !== null && r.score >= minScore).sort((a, b) => b.score - a.score).slice(0, limit);
|
|
8005
8190
|
};
|
|
8006
8191
|
if (scoredOrPromise instanceof Promise) {
|
|
8007
|
-
return scoredOrPromise.then(
|
|
8192
|
+
return scoredOrPromise.then(
|
|
8193
|
+
(raw) => buildResults(applyRoleWeight(raw, docs, rw))
|
|
8194
|
+
);
|
|
8008
8195
|
}
|
|
8009
8196
|
return buildResults(applyRoleWeight(scoredOrPromise, docs, rw));
|
|
8010
8197
|
}
|