wednesdayai 0.4.12-dev.716 → 0.4.12-dev.719

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 (437) hide show
  1. package/dist/{agent-scope-cbxkoURo.js → agent-scope-DxKPMu8w.js} +3 -3
  2. package/dist/{agent-turn-enqueue-N-q0v3mc.js → agent-turn-enqueue-DEStltEg.js} +4 -4
  3. package/dist/{agent-turn-enqueue-Cqo34Swm.js → agent-turn-enqueue-DzWOPhgy.js} +4 -4
  4. package/dist/{agent-turn-execute-Bw9hhkAP.js → agent-turn-execute-CzOC4mHw.js} +124 -97
  5. package/dist/{agent-turn-recovery-adapter-BkIal4FW.js → agent-turn-recovery-adapter-CdLD3DuI.js} +1 -1
  6. package/dist/{agent-turn-recovery-adapter-CLY2Dn04.js → agent-turn-recovery-adapter-DnvjgbK0.js} +1 -1
  7. package/dist/{agent-turn-runner-Vd3aTCni.js → agent-turn-runner-BEvwtTis.js} +1 -1
  8. package/dist/{agent-turn-runner-Bvj00mHU.js → agent-turn-runner-BsxQBFRB.js} +5 -5
  9. package/dist/{agent-turn-runner-CUCOdxhH.js → agent-turn-runner-C1u8sVfA.js} +1 -1
  10. package/dist/{agent-turn-runner-CImqp_RN.js → agent-turn-runner-DpICdamt.js} +1 -1
  11. package/dist/{agents-BBoIqOw6.js → agents-C61lzbyw.js} +4 -4
  12. package/dist/{agents.config-Ctnm8o8d.js → agents.config-BcD-ZJ0N.js} +1 -1
  13. package/dist/{agents.config-C8RJrfbr.js → agents.config-DAh5Ah1J.js} +1 -1
  14. package/dist/{api-key-rotation-BMnyfyGD.js → api-key-rotation-Br7_jaAV.js} +2 -2
  15. package/dist/{artifacts-DUhYSSmK.js → artifacts-QHme-vnS.js} +4 -4
  16. package/dist/{audio-preflight-yuM9Q3qh.js → audio-preflight-B_5sTSyb.js} +27 -27
  17. package/dist/{audio-preflight-bEi-KkBn.js → audio-preflight-CehYz7wU.js} +6 -6
  18. package/dist/{audio-preflight-BKQpd1eU.js → audio-preflight-uatGs8bC.js} +6 -6
  19. package/dist/{audio-transcription-runner-CGTNNwbm.js → audio-transcription-runner-BvZFFknx.js} +1 -1
  20. package/dist/{audio-transcription-runner-BD7UgbNj.js → audio-transcription-runner-CJ8YdMv-.js} +1 -1
  21. package/dist/{audio-transcription-runner-CgPA8_eG.js → audio-transcription-runner-XFfvRPXl.js} +11 -11
  22. package/dist/{audit-CcNEpaG6.js → audit-C0WHA5BX.js} +3 -3
  23. package/dist/{audit-BM8WZyx6.js → audit-UMAK8rQC.js} +3 -3
  24. package/dist/{auth-choice-DTg-b2da.js → auth-choice-BHU_G3if.js} +1 -1
  25. package/dist/{auth-choice-VnJYar-i.js → auth-choice-CHzuLxTp.js} +1 -1
  26. package/dist/{banner-_g-nCJoZ.js → banner-BAtbMrrp.js} +1 -1
  27. package/dist/build-info.json +3 -3
  28. package/dist/bundled/boot-md/handler.js +58 -58
  29. package/dist/bundled/bootstrap-extra-files/handler.js +6 -6
  30. package/dist/bundled/command-logger/handler.js +2 -2
  31. package/dist/bundled/session-journal/handler.js +58 -58
  32. package/dist/bundled/session-memory/handler.js +58 -58
  33. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  34. package/dist/{channel-activity-BJHm_pDV.js → channel-activity-DNq7LYjU.js} +3 -3
  35. package/dist/{channel-options-BX8MFfPW.js → channel-options-CsgHOF5l.js} +1 -1
  36. package/dist/{channel-options-Dod3uWTl.js → channel-options-DRnowLFK.js} +1 -1
  37. package/dist/{channels-cli-MbAArXF1.js → channels-cli-BN4oTmr6.js} +23 -23
  38. package/dist/{channels-cli-DyfFtAZa.js → channels-cli-Cn1IUfM3.js} +23 -23
  39. package/dist/{chrome-BkJgMZjT.js → chrome-FHxGdLnd.js} +23 -23
  40. package/dist/{chunk-eNEsWhab.js → chunk-BhntPUH_.js} +3 -3
  41. package/dist/cli/daemon-cli.js +1 -1
  42. package/dist/{cli-DF91S8Cf.js → cli-BGAvAUiU.js} +17 -17
  43. package/dist/{cli-CdrO5h4P.js → cli-CFIRmNaZ.js} +17 -17
  44. package/dist/{command-queue-DmXWCoY0.js → command-queue-DtybAhHH.js} +1 -1
  45. package/dist/{command-queue-DucYxKKF.js → command-queue-SzKgkaS6.js} +1 -1
  46. package/dist/{command-queue-URs9pYSC.js → command-queue-zXu22yak.js} +1 -1
  47. package/dist/{command-registry-NOHWjbDr.js → command-registry-DBfEAwIt.js} +9 -9
  48. package/dist/{commands-registry-DdQg21ct.js → commands-registry-DC0fovy_.js} +2 -2
  49. package/dist/{completion-cli-BfKoz1jW.js → completion-cli-BfRsix3J.js} +2 -2
  50. package/dist/{completion-cli-BQ5pz74O.js → completion-cli-L5YP0rxV.js} +1 -1
  51. package/dist/{config-cli-cFzUpYdg.js → config-cli-D4Gxd0pm.js} +1 -1
  52. package/dist/{config-cli-BGFZu6JD.js → config-cli-dgRsXbD3.js} +1 -1
  53. package/dist/{configure-DYAZJ3GF.js → configure-BN-JNKf7.js} +5 -5
  54. package/dist/{configure-DrrwPxlu.js → configure-DtRyMLwO.js} +5 -5
  55. package/dist/{daemon-cli-B3Q460ai.js → daemon-cli-CiPY543O.js} +5 -5
  56. package/dist/{daemon-cli-C5cAb15Z.js → daemon-cli-YmPcKhvo.js} +5 -5
  57. package/dist/daemon-cli.js +44 -3
  58. package/dist/{daemon-install-DGU1qIIK.js → daemon-install-BuETscSF.js} +3 -3
  59. package/dist/{daemon-install-CBIxgo4p.js → daemon-install-CGg5r1wy.js} +3 -3
  60. package/dist/{deliver-C5SDo7TP.js → deliver-Aw7d03gL.js} +1 -1
  61. package/dist/{deliver-fwGuXC0n.js → deliver-CXqNQ8yi.js} +24 -24
  62. package/dist/{deliver-8xg5ISEI.js → deliver-D37woOwV.js} +1 -1
  63. package/dist/{diagnostic-BB6k_yiT.js → diagnostic-Bbg-zObh.js} +5 -5
  64. package/dist/{diagnostic-D7DvV7NT.js → diagnostic-Cid_Tw67.js} +1 -1
  65. package/dist/{diagnostic-Dv8UWiI0.js → diagnostic-lG00b_zg.js} +1 -1
  66. package/dist/{diagnostics-C4-TUVnm.js → diagnostics-C6ntZHc3.js} +1 -1
  67. package/dist/{diagnostics-FIcvxigK.js → diagnostics-Ds3p_NPY.js} +1 -1
  68. package/dist/{dm-policy-shared-BLJbsZzf.js → dm-policy-shared-BJNH9gNN.js} +1 -1
  69. package/dist/{doctor-completion-B94pFOFt.js → doctor-completion-ChF4A40n.js} +1 -1
  70. package/dist/{doctor-completion-CtR8yetH.js → doctor-completion-DIFx6d6S.js} +1 -1
  71. package/dist/entry.js +2 -2
  72. package/dist/{exec-approvals-cli-t7rAulRf.js → exec-approvals-cli-BAJ3sxzP.js} +3 -3
  73. package/dist/{exec-approvals-cli-DsXabPF_.js → exec-approvals-cli-DIUYxvM0.js} +3 -3
  74. package/dist/extensionAPI.js +2 -2
  75. package/dist/{fetch-BzXaK9px.js → fetch-BoHKSk-O.js} +8 -8
  76. package/dist/{fetch-guard-0mkjBgri.js → fetch-guard-TJjLK0FV.js} +3 -3
  77. package/dist/{frontmatter-PMByWrfP.js → frontmatter-saAwiKEb.js} +5 -5
  78. package/dist/{fs-safe-DwICJjkN.js → fs-safe-LRpYbPaA.js} +4 -4
  79. package/dist/{gateway-cli-C_veSlCx.js → gateway-cli-BJ9wa3Hc.js} +48 -48
  80. package/dist/{gateway-cli-DI7_gxH-.js → gateway-cli-CVnksdlt.js} +48 -48
  81. package/dist/{github-copilot-token-WSjo05vB.js → github-copilot-token-zGOMIGSh.js} +7 -7
  82. package/dist/{health-Cooqit6V.js → health-Cxv6ou16.js} +2 -2
  83. package/dist/{health-DFat5vO5.js → health-Q4hCJ8O2.js} +2 -2
  84. package/dist/{hooks-cli-CB-96Su8.js → hooks-cli-ChZY2urb.js} +19 -19
  85. package/dist/{hooks-cli-yNAgxRQS.js → hooks-cli-DOHX--ha.js} +19 -19
  86. package/dist/{image-ops-O8pHxo7i.js → image-ops-D_fm2PuR.js} +1 -1
  87. package/dist/index.js +21 -21
  88. package/dist/{inspect-DVHAPbcZ.js → inspect-BXlZnWkg.js} +1 -1
  89. package/dist/{inspect-gvjq38z1.js → inspect-LfUprDjx.js} +1 -1
  90. package/dist/{installs-CpnJwZZ_.js → installs-78zhoWuO.js} +1 -1
  91. package/dist/{installs-CdLdL1gD.js → installs-Du8n8Do9.js} +1 -1
  92. package/dist/{ir-fzpdYPWw.js → ir-C4MMLUJr.js} +5 -5
  93. package/dist/{legacy-names-CLlrMq8r.js → legacy-names-vLJrYADD.js} +1 -1
  94. package/dist/{lifecycle-core-BdCcww82.js → lifecycle-core-CuMY0U_8.js} +3 -3
  95. package/dist/{lifecycle-core-B3-ezmTx.js → lifecycle-core-M-5Z8Xml.js} +3 -3
  96. package/dist/llm-slug-generator.js +58 -58
  97. package/dist/{logger-DNehzD_s.js → logger-a0-zAY5a.js} +1 -1
  98. package/dist/{manager-DH-MILAU.js → manager-DdA_cy40.js} +12 -12
  99. package/dist/{markdown-tables-UWspJNAH.js → markdown-tables-Dd7jV1JF.js} +2 -2
  100. package/dist/{model-selection-9qbqwsOT.js → model-selection-CdZITU0t.js} +86 -86
  101. package/dist/{models-Dlat36jl.js → models-BbhdUY5g.js} +1 -1
  102. package/dist/{models-cli-vjFaOcNS.js → models-cli-BekoSHw2.js} +18 -18
  103. package/dist/{models-cli-DMjHkAqq.js → models-cli-BmL2dpSq.js} +17 -17
  104. package/dist/{node-cli-yC-cX-mJ.js → node-cli-BTywy8AL.js} +8 -8
  105. package/dist/{node-cli-m0j_YD0V.js → node-cli-BVgH-DXq.js} +8 -8
  106. package/dist/{node-service-BnwLXY5x.js → node-service-BnyKZNqa.js} +1 -1
  107. package/dist/{node-service-r64yexlb.js → node-service-Ys7JZFz-.js} +1 -1
  108. package/dist/{npm-pack-install-DcBobJp3.js → npm-pack-install-B-cOWuiF.js} +1 -1
  109. package/dist/{npm-pack-install-B7wQANiM.js → npm-pack-install-opyKYSmS.js} +1 -1
  110. package/dist/{npm-resolution-B0rqOBgy.js → npm-resolution-51BBOWpQ.js} +2 -2
  111. package/dist/{npm-resolution-SdoNL0ud.js → npm-resolution-6WKQ6nBu.js} +2 -2
  112. package/dist/{onboard-B9-DxI_m.js → onboard-Cj-sLY2K.js} +3 -3
  113. package/dist/{onboard-D8MZoOum.js → onboard-CnRiqboN.js} +3 -3
  114. package/dist/{onboard-channels-P7F-dNwm.js → onboard-channels-DAwHVQ1P.js} +2 -2
  115. package/dist/{onboard-channels-28JqVvAv.js → onboard-channels-DYRTySsa.js} +2 -2
  116. package/dist/{onboarding-BfpXrIw7.js → onboarding-CujUbWy2.js} +3 -3
  117. package/dist/{onboarding-0WSY8o8f.js → onboarding-DidWWI3X.js} +3 -3
  118. package/dist/{onboarding.finalize-QITC8MsS.js → onboarding.finalize-CDE1nAu8.js} +26 -26
  119. package/dist/{onboarding.finalize-BnIw1M2b.js → onboarding.finalize-DTqRxVZH.js} +25 -25
  120. package/dist/{operator-commands-CtYCnspr.js → operator-commands-Bfd55UfE.js} +2 -2
  121. package/dist/{operator-commands-CIz47IKl.js → operator-commands-Ct0WXISe.js} +2 -2
  122. package/dist/{outbound-attachment-DVKqk30B.js → outbound-attachment-CqtMGpsJ.js} +2 -2
  123. package/dist/{outbound-message-hooks-S_VhlJs3.js → outbound-message-hooks-RBQbGzGm.js} +4 -4
  124. package/dist/{path-alias-guards-Cd5yHmTq.js → path-alias-guards-Zj-NwKjV.js} +1 -1
  125. package/dist/{paths-Cvc9EM8Y.js → paths-C6TxBCvO.js} +5 -5
  126. package/dist/{pi-embedded-wjGM_bNN.js → pi-embedded-B6sr5IdC.js} +102 -75
  127. package/dist/{pi-embedded-BBId5n_k.js → pi-embedded-B9bOSjfE.js} +279 -252
  128. package/dist/{pi-embedded-helpers-BU47jdPO.js → pi-embedded-helpers-BAjtRn7m.js} +1 -1
  129. package/dist/{pi-embedded-helpers-DVvJRC5S.js → pi-embedded-helpers-BYLOFsUc.js} +24 -24
  130. package/dist/{pi-embedded-helpers-i0-tPaxH.js → pi-embedded-helpers-CPorV-Mk.js} +1 -1
  131. package/dist/{pi-embedded-recovery-adapter-CNdSU-s7.js → pi-embedded-recovery-adapter-B8Goyik3.js} +8 -8
  132. package/dist/{pi-embedded-recovery-adapter-DL78oCTf.js → pi-embedded-recovery-adapter-Cs1EJElw.js} +8 -8
  133. package/dist/{pi-embedded-recovery-adapter-1Lgt8q1h.js → pi-embedded-recovery-adapter-ZPyX9YC1.js} +2 -2
  134. package/dist/{pi-embedded-recovery-adapter-B2AFWrYt.js → pi-embedded-recovery-adapter-swbNIWgT.js} +2 -2
  135. package/dist/{pi-embedded-utils-8OzPnJMh.js → pi-embedded-utils-CT_f_S3Y.js} +1 -1
  136. package/dist/{pi-embedded-utils-BoaQCwP7.js → pi-embedded-utils-DOtaZ7KV.js} +3 -3
  137. package/dist/{pi-embedded-utils-BtOzugyp.js → pi-embedded-utils-lp-U3XQ9.js} +1 -1
  138. package/dist/{pi-model-discovery-CsC6yTDG.js → pi-model-discovery-B9KKtGuw.js} +7 -7
  139. package/dist/{pi-tools.policy-DPm2eos4.js → pi-tools.policy-r9H_A-NQ.js} +1 -1
  140. package/dist/{plugin-registry-CPS5bO_-.js → plugin-registry-CwGfmKsn.js} +1 -1
  141. package/dist/{plugin-registry-CC8YsXPr.js → plugin-registry-EHKfjAoe.js} +1 -1
  142. package/dist/plugin-sdk/{agent-scope-BYp_CjdU.js → agent-scope-BLF4nZUv.js} +2 -2
  143. package/dist/plugin-sdk/{agent-turn-execute-Dd5AJiKY.js → agent-turn-execute-BVPDW02i.js} +2 -2
  144. package/dist/plugin-sdk/agent-turn-execute-zuw0S_Lh.js +61 -0
  145. package/dist/plugin-sdk/agent-turn-runner-BcrkoR1M.js +11 -0
  146. package/dist/plugin-sdk/{agent-turn-runner-DL5jOnXC.js → agent-turn-runner-DDIT9POj.js} +1 -1
  147. package/dist/plugin-sdk/{agent-turn-runner-B9_FKVSu.js → agent-turn-runner-DjK-LdTA.js} +6 -6
  148. package/dist/plugin-sdk/{api-key-rotation-CDNf_4cI.js → api-key-rotation-XDUKz2gd.js} +2 -2
  149. package/dist/plugin-sdk/{artifacts-BMLMg3MG.js → artifacts-HAYpGlG1.js} +1 -1
  150. package/dist/plugin-sdk/{audio-preflight-BmKL6FNP.js → audio-preflight-BS29OWk3.js} +2 -2
  151. package/dist/plugin-sdk/audio-preflight-DE04bi4M.js +28 -0
  152. package/dist/plugin-sdk/{audio-transcription-runner-TBjJv_mZ.js → audio-transcription-runner-BNafitZj.js} +10 -10
  153. package/dist/plugin-sdk/{auth-profiles-DHZjW8Vk.js → auth-profiles-CCJQoedi.js} +5 -5
  154. package/dist/plugin-sdk/{channel-activity-Dr4PYej7.js → channel-activity-BKwRzYJb.js} +3 -3
  155. package/dist/plugin-sdk/{chrome-BDy1zYAr.js → chrome-D0eLSqkP.js} +4 -4
  156. package/dist/plugin-sdk/{chunk-DGQdf0JN.js → chunk-CDvvv9SU.js} +3 -3
  157. package/dist/plugin-sdk/{chunk-BTSnO1wn.js → chunk-DI-5pBck.js} +6 -6
  158. package/dist/plugin-sdk/{command-detection-DdTnFMU3.js → command-detection-WNHSrul-.js} +186 -159
  159. package/dist/plugin-sdk/{command-queue-CeaLVs8O.js → command-queue-BnJsJc_w.js} +8 -8
  160. package/dist/plugin-sdk/{command-queue-DFSOdqCK.js → command-queue-CHiQj9Ji.js} +1 -1
  161. package/dist/plugin-sdk/{commands-registry-8sy0wsK_.js → commands-registry-Do_g2It_.js} +6 -6
  162. package/dist/plugin-sdk/{commands-registry-N6f_lsxF.js → commands-registry-DpLk11E7.js} +2 -2
  163. package/dist/plugin-sdk/{config-Biusjzx-.js → config-CQNfmIC8.js} +7 -7
  164. package/dist/plugin-sdk/deliver-D4fWK65M.js +32 -0
  165. package/dist/plugin-sdk/{deliver-BgHA8c9F.js → deliver-L6eu6zyG.js} +11 -11
  166. package/dist/plugin-sdk/{diagnostic-D6hSjxiv.js → diagnostic-C7lPoqyv.js} +5 -5
  167. package/dist/plugin-sdk/{diagnostic-Bni_8VyY.js → diagnostic-DfxuMWHd.js} +7 -7
  168. package/dist/plugin-sdk/{fetch-guard-C1a1KfEb.js → fetch-guard-CZT8FU1i.js} +3 -3
  169. package/dist/plugin-sdk/{fs-safe-CbZ6uRVv.js → fs-safe-B0JgGdXa.js} +3 -3
  170. package/dist/plugin-sdk/{hook-runner-global-BvxlnAyu.js → hook-runner-global-WRI53ibi.js} +3 -3
  171. package/dist/plugin-sdk/{image-ops-DY_SZfXk.js → image-ops-kuILYHZv.js} +1 -1
  172. package/dist/plugin-sdk/index.js +54 -54
  173. package/dist/plugin-sdk/{ir-BNohi6ZW.js → ir-Bm7oqkwT.js} +5 -5
  174. package/dist/plugin-sdk/{local-roots-Bm7nDW20.js → local-roots-D-CHzVr1.js} +7 -7
  175. package/dist/plugin-sdk/{logger-D6KsqbNW.js → logger-BSK-0Yjx.js} +1 -1
  176. package/dist/plugin-sdk/manager-BlYRVNJI.js +16 -0
  177. package/dist/plugin-sdk/{manager-B_vK9MbM.js → manager-D2jffdjH.js} +8 -8
  178. package/dist/plugin-sdk/{markdown-tables-G4vK24xc.js → markdown-tables-DIWQQ2W1.js} +2 -2
  179. package/dist/plugin-sdk/markdown-tables-cZSKCBuW.js +10 -0
  180. package/dist/plugin-sdk/{outbound-attachment-Cw7T2Mrt.js → outbound-attachment-CtKKNyms.js} +2 -2
  181. package/dist/plugin-sdk/{path-alias-guards-CVybi_GQ.js → path-alias-guards-CHfCMaeX.js} +1 -1
  182. package/dist/plugin-sdk/{pi-embedded-helpers-B_jgacW8.js → pi-embedded-helpers-BRymkO_1.js} +11 -11
  183. package/dist/plugin-sdk/{pi-embedded-utils-DOXEm_H8.js → pi-embedded-utils-BHmc3RVS.js} +3 -3
  184. package/dist/plugin-sdk/{pi-model-discovery-DWw1ReX-.js → pi-model-discovery-4X7_2_nP.js} +6 -6
  185. package/dist/plugin-sdk/{pi-model-discovery-DWUrLRLg.js → pi-model-discovery-6BBajZds.js} +1 -1
  186. package/dist/plugin-sdk/provider-dispatcher-B4PdTha5.js +61 -0
  187. package/dist/plugin-sdk/{provider-dispatcher-C4-urx2x.js → provider-dispatcher-D7UK3G8K.js} +2 -2
  188. package/dist/plugin-sdk/provider-image-CNlYbRab.js +22 -0
  189. package/dist/plugin-sdk/{provider-image-CEQrHWYz.js → provider-image-DBye3Ln5.js} +5 -5
  190. package/dist/plugin-sdk/provider-media-understanding.js +7 -7
  191. package/dist/plugin-sdk/proxy-D2uiu68M.js +7 -0
  192. package/dist/plugin-sdk/{proxy-BWc9guJs.js → proxy-DJ2nskkh.js} +1 -1
  193. package/dist/plugin-sdk/{proxy-fetch-BYkGxQnh.js → proxy-fetch-CuQpjpkI.js} +1 -1
  194. package/dist/plugin-sdk/{pw-ai-DQv6Xhce.js → pw-ai-BJrhPMHJ.js} +10 -10
  195. package/dist/plugin-sdk/{qmd-manager-CpV0SFnY.js → qmd-manager-DhW_frb3.js} +8 -8
  196. package/dist/plugin-sdk/{query-expansion-CwmHvvV_.js → query-expansion-NpBeKA8F.js} +3 -3
  197. package/dist/plugin-sdk/{recorder-BXZMRSjO.js → recorder-DdbAQ2HO.js} +4 -4
  198. package/dist/plugin-sdk/{redact-C88Ryyfs.js → redact-CUjmZn2Y.js} +1 -1
  199. package/dist/plugin-sdk/{replies-l2hZAzbt.js → replies-Dw3jvqpR.js} +4 -4
  200. package/dist/plugin-sdk/replies-XUkqz_7S.js +25 -0
  201. package/dist/plugin-sdk/{reply-directives-BwxzQXmX.js → reply-directives-BS8Ge06Z.js} +2 -2
  202. package/dist/plugin-sdk/{reply-prefix-qLQRxqrf.js → reply-prefix-Dt1hESHJ.js} +1 -1
  203. package/dist/plugin-sdk/reply-prefix-MU3uY52y.js +7 -0
  204. package/dist/plugin-sdk/{resolve-route-50KoArP9.js → resolve-route-BpLuk-wC.js} +4 -4
  205. package/dist/plugin-sdk/{resolve-route-6v1HVvWk.js → resolve-route-DiQTL1qI.js} +6 -6
  206. package/dist/plugin-sdk/{runs-CiohhBb8.js → runs-D6fAvItC.js} +7 -7
  207. package/dist/plugin-sdk/runs-R28wdt7j.js +25 -0
  208. package/dist/plugin-sdk/{send-Cv2CGnsK.js → send-BDwTyH6I.js} +8 -8
  209. package/dist/plugin-sdk/{send-DM6RpDCL.js → send-CE_6VOiQ.js} +7 -7
  210. package/dist/plugin-sdk/{send-Cx6gHjnA.js → send-Ce2XBaKF.js} +6 -6
  211. package/dist/plugin-sdk/send-Cg2VXcO0.js +27 -0
  212. package/dist/plugin-sdk/{send-BMSqETcU.js → send-CpXGZgrS.js} +6 -6
  213. package/dist/plugin-sdk/send-DAs6FmWB.js +23 -0
  214. package/dist/plugin-sdk/{send-DO0C4Uva.js → send-GMYUhBtJ.js} +19 -19
  215. package/dist/plugin-sdk/{send-DG4MQPPm.js → send-R0HB1-l-.js} +13 -13
  216. package/dist/plugin-sdk/send-UIQH_kN6.js +25 -0
  217. package/dist/plugin-sdk/send-tASIQF-Q.js +24 -0
  218. package/dist/plugin-sdk/{session-meta-CiqJP0pO.js → session-meta-BU2WXD0N.js} +2 -2
  219. package/dist/plugin-sdk/session-meta-Dd1ZONel.js +10 -0
  220. package/dist/plugin-sdk/{skill-commands-CE_SkRQk.js → skill-commands-BYfWIPfV.js} +5 -5
  221. package/dist/plugin-sdk/skill-commands-C7ZE3rKj.js +14 -0
  222. package/dist/plugin-sdk/{skills-CjW6uGTa.js → skills-BuJjEYto.js} +6 -6
  223. package/dist/plugin-sdk/src/agents/pi-embedded-runner/run/attempt.d.ts +3 -0
  224. package/dist/plugin-sdk/src/agents/pi-embedded-runner/tool-result-context-guard.d.ts +12 -3
  225. package/dist/plugin-sdk/{ssrf-BUCEDxp5.js → ssrf-DiAz1Z_z.js} +2 -2
  226. package/dist/plugin-sdk/{store-yBNTHg3N.js → store-Bl3Yjf_w.js} +2 -2
  227. package/dist/plugin-sdk/{subagent-registry-B0gD-Lof.js → subagent-registry-Bxwla-0-.js} +2 -2
  228. package/dist/plugin-sdk/subagent-registry-CTZBVVPF.js +61 -0
  229. package/dist/plugin-sdk/{subsystem-CUUKL6Fr.js → subsystem-B2x33s9h.js} +4 -4
  230. package/dist/plugin-sdk/{tables-DKYi6grj.js → tables-CTmQQyfU.js} +1 -1
  231. package/dist/plugin-sdk/testing.js +2 -2
  232. package/dist/plugin-sdk/{tokens-ysZUkYZZ.js → tokens-DxJSOoJn.js} +1 -1
  233. package/dist/plugin-sdk/{tool-loop-detection-LsvZ1dIY.js → tool-loop-detection-Buouaxew.js} +1 -1
  234. package/dist/plugin-sdk/{tools-PVG4MyCb.js → tools-iyXmO6p1.js} +106 -79
  235. package/dist/plugin-sdk/user-run-recording-BMikDBXR.js +11 -0
  236. package/dist/plugin-sdk/{user-run-recording-BMaK7jNR.js → user-run-recording-juCW_uQ-.js} +2 -2
  237. package/dist/{plugins-cli-yjyVyPjc.js → plugins-cli-B0I1Xkrz.js} +22 -22
  238. package/dist/{plugins-cli-Cpq4XXoA.js → plugins-cli-CmYpruM_.js} +22 -22
  239. package/dist/{program-CLZlTcBu.js → program-CA1rDqtK.js} +23 -23
  240. package/dist/{program-context-DN3ucEgK.js → program-context-BCo6By7P.js} +24 -24
  241. package/dist/{prompt-select-styled-CtLCU2VG.js → prompt-select-styled-BAmwLkut.js} +12 -12
  242. package/dist/{prompt-select-styled-BNUoeaMg.js → prompt-select-styled-cL1dmYcO.js} +12 -12
  243. package/dist/{provider-image-Bi2L9LWh.js → provider-image-BllyLBJM.js} +5 -5
  244. package/dist/{provider-image-CZlpEJVI.js → provider-image-CIpRvhkS.js} +1 -1
  245. package/dist/{provider-image-UXLX6qTH.js → provider-image-D9B_J5Ys.js} +1 -1
  246. package/dist/{proxy-env-i0jn5uxB.js → proxy-env-CzGKpJY_.js} +2 -2
  247. package/dist/{proxy-C9sq6M-h.js → proxy-fWL7CKDP.js} +1 -1
  248. package/dist/{proxy-fetch-CK5AQAYw.js → proxy-fetch-DCI0KuH6.js} +1 -1
  249. package/dist/{push-apns-DYlVj3Sd.js → push-apns-Bhf8qK68.js} +2 -2
  250. package/dist/{push-apns-uBiZYT2e.js → push-apns-BmrddV2R.js} +2 -2
  251. package/dist/{pw-ai-CZJk6UyG.js → pw-ai-CKjrjwfw.js} +1 -1
  252. package/dist/{pw-ai-pYtWxKPR.js → pw-ai-CXSJw34w.js} +14 -14
  253. package/dist/{pw-ai-2o8dgziH.js → pw-ai-Cd08hlBj.js} +1 -1
  254. package/dist/{qmd-manager-p036XU01.js → qmd-manager-BwZ0V5fL.js} +10 -10
  255. package/dist/{query-expansion-30x7RlZY.js → query-expansion-31VWpPCz.js} +5 -5
  256. package/dist/{reconcile-bundled-Dx64x8xr.js → reconcile-bundled-Bl6XpmI5.js} +1 -1
  257. package/dist/{reconcile-bundled-oQwTCU_A.js → reconcile-bundled-TswjG3xv.js} +1 -1
  258. package/dist/{recorder-C_ViZLf1.js → recorder-DNRxe9C8.js} +4 -4
  259. package/dist/{recovery-adapter-BvRiQZIb.js → recovery-adapter-DOizlZvv.js} +8 -8
  260. package/dist/{recovery-adapter-BcPtMfaC.js → recovery-adapter-DW0R_vFE.js} +1 -1
  261. package/dist/{recovery-adapter-BT7EyQzh.js → recovery-adapter-DyPV7syS.js} +8 -8
  262. package/dist/{recovery-adapter-CTqGLqLj.js → recovery-adapter-mi8jbyvy.js} +1 -1
  263. package/dist/{redact-BOHmCPP_.js → redact-DZne_lu8.js} +1 -1
  264. package/dist/{register.agent-DpYKNZhv.js → register.agent-B3BSgQcW.js} +22 -22
  265. package/dist/{register.agent-DxsC-Szl.js → register.agent-CSHtI9uN.js} +23 -23
  266. package/dist/{register.configure-CiYkPB_K.js → register.configure-CYwDM9d3.js} +26 -26
  267. package/dist/{register.configure-Ceru0oh0.js → register.configure-Cu4CPpm4.js} +26 -26
  268. package/dist/{register.maintenance-BCSq69vI.js → register.maintenance-BXiHFIyG.js} +28 -28
  269. package/dist/{register.maintenance-D-kzdtog.js → register.maintenance-C6vjRY-I.js} +29 -29
  270. package/dist/{register.message-B3NWvxgd.js → register.message-BsBClRov.js} +18 -18
  271. package/dist/{register.message-D-e6_UXf.js → register.message-DNpBTvto.js} +18 -18
  272. package/dist/{register.onboard-BPko9BHz.js → register.onboard-BKQLGJhh.js} +2 -2
  273. package/dist/{register.onboard-BHBpxcRv.js → register.onboard-t_7lOkRu.js} +2 -2
  274. package/dist/{register.setup-BE-sR-Dc.js → register.setup-B7QHn0Qv.js} +2 -2
  275. package/dist/{register.setup-Bjx48C4T.js → register.setup-DEg7fSPZ.js} +2 -2
  276. package/dist/{register.status-health-sessions-CQQWiYcu.js → register.status-health-sessions-7E-y6cw7.js} +24 -24
  277. package/dist/{register.status-health-sessions-BczZXjHB.js → register.status-health-sessions-D9iuSOb8.js} +24 -24
  278. package/dist/{register.subclis-Bn9Re4fV.js → register.subclis-R6keQnon.js} +16 -16
  279. package/dist/{replies-BsctLhfp.js → replies-NkETqb6B.js} +4 -4
  280. package/dist/{reply-BzUdF5qW.js → reply-B4TgvJrJ.js} +124 -97
  281. package/dist/{reply-directives-D9wYtPPy.js → reply-directives-DGITtNUL.js} +2 -2
  282. package/dist/{reply-prefix-C7WlN3qm.js → reply-prefix-DVkNDBNe.js} +1 -1
  283. package/dist/{resolve-route-BV8k5qjX.js → resolve-route-jDAjkfZE.js} +5 -5
  284. package/dist/{run-main-Cfccgza4.js → run-main-CMTfGYjG.js} +30 -30
  285. package/dist/{runs-DVNBpgv0.js → runs-B0TxOQnF.js} +3 -3
  286. package/dist/{runs-i5IuTzQX.js → runs-BMp7jOLL.js} +3 -3
  287. package/dist/{runs-BauIdJqy.js → runs-DGWNXyKA.js} +8 -8
  288. package/dist/{sandbox-QsMPF2u6.js → sandbox-CQwpubTx.js} +1 -1
  289. package/dist/{sandbox-bbN1dfIo.js → sandbox-DbfWdQha.js} +1 -1
  290. package/dist/{sandbox-cli-CuG1HCrw.js → sandbox-cli-CSjghLhl.js} +2 -2
  291. package/dist/{sandbox-cli-nx3ctiYX.js → sandbox-cli-DwhgE7u4.js} +2 -2
  292. package/dist/{security-cli-BmfAwh-0.js → security-cli-DSB1NLa6.js} +4 -4
  293. package/dist/{security-cli-BfZEQFxV.js → security-cli-DlMcCXl1.js} +4 -4
  294. package/dist/{send-Tx-ew59_.js → send-CNLmncRW.js} +6 -6
  295. package/dist/{send-CvkM5xAx.js → send-DAYMV49d.js} +1 -1
  296. package/dist/{send-Dd2SE0h0.js → send-DEFcgo-1.js} +27 -27
  297. package/dist/{send-BGps2i_C.js → send-Do1AlhD5.js} +8 -8
  298. package/dist/{send-BiDcVZSc.js → send-Dq8ChBfS.js} +6 -6
  299. package/dist/{send-Ba3pDq6E.js → send-ENMm5qbW.js} +7 -7
  300. package/dist/{send-BKkvuHI9.js → send-l57G-s8y.js} +1 -1
  301. package/dist/{server-BMSgu_SV.js → server-BAGUd2MH.js} +4 -4
  302. package/dist/{server-DRVR_pkr.js → server-IDopagLT.js} +4 -4
  303. package/dist/{server-context-CTilcbO4.js → server-context-BUX61Gwl.js} +2 -2
  304. package/dist/{server-context-Bbi-nqKD.js → server-context-FPrSnBNG.js} +2 -2
  305. package/dist/{server-lifecycle-DrAGY_SC.js → server-lifecycle-7QoL5fyb.js} +1 -1
  306. package/dist/{server-lifecycle-BIOS9ErD.js → server-lifecycle-DXRap2AR.js} +1 -1
  307. package/dist/{server-node-events-B3c2ctcO.js → server-node-events-DSTI4JnV.js} +18 -18
  308. package/dist/{server-node-events-lwnuZDvV.js → server-node-events-MOX6FUiJ.js} +18 -18
  309. package/dist/{service-Hy5BSgmp.js → service-C_LTJsJU.js} +1 -1
  310. package/dist/{service-RnhuB5cG.js → service-Dkcqg-rd.js} +1 -1
  311. package/dist/{session-meta-DH__PMKt.js → session-meta-DuK_BrWT.js} +2 -2
  312. package/dist/{sessions-DCXadUdD.js → sessions-CgVN798h.js} +4 -4
  313. package/dist/{sessions-Cy_VVMEN.js → sessions-Dcu0bdQ7.js} +4 -4
  314. package/dist/{shared-Bc-7t0_-.js → shared-6Uo_6p6X.js} +1 -1
  315. package/dist/{shared-CJd0QML9.js → shared-Cj18nzyW.js} +1 -1
  316. package/dist/{skill-commands-CRZajtK_.js → skill-commands-BhMQp_i8.js} +9 -9
  317. package/dist/{skills-DOc6uEd1.js → skills-ckuLxkyg.js} +21 -21
  318. package/dist/{status-PwhjcAYw.js → status-B3eNMcE3.js} +7 -7
  319. package/dist/{status-Dh0qVJb_.js → status-C5pbfqhh.js} +7 -7
  320. package/dist/{store-xxN6qyAh.js → store-gQ6FSjVk.js} +2 -2
  321. package/dist/{subsystem-BCjklMkJ.js → subsystem-CPYnUTN4.js} +64 -64
  322. package/dist/{systemd-B5tdOLBg.js → systemd-BJqlwupF.js} +1 -1
  323. package/dist/{systemd-DsBMxUv1.js → systemd-D6tSdsgx.js} +1 -1
  324. package/dist/{systemd-hints-DH86kn6U.js → systemd-hints-Cp0IfOPD.js} +45 -4
  325. package/dist/{systemd-hints-WHzM5Tf8.js → systemd-hints-DzBfweRH.js} +45 -4
  326. package/dist/{systemd-linger-BPzLwumk.js → systemd-linger-Dk1GWduD.js} +1 -1
  327. package/dist/{systemd-linger-EvpJ4ZxF.js → systemd-linger-NvIOU-Ez.js} +1 -1
  328. package/dist/{tables-o3ZpyPWV.js → tables-DEyD0zuy.js} +1 -1
  329. package/dist/{task-pipeline-boot-CcSZVGUe.js → task-pipeline-boot-BLEjtMkt.js} +17 -17
  330. package/dist/{task-pipeline-boot-UcskPjY2.js → task-pipeline-boot-DKqT4VdZ.js} +17 -17
  331. package/dist/{tokens-9Mla_HDp.js → tokens-9BPY4SaX.js} +1 -1
  332. package/dist/{tool-loop-detection-8uvf8mSd.js → tool-loop-detection-C1fqyXXD.js} +2 -2
  333. package/dist/{tui-WSQKUD4o.js → tui-5QhX2Lcm.js} +1 -1
  334. package/dist/{tui-dccCFhet.js → tui-CetFSZIt.js} +1 -1
  335. package/dist/{tui-cli-C3Sopj4_.js → tui-cli-Bo-8qeoa.js} +4 -4
  336. package/dist/{tui-cli-CpRsjtOO.js → tui-cli-DFak7s89.js} +4 -4
  337. package/dist/{update-D86-cS_v.js → update-B3jJ2yVe.js} +1 -1
  338. package/dist/{update-DJaR3w6x.js → update-Dwt-MeRL.js} +1 -1
  339. package/dist/{update-cli-BSxfgTyN.js → update-cli-D5knJbn5.js} +34 -34
  340. package/dist/{update-cli-f5iTpbNn.js → update-cli-Dhxx3iie.js} +33 -33
  341. package/dist/{update-runner-DwM4xj8C.js → update-runner-18yD5NLo.js} +1 -1
  342. package/dist/{update-runner-DqE_9Axt.js → update-runner-DohE1D7D.js} +1 -1
  343. package/dist/{user-run-recording-CAk1Ketk.js → user-run-recording-B0XAAUwL.js} +2 -2
  344. package/dist/{validation-cli-C8XHeLjI.js → validation-cli-CAge8d_F.js} +18 -18
  345. package/dist/{validation-cli-jSmCMkkm.js → validation-cli-Dfac8Duq.js} +18 -18
  346. package/dist/{with-timeout-BvxLQUTs.js → with-timeout-1SSQaGSz.js} +2 -2
  347. package/dist/{with-timeout-CII3PkDO.js → with-timeout-DD5bV7yq.js} +2 -2
  348. package/dist/{workspace-Dbn4gFdH.js → workspace-B707AGIc.js} +9 -9
  349. package/extensions/acpx/package.json +1 -1
  350. package/extensions/anthropic/package.json +1 -1
  351. package/extensions/bifrost/package.json +1 -1
  352. package/extensions/bluebubbles/package.json +1 -1
  353. package/extensions/copilot-proxy/package.json +1 -1
  354. package/extensions/deepgram/package.json +1 -1
  355. package/extensions/deepinfra/package.json +1 -1
  356. package/extensions/diagnostics-otel/package.json +1 -1
  357. package/extensions/diffs/package.json +1 -1
  358. package/extensions/discord/package.json +1 -1
  359. package/extensions/dream-cycle/package.json +1 -1
  360. package/extensions/elevenlabs/package.json +1 -1
  361. package/extensions/feishu/package.json +1 -1
  362. package/extensions/gemini-search/package.json +1 -1
  363. package/extensions/google/package.json +1 -1
  364. package/extensions/google-gemini-cli-auth/package.json +1 -1
  365. package/extensions/googlechat/package.json +1 -1
  366. package/extensions/grok-search/package.json +1 -1
  367. package/extensions/groq/package.json +1 -1
  368. package/extensions/imessage/package.json +1 -1
  369. package/extensions/irc/package.json +1 -1
  370. package/extensions/kimi-search/package.json +1 -1
  371. package/extensions/learning-core/package.json +1 -1
  372. package/extensions/learning-core/src/bounded-store-reads.conformance.test.ts +23 -411
  373. package/extensions/learning-core/src/bounded-store-reads.pg.integration.test.ts +52 -0
  374. package/extensions/learning-core/src/bounded-store-reads.test-helpers.ts +387 -0
  375. package/extensions/learning-core/src/lesson-store-conformance.pg.integration.test.ts +77 -0
  376. package/extensions/learning-core/src/lesson-store-conformance.test-helpers.ts +1406 -0
  377. package/extensions/learning-core/src/lesson-store-conformance.test.ts +27 -1509
  378. package/extensions/learning-core/src/lesson-store-postgres.test.ts +9 -7
  379. package/extensions/line/package.json +1 -1
  380. package/extensions/llm-task/package.json +1 -1
  381. package/extensions/lobster/package.json +1 -1
  382. package/extensions/matrix/CHANGELOG.md +1 -1
  383. package/extensions/matrix/package.json +1 -1
  384. package/extensions/mattermost/package.json +1 -1
  385. package/extensions/memory-core/package.json +1 -1
  386. package/extensions/memory-lancedb/package.json +1 -1
  387. package/extensions/minimax/package.json +1 -1
  388. package/extensions/minimax-portal-auth/package.json +1 -1
  389. package/extensions/mistral/package.json +1 -1
  390. package/extensions/moonshot/package.json +1 -1
  391. package/extensions/msteams/CHANGELOG.md +1 -1
  392. package/extensions/msteams/package.json +1 -1
  393. package/extensions/nextcloud-talk/package.json +1 -1
  394. package/extensions/nostr/CHANGELOG.md +1 -1
  395. package/extensions/nostr/package.json +1 -1
  396. package/extensions/open-prose/package.json +1 -1
  397. package/extensions/openai/package.json +1 -1
  398. package/extensions/openai-realtime/package.json +1 -1
  399. package/extensions/openrouter/package.json +1 -1
  400. package/extensions/perplexity-search/package.json +1 -1
  401. package/extensions/searxng-search/package.json +1 -1
  402. package/extensions/signal/package.json +1 -1
  403. package/extensions/slack/package.json +1 -1
  404. package/extensions/synology-chat/package.json +1 -1
  405. package/extensions/telegram/package.json +1 -1
  406. package/extensions/tlon/package.json +1 -1
  407. package/extensions/twitch/CHANGELOG.md +1 -1
  408. package/extensions/twitch/package.json +1 -1
  409. package/extensions/voice-call/CHANGELOG.md +1 -1
  410. package/extensions/voice-call/package.json +1 -1
  411. package/extensions/whatsapp/package.json +1 -1
  412. package/extensions/zai/package.json +1 -1
  413. package/extensions/zalo/CHANGELOG.md +1 -1
  414. package/extensions/zalo/package.json +1 -1
  415. package/extensions/zalouser/CHANGELOG.md +1 -1
  416. package/extensions/zalouser/package.json +1 -1
  417. package/package.json +1 -1
  418. package/dist/plugin-sdk/agent-turn-execute-BCE3FS2s.js +0 -61
  419. package/dist/plugin-sdk/agent-turn-runner-gf0ARmuP.js +0 -11
  420. package/dist/plugin-sdk/audio-preflight-DlGohKMs.js +0 -28
  421. package/dist/plugin-sdk/deliver-DBCz1GqU.js +0 -32
  422. package/dist/plugin-sdk/manager-ByaW_O4Y.js +0 -16
  423. package/dist/plugin-sdk/markdown-tables-J4hZ7eWU.js +0 -10
  424. package/dist/plugin-sdk/provider-dispatcher-Byy-KtUn.js +0 -61
  425. package/dist/plugin-sdk/provider-image-B_dJDOl5.js +0 -22
  426. package/dist/plugin-sdk/proxy-DwbYzxBy.js +0 -7
  427. package/dist/plugin-sdk/replies-B9uDLFOE.js +0 -25
  428. package/dist/plugin-sdk/reply-prefix-BQMEQam1.js +0 -7
  429. package/dist/plugin-sdk/runs-BQhYekhr.js +0 -25
  430. package/dist/plugin-sdk/send-CeWqZTK0.js +0 -23
  431. package/dist/plugin-sdk/send-CzcKgBBf.js +0 -25
  432. package/dist/plugin-sdk/send-Dvna5ey-.js +0 -27
  433. package/dist/plugin-sdk/send-xPV0QIjh.js +0 -24
  434. package/dist/plugin-sdk/session-meta-n4SCcAbJ.js +0 -10
  435. package/dist/plugin-sdk/skill-commands-BOV3NIbU.js +0 -14
  436. package/dist/plugin-sdk/subagent-registry-CZBK6615.js +0 -61
  437. package/dist/plugin-sdk/user-run-recording-DiKcNdjn.js +0 -11
@@ -0,0 +1,387 @@
1
+ import crypto from "node:crypto";
2
+ import type { DatabaseSync } from "node:sqlite";
3
+ import { describe, expect, it } from "vitest";
4
+ import { readRankingPool, RANKING_SCAN_MAX_ROWS } from "./consolidation-judge.js";
5
+ import { withCandidateDefaults } from "./extraction-candidate.js";
6
+ import { createLearningOverview } from "./gateway-methods.js";
7
+ import { withLessonDefaults } from "./lesson-record.js";
8
+ import type { PgClientLike, PgPoolLike } from "./lesson-store-postgres.js";
9
+ import type { SqliteDatabaseLike } from "./lesson-store-sqlite.js";
10
+ import {
11
+ LESSON_EXCERPT_MAX_BYTES,
12
+ LESSON_PAGE_MAX_BYTES,
13
+ type ExtractionCandidate,
14
+ type LessonStore,
15
+ type SkillProposal,
16
+ } from "./types.js";
17
+
18
+ // Spec "Bounded store reads, scans, and success evidence": verification asserts rows AND bytes
19
+ // read, not just result length. Every SQL leg runs through a meter that counts the rows the
20
+ // database handed back and the payload bytes among them, so a materialize-then-filter read (the
21
+ // pre-change readPayloads path) fails here even when its result is correct.
22
+
23
+ type Meter = { rows: number; payloadBytes: number; excerptBytes: number };
24
+
25
+ function newMeter(): Meter {
26
+ return { rows: 0, payloadBytes: 0, excerptBytes: 0 };
27
+ }
28
+
29
+ // One wrapped handle per test (the stores memoise schema init on the handle), metering into
30
+ // whichever meter the last make() installed.
31
+ let activeMeter: Meter = newMeter();
32
+
33
+ function countRows(rows: unknown[]): void {
34
+ const meter = activeMeter;
35
+ for (const row of rows) {
36
+ meter.rows += 1;
37
+ for (const [column, value] of Object.entries(row as Record<string, unknown>)) {
38
+ if (column === "payload_json") {
39
+ meter.payloadBytes += Buffer.byteLength(
40
+ typeof value === "string" ? value : JSON.stringify(value),
41
+ );
42
+ } else if (column === "excerpt" && value instanceof Uint8Array) {
43
+ meter.excerptBytes += value.length;
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ export function meteredSqlite(db: DatabaseSync): SqliteDatabaseLike {
50
+ return {
51
+ exec: (sql) => db.exec(sql),
52
+ prepare(sql) {
53
+ const statement = db.prepare(sql);
54
+ return {
55
+ run: (...params) => statement.run(...(params as never[])),
56
+ get: (...params) => {
57
+ const row = statement.get(...(params as never[]));
58
+ countRows(row === undefined ? [] : [row]);
59
+ return row;
60
+ },
61
+ all: (...params) => {
62
+ const rows = statement.all(...(params as never[]));
63
+ countRows(rows);
64
+ return rows;
65
+ },
66
+ };
67
+ },
68
+ };
69
+ }
70
+
71
+ export function meteredPool(pool: PgPoolLike): PgPoolLike {
72
+ const wrap = async (result: Promise<{ rows: Record<string, unknown>[] }>) => {
73
+ const settled = await result;
74
+ countRows(settled.rows);
75
+ return settled;
76
+ };
77
+ return {
78
+ query: (sql, values) => wrap(pool.query(sql, values)),
79
+ async connect(): Promise<PgClientLike> {
80
+ const client = await pool.connect();
81
+ return {
82
+ query: (sql, values) => wrap(client.query(sql, values)),
83
+ release: () => client.release(),
84
+ };
85
+ },
86
+ };
87
+ }
88
+
89
+ const RUN_TOKEN = crypto.randomUUID().replaceAll("-", "");
90
+ export const TEST_SCHEMA = `plugin_learning_core_bounded_${RUN_TOKEN}`;
91
+ export const NOW = "2026-06-01T00:00:00.000Z";
92
+ export const PAST = "2026-05-01T00:00:00.000Z";
93
+ const FUTURE = "2027-01-01T00:00:00.000Z";
94
+
95
+ export type SqlLeg = {
96
+ label: string;
97
+ /** Fixture sizes; the live leg is smaller only to keep a shared server fast. */
98
+ scale: number;
99
+ make: (meter: Meter) => LessonStore;
100
+ /** A store scoped to one row's own scope, over the same metered handle `make` reads through. */
101
+ writer: (scope: { workspaceId: string; agentId: string }) => LessonStore;
102
+ };
103
+
104
+ export function metering<T>(meter: Meter, value: T): T {
105
+ activeMeter = meter;
106
+ return value;
107
+ }
108
+
109
+ function iso(ms: number): string {
110
+ return new Date(Date.parse(PAST) + ms).toISOString();
111
+ }
112
+
113
+ export function candidate(
114
+ index: number,
115
+ status: ExtractionCandidate["status"],
116
+ ): ExtractionCandidate {
117
+ return withCandidateDefaults(
118
+ {
119
+ sessionId: `session-${String(index).padStart(6, "0")}`,
120
+ agentId: `agent-${index % 3}`,
121
+ workspaceId: `ws-${index % 2}`,
122
+ excerpt: `candidate ${index} ${"x".repeat(900)}`,
123
+ tags: index % 2 === 0 ? ["correction"] : ["failure"],
124
+ status,
125
+ },
126
+ iso(index * 1000),
127
+ );
128
+ }
129
+
130
+ export function lesson(
131
+ index: number,
132
+ text: string,
133
+ opts?: { invalidAt?: string; validFrom?: string },
134
+ ) {
135
+ const at = iso(index * 1000);
136
+ return withLessonDefaults(
137
+ {
138
+ id: `lesson-${String(index).padStart(6, "0")}`,
139
+ scope: { agentId: `agent-${index % 3}`, workspaceId: `ws-${index % 2}` },
140
+ kind: "procedure" as const,
141
+ text,
142
+ confidence: 0.9,
143
+ occurrences: 1,
144
+ distinctSessionIds: [`s-${index}`],
145
+ evidence: [],
146
+ createdAt: at,
147
+ updatedAt: at,
148
+ ...(opts?.validFrom ? { validFrom: opts.validFrom } : {}),
149
+ ...(opts?.invalidAt ? { invalidAt: opts.invalidAt } : {}),
150
+ },
151
+ at,
152
+ );
153
+ }
154
+
155
+ export function proposal(index: number, status: SkillProposal["status"]): SkillProposal {
156
+ return {
157
+ id: `proposal-${index}`,
158
+ lessonIds: [`lesson-${String(index).padStart(6, "0")}`],
159
+ status,
160
+ skillName: `skill-${index}`,
161
+ title: `Proposal ${index}`,
162
+ body: "b".repeat(4000),
163
+ scannerFindings: [],
164
+ createdAt: iso(index),
165
+ updatedAt: iso(index),
166
+ };
167
+ }
168
+
169
+ // Mixed 1-, 2- and 3-byte characters, so a byte cut can land inside a character.
170
+ const LONG_TEXT = `${"é".repeat(3000)}${"界".repeat(2000)} tail`;
171
+
172
+ async function seedScoped(
173
+ writer: (scope: { workspaceId: string; agentId: string }) => LessonStore,
174
+ items: Array<{
175
+ scope: { workspaceId: string; agentId: string };
176
+ write: (store: LessonStore) => Promise<void>;
177
+ }>,
178
+ ): Promise<void> {
179
+ for (const item of items) {
180
+ await item.write(writer(item.scope));
181
+ }
182
+ }
183
+
184
+ export function registerBoundedSqlLegSuite(leg: SqlLeg): void {
185
+ describe(`bounded SQL store reads — ${leg.label}`, () => {
186
+ // Writes go through a store scoped to the row's own scope (as production capture does), reads
187
+ // through the unscoped store the gateway and the passes use.
188
+ const scopedWriter = (meter: Meter) => (scope: { workspaceId: string; agentId: string }) => {
189
+ activeMeter = meter;
190
+ return leg.writer(scope);
191
+ };
192
+ const scopeOf = (index: number) => ({
193
+ agentId: `agent-${index % 3}`,
194
+ workspaceId: `ws-${index % 2}`,
195
+ });
196
+
197
+ it("pending candidates: rows and payload bytes read are the pending set only, keyset-paged", async () => {
198
+ const total = Math.round(2000 * leg.scale);
199
+ const pendingEvery = 100;
200
+ const seedMeter = newMeter();
201
+ const writer = scopedWriter(seedMeter);
202
+ const all: ExtractionCandidate[] = [];
203
+ for (let index = 0; index < total; index += 1) {
204
+ const entry = candidate(index, index % pendingEvery === 0 ? "pending" : "processed");
205
+ all.push(entry);
206
+ await writer(scopeOf(index)).upsertCandidate(entry);
207
+ }
208
+ const expected = all.filter((entry) => entry.status === "pending");
209
+ const pendingBytes = expected.reduce(
210
+ (sum, entry) => sum + Buffer.byteLength(JSON.stringify(entry)),
211
+ 0,
212
+ );
213
+ const allBytes = all.reduce(
214
+ (sum, entry) => sum + Buffer.byteLength(JSON.stringify(entry)),
215
+ 0,
216
+ );
217
+
218
+ const meter = newMeter();
219
+ const store = leg.make(meter);
220
+ const pending = await store.listPendingCandidates();
221
+ expect(pending.map((entry) => entry.sessionId)).toEqual(
222
+ expected.map((entry) => entry.sessionId),
223
+ );
224
+ expect(meter.rows, "rows read must be the pending rows, not every candidate").toBe(
225
+ expected.length,
226
+ );
227
+ // jsonb re-serialization may reorder keys but never grows a row by more than its key quotes.
228
+ expect(meter.payloadBytes).toBeLessThanOrEqual(pendingBytes * 1.1);
229
+ expect(meter.payloadBytes).toBeLessThan(allBytes / 20);
230
+
231
+ // Keyset pages: LIMIT applies in SQL, pages chain without gaps or repeats, tags filter.
232
+ const pageMeter = newMeter();
233
+ const paged = leg.make(pageMeter);
234
+ const first = await paged.listPendingCandidatesPage({ limit: 7 });
235
+ expect(pageMeter.rows).toBe(7);
236
+ const seen = [...first.candidates];
237
+ let cursor = first.nextCursor;
238
+ while (cursor) {
239
+ const page = await paged.listPendingCandidatesPage({ after: cursor, limit: 7 });
240
+ seen.push(...page.candidates);
241
+ cursor = page.nextCursor;
242
+ }
243
+ expect(seen.map((entry) => entry.sessionId)).toEqual(
244
+ expected.map((entry) => entry.sessionId),
245
+ );
246
+ const tagged = await paged.listPendingCandidates({ tags: ["failure"] });
247
+ expect(tagged.map((entry) => entry.sessionId)).toEqual(
248
+ expected.filter((entry) => entry.tags.includes("failure")).map((entry) => entry.sessionId),
249
+ );
250
+ const limited = await paged.listPendingCandidates({ limit: 3 });
251
+ expect(limited.map((entry) => entry.sessionId)).toEqual(
252
+ expected.slice(0, 3).map((entry) => entry.sessionId),
253
+ );
254
+ });
255
+
256
+ it("similar-lesson ranking reads { id, excerpt } pages: no payload bytes, 2 KiB rows, 256 KiB pages", async () => {
257
+ const activeCount = Math.round(450 * leg.scale);
258
+ const seedMeter = newMeter();
259
+ const writer = scopedWriter(seedMeter);
260
+ const activeIds: string[] = [];
261
+ for (let index = 0; index < activeCount; index += 1) {
262
+ const entry = lesson(index, index % 5 === 0 ? `short ${index}` : `${LONG_TEXT} ${index}`);
263
+ activeIds.push(entry.id);
264
+ await writer(scopeOf(index)).upsertLesson(entry);
265
+ }
266
+ // Inactive rows the SQL predicate must drop: invalidated, and not yet valid.
267
+ for (let index = activeCount; index < activeCount + 40; index += 1) {
268
+ await writer(scopeOf(index)).upsertLesson(
269
+ lesson(index, LONG_TEXT, index % 2 === 0 ? { invalidAt: PAST } : { validFrom: FUTURE }),
270
+ );
271
+ }
272
+
273
+ const meter = newMeter();
274
+ const store = leg.make(meter);
275
+ const first = await store.listActiveLessonsPage({ now: NOW, limit: 200 });
276
+ expect(meter.payloadBytes, "no payload_json may leave the database").toBe(0);
277
+ expect(first.lessons.length).toBeLessThanOrEqual(200);
278
+ expect(first.nextCursor).toBeDefined();
279
+ const firstBytes = first.lessons.reduce(
280
+ (sum, entry) => sum + Buffer.byteLength(entry.excerpt),
281
+ 0,
282
+ );
283
+ expect(firstBytes).toBeLessThanOrEqual(LESSON_PAGE_MAX_BYTES);
284
+ expect(
285
+ meter.excerptBytes,
286
+ "the database returned at most one page of excerpts",
287
+ ).toBeLessThanOrEqual(LESSON_PAGE_MAX_BYTES);
288
+ for (const entry of first.lessons) {
289
+ expect(Buffer.byteLength(entry.excerpt)).toBeLessThanOrEqual(LESSON_EXCERPT_MAX_BYTES);
290
+ expect(entry.excerpt).not.toContain("�");
291
+ }
292
+
293
+ const walkMeter = newMeter();
294
+ const walker = leg.make(walkMeter);
295
+ const pool = await readRankingPool(walker, NOW);
296
+ expect(pool.truncated).toBe(false);
297
+ expect(pool.lessons.map((entry) => entry.id).toSorted()).toEqual(activeIds.toSorted());
298
+ expect(walkMeter.rows, "every active row read exactly once, inactive never").toBe(
299
+ activeCount,
300
+ );
301
+ expect(walkMeter.payloadBytes).toBe(0);
302
+ });
303
+
304
+ it("the ranking scan stops at its 2,000-row ceiling", async () => {
305
+ if (leg.label.includes("live")) {
306
+ return;
307
+ }
308
+ const writer = scopedWriter(newMeter());
309
+ for (let index = 0; index < RANKING_SCAN_MAX_ROWS + 50; index += 1) {
310
+ await writer(scopeOf(index)).upsertLesson(lesson(index, `tiny ${index}`));
311
+ }
312
+ const meter = newMeter();
313
+ const pool = await readRankingPool(leg.make(meter), NOW);
314
+ expect(pool.truncated).toBe(true);
315
+ expect(pool.lessons).toHaveLength(RANKING_SCAN_MAX_ROWS);
316
+ expect(meter.rows).toBe(RANKING_SCAN_MAX_ROWS);
317
+ });
318
+
319
+ it("overview counts are SQL aggregates: a handful of rows, no payload bytes", async () => {
320
+ const seedMeter = newMeter();
321
+ const writer = scopedWriter(seedMeter);
322
+ const lessons = Math.round(300 * leg.scale);
323
+ const items: Parameters<typeof seedScoped>[1] = [];
324
+ for (let index = 0; index < lessons; index += 1) {
325
+ items.push({
326
+ scope: scopeOf(index),
327
+ write: (store) =>
328
+ store.upsertLesson(
329
+ lesson(index, "t", index % 10 === 0 ? { invalidAt: PAST } : undefined),
330
+ ),
331
+ });
332
+ }
333
+ const statuses: SkillProposal["status"][] = ["pending", "applied", "rejected", "quarantined"];
334
+ for (let index = 0; index < 40; index += 1) {
335
+ items.push({
336
+ scope: scopeOf(index),
337
+ write: (store) => store.upsertProposal(proposal(index, statuses[index % 4])),
338
+ });
339
+ }
340
+ await seedScoped(writer, items);
341
+
342
+ const meter = newMeter();
343
+ const store = leg.make(meter);
344
+ const counts = await store.countOverview({ now: NOW });
345
+ expect(counts).toEqual({
346
+ proposals: { pending: 10, applied: 10, rejected: 10, quarantined: 10 },
347
+ lessons: lessons - lessons / 10,
348
+ scopes: 6,
349
+ truncated: false,
350
+ });
351
+ expect(meter.payloadBytes).toBe(0);
352
+ expect(meter.rows).toBeLessThanOrEqual(8);
353
+
354
+ // The real entry point: learning.overview over the same store.
355
+ const calls: Array<{ ok: boolean; payload?: unknown }> = [];
356
+ const handlerMeter = newMeter();
357
+ await createLearningOverview({
358
+ readResolution: async () => ({}),
359
+ lessonStore: () => leg.make(handlerMeter),
360
+ now: () => NOW,
361
+ })({
362
+ params: {},
363
+ respond: (ok: boolean, payload?: unknown) => calls.push({ ok, payload }),
364
+ } as never);
365
+ expect(calls[0]).toMatchObject({
366
+ ok: true,
367
+ payload: { lessons: counts.lessons, scopes: 6, truncated: false },
368
+ });
369
+ expect(handlerMeter.payloadBytes).toBe(0);
370
+ });
371
+
372
+ it("getLesson and getLessonsByIds read only the named rows", async () => {
373
+ const writer = scopedWriter(newMeter());
374
+ for (let index = 0; index < 200; index += 1) {
375
+ await writer(scopeOf(index)).upsertLesson(lesson(index, LONG_TEXT));
376
+ }
377
+ const meter = newMeter();
378
+ const store = leg.make(meter);
379
+ const found = await store.getLessonsByIds(["lesson-000003", "lesson-000150", "missing"]);
380
+ expect(found.map((entry) => entry.id).toSorted()).toEqual(["lesson-000003", "lesson-000150"]);
381
+ expect(meter.rows).toBe(2);
382
+ const one = newMeter();
383
+ expect((await leg.make(one).getLesson("lesson-000007"))?.id).toBe("lesson-000007");
384
+ expect(one.rows).toBe(1);
385
+ });
386
+ });
387
+ }
@@ -0,0 +1,77 @@
1
+ import { afterAll, afterEach, beforeAll, describe, expect } from "vitest";
2
+ import {
3
+ PG_TABLE,
4
+ registerLessonStoreConformance,
5
+ RUN_ID,
6
+ TEST_SCHEMA,
7
+ type Backend,
8
+ } from "./lesson-store-conformance.test-helpers.js";
9
+ import {
10
+ createDefaultLearningPgPool,
11
+ PostgresLessonStore,
12
+ type PgPoolLike,
13
+ } from "./lesson-store-postgres.js";
14
+
15
+ // Live-server leg of the LessonStore conformance suite (`pnpm test:pg`): the contract the fs-jsonl,
16
+ // sqlite and in-memory-double legs run in lesson-store-conformance.test.ts, against a real
17
+ // Postgres. This leg, not the double, is the authority on real dialect behaviour.
18
+ const databaseUrl = process.env.OPENCLAW_DATABASE_URL;
19
+ const live = process.env.OPENCLAW_LIVE_PG_TEST === "1" && Boolean(databaseUrl);
20
+
21
+ type ClosablePool = PgPoolLike & { end?: () => Promise<void> };
22
+ let sharedPool: ClosablePool;
23
+
24
+ async function cleanupPostgresRows(): Promise<void> {
25
+ // The table only exists once the postgres leg has run its DDL; probing avoids swallowing a
26
+ // real error in a bare catch.
27
+ const probe = await sharedPool.query("SELECT to_regclass($1) AS reg", [PG_TABLE]);
28
+ if (!probe.rows[0]?.reg) {
29
+ return;
30
+ }
31
+ await sharedPool.query(`DELETE FROM ${PG_TABLE} WHERE workspace_id LIKE $1`, [`${RUN_ID}%`]);
32
+ }
33
+
34
+ const liveBackend: Backend = {
35
+ name: "postgres",
36
+ label: "postgres (live server)",
37
+ make: async (scope) => new PostgresLessonStore({ pool: sharedPool, schema: TEST_SCHEMA, scope }),
38
+ snapshot: async () => {
39
+ const result = await sharedPool.query(
40
+ `SELECT * FROM ${PG_TABLE} WHERE workspace_id LIKE $1
41
+ ORDER BY workspace_id, agent_id, record_type, record_id`,
42
+ [`${RUN_ID}%`],
43
+ );
44
+ return JSON.stringify(result.rows);
45
+ },
46
+ assertSearchIndex: async () => {
47
+ const cols = await sharedPool.query(
48
+ `SELECT column_name FROM information_schema.columns
49
+ WHERE table_schema = $1 AND table_name = 'learning_records' AND column_name = 'search_tsv'`,
50
+ [TEST_SCHEMA],
51
+ );
52
+ expect(cols.rows.length).toBeGreaterThan(0);
53
+ const idx = await sharedPool.query(
54
+ `SELECT indexname FROM pg_indexes
55
+ WHERE schemaname = $1 AND tablename = 'learning_records' AND indexdef ILIKE '%gin%'`,
56
+ [TEST_SCHEMA],
57
+ );
58
+ expect(idx.rows.length).toBeGreaterThan(0);
59
+ },
60
+ };
61
+
62
+ describe.skipIf(!live)("live postgres", () => {
63
+ beforeAll(() => {
64
+ sharedPool = createDefaultLearningPgPool(databaseUrl!);
65
+ });
66
+
67
+ afterEach(async () => {
68
+ await cleanupPostgresRows();
69
+ });
70
+
71
+ afterAll(async () => {
72
+ await sharedPool.query(`DROP SCHEMA IF EXISTS ${TEST_SCHEMA} CASCADE`);
73
+ await sharedPool.end?.();
74
+ });
75
+
76
+ registerLessonStoreConformance(liveBackend);
77
+ });