acp-kernel 0.0.94 → 0.0.95-pr.235.306

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.
Files changed (84) hide show
  1. package/DESIGN.md +158 -137
  2. package/PROVENANCE.md +44 -40
  3. package/README.md +45 -32
  4. package/dist/boundaries.d.ts +3 -3
  5. package/dist/boundaries.d.ts.map +1 -1
  6. package/dist/cache-report.d.ts.map +1 -1
  7. package/dist/ccr.d.ts.map +1 -1
  8. package/dist/{chunk-NUQZKPQS.js → chunk-TQ6I62XC.js} +13 -6
  9. package/dist/chunk-TQ6I62XC.js.map +1 -0
  10. package/dist/compress-tools.d.ts +282 -254
  11. package/dist/compress-tools.d.ts.map +1 -1
  12. package/dist/compress.d.ts.map +1 -1
  13. package/dist/compression-rules.d.ts +9 -3
  14. package/dist/compression-rules.d.ts.map +1 -1
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/decompress.d.ts.map +1 -1
  17. package/dist/filter/apply.d.ts.map +1 -1
  18. package/dist/filter/index.d.ts +1 -1
  19. package/dist/filter/index.d.ts.map +1 -1
  20. package/dist/filter/types.d.ts.map +1 -1
  21. package/dist/handoff.d.ts.map +1 -1
  22. package/dist/hide-consumed.d.ts.map +1 -1
  23. package/dist/image-compress.d.ts.map +1 -1
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +477 -193
  27. package/dist/index.js.map +1 -1
  28. package/dist/message-kind.d.ts.map +1 -1
  29. package/dist/nudge-text.d.ts.map +1 -1
  30. package/dist/packs.d.ts +1 -1
  31. package/dist/packs.d.ts.map +1 -1
  32. package/dist/panel/cache.d.ts.map +1 -1
  33. package/dist/panel/index.js +29 -10
  34. package/dist/panel/index.js.map +1 -1
  35. package/dist/panel/panel.d.ts.map +1 -1
  36. package/dist/panel/topic.d.ts.map +1 -1
  37. package/dist/parse-compress-input.d.ts.map +1 -1
  38. package/dist/persist/index.d.ts +1 -1
  39. package/dist/persist/index.d.ts.map +1 -1
  40. package/dist/persist/index.js +49 -12
  41. package/dist/persist/index.js.map +1 -1
  42. package/dist/persist/state-merge.d.ts.map +1 -1
  43. package/dist/persist/store.d.ts.map +1 -1
  44. package/dist/protected.d.ts.map +1 -1
  45. package/dist/rebuild.d.ts.map +1 -1
  46. package/dist/recommend.d.ts.map +1 -1
  47. package/dist/render-refs.d.ts.map +1 -1
  48. package/dist/report.d.ts.map +1 -1
  49. package/dist/search/algorithms/bm25.d.ts.map +1 -1
  50. package/dist/search/algorithms/fuzzy.d.ts.map +1 -1
  51. package/dist/search/algorithms/hybrid.d.ts.map +1 -1
  52. package/dist/search/algorithms/semantic.d.ts.map +1 -1
  53. package/dist/search/algorithms/substring.d.ts.map +1 -1
  54. package/dist/search/doc-cache.d.ts.map +1 -1
  55. package/dist/search/index.d.ts +1 -1
  56. package/dist/search/index.d.ts.map +1 -1
  57. package/dist/search/registry.d.ts.map +1 -1
  58. package/dist/search/stemmer.d.ts.map +1 -1
  59. package/dist/search/tokenizer.d.ts.map +1 -1
  60. package/dist/search/types.d.ts.map +1 -1
  61. package/dist/search.d.ts +3 -3
  62. package/dist/search.d.ts.map +1 -1
  63. package/dist/segment.d.ts +33 -0
  64. package/dist/segment.d.ts.map +1 -0
  65. package/dist/surface-config.d.ts.map +1 -1
  66. package/dist/tool-pairs.d.ts.map +1 -1
  67. package/dist/truncate-tools.d.ts.map +1 -1
  68. package/dist/truncate.d.ts.map +1 -1
  69. package/dist/turn-integrity.d.ts.map +1 -1
  70. package/dist/wire/anthropic.d.ts.map +1 -1
  71. package/dist/wire/bili-message.d.ts.map +1 -1
  72. package/dist/wire/compress-detect.d.ts.map +1 -1
  73. package/dist/wire/demoted-thinking.d.ts.map +1 -1
  74. package/dist/wire/formats.d.ts.map +1 -1
  75. package/dist/wire/index.js +476 -129
  76. package/dist/wire/index.js.map +1 -1
  77. package/dist/wire/message-id.d.ts.map +1 -1
  78. package/dist/wire/mirror.d.ts.map +1 -1
  79. package/dist/wire/openai.d.ts.map +1 -1
  80. package/dist/wire/responses.d.ts.map +1 -1
  81. package/dist/wire/strip-images.d.ts.map +1 -1
  82. package/dist/wire/util.d.ts.map +1 -1
  83. package/package.json +66 -66
  84. package/dist/chunk-NUQZKPQS.js.map +0 -1
@@ -27,7 +27,13 @@ function extractSystem(system) {
27
27
  function buildSystem(text, original) {
28
28
  if (Array.isArray(original) && original.length > 0) {
29
29
  const ccBlock = original.find((b) => b.cache_control);
30
- return [{ type: "text", text, ...ccBlock ? { cache_control: ccBlock.cache_control } : {} }];
30
+ return [
31
+ {
32
+ type: "text",
33
+ text,
34
+ ...ccBlock ? { cache_control: ccBlock.cache_control } : {}
35
+ }
36
+ ];
31
37
  }
32
38
  return text;
33
39
  }
@@ -48,10 +54,15 @@ function anthropicToCore(body) {
48
54
  break;
49
55
  }
50
56
  case "tool_use": {
51
- const base = deriveMessageId("assistant", "tool-call", safeStringify(b.input), {
52
- toolCallId: b.id,
53
- toolName: b.name
54
- });
57
+ const base = deriveMessageId(
58
+ "assistant",
59
+ "tool-call",
60
+ safeStringify(b.input),
61
+ {
62
+ toolCallId: b.id,
63
+ toolName: b.name
64
+ }
65
+ );
55
66
  const id = clusters.next(base);
56
67
  msgs.push({
57
68
  id,
@@ -68,7 +79,9 @@ function anthropicToCore(body) {
68
79
  case "tool_result": {
69
80
  const hasNonText = Array.isArray(b.content) && b.content.some((c) => c.type !== "text");
70
81
  const text = typeof b.content === "string" ? b.content : b.content.map((c) => c.type === "text" ? c.text : "").join("\n");
71
- const base = deriveMessageId("tool", "tool-result", text, { toolCallId: b.tool_use_id });
82
+ const base = deriveMessageId("tool", "tool-result", text, {
83
+ toolCallId: b.tool_use_id
84
+ });
72
85
  const id = clusters.next(base);
73
86
  const name = toolNames.get(b.tool_use_id);
74
87
  msgs.push({
@@ -250,7 +263,13 @@ function openaiToCore(body) {
250
263
  break;
251
264
  }
252
265
  const base = deriveMessageId(m.role, "text", stringContent(m.content));
253
- msgs.push({ id: clusters.next(base), role: "system", contentType: "text", text: stringContent(m.content), originalRole: m.role });
266
+ msgs.push({
267
+ id: clusters.next(base),
268
+ role: "system",
269
+ contentType: "text",
270
+ text: stringContent(m.content),
271
+ originalRole: m.role
272
+ });
254
273
  break;
255
274
  }
256
275
  case "user": {
@@ -276,7 +295,10 @@ function openaiToCore(body) {
276
295
  rawOpenaiContent: imgs[0],
277
296
  // data: URLs only — remote URLs ride rawOpenaiContent
278
297
  // verbatim (#187/#291)
279
- ...firstParsed ? { imageMediaType: firstParsed.mediaType, imageBase64: firstParsed.base64 } : {}
298
+ ...firstParsed ? {
299
+ imageMediaType: firstParsed.mediaType,
300
+ imageBase64: firstParsed.base64
301
+ } : {}
280
302
  } : nonText.length > 0 ? { rawOpenaiContentParts: nonText } : {}
281
303
  });
282
304
  break;
@@ -307,14 +329,25 @@ function openaiToCore(body) {
307
329
  }
308
330
  if (text) {
309
331
  const base = deriveMessageId("assistant", "text", text);
310
- msgs.push({ id: clusters.next(base), role: "assistant", contentType: "text", text, ...blankEcho ? { reasoningPresent: true } : {} });
332
+ msgs.push({
333
+ id: clusters.next(base),
334
+ role: "assistant",
335
+ contentType: "text",
336
+ text,
337
+ ...blankEcho ? { reasoningPresent: true } : {}
338
+ });
311
339
  }
312
340
  if (Array.isArray(m.tool_calls)) {
313
341
  for (const tc of m.tool_calls) {
314
- const base = deriveMessageId("assistant", "tool-call", tc.function.arguments ?? "", {
315
- toolCallId: tc.id,
316
- toolName: tc.function.name
317
- });
342
+ const base = deriveMessageId(
343
+ "assistant",
344
+ "tool-call",
345
+ tc.function.arguments ?? "",
346
+ {
347
+ toolCallId: tc.id,
348
+ toolName: tc.function.name
349
+ }
350
+ );
318
351
  msgs.push({
319
352
  id: clusters.next(base),
320
353
  role: "assistant",
@@ -330,9 +363,14 @@ function openaiToCore(body) {
330
363
  break;
331
364
  }
332
365
  case "tool": {
333
- const base = deriveMessageId("tool", "tool-result", stringContent(m.content), {
334
- toolCallId: m.tool_call_id ?? ""
335
- });
366
+ const base = deriveMessageId(
367
+ "tool",
368
+ "tool-result",
369
+ stringContent(m.content),
370
+ {
371
+ toolCallId: m.tool_call_id ?? ""
372
+ }
373
+ );
336
374
  const name = m.name || toolNames.get(m.tool_call_id ?? "");
337
375
  msgs.push({
338
376
  id: clusters.next(base),
@@ -365,13 +403,23 @@ function coreToOpenai(messages) {
365
403
  } else if (pending.text !== null) {
366
404
  out.push({ role: "assistant", content: pending.text, ...reasoningField });
367
405
  } else if (reasoning) {
368
- out.push({ role: "assistant", content: null, reasoning_content: reasoning });
406
+ out.push({
407
+ role: "assistant",
408
+ content: null,
409
+ reasoning_content: reasoning
410
+ });
369
411
  }
370
412
  pending = null;
371
413
  };
372
414
  for (const m of messages) {
373
415
  if (m.role === "assistant") {
374
- if (!pending) pending = { text: null, toolCalls: [], reasoning: null, reasoningPresent: false };
416
+ if (!pending)
417
+ pending = {
418
+ text: null,
419
+ toolCalls: [],
420
+ reasoning: null,
421
+ reasoningPresent: false
422
+ };
375
423
  if (m.reasoningPresent) pending.reasoningPresent = true;
376
424
  if (m.contentType === "reasoning") {
377
425
  pending.reasoning = (pending.reasoning ?? "") + (m.reasoningContent ?? m.text ?? "");
@@ -387,24 +435,37 @@ function coreToOpenai(messages) {
387
435
  } else {
388
436
  flush();
389
437
  if (m.role === "system") {
390
- out.push({ role: m.originalRole === "developer" ? "developer" : "system", content: m.text ?? "" });
438
+ out.push({
439
+ role: m.originalRole === "developer" ? "developer" : "system",
440
+ content: m.text ?? ""
441
+ });
391
442
  } else if (m.role === "user") {
392
443
  if (m.rawOpenaiContent || m.imageBase64 || m.rawOpenaiContentParts) {
393
444
  const parts = [];
394
445
  if (m.text) parts.push({ type: "text", text: m.text });
395
446
  if (m.rawOpenaiContentParts && m.rawOpenaiContentParts.length > 0) {
396
- for (const part of m.rawOpenaiContentParts) parts.push(part);
447
+ for (const part of m.rawOpenaiContentParts)
448
+ parts.push(part);
397
449
  } else if (m.rawOpenaiContent) {
398
450
  parts.push(m.rawOpenaiContent);
399
451
  } else if (m.imageBase64 && m.imageMediaType) {
400
- parts.push({ type: "image_url", image_url: { url: `data:${m.imageMediaType};base64,${m.imageBase64}` } });
452
+ parts.push({
453
+ type: "image_url",
454
+ image_url: {
455
+ url: `data:${m.imageMediaType};base64,${m.imageBase64}`
456
+ }
457
+ });
401
458
  }
402
459
  out.push({ role: "user", content: parts });
403
460
  } else {
404
461
  out.push({ role: "user", content: m.text ?? "" });
405
462
  }
406
463
  } else if (m.role === "tool") {
407
- out.push({ role: "tool", tool_call_id: m.toolCallId ?? "", content: m.text ?? "" });
464
+ out.push({
465
+ role: "tool",
466
+ tool_call_id: m.toolCallId ?? "",
467
+ content: m.text ?? ""
468
+ });
408
469
  }
409
470
  }
410
471
  }
@@ -437,7 +498,9 @@ function stringContent(content) {
437
498
  if (content == null) return "";
438
499
  if (typeof content === "string") return content;
439
500
  if (Array.isArray(content)) {
440
- return content.map((p) => typeof p === "string" ? p : p.type === "text" ? p.text ?? "" : "").join("\n");
501
+ return content.map(
502
+ (p) => typeof p === "string" ? p : p.type === "text" ? p.text ?? "" : ""
503
+ ).join("\n");
441
504
  }
442
505
  return "";
443
506
  }
@@ -446,7 +509,8 @@ function allImageParts(content) {
446
509
  const out = [];
447
510
  for (const p of content) {
448
511
  if (typeof p !== "object" || p === null) continue;
449
- if (!("type" in p) || p.type !== "image_url" || !("image_url" in p)) continue;
512
+ if (!("type" in p) || p.type !== "image_url" || !("image_url" in p))
513
+ continue;
450
514
  const imagePart = p;
451
515
  const url = imagePart.image_url?.url;
452
516
  if (typeof url === "string") out.push(p);
@@ -465,10 +529,7 @@ function allNonTextParts(content) {
465
529
  }
466
530
 
467
531
  // src/wire/responses.ts
468
- var OPAQUE_ITEM_TYPES = /* @__PURE__ */ new Set([
469
- "additional_tools",
470
- "mcp_list_tools"
471
- ]);
532
+ var OPAQUE_ITEM_TYPES = /* @__PURE__ */ new Set(["additional_tools", "mcp_list_tools"]);
472
533
  function isOpaqueItem(item) {
473
534
  return OPAQUE_ITEM_TYPES.has(item.type);
474
535
  }
@@ -476,7 +537,10 @@ var EASY_INPUT_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "system", "
476
537
  function normalizeEasyInputItem(item) {
477
538
  if (typeof item.type === "string") return item;
478
539
  if (EASY_INPUT_ROLES.has(String(item.role))) {
479
- return { ...item, type: "message" };
540
+ return {
541
+ ...item,
542
+ type: "message"
543
+ };
480
544
  }
481
545
  return item;
482
546
  }
@@ -495,7 +559,9 @@ function messageContent(content) {
495
559
  function userDisplayText(content, text) {
496
560
  if (typeof content === "string") return text;
497
561
  const hasImage = content.some((part) => part.type === "input_image");
498
- const hasTextPart = content.some((part) => part.type === "input_text" || part.type === "output_text");
562
+ const hasTextPart = content.some(
563
+ (part) => part.type === "input_text" || part.type === "output_text"
564
+ );
499
565
  return !text || hasImage && !hasTextPart ? "[image]" : text;
500
566
  }
501
567
  function reasoningText(item) {
@@ -505,7 +571,8 @@ function reasoningText(item) {
505
571
  for (const part of parts) {
506
572
  if (part && typeof part === "object" && "type" in part && "text" in part) {
507
573
  const rec = part;
508
- if (rec.type === type && typeof rec.text === "string") texts.push(rec.text);
574
+ if (rec.type === type && typeof rec.text === "string")
575
+ texts.push(rec.text);
509
576
  }
510
577
  }
511
578
  return texts.join("\n");
@@ -524,11 +591,20 @@ function responsesToCore(body) {
524
591
  const clusters = new ClusterCounter();
525
592
  const toolNames = /* @__PURE__ */ new Map();
526
593
  let idx = 0;
527
- if (typeof body.instructions === "string" && body.instructions.trim()) systemParts.push(body.instructions);
594
+ if (typeof body.instructions === "string" && body.instructions.trim())
595
+ systemParts.push(body.instructions);
528
596
  if (typeof body.input === "string") {
529
597
  const id = clusters.next(deriveMessageId("user", "text", body.input));
530
598
  msgs.push({ id, role: "user", contentType: "text", text: body.input });
531
- return { msgs, systemParts, preamble, customToolCallIds, layout, droppedReasoning, stringInput: { original: body.input, coreId: id } };
599
+ return {
600
+ msgs,
601
+ systemParts,
602
+ preamble,
603
+ customToolCallIds,
604
+ layout,
605
+ droppedReasoning,
606
+ stringInput: { original: body.input, coreId: id }
607
+ };
532
608
  }
533
609
  for (const raw of body.input) {
534
610
  const item = normalizeEasyInputItem(raw);
@@ -566,7 +642,9 @@ function responsesToCore(body) {
566
642
  const split = splitDemotedThinking(text);
567
643
  if (split) {
568
644
  msgs.push({
569
- id: clusters.next(deriveMessageId("assistant", "reasoning", split.reasoning)),
645
+ id: clusters.next(
646
+ deriveMessageId("assistant", "reasoning", split.reasoning)
647
+ ),
570
648
  role: "assistant",
571
649
  contentType: "reasoning",
572
650
  text: split.reasoning,
@@ -579,7 +657,9 @@ function responsesToCore(body) {
579
657
  if (effText || role === "user" && hasImage) {
580
658
  const displayText = role === "user" ? userDisplayText(message.content, effText) : effText;
581
659
  coreId = clusters.next(deriveMessageId(role, "text", displayText));
582
- const imageUrl = Array.isArray(message.content) ? message.content.find((part) => part.type === "input_image" && typeof part.image_url === "string")?.image_url : void 0;
660
+ const imageUrl = Array.isArray(message.content) ? message.content.find(
661
+ (part) => part.type === "input_image" && typeof part.image_url === "string"
662
+ )?.image_url : void 0;
583
663
  const image = typeof imageUrl === "string" ? parseDataUrl(imageUrl) : void 0;
584
664
  msgs.push({
585
665
  id: coreId,
@@ -595,10 +675,12 @@ function responsesToCore(body) {
595
675
  }
596
676
  case "function_call": {
597
677
  const call = item;
598
- coreId = clusters.next(deriveMessageId("assistant", "tool-call", call.arguments ?? "", {
599
- toolCallId: call.call_id,
600
- toolName: call.name
601
- }));
678
+ coreId = clusters.next(
679
+ deriveMessageId("assistant", "tool-call", call.arguments ?? "", {
680
+ toolCallId: call.call_id,
681
+ toolName: call.name
682
+ })
683
+ );
602
684
  msgs.push({
603
685
  id: coreId,
604
686
  role: "assistant",
@@ -614,9 +696,21 @@ function responsesToCore(body) {
614
696
  case "function_call_output": {
615
697
  const output = item;
616
698
  const text = typeof output.output === "string" ? output.output : JSON.stringify(output.output);
617
- coreId = clusters.next(deriveMessageId("tool", "tool-result", text, { toolCallId: output.call_id }));
699
+ coreId = clusters.next(
700
+ deriveMessageId("tool", "tool-result", text, {
701
+ toolCallId: output.call_id
702
+ })
703
+ );
618
704
  const name = toolNames.get(output.call_id);
619
- msgs.push({ id: coreId, role: "tool", contentType: "tool-result", toolCallId: output.call_id, text, ...name ? { toolName: name } : {}, rawResponsesItem: item });
705
+ msgs.push({
706
+ id: coreId,
707
+ role: "tool",
708
+ contentType: "tool-result",
709
+ toolCallId: output.call_id,
710
+ text,
711
+ ...name ? { toolName: name } : {},
712
+ rawResponsesItem: item
713
+ });
620
714
  break;
621
715
  }
622
716
  case "computer_call":
@@ -627,8 +721,16 @@ function responsesToCore(body) {
627
721
  case "code_interpreter_call":
628
722
  case "mcp_call": {
629
723
  const rid = typeof item.id === "string" ? String(item.id) : hashId(JSON.stringify(item));
630
- coreId = clusters.next(deriveMessageId("assistant", "responses-call", rid));
631
- msgs.push({ id: coreId, role: "assistant", contentType: "reasoning", text: rid, rawResponsesItem: item });
724
+ coreId = clusters.next(
725
+ deriveMessageId("assistant", "responses-call", rid)
726
+ );
727
+ msgs.push({
728
+ id: coreId,
729
+ role: "assistant",
730
+ contentType: "reasoning",
731
+ text: rid,
732
+ rawResponsesItem: item
733
+ });
632
734
  break;
633
735
  }
634
736
  case "custom_tool_call": {
@@ -636,8 +738,21 @@ function responsesToCore(body) {
636
738
  const callId = ctc.call_id ?? `call_${idx}`;
637
739
  customToolCallIds.add(callId);
638
740
  const argText = ctc.input ?? ctc.arguments ?? "";
639
- coreId = clusters.next(deriveMessageId("assistant", "tool-call", argText, { toolCallId: callId, toolName: ctc.name ?? "custom" }));
640
- msgs.push({ id: coreId, role: "assistant", contentType: "tool-call", toolName: ctc.name ?? "custom", toolCallId: callId, text: argText, rawResponsesItem: item });
741
+ coreId = clusters.next(
742
+ deriveMessageId("assistant", "tool-call", argText, {
743
+ toolCallId: callId,
744
+ toolName: ctc.name ?? "custom"
745
+ })
746
+ );
747
+ msgs.push({
748
+ id: coreId,
749
+ role: "assistant",
750
+ contentType: "tool-call",
751
+ toolName: ctc.name ?? "custom",
752
+ toolCallId: callId,
753
+ text: argText,
754
+ rawResponsesItem: item
755
+ });
641
756
  toolNames.set(callId, ctc.name ?? "custom");
642
757
  break;
643
758
  }
@@ -646,9 +761,21 @@ function responsesToCore(body) {
646
761
  const callId = ctco.call_id ?? `call_${idx}`;
647
762
  customToolCallIds.add(callId);
648
763
  const outText = typeof ctco.output === "string" ? ctco.output : JSON.stringify(ctco.output ?? "");
649
- coreId = clusters.next(deriveMessageId("tool", "tool-result", outText, { toolCallId: callId }));
764
+ coreId = clusters.next(
765
+ deriveMessageId("tool", "tool-result", outText, {
766
+ toolCallId: callId
767
+ })
768
+ );
650
769
  const name = toolNames.get(callId);
651
- msgs.push({ id: coreId, role: "tool", contentType: "tool-result", toolCallId: callId, text: outText, ...name ? { toolName: name } : {}, rawResponsesItem: item });
770
+ msgs.push({
771
+ id: coreId,
772
+ role: "tool",
773
+ contentType: "tool-result",
774
+ toolCallId: callId,
775
+ text: outText,
776
+ ...name ? { toolName: name } : {},
777
+ rawResponsesItem: item
778
+ });
652
779
  break;
653
780
  }
654
781
  default:
@@ -658,7 +785,14 @@ function responsesToCore(body) {
658
785
  layout.push({ original: item, coreId });
659
786
  idx++;
660
787
  }
661
- return { msgs, systemParts, preamble, customToolCallIds, layout, droppedReasoning };
788
+ return {
789
+ msgs,
790
+ systemParts,
791
+ preamble,
792
+ customToolCallIds,
793
+ layout,
794
+ droppedReasoning
795
+ };
662
796
  }
663
797
  function patchTextParts(parts, text) {
664
798
  const textIndexes = parts.flatMap(
@@ -674,7 +808,8 @@ function patchTextParts(parts, text) {
674
808
  });
675
809
  }
676
810
  function patchOriginalItem(original, source, next) {
677
- if (source.text === next.text && source.toolName === next.toolName && source.toolCallId === next.toolCallId && source.role === next.role && source.contentType === next.contentType) return original;
811
+ if (source.text === next.text && source.toolName === next.toolName && source.toolCallId === next.toolCallId && source.role === next.role && source.contentType === next.contentType)
812
+ return original;
678
813
  if (original.type === "message") {
679
814
  const message = original;
680
815
  const content = typeof message.content === "string" ? next.text ?? "" : patchTextParts(message.content, next.text ?? "");
@@ -689,20 +824,30 @@ function patchOriginalItem(original, source, next) {
689
824
  };
690
825
  }
691
826
  if (original.type === "function_call_output") {
692
- return { ...original, call_id: next.toolCallId ?? String(original.call_id ?? ""), output: next.text ?? "" };
827
+ return {
828
+ ...original,
829
+ call_id: next.toolCallId ?? String(original.call_id ?? ""),
830
+ output: next.text ?? ""
831
+ };
693
832
  }
694
833
  return original;
695
834
  }
696
835
  function patchResponsesInput(projection, messages) {
697
836
  if (projection.stringInput) {
698
- const original = projection.msgs.find((message) => message.id === projection.stringInput?.coreId);
699
- const next = messages.find((message) => message.id === projection.stringInput?.coreId);
837
+ const original = projection.msgs.find(
838
+ (message) => message.id === projection.stringInput?.coreId
839
+ );
840
+ const next = messages.find(
841
+ (message) => message.id === projection.stringInput?.coreId
842
+ );
700
843
  if (original && next && messages.length === 1 && next.role === "user" && next.contentType === "text") {
701
844
  return next.text === original.text ? projection.stringInput.original : next.text ?? "";
702
845
  }
703
846
  return coreToResponses(messages, projection.customToolCallIds);
704
847
  }
705
- const sourceById = new Map(projection.msgs.map((message) => [message.id, message]));
848
+ const sourceById = new Map(
849
+ projection.msgs.map((message) => [message.id, message])
850
+ );
706
851
  const nextById = new Map(messages.map((message) => [message.id, message]));
707
852
  const slotById = /* @__PURE__ */ new Map();
708
853
  projection.layout.forEach((slot, index) => {
@@ -721,7 +866,8 @@ function patchResponsesInput(projection, messages) {
721
866
  }
722
867
  }
723
868
  const generated = coreToResponses([message], projection.customToolCallIds);
724
- if (generated.length > 0) insertions.set(target, [...insertions.get(target) ?? [], ...generated]);
869
+ if (generated.length > 0)
870
+ insertions.set(target, [...insertions.get(target) ?? [], ...generated]);
725
871
  }
726
872
  const out = [];
727
873
  projection.layout.forEach((slot, index) => {
@@ -732,7 +878,8 @@ function patchResponsesInput(projection, messages) {
732
878
  }
733
879
  const source = sourceById.get(slot.coreId);
734
880
  const next = nextById.get(slot.coreId);
735
- if (source && next) out.push(patchOriginalItem(slot.original, source, next));
881
+ if (source && next)
882
+ out.push(patchOriginalItem(slot.original, source, next));
736
883
  });
737
884
  out.push(...insertions.get(projection.layout.length) ?? []);
738
885
  return out;
@@ -743,20 +890,48 @@ function coreToResponses(messages, customToolCallIds = /* @__PURE__ */ new Set()
743
890
  const biliMessage = message;
744
891
  const raw = biliMessage.rawResponsesItem;
745
892
  if (message.role === "system") {
746
- out.push({ type: "message", role: "developer", content: message.text ?? "" });
893
+ out.push({
894
+ type: "message",
895
+ role: "developer",
896
+ content: message.text ?? ""
897
+ });
747
898
  } else if (message.role === "user") {
748
899
  const rawMessage = raw?.type === "message" ? raw : void 0;
749
- if (rawMessage && userDisplayText(rawMessage.content, messageContent(rawMessage.content)) === (message.text ?? "")) out.push(rawMessage);
750
- else out.push({ type: "message", role: "user", content: message.text ?? "" });
900
+ if (rawMessage && userDisplayText(
901
+ rawMessage.content,
902
+ messageContent(rawMessage.content)
903
+ ) === (message.text ?? ""))
904
+ out.push(rawMessage);
905
+ else
906
+ out.push({
907
+ type: "message",
908
+ role: "user",
909
+ content: message.text ?? ""
910
+ });
751
911
  } else if (message.role === "assistant") {
752
912
  if (message.contentType === "text") {
753
- out.push({ type: "message", role: "assistant", content: message.text ?? "" });
913
+ out.push({
914
+ type: "message",
915
+ role: "assistant",
916
+ content: message.text ?? ""
917
+ });
754
918
  } else if (message.contentType === "tool-call") {
755
919
  const callId = message.toolCallId ?? `call_${message.id}`;
756
920
  if (customToolCallIds.has(callId)) {
757
- out.push({ type: "custom_tool_call", call_id: callId, name: message.toolName ?? "unknown", input: message.text ?? "", status: "completed" });
921
+ out.push({
922
+ type: "custom_tool_call",
923
+ call_id: callId,
924
+ name: message.toolName ?? "unknown",
925
+ input: message.text ?? "",
926
+ status: "completed"
927
+ });
758
928
  } else {
759
- out.push({ type: "function_call", call_id: callId, name: message.toolName ?? "unknown", arguments: message.text ?? "" });
929
+ out.push({
930
+ type: "function_call",
931
+ call_id: callId,
932
+ name: message.toolName ?? "unknown",
933
+ arguments: message.text ?? ""
934
+ });
760
935
  }
761
936
  } else if (message.contentType === "reasoning") {
762
937
  if (raw) out.push(raw);
@@ -764,9 +939,17 @@ function coreToResponses(messages, customToolCallIds = /* @__PURE__ */ new Set()
764
939
  } else if (message.role === "tool") {
765
940
  const callId = message.toolCallId ?? "";
766
941
  if (customToolCallIds.has(callId)) {
767
- out.push({ type: "custom_tool_call_output", call_id: callId, output: message.text ?? "" });
942
+ out.push({
943
+ type: "custom_tool_call_output",
944
+ call_id: callId,
945
+ output: message.text ?? ""
946
+ });
768
947
  } else {
769
- out.push({ type: "function_call_output", call_id: callId, output: message.text ?? "" });
948
+ out.push({
949
+ type: "function_call_output",
950
+ call_id: callId,
951
+ output: message.text ?? ""
952
+ });
770
953
  }
771
954
  }
772
955
  }
@@ -780,18 +963,39 @@ function injectResponsesDeveloperMessage(input, content) {
780
963
  return items;
781
964
  }
782
965
  function conversationIdentityResponses(body, headerValue) {
783
- if (headerValue?.trim()) return { value: headerValue.trim(), source: "header", clientProvided: true };
966
+ if (headerValue?.trim())
967
+ return {
968
+ value: headerValue.trim(),
969
+ source: "header",
970
+ clientProvided: true
971
+ };
784
972
  if (typeof body.session_id === "string" && body.session_id.trim()) {
785
- return { value: body.session_id.trim(), source: "body-session", clientProvided: true };
973
+ return {
974
+ value: body.session_id.trim(),
975
+ source: "body-session",
976
+ clientProvided: true
977
+ };
786
978
  }
787
979
  const metadataSession = body.metadata?.session_id;
788
980
  if (typeof metadataSession === "string" && metadataSession.trim()) {
789
- return { value: metadataSession.trim(), source: "metadata-session", clientProvided: true };
981
+ return {
982
+ value: metadataSession.trim(),
983
+ source: "metadata-session",
984
+ clientProvided: true
985
+ };
790
986
  }
791
987
  if (typeof body.previous_response_id === "string" && body.previous_response_id.trim()) {
792
- return { value: body.previous_response_id.trim(), source: "previous-response", clientProvided: false };
988
+ return {
989
+ value: body.previous_response_id.trim(),
990
+ source: "previous-response",
991
+ clientProvided: false
992
+ };
793
993
  }
794
- return { value: hashId(JSON.stringify(body.input ?? [])), source: "content-fingerprint", clientProvided: false };
994
+ return {
995
+ value: hashId(JSON.stringify(body.input ?? [])),
996
+ source: "content-fingerprint",
997
+ clientProvided: false
998
+ };
795
999
  }
796
1000
  function conversationSignalResponses(body, headerValue) {
797
1001
  return conversationIdentityResponses(body, headerValue).value;
@@ -800,7 +1004,8 @@ function createSubagentNamespaces() {
800
1004
  const anchors = /* @__PURE__ */ new Map();
801
1005
  return {
802
1006
  namespaceFor(identityValue, instructions) {
803
- if (typeof instructions !== "string" || instructions.trim().length === 0) return identityValue;
1007
+ if (typeof instructions !== "string" || instructions.trim().length === 0)
1008
+ return identityValue;
804
1009
  const fp = hashId(instructions);
805
1010
  const anchor = anchors.get(identityValue);
806
1011
  if (anchor === void 0) {
@@ -1092,7 +1297,12 @@ function jsonValue(text) {
1092
1297
  }
1093
1298
 
1094
1299
  // src/wire/formats.ts
1095
- var WIRE_FORMATS = ["anthropic", "openai", "responses", "google"];
1300
+ var WIRE_FORMATS = [
1301
+ "anthropic",
1302
+ "openai",
1303
+ "responses",
1304
+ "google"
1305
+ ];
1096
1306
  function isWireFormat(value) {
1097
1307
  return typeof value === "string" && WIRE_FORMATS.includes(value);
1098
1308
  }
@@ -1137,13 +1347,17 @@ function thinkingText(blocks) {
1137
1347
  return blocks?.filter((b) => b.type === "thinking" && b.thinking.trim().length > 0).map((b) => b.thinking).join("\n") ?? "";
1138
1348
  }
1139
1349
  function mirrorOpenaiMessages(view, systemText) {
1140
- const messages = [{ role: "system", content: systemText }];
1350
+ const messages = [
1351
+ { role: "system", content: systemText }
1352
+ ];
1141
1353
  for (const message of view) {
1142
1354
  if (message.role === "user") {
1143
1355
  const text = joinText(message.blocks);
1144
1356
  if (text) messages.push({ role: "user", content: text });
1145
1357
  } else if (message.role === "assistant") {
1146
- const calls = (message.blocks ?? []).filter((b) => b.type === "toolCall");
1358
+ const calls = (message.blocks ?? []).filter(
1359
+ (b) => b.type === "toolCall"
1360
+ );
1147
1361
  const reasoning = thinkingText(message.blocks);
1148
1362
  const text = joinText(message.blocks);
1149
1363
  if (calls.length > 0) {
@@ -1154,14 +1368,25 @@ function mirrorOpenaiMessages(view, systemText) {
1154
1368
  tool_calls: calls.map((c) => ({
1155
1369
  id: c.id,
1156
1370
  type: "function",
1157
- function: { name: c.name ?? "", arguments: JSON.stringify(c.arguments ?? {}) }
1371
+ function: {
1372
+ name: c.name ?? "",
1373
+ arguments: JSON.stringify(c.arguments ?? {})
1374
+ }
1158
1375
  }))
1159
1376
  });
1160
1377
  } else if (text || reasoning) {
1161
- messages.push({ role: "assistant", content: text, ...reasoning ? { reasoning_content: reasoning } : {} });
1378
+ messages.push({
1379
+ role: "assistant",
1380
+ content: text,
1381
+ ...reasoning ? { reasoning_content: reasoning } : {}
1382
+ });
1162
1383
  }
1163
1384
  } else if (message.role === "toolResult") {
1164
- messages.push({ role: "tool", tool_call_id: message.toolCallId ?? "", content: joinText(message.blocks) });
1385
+ messages.push({
1386
+ role: "tool",
1387
+ tool_call_id: message.toolCallId ?? "",
1388
+ content: joinText(message.blocks)
1389
+ });
1165
1390
  } else {
1166
1391
  const text = message.text ?? "";
1167
1392
  if (text) messages.push({ role: "developer", content: text });
@@ -1174,7 +1399,8 @@ function mirrorAnthropicMessages(view) {
1174
1399
  for (const message of view) {
1175
1400
  if (message.role === "user") {
1176
1401
  const text = joinText(message.blocks);
1177
- if (text) messages.push({ role: "user", content: [{ type: "text", text }] });
1402
+ if (text)
1403
+ messages.push({ role: "user", content: [{ type: "text", text }] });
1178
1404
  } else if (message.role === "assistant") {
1179
1405
  const content = [];
1180
1406
  for (const b of message.blocks ?? []) {
@@ -1193,18 +1419,30 @@ function mirrorAnthropicMessages(view) {
1193
1419
  } catch {
1194
1420
  input = {};
1195
1421
  }
1196
- content.push({ type: "tool_use", id: b.id, name: b.name ?? "", input });
1422
+ content.push({
1423
+ type: "tool_use",
1424
+ id: b.id,
1425
+ name: b.name ?? "",
1426
+ input
1427
+ });
1197
1428
  }
1198
1429
  }
1199
1430
  if (content.length > 0) messages.push({ role: "assistant", content });
1200
1431
  } else if (message.role === "toolResult") {
1201
1432
  messages.push({
1202
1433
  role: "user",
1203
- content: [{ type: "tool_result", tool_use_id: message.toolCallId ?? "", content: joinText(message.blocks) }]
1434
+ content: [
1435
+ {
1436
+ type: "tool_result",
1437
+ tool_use_id: message.toolCallId ?? "",
1438
+ content: joinText(message.blocks)
1439
+ }
1440
+ ]
1204
1441
  });
1205
1442
  } else {
1206
1443
  const text = message.text ?? "";
1207
- if (text) messages.push({ role: "user", content: [{ type: "text", text }] });
1444
+ if (text)
1445
+ messages.push({ role: "user", content: [{ type: "text", text }] });
1208
1446
  }
1209
1447
  }
1210
1448
  return messages;
@@ -1214,13 +1452,25 @@ function mirrorResponsesInput(view) {
1214
1452
  for (const message of view) {
1215
1453
  if (message.role === "user") {
1216
1454
  const text = joinText(message.blocks);
1217
- if (text) input.push({ type: "message", role: "user", content: [{ type: "input_text", text }] });
1455
+ if (text)
1456
+ input.push({
1457
+ type: "message",
1458
+ role: "user",
1459
+ content: [{ type: "input_text", text }]
1460
+ });
1218
1461
  } else if (message.role === "assistant") {
1219
1462
  for (const b of message.blocks ?? []) {
1220
1463
  if (b.type === "thinking" && b.thinking.trim().length > 0) {
1221
- input.push({ type: "reasoning", summary: [{ type: "summary_text", text: b.thinking }] });
1464
+ input.push({
1465
+ type: "reasoning",
1466
+ summary: [{ type: "summary_text", text: b.thinking }]
1467
+ });
1222
1468
  } else if (b.type === "text" && b.text.trim().length > 0) {
1223
- input.push({ type: "message", role: "assistant", content: [{ type: "output_text", text: b.text }] });
1469
+ input.push({
1470
+ type: "message",
1471
+ role: "assistant",
1472
+ content: [{ type: "output_text", text: b.text }]
1473
+ });
1224
1474
  } else if (b.type === "toolCall") {
1225
1475
  let args = "{}";
1226
1476
  try {
@@ -1228,14 +1478,28 @@ function mirrorResponsesInput(view) {
1228
1478
  } catch {
1229
1479
  args = "{}";
1230
1480
  }
1231
- input.push({ type: "function_call", call_id: b.id ?? "", name: b.name ?? "", arguments: args });
1481
+ input.push({
1482
+ type: "function_call",
1483
+ call_id: b.id ?? "",
1484
+ name: b.name ?? "",
1485
+ arguments: args
1486
+ });
1232
1487
  }
1233
1488
  }
1234
1489
  } else if (message.role === "toolResult") {
1235
- input.push({ type: "function_call_output", call_id: message.toolCallId ?? "", output: joinText(message.blocks) });
1490
+ input.push({
1491
+ type: "function_call_output",
1492
+ call_id: message.toolCallId ?? "",
1493
+ output: joinText(message.blocks)
1494
+ });
1236
1495
  } else {
1237
1496
  const text = message.text ?? "";
1238
- if (text) input.push({ type: "message", role: "user", content: [{ type: "input_text", text }] });
1497
+ if (text)
1498
+ input.push({
1499
+ type: "message",
1500
+ role: "user",
1501
+ content: [{ type: "input_text", text }]
1502
+ });
1239
1503
  }
1240
1504
  }
1241
1505
  return input;
@@ -1277,7 +1541,11 @@ function compressToolArgs(call) {
1277
1541
  if (!args || typeof args !== "object" || Array.isArray(args)) return null;
1278
1542
  const a = args;
1279
1543
  if (call.name === "compress") {
1280
- return Array.isArray(a.content) ? { content: a.content, topic: a.topic, summaryMaxChars: a.summaryMaxChars } : null;
1544
+ return Array.isArray(a.content) ? {
1545
+ content: a.content,
1546
+ topic: a.topic,
1547
+ summaryMaxChars: a.summaryMaxChars
1548
+ } : null;
1281
1549
  }
1282
1550
  if (call.name !== "write") return null;
1283
1551
  const path = typeof a.path === "string" ? a.path.split("?")[0].replace(/\/+$/, "") : "";
@@ -1293,12 +1561,17 @@ function compressToolArgs(call) {
1293
1561
  if (!inner || typeof inner !== "object") return null;
1294
1562
  if (Array.isArray(inner)) return { content: inner };
1295
1563
  const ia = inner;
1296
- return Array.isArray(ia.content) ? { content: ia.content, topic: ia.topic, summaryMaxChars: ia.summaryMaxChars } : { content: [ia] };
1564
+ return Array.isArray(ia.content) ? {
1565
+ content: ia.content,
1566
+ topic: ia.topic,
1567
+ summaryMaxChars: ia.summaryMaxChars
1568
+ } : { content: [ia] };
1297
1569
  }
1298
1570
  function toolCallNames(msgs) {
1299
1571
  const names = /* @__PURE__ */ new Map();
1300
1572
  for (const m of msgs) {
1301
- if (m.contentType === "tool-call" && m.toolCallId && m.toolName) names.set(m.toolCallId, m.toolName);
1573
+ if (m.contentType === "tool-call" && m.toolCallId && m.toolName)
1574
+ names.set(m.toolCallId, m.toolName);
1302
1575
  }
1303
1576
  return names;
1304
1577
  }
@@ -1320,7 +1593,8 @@ function findCompressCallsCore(msg) {
1320
1593
  const callTopic = typeof args.topic === "string" ? args.topic : void 0;
1321
1594
  for (const item of content) {
1322
1595
  const r = item;
1323
- if (typeof r.startId !== "string" || typeof r.endId !== "string" || typeof r.summary !== "string" || r.summary.length === 0) continue;
1596
+ if (typeof r.startId !== "string" || typeof r.endId !== "string" || typeof r.summary !== "string" || r.summary.length === 0)
1597
+ continue;
1324
1598
  ranges.push({
1325
1599
  startRef: r.startId,
1326
1600
  endRef: r.endId,
@@ -1375,7 +1649,8 @@ function boundaryIndexCore(ref, byRef, blocks, coreMessages, pick, fallbackIdx =
1375
1649
  function refOfPieceCore(coreMessages, idx, byRef) {
1376
1650
  const id = coreMessages[idx]?.id;
1377
1651
  if (!id) return "";
1378
- for (const [ref, mapped] of Object.entries(byRef)) if (mapped === id) return ref;
1652
+ for (const [ref, mapped] of Object.entries(byRef))
1653
+ if (mapped === id) return ref;
1379
1654
  return "";
1380
1655
  }
1381
1656
  function staleRangeCore(r, rangeIndex, resultText, coreMessages, callIndex, byRef, blocks) {
@@ -1385,7 +1660,13 @@ function staleRangeCore(r, rangeIndex, resultText, coreMessages, callIndex, byRe
1385
1660
  const [ps, pe] = pair === "-" ? ["", ""] : pair.split("-");
1386
1661
  const fbStart = ps && ps !== "" ? Number.parseInt(ps, 10) : -1;
1387
1662
  const fbEnd = pe && pe !== "" ? Number.parseInt(pe, 10) : -1;
1388
- const startRaw = boundaryRawCore(r.startRef, byRef, blocks, coreMessages, "min");
1663
+ const startRaw = boundaryRawCore(
1664
+ r.startRef,
1665
+ byRef,
1666
+ blocks,
1667
+ coreMessages,
1668
+ "min"
1669
+ );
1389
1670
  const endRaw = boundaryRawCore(r.endRef, byRef, blocks, coreMessages, "max");
1390
1671
  const rawStartIdx = startRaw ? coreMessages.findIndex((cm) => cm.id === startRaw) : -1;
1391
1672
  const rawEndIdx = endRaw ? coreMessages.findIndex((cm) => cm.id === endRaw) : -1;
@@ -1393,27 +1674,46 @@ function staleRangeCore(r, rangeIndex, resultText, coreMessages, callIndex, byRe
1393
1674
  const endIdx = rawEndIdx >= 0 ? rawEndIdx : fbEnd >= 0 && fbEnd < coreMessages.length ? fbEnd : -1;
1394
1675
  if (startIdx < 0 || endIdx < 0) {
1395
1676
  if (!/^b\d+$/i.test(r.startRef.trim()) && !/^b\d+$/i.test(r.endRef.trim()))
1396
- return { reject: `unresolved ${r.startRef}..${r.endRef} -> ${startIdx}..${endIdx}`, ...hinted ? { hint: true } : {} };
1677
+ return {
1678
+ reject: `unresolved ${r.startRef}..${r.endRef} -> ${startIdx}..${endIdx}`,
1679
+ ...hinted ? { hint: true } : {}
1680
+ };
1397
1681
  return {};
1398
1682
  }
1399
- if (endIdx > callIndex) return { reject: `end idx ${endIdx} > callIndex ${callIndex}`, ...hinted ? { hint: true } : {} };
1683
+ if (endIdx > callIndex)
1684
+ return {
1685
+ reject: `end idx ${endIdx} > callIndex ${callIndex}`,
1686
+ ...hinted ? { hint: true } : {}
1687
+ };
1400
1688
  const m = resultText.match(/\[fp=([0-9a-f,-]+)\]/);
1401
1689
  if (m) {
1402
1690
  const want = m[1].split(",")[rangeIndex];
1403
1691
  if (want !== void 0 && want !== "-") {
1404
1692
  const got = spanFingerprintCoreIdx(coreMessages, startIdx, endIdx);
1405
- if (want !== got) return { reject: `fp ${r.startRef}..${r.endRef} want ${want} got ${got} @${startIdx}..${endIdx}`, ...hinted ? { hint: true } : {} };
1693
+ if (want !== got)
1694
+ return {
1695
+ reject: `fp ${r.startRef}..${r.endRef} want ${want} got ${got} @${startIdx}..${endIdx}`,
1696
+ ...hinted ? { hint: true } : {}
1697
+ };
1406
1698
  }
1407
1699
  }
1408
1700
  const remap = {};
1409
1701
  if (/^m\d+$/i.test(r.startRef.trim()) && rawStartIdx < 0) {
1410
1702
  const ref = refOfPieceCore(coreMessages, startIdx, byRef);
1411
- if (!ref) return { reject: `recovered ${r.startRef} @${startIdx} has no ref (protected piece)`, ...hinted ? { hint: true } : {} };
1703
+ if (!ref)
1704
+ return {
1705
+ reject: `recovered ${r.startRef} @${startIdx} has no ref (protected piece)`,
1706
+ ...hinted ? { hint: true } : {}
1707
+ };
1412
1708
  remap.startRef = ref;
1413
1709
  }
1414
1710
  if (/^m\d+$/i.test(r.endRef.trim()) && rawEndIdx < 0) {
1415
1711
  const ref = refOfPieceCore(coreMessages, endIdx, byRef);
1416
- if (!ref) return { reject: `recovered ${r.endRef} @${endIdx} has no ref (protected piece)`, ...hinted ? { hint: true } : {} };
1712
+ if (!ref)
1713
+ return {
1714
+ reject: `recovered ${r.endRef} @${endIdx} has no ref (protected piece)`,
1715
+ ...hinted ? { hint: true } : {}
1716
+ };
1417
1717
  remap.endRef = ref;
1418
1718
  }
1419
1719
  if (!remap.startRef && !remap.endRef) return {};
@@ -1421,7 +1721,13 @@ function staleRangeCore(r, rangeIndex, resultText, coreMessages, callIndex, byRe
1421
1721
  }
1422
1722
  function rangeFingerprintsCore(ranges, coreMessages, byRef, blocks) {
1423
1723
  return ranges.map((r) => {
1424
- const start = boundaryRawCore(r.startRef, byRef, blocks, coreMessages, "min");
1724
+ const start = boundaryRawCore(
1725
+ r.startRef,
1726
+ byRef,
1727
+ blocks,
1728
+ coreMessages,
1729
+ "min"
1730
+ );
1425
1731
  const end = start ? boundaryRawCore(r.endRef, byRef, blocks, coreMessages, "max") : "";
1426
1732
  if (start && end) {
1427
1733
  const fp = spanFingerprintCore(coreMessages, start, end);
@@ -1456,6 +1762,63 @@ function placeholderContent(protocol) {
1456
1762
  const type = protocol === "responses" ? "input_text" : "text";
1457
1763
  return [{ type, text: IMAGE_PLACEHOLDER }];
1458
1764
  }
1765
+ function isGoogleNestedImage(part) {
1766
+ if (!isObj(part)) return false;
1767
+ const media = isObj(part.inlineData) ? part.inlineData : part.fileData;
1768
+ return isObj(media) && typeof media.mimeType === "string" && media.mimeType.startsWith("image/");
1769
+ }
1770
+ function stripNestedImages(protocol, part) {
1771
+ if (!isObj(part)) return { part, removed: 0 };
1772
+ if (protocol === "anthropic" && part.type === "tool_result" && Array.isArray(part.content)) {
1773
+ const inner = part.content;
1774
+ const kept = inner.filter((p) => !isImagePart(protocol, p));
1775
+ const removed = inner.length - kept.length;
1776
+ if (removed === 0) return { part, removed: 0 };
1777
+ return {
1778
+ part: {
1779
+ ...part,
1780
+ content: kept.length > 0 ? kept : placeholderContent(protocol)
1781
+ },
1782
+ removed
1783
+ };
1784
+ }
1785
+ if (protocol === "google" && isObj(part.functionResponse) && Array.isArray(part.functionResponse.parts)) {
1786
+ const fr = part.functionResponse;
1787
+ if (JSON.stringify(fr.response ?? null).includes('"$ref"'))
1788
+ return { part, removed: 0 };
1789
+ const inner = fr.parts;
1790
+ const kept = inner.filter((p) => !isGoogleNestedImage(p));
1791
+ const removed = inner.length - kept.length;
1792
+ if (removed === 0) return { part, removed: 0 };
1793
+ const { parts: _, ...rest } = fr;
1794
+ return {
1795
+ part: {
1796
+ ...part,
1797
+ functionResponse: kept.length > 0 ? { ...fr, parts: kept } : rest
1798
+ },
1799
+ removed
1800
+ };
1801
+ }
1802
+ return { part, removed: 0 };
1803
+ }
1804
+ function stripParts(protocol, parts) {
1805
+ let removed = 0;
1806
+ const kept = [];
1807
+ for (const p of parts) {
1808
+ if (isImagePart(protocol, p)) {
1809
+ removed++;
1810
+ continue;
1811
+ }
1812
+ const nested = stripNestedImages(protocol, p);
1813
+ removed += nested.removed;
1814
+ kept.push(nested.part);
1815
+ }
1816
+ if (removed === 0) return null;
1817
+ return {
1818
+ parts: kept.length > 0 ? kept : placeholderContent(protocol),
1819
+ removed
1820
+ };
1821
+ }
1459
1822
  function stripHistoricalImages(body, protocol, keepRecent) {
1460
1823
  if (!protocol || !isObj(body)) return { body, removed: 0 };
1461
1824
  const recentCount = Math.max(0, Math.floor(keepRecent));
@@ -1466,20 +1829,14 @@ function stripHistoricalImages(body, protocol, keepRecent) {
1466
1829
  let removed2 = 0;
1467
1830
  let touched2 = false;
1468
1831
  const nextInput = input.map((item, i) => {
1469
- if (i < cutoff2 && isObj(item) && Array.isArray(item.content)) {
1470
- const content = item.content;
1471
- const imgs = content.filter((p) => isImagePart("responses", p)).length;
1472
- if (imgs > 0) {
1473
- removed2 += imgs;
1474
- touched2 = true;
1475
- const kept = content.filter((p) => !isImagePart("responses", p));
1476
- return {
1477
- ...item,
1478
- content: kept.length > 0 ? kept : placeholderContent("responses")
1479
- };
1480
- }
1481
- }
1482
- return item;
1832
+ if (i >= cutoff2 || !isObj(item)) return item;
1833
+ const key = item.type === "function_call_output" || item.type === "custom_tool_call_output" ? "output" : "content";
1834
+ if (!Array.isArray(item[key])) return item;
1835
+ const r = stripParts("responses", item[key]);
1836
+ if (!r) return item;
1837
+ removed2 += r.removed;
1838
+ touched2 = true;
1839
+ return { ...item, [key]: r.parts };
1483
1840
  });
1484
1841
  if (!touched2) return { body, removed: 0 };
1485
1842
  return { body: { ...body, input: nextInput }, removed: removed2 };
@@ -1492,16 +1849,11 @@ function stripHistoricalImages(body, protocol, keepRecent) {
1492
1849
  let touched2 = false;
1493
1850
  const nextContents = contents.map((c, i) => {
1494
1851
  if (i < cutoff2 && isObj(c) && Array.isArray(c.parts)) {
1495
- const parts = c.parts;
1496
- const imgs = parts.filter((p) => isImagePart("google", p)).length;
1497
- if (imgs > 0) {
1498
- removed2 += imgs;
1852
+ const r = stripParts("google", c.parts);
1853
+ if (r) {
1854
+ removed2 += r.removed;
1499
1855
  touched2 = true;
1500
- const kept = parts.filter((p) => !isImagePart("google", p));
1501
- return {
1502
- ...c,
1503
- parts: kept.length > 0 ? kept : placeholderContent("google")
1504
- };
1856
+ return { ...c, parts: r.parts };
1505
1857
  }
1506
1858
  }
1507
1859
  return c;
@@ -1516,16 +1868,11 @@ function stripHistoricalImages(body, protocol, keepRecent) {
1516
1868
  let touched = false;
1517
1869
  const nextMessages = messages.map((m, i) => {
1518
1870
  if (i < cutoff && isObj(m) && Array.isArray(m.content)) {
1519
- const content = m.content;
1520
- const imgs = content.filter((p) => isImagePart(protocol, p)).length;
1521
- if (imgs > 0) {
1522
- removed += imgs;
1871
+ const r = stripParts(protocol, m.content);
1872
+ if (r) {
1873
+ removed += r.removed;
1523
1874
  touched = true;
1524
- const kept = content.filter((p) => !isImagePart(protocol, p));
1525
- return {
1526
- ...m,
1527
- content: kept.length > 0 ? kept : placeholderContent(protocol)
1528
- };
1875
+ return { ...m, content: r.parts };
1529
1876
  }
1530
1877
  }
1531
1878
  return m;