billion-context-omp 0.2.7 → 0.2.9
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/index.js +247 -94
- package/dist/index.js.map +1 -1
- package/dist/wire-fold.d.ts +27 -3
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -395,8 +395,13 @@ function resolveBoundaries(input) {
|
|
|
395
395
|
input.messages.forEach(
|
|
396
396
|
(message, index) => indexByRawId.set(message.id, index)
|
|
397
397
|
);
|
|
398
|
-
let
|
|
399
|
-
|
|
398
|
+
let snappedBoundaries = [];
|
|
399
|
+
const startAnchor = resolveAnchorIndex(start, input.state, indexByRawId, "start");
|
|
400
|
+
if (startAnchor.snapped) snappedBoundaries.push(startAnchor.snapped);
|
|
401
|
+
const endAnchor = resolveAnchorIndex(end, input.state, indexByRawId, "end");
|
|
402
|
+
if (endAnchor.snapped) snappedBoundaries.push(endAnchor.snapped);
|
|
403
|
+
let startIndex = startAnchor.index;
|
|
404
|
+
let endIndex = endAnchor.index;
|
|
400
405
|
if (startIndex > endIndex) {
|
|
401
406
|
[startIndex, endIndex] = [endIndex, startIndex];
|
|
402
407
|
}
|
|
@@ -424,7 +429,8 @@ function resolveBoundaries(input) {
|
|
|
424
429
|
messageIds,
|
|
425
430
|
nestedBlockIds,
|
|
426
431
|
boundaryKind,
|
|
427
|
-
protectedGaps
|
|
432
|
+
protectedGaps,
|
|
433
|
+
snappedBoundaries
|
|
428
434
|
};
|
|
429
435
|
}
|
|
430
436
|
function resolveAnchorIndex(boundary, state, indexByRawId, endpoint) {
|
|
@@ -439,14 +445,21 @@ function resolveAnchorIndex(boundary, state, indexByRawId, endpoint) {
|
|
|
439
445
|
);
|
|
440
446
|
}
|
|
441
447
|
const index = indexByRawId.get(rawId);
|
|
442
|
-
if (index
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
+
if (index !== void 0) {
|
|
449
|
+
return { index, snapped: null };
|
|
450
|
+
}
|
|
451
|
+
const owner2 = activeOwnerAnchor(state, [rawId], indexByRawId);
|
|
452
|
+
if (owner2 !== null) {
|
|
453
|
+
return {
|
|
454
|
+
index: owner2,
|
|
455
|
+
snapped: `${label}="${boundary.raw}" refers to a message already compressed into an active block \u2014 anchored to that block's summary instead.`
|
|
456
|
+
};
|
|
448
457
|
}
|
|
449
|
-
|
|
458
|
+
throw new BoundaryNotFoundError(
|
|
459
|
+
"consumed",
|
|
460
|
+
endpoint,
|
|
461
|
+
`${label}="${boundary.raw}" not found in visible context (likely consumed by an existing block).`
|
|
462
|
+
);
|
|
450
463
|
}
|
|
451
464
|
const block = blockById(state, `b${boundary.numericId}`);
|
|
452
465
|
if (!block) {
|
|
@@ -456,6 +469,19 @@ function resolveAnchorIndex(boundary, state, indexByRawId, endpoint) {
|
|
|
456
469
|
`${label}="b${boundary.numericId}" does not exist in this session (typo or wrong session) \u2014 run acp_status for current refs.`
|
|
457
470
|
);
|
|
458
471
|
}
|
|
472
|
+
if (block.active) {
|
|
473
|
+
const anchor = earliestIndexOfIds(block.effectiveMessageIds, indexByRawId);
|
|
474
|
+
if (anchor !== null) {
|
|
475
|
+
return { index: anchor, snapped: null };
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
const owner = activeOwnerAnchor(state, block.effectiveMessageIds, indexByRawId);
|
|
479
|
+
if (owner !== null) {
|
|
480
|
+
return {
|
|
481
|
+
index: owner,
|
|
482
|
+
snapped: `${label}="b${boundary.numericId}" was consumed by a higher-tier block \u2014 anchored to the active block covering its content instead.`
|
|
483
|
+
};
|
|
484
|
+
}
|
|
459
485
|
if (!block.active) {
|
|
460
486
|
throw new BoundaryNotFoundError(
|
|
461
487
|
"consumed",
|
|
@@ -463,15 +489,26 @@ function resolveAnchorIndex(boundary, state, indexByRawId, endpoint) {
|
|
|
463
489
|
`${label}="b${boundary.numericId}" not found in visible context (block distilled/consumed by a higher-tier block).`
|
|
464
490
|
);
|
|
465
491
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
492
|
+
throw new BoundaryNotFoundError(
|
|
493
|
+
"consumed",
|
|
494
|
+
endpoint,
|
|
495
|
+
`${label}="b${boundary.numericId}" not found in visible context (block messages consumed by a higher-tier block).`
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
function activeOwnerAnchor(state, ownedIds, indexByRawId) {
|
|
499
|
+
if (ownedIds.length === 0) return null;
|
|
500
|
+
const owned = new Set(ownedIds);
|
|
501
|
+
let best = null;
|
|
502
|
+
for (const block of state.blocks) {
|
|
503
|
+
if (!block.active) continue;
|
|
504
|
+
const anchor = earliestIndexOfIds(block.effectiveMessageIds, indexByRawId);
|
|
505
|
+
if (anchor === null) continue;
|
|
506
|
+
const ownsContent = block.effectiveMessageIds.some((id) => owned.has(id));
|
|
507
|
+
if (ownsContent && (best === null || anchor < best)) {
|
|
508
|
+
best = anchor;
|
|
509
|
+
}
|
|
473
510
|
}
|
|
474
|
-
return
|
|
511
|
+
return best;
|
|
475
512
|
}
|
|
476
513
|
function formatPaddedRef(index) {
|
|
477
514
|
return `m${String(index).padStart(5, "0")}`;
|
|
@@ -748,12 +785,6 @@ function renderMessage(message, map, countTokens, strategy, snapshot = null) {
|
|
|
748
785
|
if (!cleanText) return { ...message, text: prefix };
|
|
749
786
|
return { ...message, text: prefix + cleanText };
|
|
750
787
|
}
|
|
751
|
-
function renderVisibleRefs(messages, state, countTokens = (text) => Math.ceil(text.length / 4), strategy = "all") {
|
|
752
|
-
const map = state.messageRefs;
|
|
753
|
-
return messages.map(
|
|
754
|
-
(message) => renderMessage(message, map, countTokens, strategy)
|
|
755
|
-
);
|
|
756
|
-
}
|
|
757
788
|
function renderWithSnapshot(messages, state, countTokens = (text) => Math.ceil(text.length / 4), strategy = "all") {
|
|
758
789
|
const map = state.messageRefs;
|
|
759
790
|
const snapshot = { ...state.tokenSnapshot ?? {} };
|
|
@@ -1098,6 +1129,10 @@ function runPipeline(nodes, initial, ctx) {
|
|
|
1098
1129
|
function rangeError(spec, message) {
|
|
1099
1130
|
return `range ${spec.startRef}..${spec.endRef}: ${message}`;
|
|
1100
1131
|
}
|
|
1132
|
+
function numericBlockId(id) {
|
|
1133
|
+
const parsed = /^b(\d+)$/.exec(id);
|
|
1134
|
+
return parsed ? Number(parsed[1]) : 0;
|
|
1135
|
+
}
|
|
1101
1136
|
function createCore(ports = {}) {
|
|
1102
1137
|
const countTokens = ports.countTokens ?? defaultCountTokens;
|
|
1103
1138
|
function applyCompression(input) {
|
|
@@ -1143,6 +1178,12 @@ function createCore(ports = {}) {
|
|
|
1143
1178
|
}
|
|
1144
1179
|
}
|
|
1145
1180
|
}
|
|
1181
|
+
let resolvableCount = 0;
|
|
1182
|
+
let unknownCount = 0;
|
|
1183
|
+
for (const resolution of classifications.values()) {
|
|
1184
|
+
if (resolution.status === "ok") resolvableCount++;
|
|
1185
|
+
else if (resolution.status === "unknown") unknownCount++;
|
|
1186
|
+
}
|
|
1146
1187
|
const rangeIndexSets = [];
|
|
1147
1188
|
for (const [spec, resolution] of classifications) {
|
|
1148
1189
|
if (resolution.status !== "ok") continue;
|
|
@@ -1187,7 +1228,9 @@ function createCore(ports = {}) {
|
|
|
1187
1228
|
}
|
|
1188
1229
|
}
|
|
1189
1230
|
if (!hasBlockBoundaryRange && totalRangeChars < input.config.compress.minCompressRange) {
|
|
1190
|
-
const
|
|
1231
|
+
const live = activeBlocks(state).map((b) => b.blockId).sort((x, y) => numericBlockId(x) - numericBlockId(y));
|
|
1232
|
+
const liveHint = live.length > 0 ? ` Current active blocks span ${live[0]}..${live[live.length - 1]} \u2014 retry with startId/endId set to active block IDs in that span.` : "";
|
|
1233
|
+
const gateMessage = resolvableCount === 0 && consumedRanges.length === 0 && unknownCount > 0 ? `None of the ${input.ranges.length} requested range(s) resolved \u2014 every ref failed with "does not exist in this session". Refs recorded before an earlier compress are stale: each successful compress renumbers the remaining refs. Run acp_status, then re-issue the compress in the same turn using only the refs it reports.` : 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.${liveHint}` : `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.`;
|
|
1191
1234
|
return {
|
|
1192
1235
|
state: input.state,
|
|
1193
1236
|
result: {
|
|
@@ -1213,6 +1256,7 @@ function createCore(ports = {}) {
|
|
|
1213
1256
|
errors.push(rangeError(spec, resolution.error.message));
|
|
1214
1257
|
continue;
|
|
1215
1258
|
}
|
|
1259
|
+
warnings.push(...resolution.resolved.snappedBoundaries);
|
|
1216
1260
|
try {
|
|
1217
1261
|
const outcome = applySingleRange({
|
|
1218
1262
|
spec,
|
|
@@ -2428,24 +2472,6 @@ function renderCompressedDrilldown(blocks, state, sort, limit, countTokens) {
|
|
|
2428
2472
|
}
|
|
2429
2473
|
return lines.join("\n");
|
|
2430
2474
|
}
|
|
2431
|
-
var substringAlgorithm = {
|
|
2432
|
-
name: "substring",
|
|
2433
|
-
description: "Exact substring counting (original baseline). Predictable, no normalization.",
|
|
2434
|
-
score(docs, query) {
|
|
2435
|
-
const terms = query.toLowerCase().trim().split(/\s+/).filter((t) => t.length > 0);
|
|
2436
|
-
if (terms.length === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
|
|
2437
|
-
return docs.map((d) => {
|
|
2438
|
-
const haystack = d.text.toLowerCase();
|
|
2439
|
-
let score = 0;
|
|
2440
|
-
for (const term of terms) score += countOccurrences2(haystack, term);
|
|
2441
|
-
return { ref: d.ref, score };
|
|
2442
|
-
});
|
|
2443
|
-
}
|
|
2444
|
-
};
|
|
2445
|
-
function countOccurrences2(haystack, needle) {
|
|
2446
|
-
if (!needle) return 0;
|
|
2447
|
-
return haystack.split(needle).length - 1;
|
|
2448
|
-
}
|
|
2449
2475
|
function stem(word) {
|
|
2450
2476
|
let w = word;
|
|
2451
2477
|
if (w.length <= 3) return w;
|
|
@@ -2464,8 +2490,17 @@ function stem(word) {
|
|
|
2464
2490
|
return w;
|
|
2465
2491
|
}
|
|
2466
2492
|
var CJK = /[\u3400-\u9fff\uf900-\ufaff\u3040-\u30ff\uac00-\ud7af]/;
|
|
2467
|
-
var CJK_RUN = new RegExp(`${CJK.source}+`, "g");
|
|
2468
2493
|
var LATIN_WORD = /[a-z][a-z0-9_]*[a-z0-9]|[a-z0-9]/g;
|
|
2494
|
+
var cjkSegmenter = new Intl.Segmenter("zh", { granularity: "word" });
|
|
2495
|
+
function cjkRunTokens(segs) {
|
|
2496
|
+
const words = segs.filter((w) => w.length >= 2);
|
|
2497
|
+
if (words.length > 0) return words;
|
|
2498
|
+
const run = segs.join("");
|
|
2499
|
+
const out = [];
|
|
2500
|
+
for (let i = 0; i < run.length - 1; i++) out.push(run.slice(i, i + 2));
|
|
2501
|
+
for (const ch of run) out.push(ch);
|
|
2502
|
+
return out;
|
|
2503
|
+
}
|
|
2469
2504
|
function tokenize(text, opts = {}) {
|
|
2470
2505
|
const lower = text.toLowerCase();
|
|
2471
2506
|
const tokens = [];
|
|
@@ -2476,15 +2511,23 @@ function tokenize(text, opts = {}) {
|
|
|
2476
2511
|
tokens.push(w);
|
|
2477
2512
|
}
|
|
2478
2513
|
}
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2514
|
+
if (!CJK.test(lower)) return tokens;
|
|
2515
|
+
const runSegs = [];
|
|
2516
|
+
let cur = null;
|
|
2517
|
+
for (const s of cjkSegmenter.segment(lower)) {
|
|
2518
|
+
const t = s.segment;
|
|
2519
|
+
if (t.length === 0) continue;
|
|
2520
|
+
if (CJK.test(t)) {
|
|
2521
|
+
(cur ??= []).push(t);
|
|
2522
|
+
} else if (cur) {
|
|
2523
|
+
runSegs.push(cur);
|
|
2524
|
+
cur = null;
|
|
2486
2525
|
}
|
|
2487
2526
|
}
|
|
2527
|
+
if (cur) runSegs.push(cur);
|
|
2528
|
+
for (const segs of runSegs) {
|
|
2529
|
+
tokens.push(...cjkRunTokens(segs));
|
|
2530
|
+
}
|
|
2488
2531
|
return tokens;
|
|
2489
2532
|
}
|
|
2490
2533
|
function charBigrams(text) {
|
|
@@ -2500,6 +2543,50 @@ function tfMap(text, stem22) {
|
|
|
2500
2543
|
for (const t of tokenize(text, { stem: stem22 })) m.set(t, (m.get(t) ?? 0) + 1);
|
|
2501
2544
|
return m;
|
|
2502
2545
|
}
|
|
2546
|
+
var DEFAULT_CAP_CHARS = 8 * 1024 * 1024;
|
|
2547
|
+
var capChars = DEFAULT_CAP_CHARS;
|
|
2548
|
+
var cache = /* @__PURE__ */ new Map();
|
|
2549
|
+
var cachedChars = 0;
|
|
2550
|
+
function build(text) {
|
|
2551
|
+
const tf = tfMap(text, true);
|
|
2552
|
+
let len = 0;
|
|
2553
|
+
for (const v of tf.values()) len += v;
|
|
2554
|
+
const lower = text.toLowerCase();
|
|
2555
|
+
return { tf, len, lower, grams: new Set(charBigrams(lower)) };
|
|
2556
|
+
}
|
|
2557
|
+
function docFeatures(text) {
|
|
2558
|
+
const hit = cache.get(text);
|
|
2559
|
+
if (hit) return hit;
|
|
2560
|
+
const f = build(text);
|
|
2561
|
+
if (text.length > 0 && text.length <= capChars) {
|
|
2562
|
+
while (cachedChars + text.length > capChars && cache.size > 0) {
|
|
2563
|
+
const k = cache.keys().next().value;
|
|
2564
|
+
cachedChars -= k.length;
|
|
2565
|
+
cache.delete(k);
|
|
2566
|
+
}
|
|
2567
|
+
cache.set(text, f);
|
|
2568
|
+
cachedChars += text.length;
|
|
2569
|
+
}
|
|
2570
|
+
return f;
|
|
2571
|
+
}
|
|
2572
|
+
var substringAlgorithm = {
|
|
2573
|
+
name: "substring",
|
|
2574
|
+
description: "Exact substring counting (original baseline). Predictable, no normalization.",
|
|
2575
|
+
score(docs, query) {
|
|
2576
|
+
const terms = query.toLowerCase().trim().split(/\s+/).filter((t) => t.length > 0);
|
|
2577
|
+
if (terms.length === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
|
|
2578
|
+
return docs.map((d) => {
|
|
2579
|
+
const haystack = docFeatures(d.text).lower;
|
|
2580
|
+
let score = 0;
|
|
2581
|
+
for (const term of terms) score += countOccurrences2(haystack, term);
|
|
2582
|
+
return { ref: d.ref, score };
|
|
2583
|
+
});
|
|
2584
|
+
}
|
|
2585
|
+
};
|
|
2586
|
+
function countOccurrences2(haystack, needle) {
|
|
2587
|
+
if (!needle) return 0;
|
|
2588
|
+
return haystack.split(needle).length - 1;
|
|
2589
|
+
}
|
|
2503
2590
|
var bm25Algorithm = {
|
|
2504
2591
|
name: "bm25",
|
|
2505
2592
|
description: "BM25 with stemming + CJK bigram tokenization. IR-standard relevance ranking.",
|
|
@@ -2508,11 +2595,8 @@ var bm25Algorithm = {
|
|
|
2508
2595
|
const k1 = 1.2;
|
|
2509
2596
|
const b = 0.75;
|
|
2510
2597
|
const parsed = docs.map((d) => {
|
|
2511
|
-
const
|
|
2512
|
-
|
|
2513
|
-
let len = 0;
|
|
2514
|
-
for (const v of tf.values()) len += v;
|
|
2515
|
-
return { id: d.ref, tf, len };
|
|
2598
|
+
const f = docFeatures(d.text);
|
|
2599
|
+
return { id: d.ref, tf: f.tf, len: f.len };
|
|
2516
2600
|
});
|
|
2517
2601
|
const avgdl = parsed.reduce((s, d) => s + d.len, 0) / (N || 1);
|
|
2518
2602
|
const qTerms = tokenize(query, { stem: true });
|
|
@@ -2539,14 +2623,13 @@ var fuzzyAlgorithm = {
|
|
|
2539
2623
|
name: "fuzzy",
|
|
2540
2624
|
description: "Character bigram overlap. Typo-tolerant, script-agnostic, high recall.",
|
|
2541
2625
|
score(docs, query) {
|
|
2542
|
-
const qTokens = query.toLowerCase().split(/[\s,]+/).filter((t) => t.length >= 4);
|
|
2626
|
+
const qTokens = query.toLowerCase().split(/[\s,]+/).filter((t) => t.length >= 4 || t.length >= 2 && CJK.test(t));
|
|
2543
2627
|
if (qTokens.length === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
|
|
2544
2628
|
const qGrams = /* @__PURE__ */ new Set();
|
|
2545
2629
|
for (const t of qTokens) for (const g of charBigrams(t)) qGrams.add(g);
|
|
2546
2630
|
if (qGrams.size === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
|
|
2547
2631
|
return docs.map((d) => {
|
|
2548
|
-
const
|
|
2549
|
-
const docGrams = new Set(charBigrams(haystack));
|
|
2632
|
+
const docGrams = docFeatures(d.text).grams;
|
|
2550
2633
|
let hits = 0;
|
|
2551
2634
|
for (const g of qGrams) if (docGrams.has(g)) hits++;
|
|
2552
2635
|
return { ref: d.ref, score: hits / qGrams.size };
|
|
@@ -3105,14 +3188,17 @@ function openaiToCore(body) {
|
|
|
3105
3188
|
}
|
|
3106
3189
|
case "user": {
|
|
3107
3190
|
const text = stringContent(m.content);
|
|
3108
|
-
const
|
|
3191
|
+
const imgs = allImageParts(m.content);
|
|
3192
|
+
const firstImg = imgs[0];
|
|
3193
|
+
const firstUrl = firstImg ? firstImg.image_url.url : void 0;
|
|
3194
|
+
const firstParsed = firstUrl ? parseDataUrl(firstUrl) : void 0;
|
|
3109
3195
|
const base = deriveMessageId("user", "text", text);
|
|
3110
3196
|
msgs.push({
|
|
3111
3197
|
id: clusters.next(base),
|
|
3112
3198
|
role: "user",
|
|
3113
3199
|
contentType: "text",
|
|
3114
3200
|
text,
|
|
3115
|
-
...
|
|
3201
|
+
...imgs.length === 1 && firstParsed ? { rawOpenaiContent: imgs[0], imageMediaType: firstParsed.mediaType, imageBase64: firstParsed.base64 } : imgs.length > 1 ? { rawOpenaiContentParts: imgs } : {}
|
|
3116
3202
|
});
|
|
3117
3203
|
break;
|
|
3118
3204
|
}
|
|
@@ -3207,10 +3293,12 @@ function coreToOpenai(messages) {
|
|
|
3207
3293
|
if (m.role === "system") {
|
|
3208
3294
|
out.push({ role: m.originalRole === "developer" ? "developer" : "system", content: m.text ?? "" });
|
|
3209
3295
|
} else if (m.role === "user") {
|
|
3210
|
-
if (m.rawOpenaiContent || m.imageBase64) {
|
|
3296
|
+
if (m.rawOpenaiContent || m.imageBase64 || m.rawOpenaiContentParts) {
|
|
3211
3297
|
const parts = [];
|
|
3212
3298
|
if (m.text) parts.push({ type: "text", text: m.text });
|
|
3213
|
-
if (m.
|
|
3299
|
+
if (m.rawOpenaiContentParts && m.rawOpenaiContentParts.length > 0) {
|
|
3300
|
+
for (const part of m.rawOpenaiContentParts) parts.push(part);
|
|
3301
|
+
} else if (m.rawOpenaiContent) {
|
|
3214
3302
|
parts.push(m.rawOpenaiContent);
|
|
3215
3303
|
} else if (m.imageBase64 && m.imageMediaType) {
|
|
3216
3304
|
parts.push({ type: "image_url", image_url: { url: `data:${m.imageMediaType};base64,${m.imageBase64}` } });
|
|
@@ -3235,19 +3323,17 @@ function stringContent(content) {
|
|
|
3235
3323
|
}
|
|
3236
3324
|
return "";
|
|
3237
3325
|
}
|
|
3238
|
-
function
|
|
3239
|
-
if (!Array.isArray(content)) return
|
|
3326
|
+
function allImageParts(content) {
|
|
3327
|
+
if (!Array.isArray(content)) return [];
|
|
3328
|
+
const out = [];
|
|
3240
3329
|
for (const p of content) {
|
|
3241
|
-
if (
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
if (parsed) return { part: p, mediaType: parsed.mediaType, base64: parsed.base64 };
|
|
3247
|
-
}
|
|
3248
|
-
}
|
|
3330
|
+
if (typeof p !== "object" || p === null) continue;
|
|
3331
|
+
if (!("type" in p) || p.type !== "image_url" || !("image_url" in p)) continue;
|
|
3332
|
+
const imagePart = p;
|
|
3333
|
+
const url = imagePart.image_url.url;
|
|
3334
|
+
if (typeof url === "string" && parseDataUrl(url)) out.push(p);
|
|
3249
3335
|
}
|
|
3250
|
-
return
|
|
3336
|
+
return out;
|
|
3251
3337
|
}
|
|
3252
3338
|
function createSubagentNamespaces() {
|
|
3253
3339
|
const anchors = /* @__PURE__ */ new Map();
|
|
@@ -3693,15 +3779,75 @@ function payloadToCore(payload, fmt2) {
|
|
|
3693
3779
|
function coreToPayloadMessages(msgs, fmt2, cacheControls) {
|
|
3694
3780
|
return fmt2 === "anthropic" ? coreToAnthropic(msgs, cacheControls) : coreToOpenai(msgs);
|
|
3695
3781
|
}
|
|
3696
|
-
|
|
3782
|
+
var ANTHROPIC_CODEC_BLOCKS = /* @__PURE__ */ new Set(["text", "tool_use", "tool_result", "thinking", "image"]);
|
|
3783
|
+
var OPENAI_CODEC_ROLES = /* @__PURE__ */ new Set(["system", "developer", "user", "assistant", "tool"]);
|
|
3784
|
+
function payloadRepresentable(payload, fmt2) {
|
|
3785
|
+
const messages = payload.messages;
|
|
3786
|
+
if (!Array.isArray(messages)) return { ok: false, reason: "messages not an array" };
|
|
3787
|
+
for (const message of messages) {
|
|
3788
|
+
if (message === null || typeof message !== "object") return { ok: false, reason: "message not an object" };
|
|
3789
|
+
const bad = fmt2 === "anthropic" ? unrepresentableAnthropicMessage(message) : unrepresentableOpenaiMessage(message);
|
|
3790
|
+
if (bad) return { ok: false, reason: bad };
|
|
3791
|
+
}
|
|
3792
|
+
return { ok: true };
|
|
3793
|
+
}
|
|
3794
|
+
function unrepresentableAnthropicMessage(message) {
|
|
3795
|
+
const content = message.content;
|
|
3796
|
+
if (content == null || typeof content === "string") return null;
|
|
3797
|
+
if (!Array.isArray(content)) return "content neither string nor block array";
|
|
3798
|
+
for (const block of content) {
|
|
3799
|
+
const type5 = block?.type;
|
|
3800
|
+
if (typeof type5 !== "string" || !ANTHROPIC_CODEC_BLOCKS.has(type5)) {
|
|
3801
|
+
return `anthropic block type ${JSON.stringify(type5) ?? "missing"}`;
|
|
3802
|
+
}
|
|
3803
|
+
if (type5 === "tool_result") {
|
|
3804
|
+
const inner = block.content;
|
|
3805
|
+
if (Array.isArray(inner) && inner.some((c) => c?.type !== "text")) {
|
|
3806
|
+
return "tool_result content carries non-text parts (images are flattened away)";
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
if (type5 === "thinking" && block.cache_control != null) {
|
|
3810
|
+
return "cache_control on a thinking block is not re-attached";
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3813
|
+
return null;
|
|
3814
|
+
}
|
|
3815
|
+
function unrepresentableOpenaiMessage(message) {
|
|
3816
|
+
const role = message.role;
|
|
3817
|
+
if (typeof role !== "string" || !OPENAI_CODEC_ROLES.has(role)) {
|
|
3818
|
+
return `openai role ${JSON.stringify(role) ?? "missing"}`;
|
|
3819
|
+
}
|
|
3820
|
+
const content = message.content;
|
|
3821
|
+
if (content == null || typeof content === "string") return null;
|
|
3822
|
+
if (!Array.isArray(content)) return "content neither string nor part array";
|
|
3823
|
+
for (const part of content) {
|
|
3824
|
+
if (typeof part === "string") continue;
|
|
3825
|
+
const type5 = part?.type;
|
|
3826
|
+
if (type5 === "text") continue;
|
|
3827
|
+
if (type5 === "image_url" && role === "user") {
|
|
3828
|
+
const url = part?.image_url?.url;
|
|
3829
|
+
if (typeof url !== "string" || !url.startsWith("data:")) return "image_url without a data: URL is dropped";
|
|
3830
|
+
continue;
|
|
3831
|
+
}
|
|
3832
|
+
return `openai content part type ${JSON.stringify(type5) ?? "missing"}`;
|
|
3833
|
+
}
|
|
3834
|
+
return null;
|
|
3835
|
+
}
|
|
3836
|
+
var renderRefsAll = createRenderRefsNode("all");
|
|
3837
|
+
function applyWireTagContract(msgs, state, scope) {
|
|
3838
|
+
const stripAssistantTags = (m) => m.contentType === "text" && m.role === "assistant" ? { ...m, text: stripRefTag(m.text ?? "") } : m;
|
|
3697
3839
|
const toolResults = msgs.filter((m) => m.contentType === "tool-result");
|
|
3698
|
-
|
|
3699
|
-
const
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3840
|
+
if (toolResults.length === 0) return msgs.map(stripAssistantTags);
|
|
3841
|
+
const names = toolCallNames(msgs);
|
|
3842
|
+
const named = toolResults.map((m) => m.toolName ? m : { ...m, toolName: names.get(m.toolCallId ?? "") ?? "tool" });
|
|
3843
|
+
const io = renderRefsAll.run(
|
|
3844
|
+
{ messages: named, state, effects: {} },
|
|
3845
|
+
{ config: scope.config, tokenCount: scope.tokenCount, countTokens: defaultCountTokens }
|
|
3846
|
+
);
|
|
3847
|
+
if (io.state !== state) state.tokenSnapshot = io.state.tokenSnapshot;
|
|
3848
|
+
const tagged = io.messages;
|
|
3849
|
+
const bySource = new Map(toolResults.map((m, i) => [m, tagged[i]]));
|
|
3850
|
+
return msgs.map((m) => m.contentType === "tool-result" ? bySource.get(m) ?? m : stripAssistantTags(m));
|
|
3705
3851
|
}
|
|
3706
3852
|
function coreIdentity(msg) {
|
|
3707
3853
|
return JSON.stringify({
|
|
@@ -4793,7 +4939,7 @@ function renderMessage2(message, map, countTokens, strategy) {
|
|
|
4793
4939
|
if (!cleanText) return { ...message, text: prefix };
|
|
4794
4940
|
return { ...message, text: prefix + cleanText };
|
|
4795
4941
|
}
|
|
4796
|
-
function
|
|
4942
|
+
function renderVisibleRefs(messages, state, countTokens = (text) => Math.ceil(text.length / 4), strategy = "all") {
|
|
4797
4943
|
const map = state.messageRefs;
|
|
4798
4944
|
return messages.map(
|
|
4799
4945
|
(message) => renderMessage2(message, map, countTokens, strategy)
|
|
@@ -4805,7 +4951,7 @@ function createRenderRefsNode2(strategy) {
|
|
|
4805
4951
|
run(io, ctx) {
|
|
4806
4952
|
return {
|
|
4807
4953
|
...io,
|
|
4808
|
-
messages:
|
|
4954
|
+
messages: renderVisibleRefs(io.messages, io.state, ctx.countTokens, strategy)
|
|
4809
4955
|
};
|
|
4810
4956
|
}
|
|
4811
4957
|
};
|
|
@@ -5040,7 +5186,7 @@ function stem2(word) {
|
|
|
5040
5186
|
return w;
|
|
5041
5187
|
}
|
|
5042
5188
|
var CJK2 = /[\u3400-\u9fff\uf900-\ufaff\u3040-\u30ff\uac00-\ud7af]/;
|
|
5043
|
-
var
|
|
5189
|
+
var CJK_RUN = new RegExp(`${CJK2.source}+`, "g");
|
|
5044
5190
|
var LATIN_WORD2 = /[a-z][a-z0-9_]*[a-z0-9]|[a-z0-9]/g;
|
|
5045
5191
|
function tokenize2(text, opts = {}) {
|
|
5046
5192
|
const lower = text.toLowerCase();
|
|
@@ -5052,7 +5198,7 @@ function tokenize2(text, opts = {}) {
|
|
|
5052
5198
|
tokens.push(w);
|
|
5053
5199
|
}
|
|
5054
5200
|
}
|
|
5055
|
-
const cjkRuns = lower.match(
|
|
5201
|
+
const cjkRuns = lower.match(CJK_RUN) ?? [];
|
|
5056
5202
|
for (const run of cjkRuns) {
|
|
5057
5203
|
if (run.length === 1) {
|
|
5058
5204
|
tokens.push(run);
|
|
@@ -5416,7 +5562,7 @@ async function statusReport(runtime, ctx) {
|
|
|
5416
5562
|
const coveredIds = collectCoveredMessageIds(state);
|
|
5417
5563
|
const sentTokens = estimateTokens(coreMessages, coveredIds) + systemPromptTokens;
|
|
5418
5564
|
const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: sentTokens });
|
|
5419
|
-
const versionStr = "0.2.
|
|
5565
|
+
const versionStr = "0.2.9" ? `billion-context-omp@${"0.2.9"}` : void 0;
|
|
5420
5566
|
return buildStatusPanel({
|
|
5421
5567
|
version: versionStr,
|
|
5422
5568
|
tokenCount: sessionTokens,
|
|
@@ -5710,7 +5856,7 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
5710
5856
|
const data = await res.json();
|
|
5711
5857
|
const latest = data.version;
|
|
5712
5858
|
if (!latest) return;
|
|
5713
|
-
const current = runtimeVersion ?? "0.2.
|
|
5859
|
+
const current = runtimeVersion ?? "0.2.9";
|
|
5714
5860
|
const hasUpdate = isNewer(latest, current);
|
|
5715
5861
|
debug.event("update-check", {
|
|
5716
5862
|
current,
|
|
@@ -5985,9 +6131,9 @@ var index_default = createAcpExtension();
|
|
|
5985
6131
|
function wireSessionLifecycle(pi, runtime) {
|
|
5986
6132
|
pi.on("session_start", async (_event, ctx) => {
|
|
5987
6133
|
const sid = ctx.sessionManager.getSessionId();
|
|
5988
|
-
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.2.
|
|
6134
|
+
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.2.9" : null });
|
|
5989
6135
|
const selfPath = import.meta.url;
|
|
5990
|
-
const conflict = stampAndDetect(selfPath, true ? "0.2.
|
|
6136
|
+
const conflict = stampAndDetect(selfPath, true ? "0.2.9" : null);
|
|
5991
6137
|
if (conflict) {
|
|
5992
6138
|
logWarn("instance", { event: "dual-instance", self: selfPath, other: conflict.path, otherPid: conflict.pid, otherVersion: conflict.version });
|
|
5993
6139
|
try {
|
|
@@ -6174,6 +6320,12 @@ function wireProviderTransform(pi, runtime) {
|
|
|
6174
6320
|
debug.event("provider-transform-unknown-format", { sid });
|
|
6175
6321
|
return void 0;
|
|
6176
6322
|
}
|
|
6323
|
+
const representable = payloadRepresentable(payload, fmt2);
|
|
6324
|
+
if (!representable.ok) {
|
|
6325
|
+
logInfo("provider-transform", { sid, fmt: fmt2, event: "unrepresentable", reason: representable.reason });
|
|
6326
|
+
debug.event("provider-transform-unrepresentable", { sid, fmt: fmt2, reason: representable.reason });
|
|
6327
|
+
return void 0;
|
|
6328
|
+
}
|
|
6177
6329
|
try {
|
|
6178
6330
|
const { msgs, cacheControls } = payloadToCore(payload, fmt2);
|
|
6179
6331
|
if (msgs.length === 0) return void 0;
|
|
@@ -6256,7 +6408,8 @@ async function transformStreamCore(ctx, runtime, wireMsgs, fmt2) {
|
|
|
6256
6408
|
});
|
|
6257
6409
|
const coreOut = applyWireTagContract(
|
|
6258
6410
|
turn.messages.filter((m) => !m.id.startsWith("acp_summary_")),
|
|
6259
|
-
turn.state
|
|
6411
|
+
turn.state,
|
|
6412
|
+
{ config, tokenCount }
|
|
6260
6413
|
);
|
|
6261
6414
|
let nudgeInjected = false;
|
|
6262
6415
|
if (turn.nudge?.shouldInject) {
|
|
@@ -6326,18 +6479,18 @@ function wireProviderDebug(pi) {
|
|
|
6326
6479
|
pi.on("after_provider_response", (event, ctx) => {
|
|
6327
6480
|
if (!debug.enabled) return;
|
|
6328
6481
|
const h = event.headers;
|
|
6329
|
-
const
|
|
6482
|
+
const cache2 = {};
|
|
6330
6483
|
for (const [k, v] of Object.entries(h)) {
|
|
6331
6484
|
const lk = k.toLowerCase();
|
|
6332
6485
|
if (lk.includes("cache") || lk.includes("usage") || lk.includes("token") || lk.includes("rate") || lk.includes("x-")) {
|
|
6333
|
-
|
|
6486
|
+
cache2[lk] = v;
|
|
6334
6487
|
}
|
|
6335
6488
|
}
|
|
6336
6489
|
debug.event("provider-response", {
|
|
6337
6490
|
sid: ctx.sessionManager.getSessionId(),
|
|
6338
6491
|
status: event.status,
|
|
6339
6492
|
requestId: event.requestId ?? null,
|
|
6340
|
-
cache
|
|
6493
|
+
cache: cache2
|
|
6341
6494
|
});
|
|
6342
6495
|
});
|
|
6343
6496
|
}
|