chainlesschain 0.166.114 → 0.166.117

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 (183) hide show
  1. package/README.md +23 -3
  2. package/package.json +3 -3
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-CVac3rIN.js → AIOps-C9tSCImB.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-ChM9GxMl.js → ActionButton-CXKExmT_.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-CV5399Js.js → Analytics-DE8WBWHo.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-CuonVXhg.js → AppLayout-BdpwNM08.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-D9qKfgb6.js → Artifacts-94TQpe38.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-DUvLysQc.js → Audit-DdDEv5Ej.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-DfKohQeT.js → BackgroundAgents-TU9nlV7j.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-CohoEI8R.js → Backup-C0GPoUUq.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-BwdoA3xv.js → BaseInput-iyrVn2I6.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-DRkuz1d2.js → Chat-Dqo8spwp.js} +5 -5
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-v3pzeHNC.js → ChatBubbleRenderer-CDqHSzc4.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-B-GNGpKv.js → Checkbox-BF_XJvQi.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-Bs2lAsoZ.js → Codegen-5tUWoOa9.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-Bk1mJKDZ.js → Col-BQxSeRvG.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-B_FDSCOo.js → Community-B2Ra7w-J.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-No1qSLLH.js → Compact-GjxJwlr0.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CcrG43-d.js → Compliance-BTUP6RTA.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-DLkj2ywK.js → Cowork-DiwfL16s.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-sQHELVEz.js → Cron-1ceOo5ux.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-CRTZ3GZg.js → Crosschain-aHYxLu0u.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-Ds2bjvxE.js → DID-eeTjzOLV.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-DOONG2NX.js → Dashboard-CT3fpkvX.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-Br3PNA2L.js → Dropdown-B3UpOy-N.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-DT6UUqjZ.js → EmailListRenderer-Ba2Rvoru.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-BSLuEjlT.js → EvolutionSettings-CGtn93on.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-2aEM9avE.js → FamilyGuardDashboard-C0IUdHQt.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-D3B0tlQU.js → Federation-1QIDwemn.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-DTVkVVQP.js → FormItemContext-NGbSsdje.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-BgFEgP4y.js → GenericCardRenderer-DzVZc2Ba.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-3t71m6Xd.js → Git-B_1TDbSr.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-DS7WvlaX.js → Governance-BDl_ySyI.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CeT-xWrI.js → Inference-CAp-wcCK.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-BQzMncp5.js → KnowledgeGraph-DRjRcxul.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-CC5DOKhV.js → Logs-qSuwMwk7.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-BgnYTegK.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-CpYDyy3o.js → Marketplace-DfiXL6UO.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-DRdAZPMr.js → McpTools-D9rIvFjN.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-CBLRr-l8.js → Memory-D-p7yDzj.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-Bnj9veNN.js → MobileBridge-D0XT5B6m.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-lYFPD24p.js → MobileProjects-CL9cHVIk.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-BMU_C9vD.js → Mtc-CME4kDmC.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-DQV-zumU.js → MtcAudit-BjGOXFnn.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-LpqpqV1d.js → Multisig-CSzc53e0.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-C4OMklSO.js → NLProgramming-BYjZnaH8.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Cg0QCinP.js → Notes-BUPOYE0C.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-amoZoMna.js → NotificationSettings-BK8YADru.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-CxNvhf5n.js → OrderTableRenderer-B5F8bnWt.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-BetJmyX5.js → Organization-B0WNlhMd.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-DbeoPtVD.js → Overflow-CED6ZO87.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-B5sitQWT.js → P2P-CBdc8fkP.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-AP9SG2ic.js → PdhVaultBrowser-DuauYi03.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-Bc7fgNKx.js → Permissions-kfgY0ukN.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BwdGMcWZ.js → PersonalDataHub-CDY3I1Do.js} +3 -3
  58. package/src/assets/web-panel/assets/{Pipeline-DVuJA9BA.js → Pipeline-B9x0wKSK.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-BGzwOYRG.js → Privacy-Cqhcr_Qv.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-BpHcC5br.js → ProjectInit-CFhoyo57.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-BI5G5gsc.js → ProjectSettings-DCBjV2Hm.js} +2 -2
  62. package/src/assets/web-panel/assets/Projects-C51w0LnM.js +1 -0
  63. package/src/assets/web-panel/assets/{Providers-CRHCcLFS.js → Providers-BuCIWZY1.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-qSeg5xag.js → QrScannerModal-CEXNL5CB.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-CA8oSceR.js → QuickAsk-DgK8aLAU.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-DMvPodNo.js → Recommend-BxEYQRAs.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BWsapEyN.js → RemoteSession-PRsxNsYU.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-BZJETVmC.js → Reputation-S-tQH70r.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-CUE1OSMp.js → Row-U1Ws3CJl.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-DvMazcUD.js → RssFeed-BftCyeii.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-e1c-NXWv.js → Search-o4gK0cPy.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-Dc9GZsx2.js → Security-U2ZRpsbA.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-AFz6ke-4.js → Services-D0tRjWl_.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-gow6MYcY.js → Skeleton-DzZ8TFsB.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-h6AxYjUP.js → Skills-B1cC7rju.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-Cr4CkJ0O.js → Sla-CtIHOR0J.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-Bd5yuBtH.js → SpeechSettings-CD8ZlQpW.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-1t4QZMLW.js → SyncSettings-BilFQWQk.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-u-DrjLRM.js → Tasks-Bmg2qLXl.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-C0yLUC9b.js → Templates-D6yofyC1.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-ds1YT5iS.js → Tenant-BzttD-Gp.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-BoIskW2m.js → Terminal-DyRXeYuH.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-BkdVK24X.js → TimelineRenderer-Bdmkx-Tr.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-djyDgmfk.js → Tokens-10RcVAVJ.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CYefDS3H.js → Trigger-CKV-9DdV.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-CE_dbep_.js → Trust-BEc-sW1q.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-DwVs_fey.js → UkeySign-BSql8piX.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-BTUqMHAV.js → VideoEditing-C4OH2f4s.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-Bu_E7Rrc.js → Wallet-BSSvWKmv.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-DTbre5AB.js → WebAuthn-LxIzXo9d.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-BsBzd3gt.js → WorkflowEditor-DWwdfcte.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-tdifQQvu.js → chat-DWxYYLD5.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-D3SNW2Vx.js → colors-BxEcQqtg.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-UBlCjrAW.js → compact-item-DNbezFOJ.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-DKsnEnFt.js → createContext-DaJXc5nx.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-CRyXoGo9.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-BkeySXWe.js → hasIn-BMrw3sg3.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CXkn77ZN.js → index-2c0bL3SE.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DtxUSZSS.js → index-6W0V5G2t.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DFMrIEIt.js → index-7zzLqfvI.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-D9m1HQzl.js → index-B9b6UaZl.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-bOIcWW8F.js → index-BAV07GDK.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BV2zQteq.js → index-BCCd8Rj6.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DlO6HdD9.js → index-BNZDGV2q.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DfrW-iVs.js → index-BR4nWOmR.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-PWScrdlX.js → index-B_b9_6wQ.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-SpQ26gD6.js → index-BaByEdBj.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-D5Umd_Z-.js → index-BcuytRTa.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Dg8-Duze.js → index-Bs2QyMPQ.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DlEIp1gJ.js → index-Bum_aSyd.js} +1 -1
  111. package/src/assets/web-panel/assets/index-C-W0Ntk_.js +1 -0
  112. package/src/assets/web-panel/assets/{index-D6es7MSG.js → index-C25ig6EV.js} +1 -1
  113. package/src/assets/web-panel/assets/index-CCk_qhBx.js +1 -0
  114. package/src/assets/web-panel/assets/{index-Bw0k3VgD.js → index-CL-36X3A.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DYFjOyTH.js → index-Ca2hwPMo.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BVvz3ntc.js → index-CaxzeSIM.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-D9um0YVl.js → index-CiEdfbB9.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DugZRCiI.js → index-Cm9DYzhC.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-pgGKNvmm.js → index-CpwgF7vh.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-P-ailFQY.js → index-DEvdSKT4.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-C9ImNw5O.js → index-DL0k35f0.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DSCiZJXb.js → index-DarVV5yG.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BIeFLaMV.js → index-DpSp97J8.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C-KTHSUE.js → index-Dr18agDl.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DiDgwRty.js → index-Dwg38xTG.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-D93iSDUw.js → index-DzZHBzCb.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-6Nvzgytx.js → index-IX0g0s2t.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CG_b1xyX.js → index-LRb0QX6S.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Cuz2QCFT.js → index-NEW5EN2w.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CUjyL0ZS.js → index-T4T84G6X.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DdyTv6yc.js → index-VD-dTYQE.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BEiHKah0.js → index-cCqCEa9X.js} +3 -3
  133. package/src/assets/web-panel/assets/{index-DD6dD3LV.js → index-cKBpcInt.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-TLBpgN30.js → index-hPy_f08G.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DSe_7MSy.js → index-pzYLf5qu.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CZ6JUooI.js → index-rFaCnjXi.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-CVCXG2Hv.js → initDefaultProps-BWVLgWhF.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-Dv00jw87.js → motion-KJZ1xfDE.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-BFz51iHf.js → move-DGqU6H7M.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-BK2woIDE.js → mtc-parser-Dg0xkI5J.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-D2X_Gwoo.js → omit-B6RnMJAQ.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-CLmFyJ1q.js → pickAttrs-Ctw2i3jb.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-CCzPddQm.js → placementArrow-D3F3x8Jm.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-hcm_Zlxd.js → responsiveObserve-W6eHE0nM.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-BxfZEFVp.js → slide-BlFf8sY5.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-kzB9pT-t.js → statusUtils-Cd6LMwmy.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-CDFd7YCI.js → styleChecker-Bg5-U4Y1.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-Czl7NNhS.js → useFlexGapSupport-DTkLS3tn.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-y0SAzirG.js → useFs-CwYGzoBt.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-BvdPznrA.js → usePersonalDataHub-PCgFQXZP.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-D8mNbyZ7.js → vnode-CJM7MkrB.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-_hun6w9W.js → zoom-CP0mgaFi.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/commands/compact.js +7 -2
  155. package/src/data/changelog.json +28 -2
  156. package/src/harness/jsonl-session-store.js +78 -73
  157. package/src/harness/prompt-compressor.js +57 -3
  158. package/src/lib/context-memory-kernel/context-image-transport.js +248 -0
  159. package/src/lib/context-memory-kernel/jsonl-session-context-port.js +4 -1
  160. package/src/lib/context-memory-kernel/live-compaction.js +40 -10
  161. package/src/lib/context-memory-kernel/message-adapter.js +80 -10
  162. package/src/lib/context-memory-kernel/message-bundle-store.js +1140 -0
  163. package/src/lib/context-memory-kernel/provider-context.js +23 -8
  164. package/src/lib/evolution/agent-evolution-ingress.js +62 -12
  165. package/src/lib/evolution/agent-model-projection.js +90 -18
  166. package/src/lib/evolution/evidence-json-text.js +279 -42
  167. package/src/lib/evolution/evolution-evidence-projector.js +169 -26
  168. package/src/lib/evolution/governed-model-turn.js +2 -2
  169. package/src/lib/evolution/local-ui-evolution-deployment.js +2 -2
  170. package/src/lib/evolution/local-ui-evolution-runtime.js +4 -4
  171. package/src/lib/evolution/opaque-hex-id.js +8 -0
  172. package/src/lib/image-token-estimate.js +59 -0
  173. package/src/lib/read-file-loop-guard.js +9 -6
  174. package/src/lib/session-history-origins.js +25 -5
  175. package/src/lib/session-transcript-history.js +5 -1
  176. package/src/lib/tool-result-preview.js +276 -0
  177. package/src/runtime/agent-core.js +85 -78
  178. package/src/runtime/headless-stream.js +32 -17
  179. package/src/assets/web-panel/assets/MarkdownRenderer-5jYM4kYG.js +0 -1
  180. package/src/assets/web-panel/assets/Projects-Ce92-l1V.js +0 -1
  181. package/src/assets/web-panel/assets/devWarning-BBnVfJHh.js +0 -1
  182. package/src/assets/web-panel/assets/index-B2w_3mtS.js +0 -1
  183. package/src/assets/web-panel/assets/index-BoHurydC.js +0 -1
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.166.117",
7
+ "cliVersions": ["0.166.117"],
8
+ "date": "2026-10-23",
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Fixed - cc CLI 0.166.117: code literals at Evolution ingress and completed tool recovery (2026-10-23)",
13
+ "body": "- Recognize Python and JavaScript literals in `run_code` source and results without treating ordinary code as malformed JSON. Continue decoding quoted sensitive keys and values for redaction.\n- Keep genuine JSON validation, duplicate-key rejection, numeric limits and projection budgets; distinguish malformed JSON errors from actual JSON budget failures.\n- Preserve historical Agent projection rulesets while using a new versioned code-text policy for new requests.\n- Coordinate the bounded Agent projection and decoded-JSON node budgets with model-request capacity, and trigger canonical compaction on text byte pressure before the ingress ceiling is reached.\n- Account for image transport separately from text: retain the existing eight-image / 20 MiB message allowance, bound historical request images, and commit image digests in small evidence and context-planning records. Estimate vision tokens separately from base64 bytes.\n- Preview oversized tool results as complete JSON trees and omit incomplete host-created excerpts, retaining status fields, pagination cursors and duplicate-output recovery guards.\n- Settle completed tool rounds before terminating an Agent Run on Evolution ingress failure, retaining verified session prefix checks and removing unanswered calls from replay.\n- Preserve completed rounds on caller cancellation, session-budget exhaustion, unknown compaction usage and independent runtime-ledger failure.\n- Persist large image context bundles as private references bound to the current saved-session generation; verify bytes on restart and clean them up with session deletion. Unsaved sessions do not create persistent image bundles.\n- Publish CLI first; follow with IDE releases recommending CLI 0.166.117 after public npm readback.\n- Align Session Core 0.3.22 and Personal Data Hub 0.4.66 with their changed source trees before publishing the CLI. Candidate 0.166.116 was not published; its immutable tag remains unchanged."
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "productVersion": null,
19
+ "cliVersion": "0.166.115",
20
+ "cliVersions": ["0.166.115"],
21
+ "date": "2026-10-22",
22
+ "title": "",
23
+ "sections": [
24
+ {
25
+ "heading": "Fixed - cc CLI 0.166.115: JSON-compatible Agent tool evidence (published, 2026-10-22)",
26
+ "body": "- Resolve built-in tool descriptor categories from their telemetry metadata and use explicit null for missing optional descriptor values, so successful Git and shell tools do not terminate the Agent's signed Evolution ingress.\n- Omit absent slash-command descriptions, warnings and non-persistent code script paths; represent unknown process exit codes as null. Preserve strict evidence validation.\n- Omit unavailable ranges from repeated-file read recovery and represent missing cell IDs from legacy notebooks as null, keeping successful file tools compatible with signed evidence.\n- Encode new local signing tenant, run and evidence IDs without digits while preserving their entropy, preventing accidental payment-card matches during first use. Retain existing deployment identities and sensitive-content scanning.\n- Prepare VS Code 0.37.157 and JetBrains 0.4.174 to recommend CLI 0.166.115 after exact-source gates and public npm verification."
27
+ }
28
+ ]
29
+ },
4
30
  {
5
31
  "productVersion": null,
6
32
  "cliVersion": "0.166.114",
@@ -9,8 +35,8 @@
9
35
  "title": "",
10
36
  "sections": [
11
37
  {
12
- "heading": "Fixed - cc CLI 0.166.114: Quick Ask streaming and local Evolution setup (candidate, 2026-10-22)",
13
- "body": "- Surface provider waiting status, credential errors, and terminal streaming failures in Quick Ask; bound governed chat initialization and completion to 60 seconds and support cancellation of active requests.\n- Migrate a supported signed UI-only local Evolution host to admit `agent`, `ask`, `chat`, and `ui`, retaining its signing identity and detecting concurrent profile changes.\n- Prepare VS Code 0.37.156 and JetBrains 0.4.173 to recommend CLI 0.166.114. These versions are unreleased candidates; publication still requires the exact release commit's GitHub Actions gates, OIDC npm publication and public readback before IDE publication."
38
+ "heading": "Fixed - cc CLI 0.166.114: Quick Ask streaming and local Evolution setup (published, 2026-10-22)",
39
+ "body": "- Surface provider waiting status, credential errors, and terminal streaming failures in Quick Ask; bound governed chat initialization and completion to 60 seconds and support cancellation of active requests.\n- Migrate a supported signed UI-only local Evolution host to admit `agent`, `ask`, `chat`, and `ui`, retaining its signing identity and detecting concurrent profile changes.\n- CLI 0.166.114 and Open VSX 0.37.156 were published with verified public archives. JetBrains 0.4.173 upload succeeded before cancellation; its public download was not verified. A subsequently reported Agent tool-evidence JSON error is addressed in the .115 candidate."
14
40
  }
15
41
  ]
16
42
  },
@@ -71,6 +71,7 @@ import {
71
71
  } from "./session-list-index.js";
72
72
  import { createSessionPersistenceFailure } from "../lib/session-persistence-failure.js";
73
73
  import { withSessionHostWriteAuthority } from "../lib/session-host-lease.js";
74
+ import { withSessionMessageBundleDeletion } from "../lib/context-memory-kernel/message-bundle-store.js";
74
75
  import { createSessionTranscriptStructureProjection } from "../lib/session-transcript-structure.js";
75
76
  import {
76
77
  TOOL_ROUND_EVENT,
@@ -6240,18 +6241,20 @@ export function deleteJsonlSession(sessionId) {
6240
6241
  Number(existingMeta.updated_at_ms) ||
6241
6242
  Date.now(),
6242
6243
  ) || Date.now();
6243
- const tombstone = recordSessionDeleted(
6244
- getSessionsDir(),
6245
- sessionId,
6246
- timestamp,
6247
- );
6248
- publishSessionAntiRollbackWitness(
6249
- sessionId,
6250
- tombstone,
6251
- filePath,
6252
- "deleted",
6253
- );
6254
- return externalAnchor?.status !== "deleted";
6244
+ return withSessionMessageBundleDeletion(sessionId, () => {
6245
+ const tombstone = recordSessionDeleted(
6246
+ getSessionsDir(),
6247
+ sessionId,
6248
+ timestamp,
6249
+ );
6250
+ publishSessionAntiRollbackWitness(
6251
+ sessionId,
6252
+ tombstone,
6253
+ filePath,
6254
+ "deleted",
6255
+ );
6256
+ return externalAnchor?.status !== "deleted";
6257
+ });
6255
6258
  }
6256
6259
  if (!transcriptExists && existingMeta === null) {
6257
6260
  return false;
@@ -6276,70 +6279,72 @@ export function deleteJsonlSession(sessionId) {
6276
6279
  rebuildSessionMetaUnlocked(getSessionsDir(), sessionId, filePath);
6277
6280
  existingMeta = readSessionPersistenceWitness(sessionId);
6278
6281
  }
6279
- if (deletionWitness === null) {
6280
- assertSessionAntiRollbackBeforeWrite(
6281
- sessionId,
6282
- existingMeta,
6283
- filePath,
6284
- "live",
6285
- );
6286
- } else if (existingMeta?.deleted !== true) {
6287
- existingMeta = replaceSessionMeta(getSessionsDir(), {
6288
- ...emptySessionMeta(sessionId),
6289
- id: sessionId,
6290
- generation: deletionWitness.generation || null,
6291
- last_hash: deletionWitness.last_hash || null,
6292
- event_count: Math.max(0, Number(deletionWitness.event_count) || 0),
6293
- updated_at_ms: Math.max(
6294
- 0,
6295
- Number(deletionWitness.deleted_at_ms) || Date.now(),
6296
- ),
6297
- deleted_at_ms: Math.max(
6298
- 0,
6299
- Number(deletionWitness.deleted_at_ms) || Date.now(),
6300
- ),
6301
- deleted: true,
6302
- transcript: null,
6303
- });
6304
- }
6305
- if (transcriptExists) rmSync(filePath, { force: true });
6306
- // The external tombstone is published only after the absent transcript
6307
- // directory entry is durable. A retry after an interrupted unlink must
6308
- // repeat this barrier even though the path is already absent in memory.
6309
- fsyncParentDirectory(
6310
- filePath,
6311
- Object.freeze({ sessionId, filePath, operation: "delete" }),
6312
- "beforeDeleteDirectoryFsync",
6313
- "afterDeleteDirectoryFsync",
6314
- );
6315
- try {
6316
- const tombstone = recordSessionDeleted(getSessionsDir(), sessionId);
6317
- publishSessionAntiRollbackWitness(
6318
- sessionId,
6319
- tombstone,
6320
- filePath,
6321
- "deleted",
6322
- );
6323
- } catch (error) {
6324
- // A complete anti-rollback record is readable before its fsync. If
6325
- // rollback also fails, readback alone cannot prove durability. Only
6326
- // swallow a post-meta failure after an exact replay has settled the
6327
- // deleted record through the production persistence path.
6328
- const tombstone = readSessionMeta(getSessionsDir(), sessionId);
6329
- if (
6330
- tombstone?.deleted !== true ||
6331
- readSessionAntiRollbackAnchor(sessionId)?.status !== "deleted"
6332
- ) {
6333
- throw error;
6282
+ return withSessionMessageBundleDeletion(sessionId, () => {
6283
+ if (deletionWitness === null) {
6284
+ assertSessionAntiRollbackBeforeWrite(
6285
+ sessionId,
6286
+ existingMeta,
6287
+ filePath,
6288
+ "live",
6289
+ );
6290
+ } else if (existingMeta?.deleted !== true) {
6291
+ existingMeta = replaceSessionMeta(getSessionsDir(), {
6292
+ ...emptySessionMeta(sessionId),
6293
+ id: sessionId,
6294
+ generation: deletionWitness.generation || null,
6295
+ last_hash: deletionWitness.last_hash || null,
6296
+ event_count: Math.max(0, Number(deletionWitness.event_count) || 0),
6297
+ updated_at_ms: Math.max(
6298
+ 0,
6299
+ Number(deletionWitness.deleted_at_ms) || Date.now(),
6300
+ ),
6301
+ deleted_at_ms: Math.max(
6302
+ 0,
6303
+ Number(deletionWitness.deleted_at_ms) || Date.now(),
6304
+ ),
6305
+ deleted: true,
6306
+ transcript: null,
6307
+ });
6334
6308
  }
6335
- publishSessionAntiRollbackWitness(
6336
- sessionId,
6337
- tombstone,
6309
+ if (transcriptExists) rmSync(filePath, { force: true });
6310
+ // The external tombstone is published only after the absent transcript
6311
+ // directory entry is durable. A retry after an interrupted unlink must
6312
+ // repeat this barrier even though the path is already absent in memory.
6313
+ fsyncParentDirectory(
6338
6314
  filePath,
6339
- "deleted",
6315
+ Object.freeze({ sessionId, filePath, operation: "delete" }),
6316
+ "beforeDeleteDirectoryFsync",
6317
+ "afterDeleteDirectoryFsync",
6340
6318
  );
6341
- }
6342
- return true;
6319
+ try {
6320
+ const tombstone = recordSessionDeleted(getSessionsDir(), sessionId);
6321
+ publishSessionAntiRollbackWitness(
6322
+ sessionId,
6323
+ tombstone,
6324
+ filePath,
6325
+ "deleted",
6326
+ );
6327
+ } catch (error) {
6328
+ // A complete anti-rollback record is readable before its fsync. If
6329
+ // rollback also fails, readback alone cannot prove durability. Only
6330
+ // swallow a post-meta failure after an exact replay has settled the
6331
+ // deleted record through the production persistence path.
6332
+ const tombstone = readSessionMeta(getSessionsDir(), sessionId);
6333
+ if (
6334
+ tombstone?.deleted !== true ||
6335
+ readSessionAntiRollbackAnchor(sessionId)?.status !== "deleted"
6336
+ ) {
6337
+ throw error;
6338
+ }
6339
+ publishSessionAntiRollbackWitness(
6340
+ sessionId,
6341
+ tombstone,
6342
+ filePath,
6343
+ "deleted",
6344
+ );
6345
+ }
6346
+ return true;
6347
+ });
6343
6348
  },
6344
6349
  {
6345
6350
  failIfUnavailable: true,
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import { createHash } from "node:crypto";
13
+ import { imageTransportEstimate } from "../lib/image-token-estimate.js";
13
14
  import {
14
15
  collectFileReadProgress,
15
16
  FILE_READ_PROGRESS_PREFIX,
@@ -183,7 +184,25 @@ export function estimateMessagesTokens(messages) {
183
184
  typeof msg.content === "string"
184
185
  ? msg.content
185
186
  : JSON.stringify(msg.content || "");
186
- return sum + estimateTokens(content);
187
+ const image = imageTransportEstimate([msg]);
188
+ // Base64 is transport, not language tokens. The remaining serialized
189
+ // content is still charged, including captions and image metadata.
190
+ return (
191
+ sum + estimateTokens(content) - Math.ceil(image.bytes / 4) + image.tokens
192
+ );
193
+ }, 0);
194
+ }
195
+
196
+ // Leave space for tool definitions, protocol metadata and projection records
197
+ // before the bounded Evolution input/projected-content ceilings are reached.
198
+ export const AUTO_COMPACT_TEXT_BYTES = 768 * 1024;
199
+
200
+ export function estimateMessagesTextBytes(messages) {
201
+ return messages.reduce((sum, message) => {
202
+ const image = imageTransportEstimate([message]);
203
+ return (
204
+ sum + Buffer.byteLength(JSON.stringify(message), "utf8") - image.bytes
205
+ );
187
206
  }, 0);
188
207
  }
189
208
 
@@ -406,7 +425,9 @@ export class PromptCompressor {
406
425
  const currentTokens = estimateMessagesTokens(result);
407
426
  if (
408
427
  this.llmQuery &&
409
- (currentTokens > this.maxTokens || result.length > this.maxMessages) &&
428
+ (currentTokens > this.maxTokens ||
429
+ result.length > this.maxMessages ||
430
+ estimateMessagesTextBytes(result) > AUTO_COMPACT_TEXT_BYTES) &&
410
431
  messages.length > 4
411
432
  ) {
412
433
  const summarized = await this._summarize(result, messages);
@@ -494,7 +515,40 @@ export class PromptCompressor {
494
515
  return (
495
516
  ((!this._adaptive || this._contextWindow < 128000) &&
496
517
  messages.length > this.maxMessages) ||
497
- estimateMessagesTokens(messages) > this.maxTokens
518
+ estimateMessagesTokens(messages) > this.maxTokens ||
519
+ estimateMessagesTextBytes(messages) > AUTO_COMPACT_TEXT_BYTES
520
+ );
521
+ }
522
+
523
+ getCompactionTokenBudget(messages) {
524
+ const textBytes = estimateMessagesTextBytes(messages);
525
+ if (textBytes <= AUTO_COMPACT_TEXT_BYTES) return this.maxTokens;
526
+ const imageTokens = imageTransportEstimate(messages).tokens;
527
+ const lastUser = messages.findLast((message) => message.role === "user");
528
+ // Historical images may be dropped by the planner. Reserving all of them
529
+ // would let it satisfy this target by deleting images while retaining the
530
+ // text that caused the byte overflow.
531
+ const protectedImageTokens = imageTransportEstimate(
532
+ messages.filter(
533
+ (message) =>
534
+ message === lastUser ||
535
+ message.pinned === true ||
536
+ message._pin === true,
537
+ ),
538
+ ).tokens;
539
+ const textTokens = Math.max(
540
+ 0,
541
+ estimateMessagesTokens(messages) - imageTokens,
542
+ );
543
+ return Math.max(
544
+ 1,
545
+ Math.min(
546
+ this.maxTokens,
547
+ Math.floor(
548
+ protectedImageTokens +
549
+ textTokens * (AUTO_COMPACT_TEXT_BYTES / textBytes) * 0.75,
550
+ ),
551
+ ),
498
552
  );
499
553
  }
500
554
 
@@ -0,0 +1,248 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { normalizeContextItem } from "@chainlesschain/context-memory-kernel";
3
+ import { AGENT_MODEL_IMAGE_LIMITS } from "../evolution/agent-model-projection.js";
4
+ import {
5
+ IMAGE_TOKEN_RESERVE,
6
+ LOW_DETAIL_IMAGE_TOKEN_RESERVE,
7
+ inspectCanonicalImageDataUrl,
8
+ } from "../image-token-estimate.js";
9
+
10
+ export const CONTEXT_IMAGE_TRANSPORT_PREFIX = "cc-context-image://v1/";
11
+ const CONTEXT_IMAGE_TRANSPORT_MARKER = "cc-context-image";
12
+
13
+ const PLACEHOLDER_URL =
14
+ /^cc-context-image:\/\/v1\/([a-f0-9]{32})\/(sha256-[a-f0-9]{64})$/u;
15
+
16
+ function sha256(value) {
17
+ return `sha256-${createHash("sha256").update(value, "ascii").digest("hex")}`;
18
+ }
19
+
20
+ function supportedImageUrlBlock(message, block) {
21
+ if (
22
+ message?.role !== "user" ||
23
+ !Array.isArray(message.content) ||
24
+ !block ||
25
+ typeof block !== "object" ||
26
+ Array.isArray(block) ||
27
+ Object.keys(block).sort().join() !== "image_url,type" ||
28
+ block.type !== "image_url" ||
29
+ !block.image_url ||
30
+ typeof block.image_url !== "object" ||
31
+ Array.isArray(block.image_url) ||
32
+ Object.keys(block.image_url).some((key) => !["url", "detail"].includes(key))
33
+ )
34
+ return null;
35
+
36
+ const { url, detail } = block.image_url;
37
+ if (
38
+ typeof url !== "string" ||
39
+ (detail !== undefined && !["auto", "low", "high"].includes(detail))
40
+ )
41
+ return null;
42
+ if (
43
+ url.length >
44
+ Math.ceil(AGENT_MODEL_IMAGE_LIMITS.maxImageBytes / 3) * 4 + 128
45
+ )
46
+ throw codedTransportError(
47
+ "Image transport exceeds its per-image byte budget",
48
+ );
49
+ const image = inspectCanonicalImageDataUrl(url);
50
+ return image ? { url, detail, bytes: image.decodedBytes } : null;
51
+ }
52
+
53
+ function codedTransportError(message) {
54
+ const error = new Error(message);
55
+ error.code = "CC_CONTEXT_IMAGE_TRANSPORT_INVALID";
56
+ return error;
57
+ }
58
+
59
+ /** Replace supported user image data URLs with request-local digest commitments. */
60
+ export function captureContextImageTransport(messagesInput) {
61
+ const messages = Array.isArray(messagesInput) ? messagesInput : [];
62
+ const captures = new Map();
63
+ let requestImageBytes = 0;
64
+ let changed = false;
65
+ const transportedMessages = messages.map((message) => {
66
+ if (message?.role !== "user" || !Array.isArray(message.content)) {
67
+ return message;
68
+ }
69
+
70
+ let contentChanged = false;
71
+ let messageImageBytes = 0;
72
+ let messageImageCount = 0;
73
+ const content = message.content.map((block) => {
74
+ const image = supportedImageUrlBlock(message, block);
75
+ if (!image) return block;
76
+
77
+ messageImageCount++;
78
+ messageImageBytes += image.bytes;
79
+ requestImageBytes += image.bytes;
80
+ if (
81
+ image.bytes > AGENT_MODEL_IMAGE_LIMITS.maxImageBytes ||
82
+ messageImageCount > AGENT_MODEL_IMAGE_LIMITS.maxMessageImages ||
83
+ messageImageBytes > AGENT_MODEL_IMAGE_LIMITS.maxMessageImageBytes ||
84
+ requestImageBytes > AGENT_MODEL_IMAGE_LIMITS.maxRequestImageBytes
85
+ )
86
+ throw codedTransportError(
87
+ "Images exceed the bounded message or request image budget",
88
+ );
89
+
90
+ const digest = sha256(image.url);
91
+ const nonce = randomBytes(16).toString("hex");
92
+ const placeholder = `${CONTEXT_IMAGE_TRANSPORT_PREFIX}${nonce}/${digest}`;
93
+ captures.set(placeholder, {
94
+ url: image.url,
95
+ digest,
96
+ detail: image.detail,
97
+ hasDetail: Object.hasOwn(block.image_url, "detail"),
98
+ reserveTokens:
99
+ image.detail === "low"
100
+ ? LOW_DETAIL_IMAGE_TOKEN_RESERVE
101
+ : IMAGE_TOKEN_RESERVE,
102
+ });
103
+ contentChanged = true;
104
+ changed = true;
105
+ return {
106
+ ...block,
107
+ image_url: { ...block.image_url, url: placeholder },
108
+ };
109
+ });
110
+ return contentChanged ? { ...message, content } : message;
111
+ });
112
+
113
+ return {
114
+ messages: changed ? transportedMessages : messages,
115
+ captures,
116
+ };
117
+ }
118
+
119
+ /** Preserve image token reserves while removing transport placeholders from item digests. */
120
+ export function adjustContextImageTokenEstimates(itemsInput, captures) {
121
+ const items = Array.isArray(itemsInput) ? itemsInput : [];
122
+ if (!(captures instanceof Map) || captures.size === 0) return items;
123
+
124
+ return items.map((item) => {
125
+ if (typeof item?.content !== "string") return item;
126
+ let placeholderBytes = 0;
127
+ let reserveTokens = 0;
128
+ for (const [placeholder, capture] of captures) {
129
+ const first = item.content.indexOf(placeholder);
130
+ if (first < 0) continue;
131
+ if (item.content.indexOf(placeholder, first + placeholder.length) >= 0) {
132
+ throw codedTransportError(
133
+ "A context image transport placeholder was duplicated during planning",
134
+ );
135
+ }
136
+ placeholderBytes += Buffer.byteLength(placeholder, "utf8");
137
+ reserveTokens += capture.reserveTokens;
138
+ }
139
+ if (placeholderBytes === 0) return item;
140
+
141
+ const { digest: _previousDigest, ...withoutDigest } = item;
142
+ return normalizeContextItem({
143
+ ...withoutDigest,
144
+ tokenEstimate: Math.max(
145
+ 1,
146
+ Math.ceil(
147
+ (Buffer.byteLength(item.content, "utf8") - placeholderBytes) / 4,
148
+ ) + reserveTokens,
149
+ ),
150
+ });
151
+ });
152
+ }
153
+
154
+ function containsTransportImageUrl(messages) {
155
+ return messages.some(
156
+ (message) =>
157
+ Array.isArray(message?.content) &&
158
+ message.content.some(
159
+ (block) =>
160
+ block?.type === "image_url" &&
161
+ typeof block.image_url?.url === "string" &&
162
+ block.image_url.url.includes(CONTEXT_IMAGE_TRANSPORT_MARKER),
163
+ ),
164
+ );
165
+ }
166
+
167
+ function containsCapturedPlaceholder(value, captures, seen = new Set()) {
168
+ if (typeof value === "string") {
169
+ for (const match of value.matchAll(
170
+ /cc-context-image:\/\/v1\/[a-f0-9]{32}\/sha256-[a-f0-9]{64}/gu,
171
+ )) {
172
+ if (captures.has(match[0])) return true;
173
+ }
174
+ return false;
175
+ }
176
+ if (!value || typeof value !== "object" || seen.has(value)) return false;
177
+ seen.add(value);
178
+ return Object.values(value).some((entry) =>
179
+ containsCapturedPlaceholder(entry, captures, seen),
180
+ );
181
+ }
182
+
183
+ /** Restore captured image data URLs and reject every unrecognized or altered placeholder. */
184
+ export function restoreContextImageTransport(messagesInput, captures) {
185
+ const messages = Array.isArray(messagesInput) ? messagesInput : [];
186
+ const captured = captures instanceof Map ? captures : new Map();
187
+ const seenPlaceholders = new Set();
188
+ const restored = messages.map((message) => {
189
+ if (message?.role !== "user" || !Array.isArray(message.content)) {
190
+ return message;
191
+ }
192
+ let contentChanged = false;
193
+ const content = message.content.map((block) => {
194
+ if (
195
+ !block ||
196
+ typeof block !== "object" ||
197
+ Array.isArray(block) ||
198
+ block.type !== "image_url" ||
199
+ !block.image_url ||
200
+ typeof block.image_url !== "object" ||
201
+ Array.isArray(block.image_url) ||
202
+ typeof block.image_url.url !== "string" ||
203
+ !block.image_url.url.includes(CONTEXT_IMAGE_TRANSPORT_MARKER)
204
+ )
205
+ return block;
206
+
207
+ const placeholder = block.image_url.url;
208
+ const match = PLACEHOLDER_URL.exec(placeholder);
209
+ const capture = captured.get(placeholder);
210
+ if (
211
+ Object.keys(block).sort().join() !== "image_url,type" ||
212
+ Object.keys(block.image_url).some(
213
+ (key) => !["url", "detail"].includes(key),
214
+ ) ||
215
+ (block.image_url.detail !== undefined &&
216
+ !["auto", "low", "high"].includes(block.image_url.detail)) ||
217
+ !match ||
218
+ !capture ||
219
+ capture.hasDetail !== Object.hasOwn(block.image_url, "detail") ||
220
+ capture.detail !== block.image_url.detail ||
221
+ match[2] !== capture.digest ||
222
+ sha256(capture.url) !== capture.digest ||
223
+ seenPlaceholders.has(placeholder)
224
+ ) {
225
+ throw codedTransportError(
226
+ "A context image transport placeholder is unknown, altered, or duplicated",
227
+ );
228
+ }
229
+ seenPlaceholders.add(placeholder);
230
+ contentChanged = true;
231
+ return {
232
+ ...block,
233
+ image_url: { ...block.image_url, url: capture.url },
234
+ };
235
+ });
236
+ return contentChanged ? { ...message, content } : message;
237
+ });
238
+
239
+ if (
240
+ containsTransportImageUrl(restored) ||
241
+ containsCapturedPlaceholder(restored, captured)
242
+ ) {
243
+ throw codedTransportError(
244
+ "An unrecognized context image transport placeholder reached provider context",
245
+ );
246
+ }
247
+ return restored;
248
+ }
@@ -120,6 +120,7 @@ export class JsonlSessionContextPort {
120
120
  items: messagesToContextItems(authority.readMessages(), {
121
121
  sessionId,
122
122
  allowedSinks: this.allowedSinks,
123
+ allowExternalization: true,
123
124
  }),
124
125
  }),
125
126
  };
@@ -215,7 +216,9 @@ export class JsonlSessionContextPort {
215
216
 
216
217
  async appendCompaction(event, expectedHead) {
217
218
  this._assertSession(event.sessionId);
218
- const messages = contextItemsToMessages(event.outputItems);
219
+ const messages = contextItemsToMessages(event.outputItems, {
220
+ sessionId: this.sessionId,
221
+ });
219
222
  const stats = compactStats(event, messages);
220
223
  const appendHead = this._appendHead(event.operationId, expectedHead);
221
224
  try {