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 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 startIndex = resolveAnchorIndex(start, input.state, indexByRawId, "start");
399
- let endIndex = resolveAnchorIndex(end, input.state, indexByRawId, "end");
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 === void 0) {
443
- throw new BoundaryNotFoundError(
444
- "consumed",
445
- endpoint,
446
- `${label}="${boundary.raw}" not found in visible context (likely consumed by an existing block).`
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
- return index;
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
- const anchor = earliestIndexOfIds(block.effectiveMessageIds, indexByRawId);
467
- if (anchor === null) {
468
- throw new BoundaryNotFoundError(
469
- "consumed",
470
- endpoint,
471
- `${label}="b${boundary.numericId}" not found in visible context (block messages consumed by a higher-tier block).`
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 anchor;
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 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.`;
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
- const cjkRuns = lower.match(CJK_RUN) ?? [];
2480
- for (const run of cjkRuns) {
2481
- if (run.length === 1) {
2482
- tokens.push(run);
2483
- } else {
2484
- for (let i = 0; i < run.length - 1; i++) tokens.push(run.slice(i, i + 2));
2485
- for (const ch of run) tokens.push(ch);
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 text = d.text;
2512
- const tf = tfMap(text, true);
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 haystack = d.text.toLowerCase();
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 img = firstImagePart(m.content);
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
- ...img ? { rawOpenaiContent: img.part, imageMediaType: img.mediaType, imageBase64: img.base64 } : {}
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.rawOpenaiContent) {
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 firstImagePart(content) {
3239
- if (!Array.isArray(content)) return void 0;
3326
+ function allImageParts(content) {
3327
+ if (!Array.isArray(content)) return [];
3328
+ const out = [];
3240
3329
  for (const p of content) {
3241
- if (p && typeof p === "object" && p.type === "image_url") {
3242
- const iu = p.image_url;
3243
- const url = iu?.url;
3244
- if (typeof url === "string") {
3245
- const parsed = parseDataUrl(url);
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 void 0;
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
- function applyWireTagContract(msgs, state) {
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
- const taggedTools = toolResults.length > 0 ? renderVisibleRefs(toolResults, state, defaultCountTokens, "all") : [];
3699
- const bySource = new Map(toolResults.map((m, i) => [m, taggedTools[i]]));
3700
- return msgs.map((m) => {
3701
- if (m.contentType === "tool-result") return bySource.get(m) ?? m;
3702
- if (m.contentType === "text" && m.role === "assistant") return { ...m, text: stripRefTag(m.text ?? "") };
3703
- return m;
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 renderVisibleRefs2(messages, state, countTokens = (text) => Math.ceil(text.length / 4), strategy = "all") {
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: renderVisibleRefs2(io.messages, io.state, ctx.countTokens, strategy)
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 CJK_RUN2 = new RegExp(`${CJK2.source}+`, "g");
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(CJK_RUN2) ?? [];
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.7" ? `billion-context-omp@${"0.2.7"}` : void 0;
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.7";
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.7" : null });
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.7" : null);
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 cache = {};
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
- cache[lk] = v;
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
  }