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