chainlesschain 0.166.47 → 0.166.56

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 (180) hide show
  1. package/README.md +22 -0
  2. package/package.json +2 -2
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-CDpT0WXV.js → AIOps-CBFnwYRX.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-BNfUljWx.js → ActionButton-Sl4eXWpR.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-C9323DEx.js → Analytics-DB0lD9Kb.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CRrjb2db.js → AppLayout-j77EmkRK.js} +3 -3
  8. package/src/assets/web-panel/assets/{Artifacts-Db-DGqJS.js → Artifacts-CU3izCW9.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-CJdHRJ0W.js → Audit-C44fSibb.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-_RSCnTYs.js → BackgroundAgents-pM_NnJW3.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-8GFQi-dM.js → Backup-AOHXqhxN.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-C87NtgUZ.js → BaseInput-DaYc8oA_.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-DcTMWS8G.js → Chat-CmlCAXxW.js} +5 -5
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-5ZDPTW_H.js → ChatBubbleRenderer-CkCSkJDJ.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-DM9EmYee.js → Checkbox-DISI7iaA.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-M2YqDRNN.js → Codegen-BYpeKUpf.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-oB1LLxyf.js → Col-Dk6VwWGq.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-TcVZK5tF.js → Community-BDyTedMu.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-XKmq-3K_.js → Compact-CTNlGM9X.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-C6CBiDRy.js → Compliance-C_tw3IdT.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-Dz9CGqXH.js → Cowork-cduHWEmo.js} +4 -4
  22. package/src/assets/web-panel/assets/{Cron-CxJDgDVL.js → Cron-Dqotjv-s.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-DMP0JsaQ.js → Crosschain-ByW7RsJQ.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-I5IQeogb.js → DID-BI-lafPj.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-BfLW2MXj.js → Dashboard-8m50TRZL.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-BK8EjAlh.js → Dropdown-CN3hmRTc.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-C3iqSv5I.js → EmailListRenderer-t0lzxsDT.js} +1 -1
  28. package/src/assets/web-panel/assets/EvolutionSettings-DabpA3cQ.js +1 -0
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-T19rnqm-.js → FamilyGuardDashboard-BYN4UshY.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-CozrbPMy.js → Federation-n44OtIXp.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-k1dCLNNJ.js → FormItemContext-B-WXDu_I.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-DbaW_Jvt.js → GenericCardRenderer-Bm7v-mTf.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-CQHRyEIt.js → Git-BMIS6sbo.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-BMJYZgMy.js → Governance-B1EhHobE.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-B7mpNU7V.js → Inference-Dy_HJWHo.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-Br0Blg6B.js → KnowledgeGraph-BVdfUbZy.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-HIdk0S6M.js → Logs-Dph_oLQk.js} +2 -2
  38. package/src/assets/web-panel/assets/MarkdownRenderer-CNHYqcxm.js +1 -0
  39. package/src/assets/web-panel/assets/{Marketplace-Bkfq69UP.js → Marketplace-Bw4HWORj.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-dtmx0bHO.js → McpTools-Be6DPfA1.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-CrRlOuEf.js → Memory-DlvLafC9.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-D4ZIZiAH.js → MobileBridge-Upc_Jwlt.js} +1 -1
  43. package/src/assets/web-panel/assets/{MobileProjects-C90Rw7GE.js → MobileProjects-I17jrUbY.js} +1 -1
  44. package/src/assets/web-panel/assets/{Mtc-CC6k_uh4.js → Mtc-DyBzY0GH.js} +4 -4
  45. package/src/assets/web-panel/assets/{MtcAudit-T_CUIYUy.js → MtcAudit-2-7xAwEo.js} +2 -2
  46. package/src/assets/web-panel/assets/{Multisig-N_e0RRWk.js → Multisig-DtUZpFmZ.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-Iq3VzEv0.js → NLProgramming-iInH7jBr.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-B5sKJUJt.js → Notes-BO3Z3vaS.js} +4 -4
  49. package/src/assets/web-panel/assets/{NotificationSettings-K8UVp8qQ.js → NotificationSettings-ClX_0jFE.js} +1 -1
  50. package/src/assets/web-panel/assets/{OrderTableRenderer-BWNyM-6m.js → OrderTableRenderer-Czw742w4.js} +1 -1
  51. package/src/assets/web-panel/assets/{Organization-DMO1NJxI.js → Organization-BATEx24i.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-BBY6b31Z.js → Overflow-B_PXMNia.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-DmsL0y0v.js → P2P-BSiE8PqT.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-C65AX_RY.js → PdhVaultBrowser-BbklUgZY.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-CWcpRtWa.js → Permissions-B7bpflT_.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub--ZNDIdsn.js → PersonalDataHub-BWZS4BLy.js} +3 -3
  57. package/src/assets/web-panel/assets/{Pipeline-DCdj5NGb.js → Pipeline-DP2YSs6H.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-BRKu7Q3E.js → Privacy-DB9ptoH0.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-BJ7ozIAb.js → ProjectInit-BAfePyYk.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-B2cVLiXW.js → ProjectSettings-BEXn4Cm3.js} +2 -2
  61. package/src/assets/web-panel/assets/{Projects-Ce9r_W-p.js → Projects-BzSs0rzn.js} +1 -1
  62. package/src/assets/web-panel/assets/{Providers-BDespvGZ.js → Providers-CRX9TdRO.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-BUNO4fDU.js → QrScannerModal-DUWcSY5L.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-D2TUqeBV.js → QuickAsk-Cgo3Z_hs.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-BNNQPHBH.js → Recommend-Dcinx0IW.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-D2t1V_Cm.js → RemoteSession-BMZzTnAN.js} +2 -2
  67. package/src/assets/web-panel/assets/{Reputation-DVK5hEqI.js → Reputation-BdZzpOp9.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-BB9RTwmE.js → Row-DqM8GVcx.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-DmEO7liZ.js → RssFeed-Soj_QBK3.js} +2 -2
  70. package/src/assets/web-panel/assets/{Search-UwEYjnDB.js → Search-Cn2es0-v.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-DebqSsMp.js → Security-t7C4hz3n.js} +3 -3
  72. package/src/assets/web-panel/assets/{Services-CuuPts3C.js → Services-ChF-e_Uf.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-DbWpmbgf.js → Skeleton-BiPIyK-2.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-BaK7SxzT.js → Skills-HgkKJenJ.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-BFHv51Jb.js → Sla-BSfluv_k.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-B9b1R6uK.js → SpeechSettings-Sm0Gz9tM.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-BnO0CN02.js → SyncSettings-DlhBMnfU.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-Dy01Vq49.js → Tasks-C7OUvsnp.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-BCy2AMHc.js → Templates-CrMtw87y.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-4Tx9y_Y1.js → Tenant-DSNSB6j5.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-CPOoUH8J.js → Terminal-Cmh78FQg.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-C85GlJzu.js → TimelineRenderer-BE8b8lHR.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-_xneFBGF.js → Tokens-BrtgdIvJ.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-BizG4rTr.js → Trigger-HCmaoKDp.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-Dh8EIn3n.js → Trust-GASQ4F-2.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-C5NWoHWQ.js → UkeySign-B8kSzWGr.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-0YfrySL6.js → VideoEditing-Nn-clhv5.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-BZVH8Ags.js → Wallet-DdYMKTYk.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-kNofa6vm.js → WebAuthn-xJXUr_eK.js} +3 -3
  90. package/src/assets/web-panel/assets/{WorkflowEditor-BNO34_j0.js → WorkflowEditor-CbSa87av.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-ifQ2FlwD.js → chat-CVrNLGUV.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-1TL8H6EH.js → colors-e2veLfIA.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-DBfRjs_T.js → compact-item-CNd7nhUq.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-Bs6V4iBf.js → createContext-DEudTVqv.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-DW7he-SA.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-Bz6LMY_0.js → hasIn-BlSAFZa3.js} +1 -1
  97. package/src/assets/web-panel/assets/{index--WvT2Il3.js → index-0y7tHZdT.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DMVktlxG.js → index-4ZT0vIJt.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B6RClMZl.js → index-7-7rr4Mf.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BB1Af7Fv.js → index-B1C1wS5c.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-lUL3bD2z.js → index-BG-VNepa.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CtB45Hok.js → index-BMIhGZUR.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DOww5Qny.js → index-BRNCKg4q.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BiZ7Nz5-.js → index-B_UNX_xq.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C9QYxq61.js → index-BmVFeSEq.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BoCTDcn6.js → index-Bp4Gcn9u.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CXtiLagi.js → index-BpH6T1gA.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-B5SJCUZ7.js → index-BptI9bLu.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Cn7EIWmI.js → index-Bqeb4jnC.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DvM2xBUA.js → index-Bwtt-0CQ.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-EK3XtMxA.js → index-C4h_Bvd2.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DDhy4eCS.js → index-C6zGNZ5H.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-rGhS02f8.js → index-CHMrAZiR.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BQL_tldd.js → index-CK6Rb66R.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C7d6QlfR.js → index-CU4Y4VVN.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Cykt9BbN.js → index-CWuv47z0.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BXJXMaZe.js → index-CYNoXhxl.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-f_7L9GvP.js → index-CgVwz2jD.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-vHtnQsnV.js → index-ClROBPWd.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BhPDhmvN.js → index-D7yJceTZ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Cu_V6ZJH.js → index-DFv-nsIT.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CNKHoXWI.js → index-DFzvcZ3Q.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-vb1XIxEB.js → index-DJ5gsewX.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DWPp-d07.js → index-DVORJydf.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-pOUFfRdN.js → index-D_D7lcnQ.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-cNwsev6n.js → index-DtrqgNBl.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CBh48_Mh.js → index-DwjWRUTf.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BxqC3LiO.js → index-DyFZ7gDd.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-XJIV7HEw.js → index-Ec6VBiV-.js} +1 -1
  130. package/src/assets/web-panel/assets/index-IkoHuWRe.js +1 -0
  131. package/src/assets/web-panel/assets/{index-CXVBQ82k.js → index-Jk99aZIr.js} +3 -3
  132. package/src/assets/web-panel/assets/{index-84mi5rsv.js → index-Lm9pm1zm.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-C6c0j-Ki.js → index-MuTb62K6.js} +1 -1
  134. package/src/assets/web-panel/assets/index-MwqsDbb1.js +1 -0
  135. package/src/assets/web-panel/assets/{index-DEPPzM8I.js → index-hzUfIn4u.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-DpRIjwTt.js → initDefaultProps-C6fpNcA5.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-CG4_9o-Z.js → motion-Bjh9Come.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-Dku1fXtf.js → move-DFa4ul-_.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-BvAVeX-3.js → mtc-parser-KoYqA_e5.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-DFu0x78D.js → omit-ByTjP-wG.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-CmI-FNcK.js → pickAttrs-CG_rmTxx.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-CGERYewB.js → placementArrow-LDePZ8V9.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-D7G8bF5J.js → responsiveObserve-DZFzH4RR.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-B2sXwWXy.js → slide-DfXQyTvD.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-DI5yh0n3.js → statusUtils-CuhqsJfO.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-deGJ5dp_.js → styleChecker-qqVjJw5u.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-OqHBXEmi.js → useFlexGapSupport-BPxnCxcb.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-Dqgx0Qv_.js → useFs-D11NLCjV.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-Be-lveh2.js → usePersonalDataHub-HbZVcaCX.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-CFxB876W.js → vnode-CZHQlfTu.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-BFOYrl4e.js → zoom-CV3rUknJ.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/commands/context.js +31 -11
  154. package/src/commands/evolution-deployment.js +70 -0
  155. package/src/commands/plugin.js +36 -5
  156. package/src/data/changelog.json +78 -0
  157. package/src/gateways/ws/evolution-deployment-topic-handlers.js +20 -0
  158. package/src/generated/cc-agent-protocol.schema.json +44 -1
  159. package/src/harness/prompt-compressor.js +12 -4
  160. package/src/lib/background-agent-list-index.js +222 -0
  161. package/src/lib/background-agent-supervisor.js +38 -0
  162. package/src/lib/codex-app-server-adapter.js +1 -0
  163. package/src/lib/context-memory-kernel/provider-context.js +69 -4
  164. package/src/lib/deferred-question-context.js +160 -4
  165. package/src/lib/eval/plugin-suite.js +286 -22
  166. package/src/lib/evolution/evolution-deployment-config.js +16 -1
  167. package/src/lib/evolution/evolution-deployment-profile.js +102 -58
  168. package/src/lib/evolution/evolution-test-deployment.js +386 -0
  169. package/src/lib/model-context-window.js +3 -2
  170. package/src/lib/runtime-usage-ledger.js +5 -0
  171. package/src/lib/session-host-snapshot.js +16 -0
  172. package/src/repl/agent-repl.js +19 -4
  173. package/src/runtime/agent-core.js +13 -0
  174. package/src/runtime/headless-runner.js +4 -0
  175. package/src/runtime/headless-stream.js +171 -14
  176. package/src/assets/web-panel/assets/EvolutionSettings-BJmBzpW6.js +0 -1
  177. package/src/assets/web-panel/assets/MarkdownRenderer-HxeocBHy.js +0 -1
  178. package/src/assets/web-panel/assets/devWarning-BHnbnuYL.js +0 -1
  179. package/src/assets/web-panel/assets/index-CsRz9-ZH.js +0 -1
  180. package/src/assets/web-panel/assets/index-DnjMFf3m.js +0 -1
@@ -12,6 +12,9 @@ import {
12
12
  messagesToContextItems,
13
13
  } from "./message-adapter.js";
14
14
 
15
+ export const SEMANTIC_CANDIDATE_REQUEST_SCHEMA =
16
+ "chainlesschain.context-memory-semantic-candidate-request/v1";
17
+
15
18
  function defaultAdmissions(sessionId, options) {
16
19
  const candidates = [
17
20
  { scope: "session", scopeId: sessionId },
@@ -32,6 +35,57 @@ function defaultAdmissions(sessionId, options) {
32
35
  });
33
36
  }
34
37
 
38
+ function semanticCandidateProvider(options) {
39
+ const provider = options.contextMemorySemanticCandidateProvider;
40
+ if (provider == null) return null;
41
+ if (typeof provider !== "function") {
42
+ throw new TypeError(
43
+ "contextMemorySemanticCandidateProvider must be a function",
44
+ );
45
+ }
46
+ return provider;
47
+ }
48
+
49
+ /**
50
+ * Ask a host-owned semantic index for opaque record identifiers. The host sees
51
+ * the query and admission boundary but never receives canonical record content;
52
+ * the kernel later validates every returned revision/digest and applies its
53
+ * lifecycle, scope, expiry, and sink filters before ranking.
54
+ */
55
+ async function resolveSemanticCandidates({
56
+ provider,
57
+ sessionId,
58
+ query,
59
+ sink,
60
+ scopeAdmissions,
61
+ limit,
62
+ }) {
63
+ if (!provider) return undefined;
64
+ const candidates = await provider(
65
+ Object.freeze({
66
+ schema: SEMANTIC_CANDIDATE_REQUEST_SCHEMA,
67
+ sessionId,
68
+ query,
69
+ sink,
70
+ scopeAdmissions: Object.freeze(
71
+ scopeAdmissions.map((entry) => Object.freeze({ ...entry })),
72
+ ),
73
+ limit,
74
+ maxCandidates: 1000,
75
+ }),
76
+ );
77
+ if (!Array.isArray(candidates)) {
78
+ throw new TypeError(
79
+ "contextMemorySemanticCandidateProvider must resolve to an array",
80
+ );
81
+ }
82
+ return candidates.map((candidate) =>
83
+ candidate && typeof candidate === "object" && !Array.isArray(candidate)
84
+ ? Object.freeze({ ...candidate })
85
+ : candidate,
86
+ );
87
+ }
88
+
35
89
  function toolDefinitionsToContextItems(definitionsInput, { sessionId, sink }) {
36
90
  const definitions = Array.isArray(definitionsInput) ? definitionsInput : [];
37
91
  return definitions.map((definition, index) => {
@@ -130,6 +184,7 @@ export async function prepareCanonicalProviderContext(
130
184
  };
131
185
  }
132
186
 
187
+ const candidateProvider = semanticCandidateProvider(options);
133
188
  const sink = String(options.contextMemorySink || `provider.${provider}`);
134
189
  const scopeAdmissions = defaultAdmissions(sessionId, options);
135
190
  const lastUser = [...messages]
@@ -139,18 +194,28 @@ export async function prepareCanonicalProviderContext(
139
194
  typeof lastUser?.content === "string" && lastUser.content.trim()
140
195
  ? lastUser.content.trim().slice(0, 32 * 1024)
141
196
  : "*";
197
+ const recallLimit = Math.max(
198
+ 1,
199
+ Math.min(32, Number(options.contextMemoryRecallLimit) || 12),
200
+ );
201
+ const semanticCandidates = await resolveSemanticCandidates({
202
+ provider: candidateProvider,
203
+ sessionId,
204
+ query,
205
+ sink,
206
+ scopeAdmissions,
207
+ limit: recallLimit,
208
+ });
142
209
  const recall = await runtime.kernel.recallMemory({
143
210
  query,
144
211
  sink,
145
212
  scopeAdmissions,
146
- limit: Math.max(
147
- 1,
148
- Math.min(32, Number(options.contextMemoryRecallLimit) || 12),
149
- ),
213
+ limit: recallLimit,
150
214
  tokenBudget: Math.max(
151
215
  1,
152
216
  Math.min(32_768, Number(options.contextMemoryRecallTokens) || 4096),
153
217
  ),
218
+ ...(semanticCandidates === undefined ? {} : { semanticCandidates }),
154
219
  });
155
220
  const messageItems = messagesToContextItems(messages, {
156
221
  sessionId,
@@ -1,6 +1,17 @@
1
+ import { normalizeInteractionBinding } from "./interaction-binding.js";
2
+
1
3
  const MAX_DEFERRED_ANSWERS_PER_CALL = 8;
2
4
  const MAX_DEFERRED_ANSWER_CHARS = 16_384;
3
5
  const MAX_DEFERRED_QUESTION_CHARS = 2_048;
6
+ const MAX_DEFERRED_QUESTIONS = 32;
7
+ const MAX_DEFERRED_OPTIONS = 32;
8
+
9
+ export const DEFERRED_QUESTION_EVENTS = Object.freeze({
10
+ REQUESTED: "deferred_question_requested",
11
+ RESOLVED: "deferred_question_resolved",
12
+ CONSUMED: "deferred_question_consumed",
13
+ EXPIRED: "deferred_question_expired",
14
+ });
4
15
 
5
16
  function boundedText(value, maxChars) {
6
17
  let text;
@@ -18,6 +29,145 @@ function boundedText(value, maxChars) {
18
29
  return `${text.slice(0, maxChars)}\n[truncated]`;
19
30
  }
20
31
 
32
+ function cloneJson(value, fallback = null) {
33
+ try {
34
+ return JSON.parse(JSON.stringify(value));
35
+ } catch {
36
+ return fallback;
37
+ }
38
+ }
39
+
40
+ function normalizeBinding(value, sessionId = null) {
41
+ const binding = normalizeInteractionBinding(value);
42
+ if (
43
+ !Number.isSafeInteger(binding.sequence) ||
44
+ binding.sequence <= 0 ||
45
+ binding.sessionId == null ||
46
+ (sessionId != null && String(binding.sessionId) !== String(sessionId))
47
+ ) {
48
+ return null;
49
+ }
50
+ return binding;
51
+ }
52
+
53
+ function sameBinding(left, right) {
54
+ return JSON.stringify(left) === JSON.stringify(right);
55
+ }
56
+
57
+ export function normalizeDeferredQuestionRequest(value, sessionId = null) {
58
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
59
+ const questionId = String(value.questionId || value.requestId || "").trim();
60
+ const binding = normalizeBinding(value.binding, sessionId);
61
+ if (!questionId || questionId.length > 160 || !binding) return null;
62
+ return Object.freeze({
63
+ questionId,
64
+ question: boundedText(value.question || "", MAX_DEFERRED_QUESTION_CHARS),
65
+ options: Array.isArray(value.options)
66
+ ? cloneJson(value.options.slice(0, MAX_DEFERRED_OPTIONS), [])
67
+ : null,
68
+ multiSelect: value.multiSelect === true,
69
+ purpose: value.purpose === "preference" ? "preference" : "information",
70
+ binding,
71
+ requestedRevision: Number.isSafeInteger(
72
+ value.requestedRevision ?? value.contextRevision,
73
+ )
74
+ ? (value.requestedRevision ?? value.contextRevision)
75
+ : null,
76
+ });
77
+ }
78
+
79
+ export function normalizeDeferredQuestionAnswer(value, sessionId = null) {
80
+ const request = normalizeDeferredQuestionRequest(value, sessionId);
81
+ if (!request) return null;
82
+ return Object.freeze({
83
+ ...request,
84
+ answer: boundedText(value.answer, MAX_DEFERRED_ANSWER_CHARS),
85
+ resolvedRevision: Number.isSafeInteger(value.resolvedRevision)
86
+ ? value.resolvedRevision
87
+ : null,
88
+ });
89
+ }
90
+
91
+ function upsertBounded(map, key, value) {
92
+ map.delete(key);
93
+ map.set(key, value);
94
+ while (map.size > MAX_DEFERRED_QUESTIONS) {
95
+ map.delete(map.keys().next().value);
96
+ }
97
+ }
98
+
99
+ export function createDeferredQuestionEventReducer({ sessionId = null } = {}) {
100
+ const pending = new Map();
101
+ const answers = new Map();
102
+ let maxSequence = 0;
103
+ return {
104
+ accept(event) {
105
+ const data = event?.data || {};
106
+ if (event?.type === DEFERRED_QUESTION_EVENTS.REQUESTED) {
107
+ const record = normalizeDeferredQuestionRequest(data, sessionId);
108
+ if (
109
+ !record ||
110
+ pending.has(record.questionId) ||
111
+ answers.has(record.questionId) ||
112
+ record.binding.sequence <= maxSequence
113
+ ) {
114
+ return;
115
+ }
116
+ maxSequence = Math.max(maxSequence, record.binding.sequence);
117
+ upsertBounded(pending, record.questionId, record);
118
+ answers.delete(record.questionId);
119
+ return;
120
+ }
121
+ if (event?.type === DEFERRED_QUESTION_EVENTS.RESOLVED) {
122
+ const record = normalizeDeferredQuestionAnswer(data, sessionId);
123
+ const requested = record && pending.get(record.questionId);
124
+ if (
125
+ !record ||
126
+ !requested ||
127
+ !sameBinding(requested.binding, record.binding)
128
+ ) {
129
+ return;
130
+ }
131
+ pending.delete(record.questionId);
132
+ upsertBounded(answers, record.questionId, record);
133
+ return;
134
+ }
135
+ if (
136
+ event?.type === DEFERRED_QUESTION_EVENTS.CONSUMED ||
137
+ event?.type === DEFERRED_QUESTION_EVENTS.EXPIRED
138
+ ) {
139
+ const ids = Array.isArray(data.questionIds)
140
+ ? data.questionIds
141
+ : [data.questionId || data.requestId];
142
+ for (const value of ids) {
143
+ const questionId = String(value || "").trim();
144
+ if (!questionId) continue;
145
+ pending.delete(questionId);
146
+ answers.delete(questionId);
147
+ }
148
+ }
149
+ },
150
+ finish() {
151
+ return Object.freeze({
152
+ pendingQuestions: Object.freeze(
153
+ [...pending.values()].map((entry) => Object.freeze({ ...entry })),
154
+ ),
155
+ answers: Object.freeze(
156
+ [...answers.values()].map((entry) => Object.freeze({ ...entry })),
157
+ ),
158
+ maxSequence,
159
+ });
160
+ },
161
+ };
162
+ }
163
+
164
+ export function reduceDeferredQuestionEvents(events, options = {}) {
165
+ const reducer = createDeferredQuestionEventReducer(options);
166
+ for (const event of Array.isArray(events) ? events : [])
167
+ reducer.accept(event);
168
+ return reducer.finish();
169
+ }
170
+
21
171
  /**
22
172
  * Session-scoped inbox for answers to non-blocking, informational questions.
23
173
  * Answers are consumed once as transient user context; they are never persisted
@@ -75,15 +225,21 @@ export class DeferredQuestionContext {
75
225
 
76
226
  prepareCall({ currentRevision = null } = {}) {
77
227
  if (this._answers.length === 0) return null;
78
- const answers = this._answers.splice(0, MAX_DEFERRED_ANSWERS_PER_CALL);
228
+ const answers = this._answers.slice(0, MAX_DEFERRED_ANSWERS_PER_CALL);
79
229
  if (this._onConsumed) {
80
230
  try {
81
- this._onConsumed(answers.map((entry) => entry.questionId));
231
+ if (
232
+ this._onConsumed(answers.map((entry) => entry.questionId)) === false
233
+ ) {
234
+ return null;
235
+ }
82
236
  } catch {
83
- // Context delivery is authoritative for this process. A persistence
84
- // callback failure must not duplicate user context in the same run.
237
+ // Do not inject context unless its one-shot consumption is durably
238
+ // acknowledged. A later call can retry without duplicating the answer.
239
+ return null;
85
240
  }
86
241
  }
242
+ this._answers.splice(0, answers.length);
87
243
  const revision = Number.isSafeInteger(currentRevision)
88
244
  ? currentRevision
89
245
  : null;