acp-kernel 0.0.93 → 0.0.94-pr.415.300
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.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +356 -145
- 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/segment.d.ts +33 -0
- package/dist/segment.d.ts.map +1 -0
- 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);
|
|
@@ -4205,14 +4237,32 @@ function computeIntegrityWithdrawals(messages, foldedIds) {
|
|
|
4205
4237
|
};
|
|
4206
4238
|
}
|
|
4207
4239
|
|
|
4240
|
+
// src/segment.ts
|
|
4241
|
+
function segmentGroups(items) {
|
|
4242
|
+
const groups = [];
|
|
4243
|
+
let cur = null;
|
|
4244
|
+
for (const item of items) {
|
|
4245
|
+
if (cur !== null && (item.isUser && cur.length >= 3 || item.gapBefore)) {
|
|
4246
|
+
groups.push(cur);
|
|
4247
|
+
cur = null;
|
|
4248
|
+
}
|
|
4249
|
+
if (cur === null) cur = [item];
|
|
4250
|
+
else cur.push(item);
|
|
4251
|
+
}
|
|
4252
|
+
if (cur !== null) groups.push(cur);
|
|
4253
|
+
return groups;
|
|
4254
|
+
}
|
|
4255
|
+
|
|
4208
4256
|
// src/recommend.ts
|
|
4209
4257
|
function estimateTextTokens(text) {
|
|
4210
4258
|
return Math.ceil(text.length / 4);
|
|
4211
4259
|
}
|
|
4212
4260
|
function isSyntheticOrPruned(message, state) {
|
|
4213
|
-
if (message.text?.startsWith("[Compressed conversation section]"))
|
|
4261
|
+
if (message.text?.startsWith("[Compressed conversation section]"))
|
|
4262
|
+
return true;
|
|
4214
4263
|
for (const block of state.blocks) {
|
|
4215
|
-
if (block.active && block.effectiveMessageIds.includes(message.id))
|
|
4264
|
+
if (block.active && block.effectiveMessageIds.includes(message.id))
|
|
4265
|
+
return true;
|
|
4216
4266
|
}
|
|
4217
4267
|
return false;
|
|
4218
4268
|
}
|
|
@@ -4223,7 +4273,12 @@ function computeProtectedRefs(messages, state, config, countTokens = estimateTex
|
|
|
4223
4273
|
const visible = [];
|
|
4224
4274
|
for (const msg of messages) {
|
|
4225
4275
|
if (isSyntheticOrPruned(msg, state)) continue;
|
|
4226
|
-
if (isNeverPreserveRecent(
|
|
4276
|
+
if (isNeverPreserveRecent(
|
|
4277
|
+
msg,
|
|
4278
|
+
config.neverPreserveRecentTools,
|
|
4279
|
+
config.preserveRecentTools
|
|
4280
|
+
))
|
|
4281
|
+
continue;
|
|
4227
4282
|
const ref = state.messageRefs.byRaw[msg.id];
|
|
4228
4283
|
if (!ref || ref === "BLOCKED") continue;
|
|
4229
4284
|
visible.push({ ref, tokens: countMessageTokens(msg, countTokens) });
|
|
@@ -4322,41 +4377,41 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
|
|
|
4322
4377
|
compressibleMsgs = kept;
|
|
4323
4378
|
}
|
|
4324
4379
|
const compressible = [];
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
cur.count++;
|
|
4348
|
-
cur.tokens += info.tokens;
|
|
4349
|
-
cur.chars = (cur.chars ?? 0) + info.chars;
|
|
4350
|
-
if (info.isUser) cur.userMsgs = (cur.userMsgs ?? 0) + 1;
|
|
4380
|
+
for (const group of segmentGroups(compressibleMsgs)) {
|
|
4381
|
+
const first = group[0];
|
|
4382
|
+
const range = {
|
|
4383
|
+
startRef: first.ref,
|
|
4384
|
+
endRef: first.ref,
|
|
4385
|
+
startIndex: first.index,
|
|
4386
|
+
endIndex: first.index,
|
|
4387
|
+
count: 1,
|
|
4388
|
+
tokens: first.tokens,
|
|
4389
|
+
chars: first.chars,
|
|
4390
|
+
toolPct: first.isTool ? 100 : 0,
|
|
4391
|
+
textPct: first.isTool ? 0 : 100,
|
|
4392
|
+
userMsgs: first.isUser ? 1 : 0
|
|
4393
|
+
};
|
|
4394
|
+
for (let i = 1; i < group.length; i++) {
|
|
4395
|
+
const info = group[i];
|
|
4396
|
+
range.endRef = info.ref;
|
|
4397
|
+
range.endIndex = info.index;
|
|
4398
|
+
range.count++;
|
|
4399
|
+
range.tokens += info.tokens;
|
|
4400
|
+
range.chars = (range.chars ?? 0) + info.chars;
|
|
4401
|
+
if (info.isUser) range.userMsgs = (range.userMsgs ?? 0) + 1;
|
|
4351
4402
|
if (info.isTool) {
|
|
4352
|
-
|
|
4403
|
+
range.toolPct = Math.round(
|
|
4404
|
+
(range.toolPct * (range.count - 1) + 100) / range.count
|
|
4405
|
+
);
|
|
4353
4406
|
} else {
|
|
4354
|
-
|
|
4407
|
+
range.toolPct = Math.round(
|
|
4408
|
+
range.toolPct * (range.count - 1) / range.count
|
|
4409
|
+
);
|
|
4355
4410
|
}
|
|
4356
|
-
|
|
4411
|
+
range.textPct = 100 - range.toolPct;
|
|
4357
4412
|
}
|
|
4413
|
+
compressible.push(range);
|
|
4358
4414
|
}
|
|
4359
|
-
if (cur) compressible.push(cur);
|
|
4360
4415
|
const protectedRanges = [];
|
|
4361
4416
|
let pcur = null;
|
|
4362
4417
|
for (const info of protectedMsgs) {
|
|
@@ -5721,9 +5776,26 @@ function countOccurrences(haystack, needle) {
|
|
|
5721
5776
|
// src/packs.ts
|
|
5722
5777
|
import { readFileSync, readdirSync } from "fs";
|
|
5723
5778
|
import * as path from "path";
|
|
5724
|
-
var PROMPT_RULE_KEYS = [
|
|
5725
|
-
|
|
5726
|
-
|
|
5779
|
+
var PROMPT_RULE_KEYS = [
|
|
5780
|
+
"compressPhilosophy",
|
|
5781
|
+
"howToCompressRules",
|
|
5782
|
+
"tier2DistillRules",
|
|
5783
|
+
"tier3CondenseRules"
|
|
5784
|
+
];
|
|
5785
|
+
var COMPRESS_SECTION_KEYS = [
|
|
5786
|
+
"acpTags",
|
|
5787
|
+
"tools",
|
|
5788
|
+
"summariesInContext",
|
|
5789
|
+
"textProtocol",
|
|
5790
|
+
"textTools",
|
|
5791
|
+
"functionTools"
|
|
5792
|
+
];
|
|
5793
|
+
var NUDGE_SECTION_KEYS = [
|
|
5794
|
+
"efficiencyNote",
|
|
5795
|
+
"emergencyHeader",
|
|
5796
|
+
"t2Guidance",
|
|
5797
|
+
"t3Guidance"
|
|
5798
|
+
];
|
|
5727
5799
|
function isValidPackName(name) {
|
|
5728
5800
|
return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) && !name.includes("..");
|
|
5729
5801
|
}
|
|
@@ -5757,7 +5829,9 @@ function sanitizePackSurface(raw) {
|
|
|
5757
5829
|
if (typeof ov.description === "string") out.description = ov.description;
|
|
5758
5830
|
if (ov.paramDescriptions && typeof ov.paramDescriptions === "object" && !Array.isArray(ov.paramDescriptions)) {
|
|
5759
5831
|
const params = {};
|
|
5760
|
-
for (const [p, d] of Object.entries(
|
|
5832
|
+
for (const [p, d] of Object.entries(
|
|
5833
|
+
ov.paramDescriptions
|
|
5834
|
+
)) {
|
|
5761
5835
|
if (typeof d === "string") params[p] = d;
|
|
5762
5836
|
}
|
|
5763
5837
|
if (Object.keys(params).length > 0) out.paramDescriptions = params;
|
|
@@ -5845,7 +5919,7 @@ var leanPack = {
|
|
|
5845
5919
|
`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
5920
|
`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
5921
|
`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
|
-
`
|
|
5922
|
+
`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
5923
|
`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
5924
|
`After an [ACP:provider-throttle] automatic retry, resume exactly where interrupted. Do not repeat completed work or discuss the retry unless asked.`,
|
|
5851
5925
|
`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 +6030,11 @@ function createPackResolver(sources) {
|
|
|
5956
6030
|
};
|
|
5957
6031
|
}
|
|
5958
6032
|
function defaultPackSources(opts) {
|
|
5959
|
-
const sources = [
|
|
5960
|
-
|
|
6033
|
+
const sources = [
|
|
6034
|
+
createDirPackSource("project", opts.projectDir)
|
|
6035
|
+
];
|
|
6036
|
+
for (const dir of opts.userDirs ?? [])
|
|
6037
|
+
sources.push(createDirPackSource("user", dir));
|
|
5961
6038
|
sources.push(builtinSource);
|
|
5962
6039
|
return sources;
|
|
5963
6040
|
}
|
|
@@ -5995,7 +6072,10 @@ function tierBreakdown(blocks, countTokens) {
|
|
|
5995
6072
|
if (tiers.length <= 1) return null;
|
|
5996
6073
|
const parts = [];
|
|
5997
6074
|
for (const tier of [1, 2, 3]) {
|
|
5998
|
-
if (tierTokens[tier])
|
|
6075
|
+
if (tierTokens[tier])
|
|
6076
|
+
parts.push(
|
|
6077
|
+
`T${tier}: ${formatTokens2(tierTokens[tier])} (${tierCounts[tier]} blocks)`
|
|
6078
|
+
);
|
|
5999
6079
|
}
|
|
6000
6080
|
return parts.join(" | ");
|
|
6001
6081
|
}
|
|
@@ -6016,14 +6096,27 @@ function collectVisible(messages, state, countTokens) {
|
|
|
6016
6096
|
toolCallNames.set(message.toolCallId, message.toolName);
|
|
6017
6097
|
}
|
|
6018
6098
|
}
|
|
6099
|
+
let pendingGap = false;
|
|
6019
6100
|
messages.forEach((message, index) => {
|
|
6020
|
-
if (coveredIds.has(message.id)) return;
|
|
6021
6101
|
const ref = refForRaw(state.messageRefs, message.id);
|
|
6022
6102
|
if (!ref) return;
|
|
6023
6103
|
const tokens = countMessageTokens(message, countTokens);
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6104
|
+
if (!coveredIds.has(message.id) && tokens > 0) {
|
|
6105
|
+
const isTool = isToolMessage(message);
|
|
6106
|
+
const tool = isTool ? message.toolName ?? (message.toolCallId ? toolCallNames.get(message.toolCallId) : void 0) ?? "tool" : "text";
|
|
6107
|
+
visible.push({
|
|
6108
|
+
ref,
|
|
6109
|
+
tokens,
|
|
6110
|
+
tool,
|
|
6111
|
+
isTool,
|
|
6112
|
+
index,
|
|
6113
|
+
isUser: message.role === "user",
|
|
6114
|
+
gapBefore: pendingGap
|
|
6115
|
+
});
|
|
6116
|
+
pendingGap = false;
|
|
6117
|
+
return;
|
|
6118
|
+
}
|
|
6119
|
+
if (ref !== BLOCKED_REF && tokens > 0) pendingGap = true;
|
|
6027
6120
|
});
|
|
6028
6121
|
return { visible, summaryTokens };
|
|
6029
6122
|
}
|
|
@@ -6035,21 +6128,43 @@ function buildStatusReport(state, messages, countTokens, options = {}) {
|
|
|
6035
6128
|
const limit = options.limit ?? 30;
|
|
6036
6129
|
const activeBlocks2 = state.blocks.filter((b) => b.active).sort((a, b) => numericPart2(a.blockId) - numericPart2(b.blockId));
|
|
6037
6130
|
if (scope === "compressed") {
|
|
6038
|
-
return renderCompressedDrilldown(
|
|
6131
|
+
return renderCompressedDrilldown(
|
|
6132
|
+
activeBlocks2,
|
|
6133
|
+
state,
|
|
6134
|
+
sort,
|
|
6135
|
+
limit,
|
|
6136
|
+
countTokens,
|
|
6137
|
+
options.meta
|
|
6138
|
+
);
|
|
6039
6139
|
}
|
|
6040
|
-
const { visible, summaryTokens } = collectVisible(
|
|
6140
|
+
const { visible, summaryTokens } = collectVisible(
|
|
6141
|
+
messages,
|
|
6142
|
+
state,
|
|
6143
|
+
countTokens
|
|
6144
|
+
);
|
|
6041
6145
|
if (scope === "uncompressed") {
|
|
6042
6146
|
if (view === "messages") {
|
|
6043
6147
|
return renderMessageDrilldown(visible, toolFilter, sort, limit);
|
|
6044
6148
|
}
|
|
6045
|
-
return renderUncompressedRanges(visible);
|
|
6149
|
+
return renderUncompressedRanges(visible, sort, limit);
|
|
6046
6150
|
}
|
|
6047
|
-
return renderOverview(
|
|
6151
|
+
return renderOverview(
|
|
6152
|
+
visible,
|
|
6153
|
+
summaryTokens,
|
|
6154
|
+
activeBlocks2,
|
|
6155
|
+
state,
|
|
6156
|
+
countTokens,
|
|
6157
|
+
limit,
|
|
6158
|
+
options.meta
|
|
6159
|
+
);
|
|
6048
6160
|
}
|
|
6049
6161
|
function surfaceLine(meta) {
|
|
6050
6162
|
if (!meta) return null;
|
|
6051
6163
|
const parts = [];
|
|
6052
|
-
if (meta.pack)
|
|
6164
|
+
if (meta.pack)
|
|
6165
|
+
parts.push(
|
|
6166
|
+
`pack=${meta.pack}${meta.packVersion ? ` v${meta.packVersion}` : ""}`
|
|
6167
|
+
);
|
|
6053
6168
|
if (meta.host) parts.push(`host=${meta.host}`);
|
|
6054
6169
|
if (parts.length === 0) return null;
|
|
6055
6170
|
return `ACTIVE SURFACE: ${parts.join(" | ")}`;
|
|
@@ -6063,9 +6178,14 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
|
|
|
6063
6178
|
}
|
|
6064
6179
|
const toolTypeMap = /* @__PURE__ */ new Map();
|
|
6065
6180
|
for (const message of visible) {
|
|
6066
|
-
toolTypeMap.set(
|
|
6181
|
+
toolTypeMap.set(
|
|
6182
|
+
message.tool,
|
|
6183
|
+
(toolTypeMap.get(message.tool) ?? 0) + message.tokens
|
|
6184
|
+
);
|
|
6067
6185
|
}
|
|
6068
|
-
const topTool = [...toolTypeMap.entries()].sort(
|
|
6186
|
+
const topTool = [...toolTypeMap.entries()].sort(
|
|
6187
|
+
(a, b) => b[1] - a[1]
|
|
6188
|
+
)[0]?.[0];
|
|
6069
6189
|
const totalTool = visible.filter((m) => m.isTool).reduce((sum, m) => sum + m.tokens, 0);
|
|
6070
6190
|
const totalText = visible.filter((m) => !m.isTool).reduce((sum, m) => sum + m.tokens, 0);
|
|
6071
6191
|
const total = summaryTokens + totalTool + totalText;
|
|
@@ -6075,14 +6195,19 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
|
|
|
6075
6195
|
);
|
|
6076
6196
|
const topTypes = [...toolTypeMap.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3);
|
|
6077
6197
|
if (topTypes.length > 0) {
|
|
6078
|
-
lines.push(
|
|
6198
|
+
lines.push(
|
|
6199
|
+
` Top tools: ${topTypes.map(([t, n]) => `${t} (${pct(n, total)}%)`).join(", ")}`
|
|
6200
|
+
);
|
|
6079
6201
|
}
|
|
6080
6202
|
lines.push("");
|
|
6081
6203
|
if (blocks.length === 0) {
|
|
6082
6204
|
lines.push("COMPRESSED BLOCKS");
|
|
6083
6205
|
lines.push(" No compressed blocks.");
|
|
6084
6206
|
} else {
|
|
6085
|
-
const totalSummary = blocks.reduce(
|
|
6207
|
+
const totalSummary = blocks.reduce(
|
|
6208
|
+
(s, b) => s + summaryTokensOf(b, countTokens),
|
|
6209
|
+
0
|
|
6210
|
+
);
|
|
6086
6211
|
const totalEffective = blocks.reduce(
|
|
6087
6212
|
(s, b) => s + effectiveCompressedTokens(b, state, countTokens),
|
|
6088
6213
|
0
|
|
@@ -6115,19 +6240,17 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
|
|
|
6115
6240
|
);
|
|
6116
6241
|
return lines.join("\n");
|
|
6117
6242
|
}
|
|
6118
|
-
function renderUncompressedRanges(visible) {
|
|
6243
|
+
function renderUncompressedRanges(visible, sort, limit) {
|
|
6119
6244
|
const lines = [];
|
|
6120
6245
|
const totalTokens = visible.reduce((s, m) => s + m.tokens, 0);
|
|
6121
|
-
lines.push(
|
|
6246
|
+
lines.push(
|
|
6247
|
+
`UNCOMPRESSED \u2014 ${formatTokens2(totalTokens)} | ${visible.length} visible messages`
|
|
6248
|
+
);
|
|
6122
6249
|
lines.push("");
|
|
6123
6250
|
if (visible.length === 0) {
|
|
6124
6251
|
lines.push(" (no uncompressed messages)");
|
|
6125
6252
|
return lines.join("\n");
|
|
6126
6253
|
}
|
|
6127
|
-
const refNum2 = (ref) => {
|
|
6128
|
-
const m = ref.match(/\d+/);
|
|
6129
|
-
return m ? parseInt(m[0], 10) : 0;
|
|
6130
|
-
};
|
|
6131
6254
|
const dominantTool = (toolTokens) => {
|
|
6132
6255
|
let best = "text";
|
|
6133
6256
|
let bestN = -1;
|
|
@@ -6140,25 +6263,37 @@ function renderUncompressedRanges(visible) {
|
|
|
6140
6263
|
return best;
|
|
6141
6264
|
};
|
|
6142
6265
|
const merged = [];
|
|
6143
|
-
for (const
|
|
6144
|
-
const
|
|
6145
|
-
const
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6266
|
+
for (const group of segmentGroups(visible)) {
|
|
6267
|
+
const first = group[0];
|
|
6268
|
+
const r = {
|
|
6269
|
+
startRef: first.ref,
|
|
6270
|
+
endRef: first.ref,
|
|
6271
|
+
startIndex: first.index,
|
|
6272
|
+
count: 1,
|
|
6273
|
+
tokens: first.tokens,
|
|
6274
|
+
toolTokens: /* @__PURE__ */ new Map([[first.tool, first.tokens]])
|
|
6275
|
+
};
|
|
6276
|
+
for (let i = 1; i < group.length; i++) {
|
|
6277
|
+
const m = group[i];
|
|
6278
|
+
r.endRef = m.ref;
|
|
6279
|
+
r.count += 1;
|
|
6280
|
+
r.tokens += m.tokens;
|
|
6281
|
+
r.toolTokens.set(m.tool, (r.toolTokens.get(m.tool) ?? 0) + m.tokens);
|
|
6282
|
+
}
|
|
6283
|
+
merged.push(r);
|
|
6284
|
+
}
|
|
6285
|
+
if (sort !== "time")
|
|
6286
|
+
merged.sort((a, b) => b.tokens - a.tokens || a.startIndex - b.startIndex);
|
|
6287
|
+
lines.push(`Sorted by ${sort === "time" ? "time" : "size"}`);
|
|
6288
|
+
lines.push("");
|
|
6289
|
+
for (const r of merged.slice(0, limit)) {
|
|
6157
6290
|
const range = r.count === 1 ? r.startRef : `${r.startRef}\u2013${r.endRef}`;
|
|
6158
|
-
lines.push(
|
|
6291
|
+
lines.push(
|
|
6292
|
+
` ${range} (${r.count} msgs, ${formatTokens2(r.tokens)}${r.count > 1 ? ` (${Math.round(r.tokens / r.count)}/msg)` : ""}) ${dominantTool(r.toolTokens)}`
|
|
6293
|
+
);
|
|
6159
6294
|
}
|
|
6160
|
-
if (merged.length >
|
|
6161
|
-
lines.push(` ... and ${merged.length -
|
|
6295
|
+
if (merged.length > limit) {
|
|
6296
|
+
lines.push(` ... and ${merged.length - limit} more ranges`);
|
|
6162
6297
|
}
|
|
6163
6298
|
return lines.join("\n");
|
|
6164
6299
|
}
|
|
@@ -6166,7 +6301,10 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
|
|
|
6166
6301
|
let filtered = visible;
|
|
6167
6302
|
if (toolFilter) filtered = filtered.filter((m) => m.tool === toolFilter);
|
|
6168
6303
|
if (sort === "time") filtered.sort((a, b) => a.index - b.index);
|
|
6169
|
-
else if (sort === "tool")
|
|
6304
|
+
else if (sort === "tool")
|
|
6305
|
+
filtered.sort(
|
|
6306
|
+
(a, b) => a.tool.localeCompare(b.tool) || b.tokens - a.tokens
|
|
6307
|
+
);
|
|
6170
6308
|
else filtered.sort((a, b) => b.tokens - a.tokens);
|
|
6171
6309
|
const totalTokens = filtered.reduce((s, m) => s + m.tokens, 0);
|
|
6172
6310
|
const allTokens = visible.reduce((s, m) => s + m.tokens, 0);
|
|
@@ -6174,7 +6312,9 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
|
|
|
6174
6312
|
const lines = [header, `Sorted by ${sort}`, ""];
|
|
6175
6313
|
const shown = filtered.slice(0, limit);
|
|
6176
6314
|
for (const message of shown) {
|
|
6177
|
-
lines.push(
|
|
6315
|
+
lines.push(
|
|
6316
|
+
` ${message.ref} (${formatTokens2(message.tokens)}) ${message.tool}`
|
|
6317
|
+
);
|
|
6178
6318
|
}
|
|
6179
6319
|
if (filtered.length > shown.length) {
|
|
6180
6320
|
lines.push("");
|
|
@@ -6185,12 +6325,16 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
|
|
|
6185
6325
|
function renderCompressedDrilldown(blocks, state, sort, limit, countTokens, meta) {
|
|
6186
6326
|
let sorted = [...blocks];
|
|
6187
6327
|
if (sort === "time") sorted.sort((a, b) => a.createdAt - b.createdAt);
|
|
6188
|
-
else if (sort === "age")
|
|
6328
|
+
else if (sort === "age")
|
|
6329
|
+
sorted.sort((a, b) => b.survivedCount - a.survivedCount);
|
|
6189
6330
|
else
|
|
6190
6331
|
sorted.sort(
|
|
6191
6332
|
(a, b) => effectiveCompressedTokens(b, state, countTokens) - effectiveCompressedTokens(a, state, countTokens) || b.createdAt - a.createdAt
|
|
6192
6333
|
);
|
|
6193
|
-
const totalSummary = sorted.reduce(
|
|
6334
|
+
const totalSummary = sorted.reduce(
|
|
6335
|
+
(s, b) => s + summaryTokensOf(b, countTokens),
|
|
6336
|
+
0
|
|
6337
|
+
);
|
|
6194
6338
|
const totalEffective = sorted.reduce(
|
|
6195
6339
|
(s, b) => s + effectiveCompressedTokens(b, state, countTokens),
|
|
6196
6340
|
0
|
|
@@ -6636,7 +6780,9 @@ function formatCacheReportSummary(report) {
|
|
|
6636
6780
|
});
|
|
6637
6781
|
const last = report.lines.length - 1;
|
|
6638
6782
|
if (!shownIdx.includes(last)) shownIdx.push(last);
|
|
6639
|
-
const kept = shownIdx.slice(
|
|
6783
|
+
const kept = shownIdx.slice(
|
|
6784
|
+
Math.max(0, shownIdx.length - SUMMARY_ANOMALY_CAP)
|
|
6785
|
+
);
|
|
6640
6786
|
const anomalies = kept.filter((i) => {
|
|
6641
6787
|
const l = report.lines[i];
|
|
6642
6788
|
if (!l) return false;
|
|
@@ -6695,10 +6841,14 @@ function renderMessage2(m) {
|
|
|
6695
6841
|
parts.push(m.text ?? "");
|
|
6696
6842
|
break;
|
|
6697
6843
|
case "tool-call":
|
|
6698
|
-
parts.push(
|
|
6844
|
+
parts.push(
|
|
6845
|
+
`\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` args: ${m.text ?? ""}`
|
|
6846
|
+
);
|
|
6699
6847
|
break;
|
|
6700
6848
|
case "tool-result":
|
|
6701
|
-
parts.push(
|
|
6849
|
+
parts.push(
|
|
6850
|
+
`\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` \u2192 ${m.text ?? ""}`
|
|
6851
|
+
);
|
|
6702
6852
|
break;
|
|
6703
6853
|
case "reasoning":
|
|
6704
6854
|
parts.push(`_reasoning_: ${m.text ?? ""}`);
|
|
@@ -6716,12 +6866,17 @@ function renderHandoff(input) {
|
|
|
6716
6866
|
if (meta.label) lines.push(`- label: ${meta.label}`);
|
|
6717
6867
|
lines.push(`- session id: ${meta.sessionId}`);
|
|
6718
6868
|
for (const bullet of meta.extraBullets ?? []) lines.push(bullet);
|
|
6719
|
-
if (meta.contextTokens)
|
|
6720
|
-
|
|
6869
|
+
if (meta.contextTokens)
|
|
6870
|
+
lines.push(`- last context tokens: ~${meta.contextTokens}`);
|
|
6871
|
+
lines.push(
|
|
6872
|
+
`- compression blocks: ${state.blocks.length} (active ${state.blocks.filter((b) => b.active).length})`
|
|
6873
|
+
);
|
|
6721
6874
|
lines.push("");
|
|
6722
6875
|
const folded = input.folded === true;
|
|
6723
6876
|
const view = full || folded ? coreMessages : prune(coreMessages, state);
|
|
6724
|
-
lines.push(
|
|
6877
|
+
lines.push(
|
|
6878
|
+
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)`
|
|
6879
|
+
);
|
|
6725
6880
|
lines.push("");
|
|
6726
6881
|
if (view.length === 0) {
|
|
6727
6882
|
lines.push("No conversation messages to export.");
|
|
@@ -6754,7 +6909,9 @@ function matchSession(sessions, selector, labelOf) {
|
|
|
6754
6909
|
if (exact.length > 0) return exact;
|
|
6755
6910
|
const byLabel = sessions.filter((s) => labelOf(s) === selector);
|
|
6756
6911
|
if (byLabel.length > 0) return byLabel;
|
|
6757
|
-
return sessions.filter(
|
|
6912
|
+
return sessions.filter(
|
|
6913
|
+
(s) => s.id.startsWith(selector) || (labelOf(s) ?? "").startsWith(selector)
|
|
6914
|
+
);
|
|
6758
6915
|
}
|
|
6759
6916
|
|
|
6760
6917
|
// src/rules.ts
|
|
@@ -6865,7 +7022,10 @@ var DEFAULT_IMAGE_COMPRESSION_CONFIG = {
|
|
|
6865
7022
|
format: "webp"
|
|
6866
7023
|
};
|
|
6867
7024
|
function resolveImageCompressionConfig(config) {
|
|
6868
|
-
return {
|
|
7025
|
+
return {
|
|
7026
|
+
...DEFAULT_IMAGE_COMPRESSION_CONFIG,
|
|
7027
|
+
...config.imageCompression ?? {}
|
|
7028
|
+
};
|
|
6869
7029
|
}
|
|
6870
7030
|
var PIXEL_IMAGE_FALLBACK_TOKENS = 16384;
|
|
6871
7031
|
var TILE_EDGE = 512;
|
|
@@ -6959,10 +7119,14 @@ var HEADER_SCAN_CHARS = 64;
|
|
|
6959
7119
|
var JPEG_SCAN_CHARS = 35e4;
|
|
6960
7120
|
function parseImageDimensionsFromBase64(b64) {
|
|
6961
7121
|
if (typeof b64 !== "string" || b64.length === 0) return void 0;
|
|
6962
|
-
const head = parseImageDimensions(
|
|
7122
|
+
const head = parseImageDimensions(
|
|
7123
|
+
Buffer.from(b64.slice(0, HEADER_SCAN_CHARS), "base64")
|
|
7124
|
+
);
|
|
6963
7125
|
if (head) return head;
|
|
6964
7126
|
if (b64.startsWith("/9j/") && b64.length > HEADER_SCAN_CHARS) {
|
|
6965
|
-
return parseImageDimensions(
|
|
7127
|
+
return parseImageDimensions(
|
|
7128
|
+
Buffer.from(b64.slice(0, JPEG_SCAN_CHARS), "base64")
|
|
7129
|
+
);
|
|
6966
7130
|
}
|
|
6967
7131
|
return void 0;
|
|
6968
7132
|
}
|
|
@@ -7020,7 +7184,8 @@ var DEFAULT_SCREENSHOT_CLASSIFIER = createHeuristicClassifier();
|
|
|
7020
7184
|
function decideImageRoute(meta, config, classifier = DEFAULT_SCREENSHOT_CLASSIFIER) {
|
|
7021
7185
|
const cfg = resolveImageCompressionConfig(config);
|
|
7022
7186
|
const estimatedTokens = estimateImageTokens(meta);
|
|
7023
|
-
if (!cfg.enabled)
|
|
7187
|
+
if (!cfg.enabled)
|
|
7188
|
+
return { action: "pass", reason: "disabled", estimatedTokens };
|
|
7024
7189
|
if (!meta.mediaType.startsWith("image/")) {
|
|
7025
7190
|
return { action: "pass", reason: "not-an-image", estimatedTokens };
|
|
7026
7191
|
}
|
|
@@ -7034,7 +7199,11 @@ function decideImageRoute(meta, config, classifier = DEFAULT_SCREENSHOT_CLASSIFI
|
|
|
7034
7199
|
action: "downsample",
|
|
7035
7200
|
reason: "downsample",
|
|
7036
7201
|
estimatedTokens,
|
|
7037
|
-
recipe: {
|
|
7202
|
+
recipe: {
|
|
7203
|
+
maxDimension: cfg.maxDimension,
|
|
7204
|
+
quality: cfg.quality,
|
|
7205
|
+
format: cfg.format
|
|
7206
|
+
}
|
|
7038
7207
|
};
|
|
7039
7208
|
}
|
|
7040
7209
|
var IMAGE_FULL_FAILURE_MARKER = "[image_full FAILED:";
|
|
@@ -7046,7 +7215,8 @@ function parseImageFullInput(input, callId, onWarn) {
|
|
|
7046
7215
|
if (typeof input === "string") {
|
|
7047
7216
|
try {
|
|
7048
7217
|
const parsed = JSON.parse(input);
|
|
7049
|
-
if (parsed && typeof parsed === "object")
|
|
7218
|
+
if (parsed && typeof parsed === "object")
|
|
7219
|
+
obj = parsed;
|
|
7050
7220
|
} catch {
|
|
7051
7221
|
obj = null;
|
|
7052
7222
|
}
|
|
@@ -7054,7 +7224,9 @@ function parseImageFullInput(input, callId, onWarn) {
|
|
|
7054
7224
|
obj = input;
|
|
7055
7225
|
}
|
|
7056
7226
|
if (!obj) {
|
|
7057
|
-
onWarn?.(
|
|
7227
|
+
onWarn?.(
|
|
7228
|
+
`[acp-image-full-input] rejected: not an object (${typeof input})`
|
|
7229
|
+
);
|
|
7058
7230
|
return null;
|
|
7059
7231
|
}
|
|
7060
7232
|
let ref;
|
|
@@ -7147,7 +7319,11 @@ function resetImageFullState(state) {
|
|
|
7147
7319
|
// src/parse-compress-input.ts
|
|
7148
7320
|
function parseCompressArgs(input, opts) {
|
|
7149
7321
|
const callId = opts?.callId;
|
|
7150
|
-
const diag = {
|
|
7322
|
+
const diag = {
|
|
7323
|
+
ok: false,
|
|
7324
|
+
kind: "ok",
|
|
7325
|
+
invalidItems: 0
|
|
7326
|
+
};
|
|
7151
7327
|
if (input === null || input === void 0) {
|
|
7152
7328
|
diag.kind = "empty-input";
|
|
7153
7329
|
return finish([], diag);
|
|
@@ -7169,7 +7345,11 @@ function parseStringInput(raw, callId, diag) {
|
|
|
7169
7345
|
if (first.ranges.length === 0 || first.diagnostics.invalidItems > 0) {
|
|
7170
7346
|
const normalized = normalizeSingleQuotes(cleaned);
|
|
7171
7347
|
if (normalized !== void 0) {
|
|
7172
|
-
const retryDiag = {
|
|
7348
|
+
const retryDiag = {
|
|
7349
|
+
ok: false,
|
|
7350
|
+
kind: "ok",
|
|
7351
|
+
invalidItems: 0
|
|
7352
|
+
};
|
|
7173
7353
|
retryDiag.rawPrefix = diag.rawPrefix;
|
|
7174
7354
|
retryDiag.length = diag.length;
|
|
7175
7355
|
const retry = parseStringCore(normalized, callId, retryDiag);
|
|
@@ -7246,7 +7426,8 @@ function parseObjectValue(value, callId, diag) {
|
|
|
7246
7426
|
if (topTopic !== void 0 || hasTopMaxChars) {
|
|
7247
7427
|
for (const r of ranges) {
|
|
7248
7428
|
if (r.topic === void 0 && topTopic !== void 0) r.topic = topTopic;
|
|
7249
|
-
if (r.summaryMaxChars === void 0 && hasTopMaxChars)
|
|
7429
|
+
if (r.summaryMaxChars === void 0 && hasTopMaxChars)
|
|
7430
|
+
r.summaryMaxChars = topMaxChars;
|
|
7250
7431
|
}
|
|
7251
7432
|
}
|
|
7252
7433
|
diag.invalidItems = invalid;
|
|
@@ -7261,7 +7442,8 @@ function parseContentArray(s) {
|
|
|
7261
7442
|
const normalized = normalizeSingleQuotes(cleaned);
|
|
7262
7443
|
if (normalized !== void 0) {
|
|
7263
7444
|
const retry = parseContentArrayCore(normalized);
|
|
7264
|
-
if (retry !== null && retry.entries.length > 0)
|
|
7445
|
+
if (retry !== null && retry.entries.length > 0)
|
|
7446
|
+
return { ...retry, quoteRepaired: true };
|
|
7265
7447
|
}
|
|
7266
7448
|
return direct;
|
|
7267
7449
|
}
|
|
@@ -7348,12 +7530,14 @@ function parseLineEntry(entry, callId) {
|
|
|
7348
7530
|
afterRefs = pair.index + pair[0].length;
|
|
7349
7531
|
} else {
|
|
7350
7532
|
const single = SINGLE_REF_IN_LINE.exec(head);
|
|
7351
|
-
if (single === null)
|
|
7533
|
+
if (single === null)
|
|
7534
|
+
return { reason: "line entry: no mNNNNN/bN refs in header" };
|
|
7352
7535
|
startRef = normalizeLineRef(single[1]);
|
|
7353
7536
|
endRef = startRef;
|
|
7354
7537
|
afterRefs = single.index + single[0].length;
|
|
7355
7538
|
}
|
|
7356
|
-
if (summary.length === 0)
|
|
7539
|
+
if (summary.length === 0)
|
|
7540
|
+
return { reason: "line entry: missing summary after the refs header line" };
|
|
7357
7541
|
const explicitTopic = head.slice(afterRefs).trim();
|
|
7358
7542
|
const range = {
|
|
7359
7543
|
startRef,
|
|
@@ -7372,7 +7556,11 @@ function deriveTopicFromSummary(summary) {
|
|
|
7372
7556
|
return text.length > 60 ? clampPrefix(text, 60).trimEnd() : text;
|
|
7373
7557
|
}
|
|
7374
7558
|
function splitLineEntries(content) {
|
|
7375
|
-
const parts = content.split(
|
|
7559
|
+
const parts = content.split(
|
|
7560
|
+
/\n(?=\s*(?:["']\s*,\s*)?["']?\s*[mb]\d{1,7}\s*(?:[-\u2013\u2014\u2026~]|\.\.\.|to)\s*[mb]\d{1,7}\b)/i
|
|
7561
|
+
).map(
|
|
7562
|
+
(p) => p.trim().replace(/^(?:["']\s*,?\s*)+/, "").replace(/["']\s*$/, "")
|
|
7563
|
+
).filter((p) => p.length > 0);
|
|
7376
7564
|
return parts.length > 0 ? parts : [content.trim()];
|
|
7377
7565
|
}
|
|
7378
7566
|
function stripJsonWrapperResidue(s) {
|
|
@@ -7385,12 +7573,15 @@ function stripJsonWrapperResidue(s) {
|
|
|
7385
7573
|
}
|
|
7386
7574
|
function validateEntry(entry, callId) {
|
|
7387
7575
|
if (typeof entry === "string") return parseLineEntry(entry, callId);
|
|
7388
|
-
if (entry === null || typeof entry !== "object" || Array.isArray(entry))
|
|
7576
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry))
|
|
7577
|
+
return { reason: "not an object" };
|
|
7389
7578
|
const e = entry;
|
|
7390
7579
|
const start = stringOr(e["startRef"]) ?? stringOr(e["startId"]) ?? stringOr(e["messageId"]);
|
|
7391
7580
|
const end = stringOr(e["endRef"]) ?? stringOr(e["endId"]) ?? stringOr(e["messageId"]);
|
|
7392
7581
|
if (start === void 0 || end === void 0) {
|
|
7393
|
-
return {
|
|
7582
|
+
return {
|
|
7583
|
+
reason: "missing range bounds (need startRef/startId and endRef/endId)"
|
|
7584
|
+
};
|
|
7394
7585
|
}
|
|
7395
7586
|
const summary = stringOr(e["summary"]);
|
|
7396
7587
|
if (summary === void 0) return { reason: "missing summary" };
|
|
@@ -7398,7 +7589,8 @@ function validateEntry(entry, callId) {
|
|
|
7398
7589
|
const topic = stringOr(e["topic"]);
|
|
7399
7590
|
if (topic !== void 0) range.topic = topic;
|
|
7400
7591
|
const maxChars = e["summaryMaxChars"];
|
|
7401
|
-
if (typeof maxChars === "number" && Number.isFinite(maxChars))
|
|
7592
|
+
if (typeof maxChars === "number" && Number.isFinite(maxChars))
|
|
7593
|
+
range.summaryMaxChars = maxChars;
|
|
7402
7594
|
if (callId !== void 0) range.compressCallId = callId;
|
|
7403
7595
|
return { range };
|
|
7404
7596
|
}
|
|
@@ -7435,7 +7627,8 @@ function tryParseLenient(s) {
|
|
|
7435
7627
|
return void 0;
|
|
7436
7628
|
}
|
|
7437
7629
|
function normalizeSingleQuotes(raw) {
|
|
7438
|
-
if (!raw.includes("'") || !raw.includes("{") && !raw.includes("["))
|
|
7630
|
+
if (!raw.includes("'") || !raw.includes("{") && !raw.includes("["))
|
|
7631
|
+
return void 0;
|
|
7439
7632
|
let out = "";
|
|
7440
7633
|
let changed = false;
|
|
7441
7634
|
let inDouble = false;
|
|
@@ -7527,8 +7720,10 @@ function stripTrailingCommas(s) {
|
|
|
7527
7720
|
}
|
|
7528
7721
|
if (ch === ",") {
|
|
7529
7722
|
let j = i + 1;
|
|
7530
|
-
while (j < s.length && (s.charAt(j) === " " || s.charAt(j) === " " || s.charAt(j) === "\n" || s.charAt(j) === "\r"))
|
|
7531
|
-
|
|
7723
|
+
while (j < s.length && (s.charAt(j) === " " || s.charAt(j) === " " || s.charAt(j) === "\n" || s.charAt(j) === "\r"))
|
|
7724
|
+
j++;
|
|
7725
|
+
if (j < s.length && (s.charAt(j) === "}" || s.charAt(j) === "]"))
|
|
7726
|
+
continue;
|
|
7532
7727
|
}
|
|
7533
7728
|
out += ch;
|
|
7534
7729
|
}
|
|
@@ -7593,7 +7788,8 @@ function repairAtParserPositions(s) {
|
|
|
7593
7788
|
if (ch === "\n") esc = "\\n";
|
|
7594
7789
|
else if (ch === "\r") esc = "\\r";
|
|
7595
7790
|
else if (ch === " ") esc = "\\t";
|
|
7596
|
-
else if (ch.charCodeAt(0) < 32)
|
|
7791
|
+
else if (ch.charCodeAt(0) < 32)
|
|
7792
|
+
esc = "\\u" + ch.charCodeAt(0).toString(16).padStart(4, "0");
|
|
7597
7793
|
if (esc === void 0) return cur;
|
|
7598
7794
|
cur = cur.slice(0, pos) + esc + cur.slice(pos + 1);
|
|
7599
7795
|
} else if (/Bad escaped character/i.test(msg)) {
|
|
@@ -7669,7 +7865,9 @@ function salvageContentEntries(raw) {
|
|
|
7669
7865
|
|
|
7670
7866
|
// src/rebuild.ts
|
|
7671
7867
|
function rebuildCompressionState(state, messages, config, ports = {}) {
|
|
7672
|
-
const core = createCore({
|
|
7868
|
+
const core = createCore({
|
|
7869
|
+
countTokens: ports.countTokens ?? defaultCountTokens
|
|
7870
|
+
});
|
|
7673
7871
|
const refResult = assignRefs(messages, {
|
|
7674
7872
|
existing: state.messageRefs,
|
|
7675
7873
|
nextIndex: highestUsedIndex(state.messageRefs) + 1,
|
|
@@ -7679,9 +7877,16 @@ function rebuildCompressionState(state, messages, config, ports = {}) {
|
|
|
7679
7877
|
const invocations = collectCompressInvocations(messages);
|
|
7680
7878
|
let blocksRebuilt = 0;
|
|
7681
7879
|
for (const invocation of invocations) {
|
|
7682
|
-
const { ranges } = parseCompressArgs(invocation.raw, {
|
|
7880
|
+
const { ranges } = parseCompressArgs(invocation.raw, {
|
|
7881
|
+
callId: invocation.callId
|
|
7882
|
+
});
|
|
7683
7883
|
if (ranges.length === 0) continue;
|
|
7684
|
-
const result = core.applyCompression({
|
|
7884
|
+
const result = core.applyCompression({
|
|
7885
|
+
ranges,
|
|
7886
|
+
messages,
|
|
7887
|
+
state: working,
|
|
7888
|
+
config
|
|
7889
|
+
});
|
|
7685
7890
|
working = result.state;
|
|
7686
7891
|
blocksRebuilt += result.result.blocksCreated;
|
|
7687
7892
|
}
|
|
@@ -7690,7 +7895,8 @@ function rebuildCompressionState(state, messages, config, ports = {}) {
|
|
|
7690
7895
|
function collectCompressInvocations(messages) {
|
|
7691
7896
|
const invocations = [];
|
|
7692
7897
|
for (const message of messages) {
|
|
7693
|
-
if (message.toolName !== "compress" || message.contentType !== "tool-call")
|
|
7898
|
+
if (message.toolName !== "compress" || message.contentType !== "tool-call")
|
|
7899
|
+
continue;
|
|
7694
7900
|
invocations.push({ callId: message.toolCallId, raw: message.text ?? "" });
|
|
7695
7901
|
}
|
|
7696
7902
|
return invocations;
|
|
@@ -7706,7 +7912,8 @@ function stem(word) {
|
|
|
7706
7912
|
let w = word;
|
|
7707
7913
|
if (w.length <= 3) return w;
|
|
7708
7914
|
if (w.endsWith("ies")) w = w.slice(0, -3) + "y";
|
|
7709
|
-
else if (w.endsWith("ses") || w.endsWith("xes") || w.endsWith("zes"))
|
|
7915
|
+
else if (w.endsWith("ses") || w.endsWith("xes") || w.endsWith("zes"))
|
|
7916
|
+
w = w.slice(0, -2);
|
|
7710
7917
|
else if (w.endsWith("ches") || w.endsWith("shes")) w = w.slice(0, -2);
|
|
7711
7918
|
else if (w.endsWith("s") && !w.endsWith("ss")) w = w.slice(0, -1);
|
|
7712
7919
|
if (w.endsWith("ing") && w.length > 5) w = w.slice(0, -3);
|
|
@@ -7883,7 +8090,8 @@ var fuzzyAlgorithm = {
|
|
|
7883
8090
|
description: "Character bigram overlap. Typo-tolerant, script-agnostic, high recall.",
|
|
7884
8091
|
score(docs, query) {
|
|
7885
8092
|
const qTokens = query.toLowerCase().split(/[\s,]+/).filter((t) => t.length >= 4 || t.length >= 2 && CJK.test(t));
|
|
7886
|
-
if (qTokens.length === 0)
|
|
8093
|
+
if (qTokens.length === 0)
|
|
8094
|
+
return docs.map((d) => ({ ref: d.ref, score: 0 }));
|
|
7887
8095
|
const qGrams = /* @__PURE__ */ new Set();
|
|
7888
8096
|
for (const t of qTokens) for (const g of charBigrams(t)) qGrams.add(g);
|
|
7889
8097
|
if (qGrams.size === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
|
|
@@ -8004,7 +8212,9 @@ function runSearch(docs, query, options) {
|
|
|
8004
8212
|
}).filter((r) => r !== null && r.score >= minScore).sort((a, b) => b.score - a.score).slice(0, limit);
|
|
8005
8213
|
};
|
|
8006
8214
|
if (scoredOrPromise instanceof Promise) {
|
|
8007
|
-
return scoredOrPromise.then(
|
|
8215
|
+
return scoredOrPromise.then(
|
|
8216
|
+
(raw) => buildResults(applyRoleWeight(raw, docs, rw))
|
|
8217
|
+
);
|
|
8008
8218
|
}
|
|
8009
8219
|
return buildResults(applyRoleWeight(scoredOrPromise, docs, rw));
|
|
8010
8220
|
}
|
|
@@ -8416,6 +8626,7 @@ export {
|
|
|
8416
8626
|
sanitizePackSurface,
|
|
8417
8627
|
searchBlocks,
|
|
8418
8628
|
searchBlocksAsync,
|
|
8629
|
+
segmentGroups,
|
|
8419
8630
|
setDocCacheCap,
|
|
8420
8631
|
storeCoveredOriginals,
|
|
8421
8632
|
storeLargeResults,
|