acp-kernel 0.0.41 → 0.0.42-pr.136.3
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/compress-tools.d.ts +669 -0
- package/dist/compress-tools.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +361 -0
- package/dist/index.js.map +1 -1
- package/dist/wire/compress-detect.d.ts +142 -0
- package/dist/wire/compress-detect.d.ts.map +1 -0
- package/dist/wire/index.d.ts +1 -0
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +189 -1
- package/dist/wire/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compress-call detection and replay-guard on the wire/core stream
|
|
3
|
+
* (Phase K2, moved from billion-context-omp `src/wire-fold.ts`).
|
|
4
|
+
*
|
|
5
|
+
* Two layers:
|
|
6
|
+
* - Detection: `compressToolArgs` accepts the two call shapes that exist in
|
|
7
|
+
* the wild (direct `compress`; legacy `write` to `xd://compress`, args
|
|
8
|
+
* JSON-encoded one or two levels deep), `findCompressCalls` /
|
|
9
|
+
* `findCompressCallsCore` turn a stream tool-call into validated ranges.
|
|
10
|
+
* - Guard: when compression state is REPLAYED against a rebuilt stream
|
|
11
|
+
* (restart, mirror divergence, host re-serialization), every recorded
|
|
12
|
+
* range must prove it still covers the same content — fingerprint match
|
|
13
|
+
* (first/last piece content key), position fallback for drifted
|
|
14
|
+
* boundaries, remap for dangling m-refs.
|
|
15
|
+
*
|
|
16
|
+
* Pure functions over BiliMessage/CoreMessage — no host types, no I/O.
|
|
17
|
+
*/
|
|
18
|
+
import type { CoreMessage } from "../types.js";
|
|
19
|
+
import type { BiliMessage } from "./bili-message.js";
|
|
20
|
+
/** A compress call carried by a stream tool-call, normalized to validated
|
|
21
|
+
* ranges. `id` is the tool-call id (replay dedup key). */
|
|
22
|
+
export interface StreamCompressCall {
|
|
23
|
+
id: string;
|
|
24
|
+
ranges: {
|
|
25
|
+
startRef: string;
|
|
26
|
+
endRef: string;
|
|
27
|
+
summary: string;
|
|
28
|
+
topic?: string;
|
|
29
|
+
summaryMaxChars?: number;
|
|
30
|
+
compressCallId: string;
|
|
31
|
+
}[];
|
|
32
|
+
}
|
|
33
|
+
/** Extract a compress tool's arguments from a stream toolCall. Two call
|
|
34
|
+
* shapes exist: (1) top-level — the tools are registered with
|
|
35
|
+
* loadMode:"essential" so hosts do NOT mount them as xd:// devices; the
|
|
36
|
+
* stream shows name:"compress" directly. (2) legacy xd:// — sessions
|
|
37
|
+
* recorded before that change (or hosts forcing discoverable mounting)
|
|
38
|
+
* invoked compress through the write tool with path "xd://compress" and
|
|
39
|
+
* the tool args JSON-encoded in the content field. Both shapes must replay
|
|
40
|
+
* from the stream. Returns normalized compress args (content array plus
|
|
41
|
+
* optional topic / summaryMaxChars from wherever they live). */
|
|
42
|
+
export declare function compressToolArgs(call: {
|
|
43
|
+
name: string;
|
|
44
|
+
arguments?: unknown;
|
|
45
|
+
}): {
|
|
46
|
+
content: unknown[];
|
|
47
|
+
topic?: unknown;
|
|
48
|
+
summaryMaxChars?: unknown;
|
|
49
|
+
} | null;
|
|
50
|
+
/** toolCallId → toolName for every tool-call piece (protected-piece
|
|
51
|
+
* detection: compress + configured tools are never folded). */
|
|
52
|
+
export declare function toolCallNames(msgs: BiliMessage[]): Map<string, string>;
|
|
53
|
+
/** toolCallId → result text for every tool-result piece (compress result
|
|
54
|
+
* rendering inside rebuilt payloads). */
|
|
55
|
+
export declare function toolResultTextsCore(msgs: BiliMessage[]): Map<string, string>;
|
|
56
|
+
/** Compress calls carried by a core tool-call piece. Same two shapes as the
|
|
57
|
+
* AgentMessage stream (direct compress; legacy xd://compress via write),
|
|
58
|
+
* with the arguments JSON-encoded in the piece's text. */
|
|
59
|
+
export declare function findCompressCallsCore(msg: BiliMessage): StreamCompressCall[];
|
|
60
|
+
/** Content key of a core piece for span fingerprints (issue #91): role,
|
|
61
|
+
* contentType, toolName and the FIRST 4096 chars of text. The 4096 cap is
|
|
62
|
+
* deliberate: a host re-serialization that drifts only the tail (beyond
|
|
63
|
+
* char 4096, e.g. truncation of a long tool output) keeps the key intact,
|
|
64
|
+
* so the replay guard tells a benign tail drift from a genuine rewrite. */
|
|
65
|
+
export declare function corePieceKey(cm: CoreMessage): string;
|
|
66
|
+
/** Span fingerprint in content-hash space: hash the content keys of the
|
|
67
|
+
* exact first/last covered pieces. Boundary ids are pre-resolved (byRef /
|
|
68
|
+
* block lookup) — unlike the pN-space spanFingerprint there is no position
|
|
69
|
+
* parsing, ids are unique per piece. */
|
|
70
|
+
export declare function spanFingerprintCore(coreMessages: CoreMessage[], startId: string, endId: string): string;
|
|
71
|
+
/** Index-based span fingerprint (issue #91 replay fallback): hash the content
|
|
72
|
+
* keys of the pieces AT the given stream positions. The stored fp still
|
|
73
|
+
* decides keep/drop — the position is only a recovery hint for a drifted
|
|
74
|
+
* boundary whose content-hash id no longer matches, so a benign tail drift
|
|
75
|
+
* (first-4096 intact) is kept while a real rewrite mismatches. */
|
|
76
|
+
export declare function spanFingerprintCoreIdx(coreMessages: CoreMessage[], startIdx: number, endIdx: number): string;
|
|
77
|
+
/** Structural subset the boundary resolvers need from a compression block
|
|
78
|
+
* (kernel CompressionBlock satisfies this; keeps the guard usable from
|
|
79
|
+
* downstreams that carry lighter block records). */
|
|
80
|
+
export interface BlockLike {
|
|
81
|
+
blockId: string;
|
|
82
|
+
effectiveMessageIds: string[];
|
|
83
|
+
}
|
|
84
|
+
/** Resolve a range boundary to the exact id of the piece it names, in
|
|
85
|
+
* content-hash space. Message refs go through byRef; block refs resolve to
|
|
86
|
+
* the earliest (min) or latest (max) covered piece by STREAM ORDER
|
|
87
|
+
* (index in coreMessages — the hash ids carry no position). */
|
|
88
|
+
export declare function boundaryRawCore(ref: string, byRef: Record<string, string>, blocks: BlockLike[], coreMessages: CoreMessage[], pick: "min" | "max"): string;
|
|
89
|
+
/** Resolve a range boundary to its STREAM INDEX in content-hash space. byRef /
|
|
90
|
+
* block lookup first (the exact piece it names, by array order); on a missed
|
|
91
|
+
* id (a drift re-hashed the piece so its carried ref dangles) fall back to
|
|
92
|
+
* the compress-time recorded index — the position hint, issue #91. -1 =
|
|
93
|
+
* unresolvable. */
|
|
94
|
+
export declare function boundaryIndexCore(ref: string, byRef: Record<string, string>, blocks: BlockLike[], coreMessages: CoreMessage[], pick: "min" | "max", fallbackIdx?: number): number;
|
|
95
|
+
/** Structured replay-guard verdict (issue #91, rework): the position
|
|
96
|
+
* fallback recovers the STREAM INDEX of a drifted boundary, but the kernel
|
|
97
|
+
* resolves ranges by REF — so when a recorded m-ref dangles, the replay
|
|
98
|
+
* must re-apply that boundary under the CURRENT ref of the recovered piece.
|
|
99
|
+
* `remap` carries exactly that (only dangling m-refs are remapped; block
|
|
100
|
+
* refs resolve themselves inside the kernel and are never touched). */
|
|
101
|
+
export type ReplayRangeVerdict = {
|
|
102
|
+
/** Stale: the range must be dropped (master semantics, unchanged). */
|
|
103
|
+
reject?: string;
|
|
104
|
+
/** Dangling m-refs recovered by position, remapped to current refs. */
|
|
105
|
+
remap?: {
|
|
106
|
+
startRef?: string;
|
|
107
|
+
endRef?: string;
|
|
108
|
+
};
|
|
109
|
+
/** True when the result text carried a [pos=] pair for this range —
|
|
110
|
+
* with `reject` set it marks a RECOVERY FAILURE (always logged). */
|
|
111
|
+
hint?: boolean;
|
|
112
|
+
/** Diagnostics — always logged when a recovery happens. */
|
|
113
|
+
recovered?: {
|
|
114
|
+
pos: string;
|
|
115
|
+
startIdx: number;
|
|
116
|
+
endIdx: number;
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
/** Current m-ref of the piece at stream index idx (inverse byRef scan).
|
|
120
|
+
* "" when the piece has no ref (protected) — the replay must fail closed
|
|
121
|
+
* rather than hand the kernel a ref it does not know. Replay-time only
|
|
122
|
+
* (replayed compress calls), so the O(refs) scan stays off the hot path. */
|
|
123
|
+
export declare function refOfPieceCore(coreMessages: BiliMessage[], idx: number, byRef: Record<string, string>): string;
|
|
124
|
+
export declare function staleRangeCore(r: {
|
|
125
|
+
startRef: string;
|
|
126
|
+
endRef: string;
|
|
127
|
+
}, rangeIndex: number, resultText: string, coreMessages: BiliMessage[], callIndex: number, byRef: Record<string, string>, blocks: BlockLike[]): ReplayRangeVerdict;
|
|
128
|
+
/** One fingerprint per range for the replay guard, content-hash space
|
|
129
|
+
* (mirrors rangeFingerprints for the pN space). */
|
|
130
|
+
export declare function rangeFingerprintsCore(ranges: Array<{
|
|
131
|
+
startRef: string;
|
|
132
|
+
endRef: string;
|
|
133
|
+
}>, coreMessages: BiliMessage[], byRef: Record<string, string>, blocks: BlockLike[]): string[];
|
|
134
|
+
/** One boundary-index pair per range for the replay fallback (issue #91),
|
|
135
|
+
* aligned with rangeFingerprintsCore: the stream index of each range's exact
|
|
136
|
+
* first/last covered piece at record time ("-1" pair when a boundary can't
|
|
137
|
+
* be positioned), so the replay can recover a drifted boundary by position. */
|
|
138
|
+
export declare function rangePositionsCore(ranges: Array<{
|
|
139
|
+
startRef: string;
|
|
140
|
+
endRef: string;
|
|
141
|
+
}>, coreMessages: CoreMessage[], byRef: Record<string, string>, blocks: BlockLike[]): string[];
|
|
142
|
+
//# sourceMappingURL=compress-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress-detect.d.ts","sourceRoot":"","sources":["../../src/wire/compress-detect.ts"],"names":[],"mappings":"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"}
|
package/dist/wire/index.d.ts
CHANGED
package/dist/wire/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/wire/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/wire/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC"}
|
package/dist/wire/index.js
CHANGED
|
@@ -919,15 +919,194 @@ function mirrorResponsesToCore(view, systemText) {
|
|
|
919
919
|
});
|
|
920
920
|
return msgs;
|
|
921
921
|
}
|
|
922
|
+
|
|
923
|
+
// src/wire/compress-detect.ts
|
|
924
|
+
import { createHash as createHash2 } from "crypto";
|
|
925
|
+
function compressToolArgs(call) {
|
|
926
|
+
let args = call.arguments;
|
|
927
|
+
if (typeof args === "string") {
|
|
928
|
+
try {
|
|
929
|
+
args = JSON.parse(args);
|
|
930
|
+
} catch {
|
|
931
|
+
return null;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
if (!args || typeof args !== "object" || Array.isArray(args)) return null;
|
|
935
|
+
const a = args;
|
|
936
|
+
if (call.name === "compress") {
|
|
937
|
+
return Array.isArray(a.content) ? { content: a.content, topic: a.topic, summaryMaxChars: a.summaryMaxChars } : null;
|
|
938
|
+
}
|
|
939
|
+
if (call.name !== "write") return null;
|
|
940
|
+
const path = typeof a.path === "string" ? a.path.split("?")[0].replace(/\/+$/, "") : "";
|
|
941
|
+
if (path !== "xd://compress") return null;
|
|
942
|
+
let inner = a.content;
|
|
943
|
+
if (typeof inner === "string") {
|
|
944
|
+
try {
|
|
945
|
+
inner = JSON.parse(inner);
|
|
946
|
+
} catch {
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
if (!inner || typeof inner !== "object") return null;
|
|
951
|
+
if (Array.isArray(inner)) return { content: inner };
|
|
952
|
+
const ia = inner;
|
|
953
|
+
return Array.isArray(ia.content) ? { content: ia.content, topic: ia.topic, summaryMaxChars: ia.summaryMaxChars } : { content: [ia] };
|
|
954
|
+
}
|
|
955
|
+
function toolCallNames(msgs) {
|
|
956
|
+
const names = /* @__PURE__ */ new Map();
|
|
957
|
+
for (const m of msgs) {
|
|
958
|
+
if (m.contentType === "tool-call" && m.toolCallId && m.toolName) names.set(m.toolCallId, m.toolName);
|
|
959
|
+
}
|
|
960
|
+
return names;
|
|
961
|
+
}
|
|
962
|
+
function toolResultTextsCore(msgs) {
|
|
963
|
+
const results = /* @__PURE__ */ new Map();
|
|
964
|
+
for (const m of msgs) {
|
|
965
|
+
if (m.contentType !== "tool-result" || !m.toolCallId) continue;
|
|
966
|
+
results.set(m.toolCallId, m.text ?? "");
|
|
967
|
+
}
|
|
968
|
+
return results;
|
|
969
|
+
}
|
|
970
|
+
function findCompressCallsCore(msg) {
|
|
971
|
+
if (msg.contentType !== "tool-call" || !msg.toolName) return [];
|
|
972
|
+
const args = compressToolArgs({ name: msg.toolName, arguments: msg.text });
|
|
973
|
+
if (!args) return [];
|
|
974
|
+
const content = args.content;
|
|
975
|
+
if (!Array.isArray(content)) return [];
|
|
976
|
+
const ranges = [];
|
|
977
|
+
const callTopic = typeof args.topic === "string" ? args.topic : void 0;
|
|
978
|
+
for (const item of content) {
|
|
979
|
+
const r = item;
|
|
980
|
+
if (typeof r.startId !== "string" || typeof r.endId !== "string" || typeof r.summary !== "string" || r.summary.length === 0) continue;
|
|
981
|
+
ranges.push({
|
|
982
|
+
startRef: r.startId,
|
|
983
|
+
endRef: r.endId,
|
|
984
|
+
summary: r.summary,
|
|
985
|
+
topic: typeof r.topic === "string" ? r.topic : callTopic,
|
|
986
|
+
summaryMaxChars: typeof args.summaryMaxChars === "number" ? args.summaryMaxChars : void 0,
|
|
987
|
+
compressCallId: msg.toolCallId ?? ""
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
return ranges.length > 0 ? [{ id: msg.toolCallId ?? "", ranges }] : [];
|
|
991
|
+
}
|
|
992
|
+
function corePieceKey(cm) {
|
|
993
|
+
return `${cm.role}|${cm.contentType}|${cm.toolName ?? ""}|${(cm.text ?? "").slice(0, 4096)}`;
|
|
994
|
+
}
|
|
995
|
+
function spanFingerprintCore(coreMessages, startId, endId) {
|
|
996
|
+
const find = (id) => coreMessages.find((cm) => cm.id === id);
|
|
997
|
+
const first = find(startId);
|
|
998
|
+
const last = find(endId);
|
|
999
|
+
if (!first || !last) return "";
|
|
1000
|
+
return createHash2("sha1").update(`${corePieceKey(first)}\0${corePieceKey(last)}`).digest("hex").slice(0, 8);
|
|
1001
|
+
}
|
|
1002
|
+
function spanFingerprintCoreIdx(coreMessages, startIdx, endIdx) {
|
|
1003
|
+
const first = coreMessages[startIdx];
|
|
1004
|
+
const last = coreMessages[endIdx];
|
|
1005
|
+
if (!first || !last) return "";
|
|
1006
|
+
return createHash2("sha1").update(`${corePieceKey(first)}\0${corePieceKey(last)}`).digest("hex").slice(0, 8);
|
|
1007
|
+
}
|
|
1008
|
+
function boundaryRawCore(ref, byRef, blocks, coreMessages, pick) {
|
|
1009
|
+
const raw = byRef[ref];
|
|
1010
|
+
if (raw) return raw;
|
|
1011
|
+
const m = /^b(\d+)$/i.exec(ref.trim());
|
|
1012
|
+
if (!m) return "";
|
|
1013
|
+
const block = blocks.find((b) => b.blockId.toLowerCase() === `b${m[1]}`);
|
|
1014
|
+
if (!block) return "";
|
|
1015
|
+
const idx = (id) => coreMessages.findIndex((cm) => cm.id === (byRef[id] ?? id));
|
|
1016
|
+
let best = -1;
|
|
1017
|
+
for (const id of block.effectiveMessageIds) {
|
|
1018
|
+
const i = idx(id);
|
|
1019
|
+
if (i < 0) continue;
|
|
1020
|
+
if (best < 0 || (pick === "min" ? i < best : i > best)) best = i;
|
|
1021
|
+
}
|
|
1022
|
+
return best < 0 ? "" : coreMessages[best]?.id ?? "";
|
|
1023
|
+
}
|
|
1024
|
+
function boundaryIndexCore(ref, byRef, blocks, coreMessages, pick, fallbackIdx = -1) {
|
|
1025
|
+
const id = boundaryRawCore(ref, byRef, blocks, coreMessages, pick);
|
|
1026
|
+
if (id) {
|
|
1027
|
+
const i = coreMessages.findIndex((cm) => cm.id === id);
|
|
1028
|
+
if (i >= 0) return i;
|
|
1029
|
+
}
|
|
1030
|
+
return fallbackIdx >= 0 && fallbackIdx < coreMessages.length ? fallbackIdx : -1;
|
|
1031
|
+
}
|
|
1032
|
+
function refOfPieceCore(coreMessages, idx, byRef) {
|
|
1033
|
+
const id = coreMessages[idx]?.id;
|
|
1034
|
+
if (!id) return "";
|
|
1035
|
+
for (const [ref, mapped] of Object.entries(byRef)) if (mapped === id) return ref;
|
|
1036
|
+
return "";
|
|
1037
|
+
}
|
|
1038
|
+
function staleRangeCore(r, rangeIndex, resultText, coreMessages, callIndex, byRef, blocks) {
|
|
1039
|
+
const pm = resultText.match(/\[pos=([0-9,-]+)\]/);
|
|
1040
|
+
const pair = pm ? pm[1].split(",")[rangeIndex] ?? "-" : "-";
|
|
1041
|
+
const hinted = pair !== "-";
|
|
1042
|
+
const [ps, pe] = pair === "-" ? ["", ""] : pair.split("-");
|
|
1043
|
+
const fbStart = ps && ps !== "" ? Number.parseInt(ps, 10) : -1;
|
|
1044
|
+
const fbEnd = pe && pe !== "" ? Number.parseInt(pe, 10) : -1;
|
|
1045
|
+
const startRaw = boundaryRawCore(r.startRef, byRef, blocks, coreMessages, "min");
|
|
1046
|
+
const endRaw = boundaryRawCore(r.endRef, byRef, blocks, coreMessages, "max");
|
|
1047
|
+
const rawStartIdx = startRaw ? coreMessages.findIndex((cm) => cm.id === startRaw) : -1;
|
|
1048
|
+
const rawEndIdx = endRaw ? coreMessages.findIndex((cm) => cm.id === endRaw) : -1;
|
|
1049
|
+
const startIdx = rawStartIdx >= 0 ? rawStartIdx : fbStart >= 0 && fbStart < coreMessages.length ? fbStart : -1;
|
|
1050
|
+
const endIdx = rawEndIdx >= 0 ? rawEndIdx : fbEnd >= 0 && fbEnd < coreMessages.length ? fbEnd : -1;
|
|
1051
|
+
if (startIdx < 0 || endIdx < 0) {
|
|
1052
|
+
if (!/^b\d+$/i.test(r.startRef.trim()) && !/^b\d+$/i.test(r.endRef.trim()))
|
|
1053
|
+
return { reject: `unresolved ${r.startRef}..${r.endRef} -> ${startIdx}..${endIdx}`, ...hinted ? { hint: true } : {} };
|
|
1054
|
+
return {};
|
|
1055
|
+
}
|
|
1056
|
+
if (endIdx > callIndex) return { reject: `end idx ${endIdx} > callIndex ${callIndex}`, ...hinted ? { hint: true } : {} };
|
|
1057
|
+
const m = resultText.match(/\[fp=([0-9a-f,-]+)\]/);
|
|
1058
|
+
if (m) {
|
|
1059
|
+
const want = m[1].split(",")[rangeIndex];
|
|
1060
|
+
if (want !== void 0 && want !== "-") {
|
|
1061
|
+
const got = spanFingerprintCoreIdx(coreMessages, startIdx, endIdx);
|
|
1062
|
+
if (want !== got) return { reject: `fp ${r.startRef}..${r.endRef} want ${want} got ${got} @${startIdx}..${endIdx}`, ...hinted ? { hint: true } : {} };
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
const remap = {};
|
|
1066
|
+
if (/^m\d+$/i.test(r.startRef.trim()) && rawStartIdx < 0) {
|
|
1067
|
+
const ref = refOfPieceCore(coreMessages, startIdx, byRef);
|
|
1068
|
+
if (!ref) return { reject: `recovered ${r.startRef} @${startIdx} has no ref (protected piece)`, ...hinted ? { hint: true } : {} };
|
|
1069
|
+
remap.startRef = ref;
|
|
1070
|
+
}
|
|
1071
|
+
if (/^m\d+$/i.test(r.endRef.trim()) && rawEndIdx < 0) {
|
|
1072
|
+
const ref = refOfPieceCore(coreMessages, endIdx, byRef);
|
|
1073
|
+
if (!ref) return { reject: `recovered ${r.endRef} @${endIdx} has no ref (protected piece)`, ...hinted ? { hint: true } : {} };
|
|
1074
|
+
remap.endRef = ref;
|
|
1075
|
+
}
|
|
1076
|
+
if (!remap.startRef && !remap.endRef) return {};
|
|
1077
|
+
return { remap, recovered: { pos: pair, startIdx, endIdx } };
|
|
1078
|
+
}
|
|
1079
|
+
function rangeFingerprintsCore(ranges, coreMessages, byRef, blocks) {
|
|
1080
|
+
return ranges.map((r) => {
|
|
1081
|
+
const start = boundaryRawCore(r.startRef, byRef, blocks, coreMessages, "min");
|
|
1082
|
+
const end = start ? boundaryRawCore(r.endRef, byRef, blocks, coreMessages, "max") : "";
|
|
1083
|
+
if (start && end) {
|
|
1084
|
+
const fp = spanFingerprintCore(coreMessages, start, end);
|
|
1085
|
+
if (fp.length > 0) return fp;
|
|
1086
|
+
}
|
|
1087
|
+
return "-";
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
function rangePositionsCore(ranges, coreMessages, byRef, blocks) {
|
|
1091
|
+
return ranges.map((r) => {
|
|
1092
|
+
const s = boundaryIndexCore(r.startRef, byRef, blocks, coreMessages, "min");
|
|
1093
|
+
const e = s >= 0 ? boundaryIndexCore(r.endRef, byRef, blocks, coreMessages, "max") : -1;
|
|
1094
|
+
return s >= 0 && e >= 0 ? `${s}-${e}` : "-";
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
922
1097
|
export {
|
|
923
1098
|
ClusterCounter,
|
|
924
1099
|
WIRE_FORMATS,
|
|
925
1100
|
anthropicToCore,
|
|
1101
|
+
boundaryIndexCore,
|
|
1102
|
+
boundaryRawCore,
|
|
926
1103
|
buildSystem,
|
|
1104
|
+
compressToolArgs,
|
|
927
1105
|
conversationIdentityResponses,
|
|
928
1106
|
conversationSignalAnthropic,
|
|
929
1107
|
conversationSignalOpenai,
|
|
930
1108
|
conversationSignalResponses,
|
|
1109
|
+
corePieceKey,
|
|
931
1110
|
coreToAnthropic,
|
|
932
1111
|
coreToOpenai,
|
|
933
1112
|
coreToResponses,
|
|
@@ -935,6 +1114,7 @@ export {
|
|
|
935
1114
|
deriveMessageId,
|
|
936
1115
|
detectWireFormat,
|
|
937
1116
|
extractSystem,
|
|
1117
|
+
findCompressCallsCore,
|
|
938
1118
|
hashId,
|
|
939
1119
|
injectOpenaiSystem,
|
|
940
1120
|
injectResponsesDeveloperMessage,
|
|
@@ -948,9 +1128,17 @@ export {
|
|
|
948
1128
|
openaiToCore,
|
|
949
1129
|
parseDataUrl,
|
|
950
1130
|
patchResponsesInput,
|
|
1131
|
+
rangeFingerprintsCore,
|
|
1132
|
+
rangePositionsCore,
|
|
1133
|
+
refOfPieceCore,
|
|
951
1134
|
responsesToCore,
|
|
1135
|
+
spanFingerprintCore,
|
|
1136
|
+
spanFingerprintCoreIdx,
|
|
952
1137
|
splitDemotedThinking,
|
|
1138
|
+
staleRangeCore,
|
|
953
1139
|
subagentNamespace,
|
|
954
|
-
toCoreMessages
|
|
1140
|
+
toCoreMessages,
|
|
1141
|
+
toolCallNames,
|
|
1142
|
+
toolResultTextsCore
|
|
955
1143
|
};
|
|
956
1144
|
//# sourceMappingURL=index.js.map
|