acp-kernel 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/boundaries.d.ts +13 -0
- package/dist/boundaries.d.ts.map +1 -1
- package/dist/compress.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +231 -61
- package/dist/index.js.map +1 -1
- package/dist/nudge-text.d.ts +2 -1
- package/dist/nudge-text.d.ts.map +1 -1
- package/dist/prompts.d.ts +48 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prune.d.ts.map +1 -1
- package/dist/reasoning-pairs.d.ts +33 -0
- package/dist/reasoning-pairs.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/boundaries.d.ts
CHANGED
|
@@ -6,6 +6,19 @@ export interface ParsedBoundary {
|
|
|
6
6
|
raw: string;
|
|
7
7
|
}
|
|
8
8
|
export declare function parseBoundary(ref: string): ParsedBoundary | null;
|
|
9
|
+
/**
|
|
10
|
+
* Thrown when a boundary ref parses but cannot be anchored in the visible
|
|
11
|
+
* context. `kind` distinguishes a ref that never existed ("unknown", e.g. a
|
|
12
|
+
* typo or a ref from another session) from one that was consumed by an
|
|
13
|
+
* existing block ("consumed", messages hidden by prune). `endpoint` names the
|
|
14
|
+
* failing side of the range so callers can attribute the error precisely.
|
|
15
|
+
*/
|
|
16
|
+
export declare class BoundaryNotFoundError extends Error {
|
|
17
|
+
readonly code = "BOUNDARY_NOT_FOUND";
|
|
18
|
+
readonly kind: "unknown" | "consumed";
|
|
19
|
+
readonly endpoint: "start" | "end";
|
|
20
|
+
constructor(kind: "unknown" | "consumed", endpoint: "start" | "end", message: string);
|
|
21
|
+
}
|
|
9
22
|
export interface ResolveBoundariesInput {
|
|
10
23
|
startRef: string;
|
|
11
24
|
endRef: string;
|
package/dist/boundaries.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundaries.d.ts","sourceRoot":"","sources":["../src/boundaries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAehE;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,aAAa,
|
|
1
|
+
{"version":3,"file":"boundaries.d.ts","sourceRoot":"","sources":["../src/boundaries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAehE;AAED;;;;;;GAMG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,wBAAwB;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,KAAK,CAAC;gBAGjC,IAAI,EAAE,SAAS,GAAG,UAAU,EAC5B,QAAQ,EAAE,OAAO,GAAG,KAAK,EACzB,OAAO,EAAE,MAAM;CAQlB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,aAAa,CAoDf;AA6DD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EAAE,EACb,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,GAAG,IAAI,CASf;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,CAMzE"}
|
package/dist/compress.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,kBAAkB,EACnB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAapB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAQvD,OAAO,EAGL,KAAK,YAAY,EAElB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAEhB,MAAM,EAEN,WAAW,EAGX,iBAAiB,EAEjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,KAAK;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IACxD,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAAC;IACvE,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,UAAU,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IACnE,MAAM,CACJ,KAAK,EAAE,gBAAgB,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,EAAE,CAAC;IACJ,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC;AAsBD,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CAwQ7D;AAiuBD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,12 +6,14 @@ export { defaultConfig, validateConfig } from "./config.js";
|
|
|
6
6
|
export { assignRefs, highestUsedIndex, emptyRefMap, indexToRef, refToIndex, refForRaw, rawForRef, BLOCKED_REF, } from "./refs.js";
|
|
7
7
|
export { prune, SUMMARY_HEADER } from "./prune.js";
|
|
8
8
|
export { syncBlocks } from "./sync.js";
|
|
9
|
-
export { resolveBoundaries, parseBoundary } from "./boundaries.js";
|
|
9
|
+
export { resolveBoundaries, parseBoundary, BoundaryNotFoundError } from "./boundaries.js";
|
|
10
10
|
export { defaultCountTokens, estimateTokensFast, createBpeTokenizer } from "./tokenize.js";
|
|
11
11
|
export type { TokenCountFn } from "./tokenize.js";
|
|
12
12
|
export { renderNudgeText, formatRanges } from "./nudge-text.js";
|
|
13
13
|
export type { NudgeVoice, RenderedNudge } from "./nudge-text.js";
|
|
14
14
|
export { COMPRESS_PHILOSOPHY, HOW_TO_COMPRESS_RULES, TIER2_DISTILL_RULES, TIER3_CONDENSE_RULES } from "./compression-rules.js";
|
|
15
|
+
export { defaultPrompts, resolvePrompts } from "./prompts.js";
|
|
16
|
+
export type { Prompts, ResolvePromptsOptions } from "./prompts.js";
|
|
15
17
|
export { truncateLargeToolOutputs } from "./truncate-tools.js";
|
|
16
18
|
export type { TruncateOptions, TruncateResult } from "./truncate-tools.js";
|
|
17
19
|
export { parseBlockIdArg, findBlocksOverlappingMessages, findActiveAncestor, deactivateBlock, buildRestoredContentPreview, collectBlockContent, } from "./decompress.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EACV,KAAK,EACL,eAAe,EACf,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EACV,KAAK,EACL,eAAe,EACf,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3F,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAChE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC/H,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EACH,eAAe,EACf,6BAA6B,EAC7B,kBAAkB,EAClB,eAAe,EACf,2BAA2B,EAC3B,mBAAmB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC3F,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtF,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzM,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACzI,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EACL,WAAW,EACX,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,eAAe,CAAC;AACvB,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -142,9 +142,11 @@ function prune(messages, state, options = {}) {
|
|
|
142
142
|
const indexById = /* @__PURE__ */ new Map();
|
|
143
143
|
messages.forEach((message, index) => indexById.set(message.id, index));
|
|
144
144
|
const anchors = inject ? collectSummaryAnchors(state, indexById) : [];
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
return stripOrphanedReasoning(
|
|
146
|
+
stripOrphanedToolResults(
|
|
147
|
+
stripOrphanedToolCalls(
|
|
148
|
+
rebuildMessages(messages, covered, firstUserIndex, anchors)
|
|
149
|
+
)
|
|
148
150
|
)
|
|
149
151
|
);
|
|
150
152
|
}
|
|
@@ -221,6 +223,24 @@ function stripOrphanedToolCalls(messages) {
|
|
|
221
223
|
(m) => m.contentType !== "tool-call" || !m.toolCallId || m.toolName === "compress" || knownResultIds.has(m.toolCallId)
|
|
222
224
|
);
|
|
223
225
|
}
|
|
226
|
+
function stripOrphanedReasoning(messages) {
|
|
227
|
+
const drop = /* @__PURE__ */ new Set();
|
|
228
|
+
for (let i = 0; i < messages.length; i++) {
|
|
229
|
+
if (drop.has(i)) continue;
|
|
230
|
+
if (messages[i].contentType !== "reasoning") continue;
|
|
231
|
+
let j = i;
|
|
232
|
+
while (j + 1 < messages.length && messages[j + 1].contentType === "reasoning") {
|
|
233
|
+
j++;
|
|
234
|
+
}
|
|
235
|
+
const companion = messages[j + 1];
|
|
236
|
+
const hasCompanion = companion !== void 0 && companion.role === "assistant" && (companion.contentType === "text" || companion.contentType === "tool-call");
|
|
237
|
+
if (!hasCompanion) {
|
|
238
|
+
for (let k = i; k <= j; k++) drop.add(k);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (drop.size === 0) return messages;
|
|
242
|
+
return messages.filter((_, i) => !drop.has(i));
|
|
243
|
+
}
|
|
224
244
|
|
|
225
245
|
// src/sync.ts
|
|
226
246
|
function syncBlocks(messages, state) {
|
|
@@ -382,6 +402,18 @@ function parseBoundary(ref) {
|
|
|
382
402
|
}
|
|
383
403
|
return null;
|
|
384
404
|
}
|
|
405
|
+
var BoundaryNotFoundError = class extends Error {
|
|
406
|
+
code = "BOUNDARY_NOT_FOUND";
|
|
407
|
+
kind;
|
|
408
|
+
endpoint;
|
|
409
|
+
constructor(kind, endpoint, message) {
|
|
410
|
+
super(message);
|
|
411
|
+
this.name = "BoundaryNotFoundError";
|
|
412
|
+
this.code = "BOUNDARY_NOT_FOUND";
|
|
413
|
+
this.kind = kind;
|
|
414
|
+
this.endpoint = endpoint;
|
|
415
|
+
}
|
|
416
|
+
};
|
|
385
417
|
function resolveBoundaries(input) {
|
|
386
418
|
const start = parseBoundary(input.startRef);
|
|
387
419
|
const end = parseBoundary(input.endRef);
|
|
@@ -394,13 +426,8 @@ function resolveBoundaries(input) {
|
|
|
394
426
|
input.messages.forEach(
|
|
395
427
|
(message, index) => indexByRawId.set(message.id, index)
|
|
396
428
|
);
|
|
397
|
-
let startIndex = resolveAnchorIndex(start, input.state, indexByRawId);
|
|
398
|
-
let endIndex = resolveAnchorIndex(end, input.state, indexByRawId);
|
|
399
|
-
if (startIndex === null || endIndex === null) {
|
|
400
|
-
throw new Error(
|
|
401
|
-
`Boundary not found in visible context (likely consumed by an existing block). startId="${input.startRef}", endId="${input.endRef}".`
|
|
402
|
-
);
|
|
403
|
-
}
|
|
429
|
+
let startIndex = resolveAnchorIndex(start, input.state, indexByRawId, "start");
|
|
430
|
+
let endIndex = resolveAnchorIndex(end, input.state, indexByRawId, "end");
|
|
404
431
|
if (startIndex > endIndex) {
|
|
405
432
|
[startIndex, endIndex] = [endIndex, startIndex];
|
|
406
433
|
}
|
|
@@ -431,16 +458,51 @@ function resolveBoundaries(input) {
|
|
|
431
458
|
protectedGaps
|
|
432
459
|
};
|
|
433
460
|
}
|
|
434
|
-
function resolveAnchorIndex(boundary, state, indexByRawId) {
|
|
461
|
+
function resolveAnchorIndex(boundary, state, indexByRawId, endpoint) {
|
|
462
|
+
const label = endpoint === "start" ? "startId" : "endId";
|
|
435
463
|
if (boundary.kind === "message") {
|
|
436
464
|
const rawId = state.messageRefs.byRef[boundary.raw] ?? state.messageRefs.byRef[formatPaddedRef(boundary.numericId)];
|
|
437
|
-
if (!rawId)
|
|
465
|
+
if (!rawId) {
|
|
466
|
+
throw new BoundaryNotFoundError(
|
|
467
|
+
"unknown",
|
|
468
|
+
endpoint,
|
|
469
|
+
`${label}="${boundary.raw}" does not exist in this session (typo or wrong session) \u2014 run acp_status for current refs.`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
438
472
|
const index = indexByRawId.get(rawId);
|
|
439
|
-
|
|
473
|
+
if (index === void 0) {
|
|
474
|
+
throw new BoundaryNotFoundError(
|
|
475
|
+
"consumed",
|
|
476
|
+
endpoint,
|
|
477
|
+
`${label}="${boundary.raw}" not found in visible context (likely consumed by an existing block).`
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
return index;
|
|
440
481
|
}
|
|
441
482
|
const block = blockById(state, `b${boundary.numericId}`);
|
|
442
|
-
if (!block
|
|
443
|
-
|
|
483
|
+
if (!block) {
|
|
484
|
+
throw new BoundaryNotFoundError(
|
|
485
|
+
"unknown",
|
|
486
|
+
endpoint,
|
|
487
|
+
`${label}="b${boundary.numericId}" does not exist in this session (typo or wrong session) \u2014 run acp_status for current refs.`
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
if (!block.active) {
|
|
491
|
+
throw new BoundaryNotFoundError(
|
|
492
|
+
"consumed",
|
|
493
|
+
endpoint,
|
|
494
|
+
`${label}="b${boundary.numericId}" not found in visible context (block distilled/consumed by a higher-tier block).`
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
const anchor = earliestIndexOfIds(block.effectiveMessageIds, indexByRawId);
|
|
498
|
+
if (anchor === null) {
|
|
499
|
+
throw new BoundaryNotFoundError(
|
|
500
|
+
"consumed",
|
|
501
|
+
endpoint,
|
|
502
|
+
`${label}="b${boundary.numericId}" not found in visible context (block messages consumed by a higher-tier block).`
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
return anchor;
|
|
444
506
|
}
|
|
445
507
|
function formatPaddedRef(index) {
|
|
446
508
|
return `m${String(index).padStart(5, "0")}`;
|
|
@@ -847,6 +909,40 @@ function adjustBoundariesForToolPairs(startIndex, endIndex, messages, maxScan =
|
|
|
847
909
|
return { startIndex: newStartIndex, endIndex: newEndIndex };
|
|
848
910
|
}
|
|
849
911
|
|
|
912
|
+
// src/reasoning-pairs.ts
|
|
913
|
+
function adjustBoundariesForReasoningPairs(startIndex, endIndex, messages) {
|
|
914
|
+
if (startIndex > endIndex) {
|
|
915
|
+
return { startIndex, endIndex };
|
|
916
|
+
}
|
|
917
|
+
let newStartIndex = startIndex;
|
|
918
|
+
let newEndIndex = endIndex;
|
|
919
|
+
for (let i = startIndex; i <= endIndex && i < messages.length; i++) {
|
|
920
|
+
const msg = messages[i];
|
|
921
|
+
if (!msg) continue;
|
|
922
|
+
if (msg.contentType === "reasoning") {
|
|
923
|
+
let j = i;
|
|
924
|
+
while (j + 1 < messages.length && messages[j + 1].contentType === "reasoning") {
|
|
925
|
+
j++;
|
|
926
|
+
}
|
|
927
|
+
const companion = messages[j + 1];
|
|
928
|
+
if (companion !== void 0 && companion.role === "assistant" && (companion.contentType === "text" || companion.contentType === "tool-call") && j + 1 > newEndIndex) {
|
|
929
|
+
newEndIndex = j + 1;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
if (msg.role === "assistant" && (msg.contentType === "text" || msg.contentType === "tool-call")) {
|
|
933
|
+
let k = i - 1;
|
|
934
|
+
while (k >= 0 && messages[k].contentType === "reasoning") {
|
|
935
|
+
k--;
|
|
936
|
+
}
|
|
937
|
+
const runStart = k + 1;
|
|
938
|
+
if (runStart < i && runStart >= 0 && messages[runStart].contentType === "reasoning" && runStart < newStartIndex) {
|
|
939
|
+
newStartIndex = runStart;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
return { startIndex: newStartIndex, endIndex: newEndIndex };
|
|
944
|
+
}
|
|
945
|
+
|
|
850
946
|
// src/recommend.ts
|
|
851
947
|
function refNum(ref) {
|
|
852
948
|
const n = parseInt(ref.slice(1), 10);
|
|
@@ -1009,6 +1105,9 @@ function runPipeline(nodes, initial, ctx) {
|
|
|
1009
1105
|
}
|
|
1010
1106
|
|
|
1011
1107
|
// src/compress.ts
|
|
1108
|
+
function rangeError(spec, message) {
|
|
1109
|
+
return `range ${spec.startRef}..${spec.endRef}: ${message}`;
|
|
1110
|
+
}
|
|
1012
1111
|
function createCore(ports = {}) {
|
|
1013
1112
|
const countTokens = ports.countTokens ?? defaultCountTokens;
|
|
1014
1113
|
function applyCompression(input) {
|
|
@@ -1020,20 +1119,44 @@ function createCore(ports = {}) {
|
|
|
1020
1119
|
const warnings = [];
|
|
1021
1120
|
const protectedMessageIds = input.protectedMessageIds ?? computeProtectedRefs(input.messages, input.state, input.config, countTokens);
|
|
1022
1121
|
const preExistingCoverage = collectCoverage(state);
|
|
1023
|
-
const
|
|
1122
|
+
const classifications = /* @__PURE__ */ new Map();
|
|
1123
|
+
const classificationErrors = [];
|
|
1124
|
+
const consumedRanges = [];
|
|
1024
1125
|
for (const spec of input.ranges) {
|
|
1025
|
-
let resolved;
|
|
1026
1126
|
try {
|
|
1027
|
-
resolved = resolveBoundaries({
|
|
1127
|
+
const resolved = resolveBoundaries({
|
|
1028
1128
|
startRef: spec.startRef,
|
|
1029
1129
|
endRef: spec.endRef,
|
|
1030
1130
|
messages: input.messages,
|
|
1031
1131
|
state
|
|
1032
1132
|
});
|
|
1033
|
-
|
|
1034
|
-
|
|
1133
|
+
classifications.set(spec, { status: "ok", resolved });
|
|
1134
|
+
} catch (error) {
|
|
1135
|
+
if (error instanceof BoundaryNotFoundError) {
|
|
1136
|
+
classifications.set(
|
|
1137
|
+
spec,
|
|
1138
|
+
error.kind === "unknown" ? { status: "unknown", error } : { status: "consumed", error }
|
|
1139
|
+
);
|
|
1140
|
+
if (error.kind === "consumed") {
|
|
1141
|
+
consumedRanges.push(spec);
|
|
1142
|
+
} else {
|
|
1143
|
+
classificationErrors.push(rangeError(spec, error.message));
|
|
1144
|
+
}
|
|
1145
|
+
} else {
|
|
1146
|
+
classifications.set(spec, {
|
|
1147
|
+
status: "invalid",
|
|
1148
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
1149
|
+
});
|
|
1150
|
+
classificationErrors.push(
|
|
1151
|
+
rangeError(spec, error instanceof Error ? error.message : String(error))
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1035
1154
|
}
|
|
1036
|
-
|
|
1155
|
+
}
|
|
1156
|
+
const rangeIndexSets = [];
|
|
1157
|
+
for (const [spec, resolution] of classifications) {
|
|
1158
|
+
if (resolution.status !== "ok") continue;
|
|
1159
|
+
const indices = resolution.resolved.messageIds.map(
|
|
1037
1160
|
(id) => input.messages.findIndex((m) => m.id === id)
|
|
1038
1161
|
).filter((i) => i >= 0);
|
|
1039
1162
|
rangeIndexSets.push({ spec, indices });
|
|
@@ -1060,37 +1183,27 @@ function createCore(ports = {}) {
|
|
|
1060
1183
|
if (input.config.compress.minCompressRange > 0 && input.ranges.length > 0) {
|
|
1061
1184
|
let totalRangeChars = 0;
|
|
1062
1185
|
let hasBlockBoundaryRange = false;
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
resolved = resolveBoundaries({
|
|
1068
|
-
startRef: spec.startRef,
|
|
1069
|
-
endRef: spec.endRef,
|
|
1070
|
-
messages: input.messages,
|
|
1071
|
-
state
|
|
1072
|
-
});
|
|
1073
|
-
} catch {
|
|
1074
|
-
continue;
|
|
1075
|
-
}
|
|
1076
|
-
if (resolved.boundaryKind === "block") {
|
|
1186
|
+
let countedRanges = 0;
|
|
1187
|
+
for (const [spec, resolution] of classifications) {
|
|
1188
|
+
if (resolution.status !== "ok" || skipSpecs.has(spec)) continue;
|
|
1189
|
+
if (resolution.resolved.boundaryKind === "block") {
|
|
1077
1190
|
hasBlockBoundaryRange = true;
|
|
1078
1191
|
continue;
|
|
1079
1192
|
}
|
|
1080
|
-
|
|
1193
|
+
countedRanges++;
|
|
1194
|
+
for (const id of resolution.resolved.messageIds) {
|
|
1081
1195
|
const msg = input.messages.find((m) => m.id === id);
|
|
1082
1196
|
totalRangeChars += msg?.text?.length ?? 0;
|
|
1083
1197
|
}
|
|
1084
1198
|
}
|
|
1085
1199
|
if (!hasBlockBoundaryRange && totalRangeChars < input.config.compress.minCompressRange) {
|
|
1200
|
+
const gateMessage = consumedRanges.length > 0 ? `Requested range(s) already compressed (e.g. ${consumedRanges[0].startRef}..${consumedRanges[0].endRef}); remaining compressible content ${totalRangeChars} chars < min ${input.config.compress.minCompressRange}. Nothing to do \u2014 run acp_status to see current compressible ranges.` : `Total compressible content too small (${totalRangeChars} chars across ${countedRanges} range(s), min ${input.config.compress.minCompressRange}). Combine more messages into your range(s) to meet the threshold.`;
|
|
1086
1201
|
return {
|
|
1087
1202
|
state: input.state,
|
|
1088
1203
|
result: {
|
|
1089
1204
|
blocksCreated: 0,
|
|
1090
1205
|
tokensCompressed: 0,
|
|
1091
|
-
errors: [
|
|
1092
|
-
`Total compressible content too small (${totalRangeChars} chars across ${input.ranges.length} range(s), min ${input.config.compress.minCompressRange}). Combine more messages into your range(s) to meet the threshold.`
|
|
1093
|
-
],
|
|
1206
|
+
errors: [gateMessage, ...classificationErrors],
|
|
1094
1207
|
warnings: []
|
|
1095
1208
|
}
|
|
1096
1209
|
};
|
|
@@ -1098,6 +1211,18 @@ function createCore(ports = {}) {
|
|
|
1098
1211
|
}
|
|
1099
1212
|
for (const spec of input.ranges) {
|
|
1100
1213
|
if (skipSpecs.has(spec)) continue;
|
|
1214
|
+
const resolution = classifications.get(spec);
|
|
1215
|
+
if (resolution === void 0) continue;
|
|
1216
|
+
if (resolution.status === "consumed") {
|
|
1217
|
+
warnings.push(
|
|
1218
|
+
`Skipped range (${spec.startRef}..${spec.endRef}) \u2014 already compressed (messages consumed by existing block(s)); nothing to compress.`
|
|
1219
|
+
);
|
|
1220
|
+
continue;
|
|
1221
|
+
}
|
|
1222
|
+
if (resolution.status === "unknown" || resolution.status === "invalid") {
|
|
1223
|
+
errors.push(rangeError(spec, resolution.error.message));
|
|
1224
|
+
continue;
|
|
1225
|
+
}
|
|
1101
1226
|
try {
|
|
1102
1227
|
const outcome = applySingleRange({
|
|
1103
1228
|
spec,
|
|
@@ -1113,7 +1238,7 @@ function createCore(ports = {}) {
|
|
|
1113
1238
|
tokensCompressed += outcome.tokens;
|
|
1114
1239
|
warnings.push(...outcome.warnings);
|
|
1115
1240
|
} catch (error) {
|
|
1116
|
-
errors.push(error instanceof Error ? error.message : String(error));
|
|
1241
|
+
errors.push(rangeError(spec, error instanceof Error ? error.message : String(error)));
|
|
1117
1242
|
}
|
|
1118
1243
|
}
|
|
1119
1244
|
state.stats.compressionCount += blocksCreated;
|
|
@@ -1321,7 +1446,7 @@ function applySingleRange(input) {
|
|
|
1321
1446
|
messages: input.messages,
|
|
1322
1447
|
state: input.state
|
|
1323
1448
|
});
|
|
1324
|
-
const rangeMessageIds =
|
|
1449
|
+
const rangeMessageIds = applyPairBoundaryAdjustments(
|
|
1325
1450
|
resolved,
|
|
1326
1451
|
input.messages
|
|
1327
1452
|
);
|
|
@@ -1435,20 +1560,33 @@ function applySingleRange(input) {
|
|
|
1435
1560
|
}
|
|
1436
1561
|
return { tokens: compressedTokens, warnings };
|
|
1437
1562
|
}
|
|
1438
|
-
function
|
|
1563
|
+
function applyPairBoundaryAdjustments(resolved, messages) {
|
|
1439
1564
|
if (resolved.boundaryKind === "block") {
|
|
1440
1565
|
return resolved.messageIds;
|
|
1441
1566
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1567
|
+
let startIndex = resolved.startIndex;
|
|
1568
|
+
let endIndex = resolved.endIndex;
|
|
1569
|
+
for (let pass = 0; pass < 2; pass++) {
|
|
1570
|
+
const reasoningAdjusted = adjustBoundariesForReasoningPairs(
|
|
1571
|
+
startIndex,
|
|
1572
|
+
endIndex,
|
|
1573
|
+
messages
|
|
1574
|
+
);
|
|
1575
|
+
const toolAdjusted = adjustBoundariesForToolPairs(
|
|
1576
|
+
reasoningAdjusted.startIndex,
|
|
1577
|
+
reasoningAdjusted.endIndex,
|
|
1578
|
+
messages
|
|
1579
|
+
);
|
|
1580
|
+
const changed = toolAdjusted.startIndex !== startIndex || toolAdjusted.endIndex !== endIndex;
|
|
1581
|
+
startIndex = toolAdjusted.startIndex;
|
|
1582
|
+
endIndex = toolAdjusted.endIndex;
|
|
1583
|
+
if (!changed) break;
|
|
1584
|
+
}
|
|
1585
|
+
if (startIndex === resolved.startIndex && endIndex === resolved.endIndex) {
|
|
1448
1586
|
return resolved.messageIds;
|
|
1449
1587
|
}
|
|
1450
1588
|
const ids = [];
|
|
1451
|
-
for (let i =
|
|
1589
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
1452
1590
|
const msg = messages[i];
|
|
1453
1591
|
if (msg) ids.push(msg.id);
|
|
1454
1592
|
}
|
|
@@ -1807,13 +1945,42 @@ DROP:
|
|
|
1807
1945
|
|
|
1808
1946
|
SIZE TARGET: 30-60 tokens per source block (including header). For a batch of N source blocks, total output \u2248 N \xD7 40 tokens. If a source block has only one trivial fact, output just the header + one line.`;
|
|
1809
1947
|
|
|
1948
|
+
// src/prompts.ts
|
|
1949
|
+
var defaultPrompts = Object.freeze({
|
|
1950
|
+
compressPhilosophy: COMPRESS_PHILOSOPHY,
|
|
1951
|
+
howToCompressRules: HOW_TO_COMPRESS_RULES,
|
|
1952
|
+
tier2DistillRules: TIER2_DISTILL_RULES,
|
|
1953
|
+
tier3CondenseRules: TIER3_CONDENSE_RULES
|
|
1954
|
+
});
|
|
1955
|
+
function resolvePrompts(overrides, options = {}) {
|
|
1956
|
+
const clean = {};
|
|
1957
|
+
if (overrides) {
|
|
1958
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
1959
|
+
if (typeof value === "string") {
|
|
1960
|
+
clean[key] = value;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
const keys = Object.keys(clean);
|
|
1965
|
+
if (keys.length > 0 && !options.acknowledgeRisk) {
|
|
1966
|
+
throw new Error(
|
|
1967
|
+
`resolvePrompts: overriding compression rules requires { acknowledgeRisk: true }. Overridden keys: ${keys.join(", ")}. These rules are quality-critical (tuned over months of production use); changing them can degrade summary quality and break retrieval (summaries may lose paths, signatures, decisions).`
|
|
1968
|
+
);
|
|
1969
|
+
}
|
|
1970
|
+
return { ...defaultPrompts, ...clean };
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1810
1973
|
// src/nudge-text.ts
|
|
1811
|
-
|
|
1974
|
+
function efficiencyNote(prompts) {
|
|
1975
|
+
return `This is an efficiency nudge to compress early and keep context lean \u2014 not an overflow warning. A separate, stronger alert will appear if the context is actually full.
|
|
1812
1976
|
|
|
1813
|
-
${
|
|
1814
|
-
|
|
1977
|
+
${prompts.compressPhilosophy}`;
|
|
1978
|
+
}
|
|
1979
|
+
function emergencyHeader(prompts) {
|
|
1980
|
+
return `\u26A0\uFE0F Context limit reached \u2014 compress now. Prioritize consumed tool outputs.
|
|
1815
1981
|
|
|
1816
|
-
${
|
|
1982
|
+
${prompts.compressPhilosophy}`;
|
|
1983
|
+
}
|
|
1817
1984
|
function formatK(n) {
|
|
1818
1985
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
1819
1986
|
return `${n}`;
|
|
@@ -1921,7 +2088,7 @@ function formatRanges(compressible, protectedRanges) {
|
|
|
1921
2088
|
return `Compressible ranges (${merged.length}, oldest first):
|
|
1922
2089
|
${lines.join("\n")}`;
|
|
1923
2090
|
}
|
|
1924
|
-
function renderNudgeText(decision) {
|
|
2091
|
+
function renderNudgeText(decision, prompts = defaultPrompts) {
|
|
1925
2092
|
const breakdownStr = formatBreakdown(decision.contextBreakdown);
|
|
1926
2093
|
const rangesStr = formatRanges(decision.compressibleRanges, decision.protectedRanges ?? []);
|
|
1927
2094
|
if (decision.tier !== null && decision.tier >= 2) {
|
|
@@ -1933,7 +2100,7 @@ function renderNudgeText(decision) {
|
|
|
1933
2100
|
return {
|
|
1934
2101
|
voice: "gentle",
|
|
1935
2102
|
text: [
|
|
1936
|
-
|
|
2103
|
+
efficiencyNote(prompts),
|
|
1937
2104
|
"",
|
|
1938
2105
|
breakdownStr,
|
|
1939
2106
|
"",
|
|
@@ -1942,9 +2109,9 @@ function renderNudgeText(decision) {
|
|
|
1942
2109
|
blockList,
|
|
1943
2110
|
`Example: compress({ content: [{ startId: "${startId}", endId: "${endId}", summary: "..." }] })`,
|
|
1944
2111
|
"",
|
|
1945
|
-
|
|
2112
|
+
prompts.howToCompressRules,
|
|
1946
2113
|
"",
|
|
1947
|
-
isT2 ?
|
|
2114
|
+
isT2 ? prompts.tier2DistillRules : prompts.tier3CondenseRules
|
|
1948
2115
|
].join("\n")
|
|
1949
2116
|
};
|
|
1950
2117
|
}
|
|
@@ -1953,11 +2120,11 @@ function renderNudgeText(decision) {
|
|
|
1953
2120
|
return {
|
|
1954
2121
|
voice: "emergency",
|
|
1955
2122
|
text: [
|
|
1956
|
-
|
|
2123
|
+
emergencyHeader(prompts),
|
|
1957
2124
|
"",
|
|
1958
2125
|
breakdownStr,
|
|
1959
2126
|
"",
|
|
1960
|
-
|
|
2127
|
+
prompts.howToCompressRules,
|
|
1961
2128
|
"",
|
|
1962
2129
|
`{ "topic": "...", "content": [{ "startId": "<ID>", "endId": "<ID>", "summary": "..." }] }`,
|
|
1963
2130
|
"Only use IDs from visible messages above. Compress older work first.",
|
|
@@ -1969,11 +2136,11 @@ function renderNudgeText(decision) {
|
|
|
1969
2136
|
return {
|
|
1970
2137
|
voice: "gentle",
|
|
1971
2138
|
text: [
|
|
1972
|
-
|
|
2139
|
+
efficiencyNote(prompts),
|
|
1973
2140
|
"",
|
|
1974
2141
|
breakdownStr,
|
|
1975
2142
|
"",
|
|
1976
|
-
|
|
2143
|
+
prompts.howToCompressRules,
|
|
1977
2144
|
"",
|
|
1978
2145
|
rangesStr,
|
|
1979
2146
|
"",
|
|
@@ -2706,6 +2873,7 @@ function makePreview(text, query, len) {
|
|
|
2706
2873
|
}
|
|
2707
2874
|
export {
|
|
2708
2875
|
BLOCKED_REF,
|
|
2876
|
+
BoundaryNotFoundError,
|
|
2709
2877
|
COMPRESS_PHILOSOPHY,
|
|
2710
2878
|
DEFAULT_ALGORITHM,
|
|
2711
2879
|
DEFAULT_ROLE_WEIGHTS,
|
|
@@ -2734,6 +2902,7 @@ export {
|
|
|
2734
2902
|
deactivateBlock,
|
|
2735
2903
|
defaultConfig,
|
|
2736
2904
|
defaultCountTokens,
|
|
2905
|
+
defaultPrompts,
|
|
2737
2906
|
emptyRefMap,
|
|
2738
2907
|
estimateTokensFast,
|
|
2739
2908
|
findActiveAncestor,
|
|
@@ -2764,6 +2933,7 @@ export {
|
|
|
2764
2933
|
renderRefsNode,
|
|
2765
2934
|
renderVisibleRefs,
|
|
2766
2935
|
resolveBoundaries,
|
|
2936
|
+
resolvePrompts,
|
|
2767
2937
|
runPipeline,
|
|
2768
2938
|
searchBlocks,
|
|
2769
2939
|
searchBlocksAsync,
|