@theokit/sdk 4.40.0 → 4.41.1
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/CHANGELOG.md +73 -0
- package/README.md +2 -2
- package/dist/{agent-BzZwYFiw.d.ts → agent-BiCINq25.d.ts} +2 -2
- package/dist/agent-JDJEBJHU.cjs +55 -0
- package/dist/{agent-OOXJJD6A.cjs.map → agent-JDJEBJHU.cjs.map} +1 -1
- package/dist/agent-LVKAYADR.js +46 -0
- package/dist/{agent-MSR3DHO4.js.map → agent-LVKAYADR.js.map} +1 -1
- package/dist/{agent-DxEL4fHh.d.cts → agent-Zta1kvGH.d.cts} +2 -2
- package/dist/agent-session-store-EPUERCUU.cjs +23 -0
- package/dist/{agent-session-store-RHTLZ5OX.cjs.map → agent-session-store-EPUERCUU.cjs.map} +1 -1
- package/dist/agent-session-store-TXP5ZVOD.js +6 -0
- package/dist/{agent-session-store-EGTTYSKS.js.map → agent-session-store-TXP5ZVOD.js.map} +1 -1
- package/dist/auth/index.cjs +19 -15
- package/dist/auth/index.d.cts +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.js +4 -4
- package/dist/{batch-WX2HLXX2.js → batch-OUF4N2TM.js} +9 -9
- package/dist/{batch-WX2HLXX2.js.map → batch-OUF4N2TM.js.map} +1 -1
- package/dist/{batch-FO2KZN7W.cjs → batch-URTEXK77.cjs} +26 -26
- package/dist/{batch-FO2KZN7W.cjs.map → batch-URTEXK77.cjs.map} +1 -1
- package/dist/{chunk-PDOLUFGY.cjs → chunk-27DYRARU.cjs} +4 -4
- package/dist/{chunk-PDOLUFGY.cjs.map → chunk-27DYRARU.cjs.map} +1 -1
- package/dist/{chunk-LYD3ALDT.js → chunk-2S6B5B2A.js} +5 -5
- package/dist/{chunk-LYD3ALDT.js.map → chunk-2S6B5B2A.js.map} +1 -1
- package/dist/{chunk-VTDQRUAJ.js → chunk-2WB6EIYW.js} +4 -4
- package/dist/{chunk-VTDQRUAJ.js.map → chunk-2WB6EIYW.js.map} +1 -1
- package/dist/{chunk-3CAQCFVZ.js → chunk-35NFZ7QB.js} +3 -3
- package/dist/{chunk-3CAQCFVZ.js.map → chunk-35NFZ7QB.js.map} +1 -1
- package/dist/{chunk-HCRCNI7A.js → chunk-3KY7MHR4.js} +3 -3
- package/dist/{chunk-HCRCNI7A.js.map → chunk-3KY7MHR4.js.map} +1 -1
- package/dist/{chunk-BURYFNOM.cjs → chunk-4JBHSLQO.cjs} +2 -2
- package/dist/chunk-4JBHSLQO.cjs.map +1 -0
- package/dist/{chunk-V7CA3CX5.cjs → chunk-4JRRFRV4.cjs} +5 -4
- package/dist/chunk-4JRRFRV4.cjs.map +1 -0
- package/dist/{chunk-5KOW3GLE.js → chunk-4QEC4CCS.js} +2 -2
- package/dist/chunk-4QEC4CCS.js.map +1 -0
- package/dist/{chunk-ALDFVGQQ.cjs → chunk-57KX5WTP.cjs} +9 -9
- package/dist/{chunk-ALDFVGQQ.cjs.map → chunk-57KX5WTP.cjs.map} +1 -1
- package/dist/{chunk-CJHBSSAF.cjs → chunk-64TJCXY5.cjs} +15 -15
- package/dist/{chunk-CJHBSSAF.cjs.map → chunk-64TJCXY5.cjs.map} +1 -1
- package/dist/{chunk-IEKSEAIV.js → chunk-6FSQ3CHQ.js} +3 -3
- package/dist/{chunk-IEKSEAIV.js.map → chunk-6FSQ3CHQ.js.map} +1 -1
- package/dist/{chunk-ZVQJHY4Y.cjs → chunk-6W4U2G3J.cjs} +5 -5
- package/dist/{chunk-ZVQJHY4Y.cjs.map → chunk-6W4U2G3J.cjs.map} +1 -1
- package/dist/{chunk-FMDZZRYE.cjs → chunk-6X2HUT4A.cjs} +8 -8
- package/dist/{chunk-FMDZZRYE.cjs.map → chunk-6X2HUT4A.cjs.map} +1 -1
- package/dist/{chunk-X2LDDKFM.cjs → chunk-7PESI6YD.cjs} +10 -10
- package/dist/{chunk-X2LDDKFM.cjs.map → chunk-7PESI6YD.cjs.map} +1 -1
- package/dist/{chunk-EYUZZXHZ.js → chunk-AF4BBKIF.js} +4 -4
- package/dist/chunk-AF4BBKIF.js.map +1 -0
- package/dist/{chunk-7GFX45DD.js → chunk-AM2CNBKE.js} +2 -2
- package/dist/chunk-AM2CNBKE.js.map +1 -0
- package/dist/{chunk-2UBBO2MD.js → chunk-AUMSEL33.js} +5 -5
- package/dist/{chunk-2UBBO2MD.js.map → chunk-AUMSEL33.js.map} +1 -1
- package/dist/{chunk-XKGOIGTJ.js → chunk-AZ6FKDQR.js} +3 -3
- package/dist/{chunk-XKGOIGTJ.js.map → chunk-AZ6FKDQR.js.map} +1 -1
- package/dist/{chunk-WPZTYOUX.cjs → chunk-BBZYXVLZ.cjs} +2 -2
- package/dist/chunk-BBZYXVLZ.cjs.map +1 -0
- package/dist/{chunk-LY4KEOOY.cjs → chunk-BRHRQOJA.cjs} +4 -4
- package/dist/{chunk-LY4KEOOY.cjs.map → chunk-BRHRQOJA.cjs.map} +1 -1
- package/dist/{chunk-4H2QARXM.cjs → chunk-BV42CCRP.cjs} +7 -7
- package/dist/{chunk-4H2QARXM.cjs.map → chunk-BV42CCRP.cjs.map} +1 -1
- package/dist/{chunk-SKWVAQAY.js → chunk-DEZ75ET5.js} +3 -3
- package/dist/{chunk-SKWVAQAY.js.map → chunk-DEZ75ET5.js.map} +1 -1
- package/dist/{chunk-ZRQZOJ3N.js → chunk-DHLVOLUX.js} +77 -56
- package/dist/chunk-DHLVOLUX.js.map +1 -0
- package/dist/{chunk-WJOLIPEM.js → chunk-EON4YTR6.js} +8 -8
- package/dist/{chunk-WJOLIPEM.js.map → chunk-EON4YTR6.js.map} +1 -1
- package/dist/{chunk-MI3OKONE.js → chunk-F4RUADRC.js} +3 -3
- package/dist/{chunk-MI3OKONE.js.map → chunk-F4RUADRC.js.map} +1 -1
- package/dist/{chunk-SEWAPWAF.cjs → chunk-FMIKUGF2.cjs} +124 -124
- package/dist/chunk-FMIKUGF2.cjs.map +1 -0
- package/dist/{chunk-XZ7PO2FM.js → chunk-FRQ6F44U.js} +4 -4
- package/dist/{chunk-XZ7PO2FM.js.map → chunk-FRQ6F44U.js.map} +1 -1
- package/dist/{chunk-3LK3ZDL5.cjs → chunk-FZ4YMZA3.cjs} +5 -5
- package/dist/{chunk-3LK3ZDL5.cjs.map → chunk-FZ4YMZA3.cjs.map} +1 -1
- package/dist/{chunk-MM2JKFQV.cjs → chunk-GC44RATP.cjs} +10 -10
- package/dist/{chunk-MM2JKFQV.cjs.map → chunk-GC44RATP.cjs.map} +1 -1
- package/dist/{chunk-LNTQRD23.cjs → chunk-GH52NOCL.cjs} +26 -26
- package/dist/chunk-GH52NOCL.cjs.map +1 -0
- package/dist/{chunk-T6KFGMNY.cjs → chunk-GLEKLAUW.cjs} +12 -12
- package/dist/chunk-GLEKLAUW.cjs.map +1 -0
- package/dist/{chunk-UIPTINIF.js → chunk-GNMPCZNN.js} +6 -6
- package/dist/chunk-GNMPCZNN.js.map +1 -0
- package/dist/{chunk-6AE4QTSF.cjs → chunk-GTLH2NI2.cjs} +24 -24
- package/dist/{chunk-6AE4QTSF.cjs.map → chunk-GTLH2NI2.cjs.map} +1 -1
- package/dist/{chunk-K6TWHNT4.cjs → chunk-HECR7KF5.cjs} +11 -11
- package/dist/{chunk-K6TWHNT4.cjs.map → chunk-HECR7KF5.cjs.map} +1 -1
- package/dist/{chunk-NHXPQN44.js → chunk-HK4HRLWE.js} +3 -3
- package/dist/{chunk-NHXPQN44.js.map → chunk-HK4HRLWE.js.map} +1 -1
- package/dist/{chunk-LWVKI75U.js → chunk-HKSSM5RK.js} +3 -3
- package/dist/{chunk-LWVKI75U.js.map → chunk-HKSSM5RK.js.map} +1 -1
- package/dist/{chunk-ELYGL52R.cjs → chunk-HLNLYLNN.cjs} +4 -4
- package/dist/{chunk-ELYGL52R.cjs.map → chunk-HLNLYLNN.cjs.map} +1 -1
- package/dist/{chunk-ONVIALVV.js → chunk-IMX5YODO.js} +15 -15
- package/dist/chunk-IMX5YODO.js.map +1 -0
- package/dist/{chunk-C64E2EJS.js → chunk-J5RW43IR.js} +4 -4
- package/dist/{chunk-C64E2EJS.js.map → chunk-J5RW43IR.js.map} +1 -1
- package/dist/{chunk-4E3HLSYE.cjs → chunk-JA4FEA5Z.cjs} +4 -4
- package/dist/{chunk-4E3HLSYE.cjs.map → chunk-JA4FEA5Z.cjs.map} +1 -1
- package/dist/{chunk-EJNFZET4.cjs → chunk-JO76RWCA.cjs} +11 -11
- package/dist/{chunk-EJNFZET4.cjs.map → chunk-JO76RWCA.cjs.map} +1 -1
- package/dist/{chunk-QMIG7TKG.cjs → chunk-KCQUYQ3V.cjs} +17 -17
- package/dist/chunk-KCQUYQ3V.cjs.map +1 -0
- package/dist/{chunk-AKMPQJPX.js → chunk-L4JFQCG4.js} +5 -5
- package/dist/chunk-L4JFQCG4.js.map +1 -0
- package/dist/{chunk-HJMFPIRM.js → chunk-LLE7HPRI.js} +5 -5
- package/dist/{chunk-HJMFPIRM.js.map → chunk-LLE7HPRI.js.map} +1 -1
- package/dist/{chunk-4H2DCO6P.js → chunk-LXKNENHK.js} +3 -3
- package/dist/{chunk-4H2DCO6P.js.map → chunk-LXKNENHK.js.map} +1 -1
- package/dist/{chunk-PY7G7YWK.cjs → chunk-MMZX557L.cjs} +5 -5
- package/dist/{chunk-PY7G7YWK.cjs.map → chunk-MMZX557L.cjs.map} +1 -1
- package/dist/{chunk-VQ33XLC6.js → chunk-MRKSSN36.js} +3 -3
- package/dist/{chunk-VQ33XLC6.js.map → chunk-MRKSSN36.js.map} +1 -1
- package/dist/{chunk-33B2BSME.cjs → chunk-NETYW4V3.cjs} +13 -5
- package/dist/chunk-NETYW4V3.cjs.map +1 -0
- package/dist/{chunk-OVGNXGCK.cjs → chunk-NNNUQELM.cjs} +9 -9
- package/dist/{chunk-OVGNXGCK.cjs.map → chunk-NNNUQELM.cjs.map} +1 -1
- package/dist/{chunk-BM7VYZED.js → chunk-NOM2YWFP.js} +5 -5
- package/dist/{chunk-BM7VYZED.js.map → chunk-NOM2YWFP.js.map} +1 -1
- package/dist/{chunk-WMWZAJMJ.cjs → chunk-NRA36JKG.cjs} +11 -11
- package/dist/{chunk-WMWZAJMJ.cjs.map → chunk-NRA36JKG.cjs.map} +1 -1
- package/dist/{chunk-4HKAZRTC.js → chunk-O3IZ7JEL.js} +3 -3
- package/dist/{chunk-4HKAZRTC.js.map → chunk-O3IZ7JEL.js.map} +1 -1
- package/dist/{chunk-RHQJX3EI.cjs → chunk-OEFFPR2S.cjs} +4 -4
- package/dist/{chunk-RHQJX3EI.cjs.map → chunk-OEFFPR2S.cjs.map} +1 -1
- package/dist/{chunk-4GGXF7YM.js → chunk-OLLOUAUJ.js} +3 -3
- package/dist/{chunk-4GGXF7YM.js.map → chunk-OLLOUAUJ.js.map} +1 -1
- package/dist/{chunk-RA2UZBYP.js → chunk-PAV4ZPSW.js} +3 -3
- package/dist/{chunk-RA2UZBYP.js.map → chunk-PAV4ZPSW.js.map} +1 -1
- package/dist/{chunk-RNCN2TTP.js → chunk-PBML2FHN.js} +2 -2
- package/dist/{chunk-A76OFN2B.cjs.map → chunk-PBML2FHN.js.map} +1 -1
- package/dist/{chunk-XRKFWV7K.js → chunk-PYM5OUL4.js} +5 -5
- package/dist/{chunk-XRKFWV7K.js.map → chunk-PYM5OUL4.js.map} +1 -1
- package/dist/{chunk-F4SQTWVR.js → chunk-Q4DTGCSD.js} +3 -3
- package/dist/{chunk-F4SQTWVR.js.map → chunk-Q4DTGCSD.js.map} +1 -1
- package/dist/{chunk-S7OEXQMI.cjs → chunk-R3CKCRK3.cjs} +4 -4
- package/dist/{chunk-S7OEXQMI.cjs.map → chunk-R3CKCRK3.cjs.map} +1 -1
- package/dist/{chunk-5COPO3H4.cjs → chunk-RBQYHEZD.cjs} +4 -4
- package/dist/{chunk-5COPO3H4.cjs.map → chunk-RBQYHEZD.cjs.map} +1 -1
- package/dist/{chunk-KRPEPZQY.js → chunk-RJBHWM6D.js} +7 -7
- package/dist/chunk-RJBHWM6D.js.map +1 -0
- package/dist/{chunk-BVGJXMSB.cjs → chunk-RPL3POFZ.cjs} +336 -315
- package/dist/chunk-RPL3POFZ.cjs.map +1 -0
- package/dist/{chunk-U53AYSHS.cjs → chunk-S4Q5OMIK.cjs} +11 -11
- package/dist/{chunk-U53AYSHS.cjs.map → chunk-S4Q5OMIK.cjs.map} +1 -1
- package/dist/{chunk-FUP3ZA5T.js → chunk-SNKY3C2L.js} +4 -4
- package/dist/{chunk-FUP3ZA5T.js.map → chunk-SNKY3C2L.js.map} +1 -1
- package/dist/{chunk-BBMN4O6E.js → chunk-TJRPNBY5.js} +4 -4
- package/dist/{chunk-BBMN4O6E.js.map → chunk-TJRPNBY5.js.map} +1 -1
- package/dist/{chunk-27E4EMR6.cjs → chunk-UJMEWGO6.cjs} +4 -4
- package/dist/{chunk-27E4EMR6.cjs.map → chunk-UJMEWGO6.cjs.map} +1 -1
- package/dist/{chunk-X627TO3A.js → chunk-UTYCG4RB.js} +12 -12
- package/dist/chunk-UTYCG4RB.js.map +1 -0
- package/dist/{chunk-5XPKYDK7.js → chunk-VQFSEKU5.js} +12 -5
- package/dist/chunk-VQFSEKU5.js.map +1 -0
- package/dist/{chunk-NJVV5OAV.cjs → chunk-WCXOKGOQ.cjs} +8 -8
- package/dist/chunk-WCXOKGOQ.cjs.map +1 -0
- package/dist/{chunk-PIBXDEZM.cjs → chunk-WIGJGFH4.cjs} +5 -5
- package/dist/{chunk-PIBXDEZM.cjs.map → chunk-WIGJGFH4.cjs.map} +1 -1
- package/dist/{chunk-LOTWA65Z.cjs → chunk-X2YQP452.cjs} +11 -11
- package/dist/{chunk-LOTWA65Z.cjs.map → chunk-X2YQP452.cjs.map} +1 -1
- package/dist/{chunk-ZAKTZ5B4.cjs → chunk-XA3TSBAH.cjs} +8 -8
- package/dist/{chunk-ZAKTZ5B4.cjs.map → chunk-XA3TSBAH.cjs.map} +1 -1
- package/dist/{chunk-H2V6CXM7.cjs → chunk-XR4LPBXH.cjs} +9 -9
- package/dist/{chunk-H2V6CXM7.cjs.map → chunk-XR4LPBXH.cjs.map} +1 -1
- package/dist/{chunk-E7WWIX34.cjs → chunk-YULF6FPB.cjs} +8 -8
- package/dist/{chunk-E7WWIX34.cjs.map → chunk-YULF6FPB.cjs.map} +1 -1
- package/dist/{chunk-23HI77BZ.js → chunk-Z6N6SDNR.js} +4 -4
- package/dist/chunk-Z6N6SDNR.js.map +1 -0
- package/dist/{chunk-A76OFN2B.cjs → chunk-ZHPET3LZ.cjs} +2 -2
- package/dist/chunk-ZHPET3LZ.cjs.map +1 -0
- package/dist/{chunk-5VKUZ26Q.js → chunk-ZNW2TXLO.js} +3 -3
- package/dist/{chunk-5VKUZ26Q.js.map → chunk-ZNW2TXLO.js.map} +1 -1
- package/dist/{chunk-N4JNY5DT.cjs → chunk-ZO2L5U6F.cjs} +32 -32
- package/dist/chunk-ZO2L5U6F.cjs.map +1 -0
- package/dist/{chunk-RMCHJZNZ.js → chunk-ZS6SLELQ.js} +4 -4
- package/dist/{chunk-RMCHJZNZ.js.map → chunk-ZS6SLELQ.js.map} +1 -1
- package/dist/{chunk-7PBAJ2WA.js → chunk-ZTEAJAE6.js} +3 -3
- package/dist/{chunk-7PBAJ2WA.js.map → chunk-ZTEAJAE6.js.map} +1 -1
- package/dist/compact-session-65XCKO6H.js +18 -0
- package/dist/{compact-session-AZU2LEAE.js.map → compact-session-65XCKO6H.js.map} +1 -1
- package/dist/compact-session-OU6SRPVJ.cjs +55 -0
- package/dist/{compact-session-TRCEYCPG.cjs.map → compact-session-OU6SRPVJ.cjs.map} +1 -1
- package/dist/compaction.cjs +16 -16
- package/dist/compaction.js +3 -3
- package/dist/concurrency.cjs +6 -6
- package/dist/concurrency.js +4 -4
- package/dist/context-2G4375BZ.cjs +22 -0
- package/dist/{context-DNFT4B5D.cjs.map → context-2G4375BZ.cjs.map} +1 -1
- package/dist/context-GSQYVVMJ.js +5 -0
- package/dist/{context-LYE6TJL5.js.map → context-GSQYVVMJ.js.map} +1 -1
- package/dist/{cron-BGR0HOz9.d.cts → cron-DgHJnMAK.d.cts} +2 -2
- package/dist/{cron-CDAIWCrL.d.ts → cron-DyWQsEG6.d.ts} +2 -2
- package/dist/cron.cjs +33 -33
- package/dist/cron.d.cts +3 -3
- package/dist/cron.d.ts +3 -3
- package/dist/cron.js +32 -32
- package/dist/{errors-DxQe4_Qy.d.ts → errors-BSoXcl3F.d.cts} +3 -3
- package/dist/{errors-L1bxHHO0.d.cts → errors-CHllybaU.d.ts} +3 -3
- package/dist/errors.cjs +21 -21
- package/dist/errors.d.cts +2 -2
- package/dist/errors.d.ts +2 -2
- package/dist/errors.js +2 -2
- package/dist/eval.cjs +43 -43
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +33 -33
- package/dist/eval.js.map +1 -1
- package/dist/{executor-TQ3FSZ7F.cjs → executor-CB75B5BH.cjs} +24 -24
- package/dist/{executor-TQ3FSZ7F.cjs.map → executor-CB75B5BH.cjs.map} +1 -1
- package/dist/{executor-PCRX3533.js → executor-VQLTQY53.js} +7 -7
- package/dist/{executor-PCRX3533.js.map → executor-VQLTQY53.js.map} +1 -1
- package/dist/filesystem/index.cjs +7 -7
- package/dist/filesystem/index.js +3 -3
- package/dist/fs-session-store-MAZV5FXJ.cjs +19 -0
- package/dist/{fs-session-store-KRZZIG3O.cjs.map → fs-session-store-MAZV5FXJ.cjs.map} +1 -1
- package/dist/fs-session-store-ZNUYZHYI.js +10 -0
- package/dist/{fs-session-store-I6GUIFRO.js.map → fs-session-store-ZNUYZHYI.js.map} +1 -1
- package/dist/generate-object-6PWGH5DZ.cjs +20 -0
- package/dist/{generate-object-QILSGTEJ.cjs.map → generate-object-6PWGH5DZ.cjs.map} +1 -1
- package/dist/generate-object-IXMJ7FUX.js +7 -0
- package/dist/{generate-object-DLHT5RXH.js.map → generate-object-IXMJ7FUX.js.map} +1 -1
- package/dist/index-manager-X5IPG2JL.js +11 -0
- package/dist/{index-manager-SXF3FAQV.js.map → index-manager-X5IPG2JL.js.map} +1 -1
- package/dist/index-manager-YFFEPISE.cjs +20 -0
- package/dist/{index-manager-LEMQ73A7.cjs.map → index-manager-YFFEPISE.cjs.map} +1 -1
- package/dist/index.cjs +139 -139
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.js +53 -53
- package/dist/index.js.map +1 -1
- package/dist/{inject-session-BVSERZCI.cjs → inject-session-DDC36KKP.cjs} +11 -11
- package/dist/{inject-session-BVSERZCI.cjs.map → inject-session-DDC36KKP.cjs.map} +1 -1
- package/dist/{inject-session-E75EP3LL.js → inject-session-UBM4KVSV.js} +8 -8
- package/dist/{inject-session-E75EP3LL.js.map → inject-session-UBM4KVSV.js.map} +1 -1
- package/dist/internal/auth/credential-store.d.ts +13 -0
- package/dist/internal/diagnostics.d.ts +2 -2
- package/dist/internal/error-mappers/anthropic.d.ts +1 -1
- package/dist/internal/eval/code-runner.d.ts +1 -1
- package/dist/internal/global-singleton.d.ts +1 -1
- package/dist/internal/judge/judge-call.d.ts +1 -1
- package/dist/internal/memory/adapters/index.cjs +8 -8
- package/dist/internal/memory/adapters/index.js +7 -7
- package/dist/internal/memory/embedding-adapter.d.ts +1 -1
- package/dist/internal/memory/memory-index.d.ts +1 -1
- package/dist/internal/persistence/atomic-write.d.cts +14 -1
- package/dist/internal/persistence/atomic-write.d.ts +14 -1
- package/dist/internal/persistence/index.cjs +25 -25
- package/dist/internal/persistence/index.js +6 -6
- package/dist/internal/persistence/jsonl.d.cts +2 -2
- package/dist/internal/persistence/jsonl.d.ts +2 -2
- package/dist/internal/persistence/session-artifacts.d.cts +27 -0
- package/dist/internal/persistence/session-artifacts.d.ts +27 -0
- package/dist/internal/persistence/session-transcript.d.cts +1 -1
- package/dist/internal/persistence/session-transcript.d.ts +1 -1
- package/dist/internal/runtime/context/context-discovery-runner.d.ts +9 -0
- package/dist/internal/runtime/context/context-import-resolver.d.ts +17 -0
- package/dist/internal/runtime/lifecycle/env-policy.d.ts +1 -1
- package/dist/internal/security/index.cjs +13 -13
- package/dist/internal/security/index.js +3 -3
- package/dist/internal/session/agent-session.d.ts +1 -1
- package/dist/internal/session/compact-session.d.ts +1 -1
- package/dist/internal/session/session-cache.d.ts +1 -1
- package/dist/judge-call-3QZO5H5N.js +5 -0
- package/dist/{judge-call-NPRU7JIQ.js.map → judge-call-3QZO5H5N.js.map} +1 -1
- package/dist/judge-call-J5EETJL3.cjs +22 -0
- package/dist/{judge-call-AIT3EULV.cjs.map → judge-call-J5EETJL3.cjs.map} +1 -1
- package/dist/models.cjs +20 -20
- package/dist/models.cjs.map +1 -1
- package/dist/models.js +5 -5
- package/dist/models.js.map +1 -1
- package/dist/path-safety.cjs +10 -10
- package/dist/path-safety.js +3 -3
- package/dist/persistence.cjs +44 -30
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.d.cts +4 -3
- package/dist/persistence.d.ts +4 -3
- package/dist/persistence.js +22 -12
- package/dist/persistence.js.map +1 -1
- package/dist/project.cjs +5 -5
- package/dist/project.js +3 -3
- package/dist/registry-KB3TS6BM.cjs +46 -0
- package/dist/{registry-VKDFTK6L.cjs.map → registry-KB3TS6BM.cjs.map} +1 -1
- package/dist/registry-PPFMCM4A.js +9 -0
- package/dist/{registry-AXQXPLFH.js.map → registry-PPFMCM4A.js.map} +1 -1
- package/dist/retry.cjs +4 -4
- package/dist/retry.js +3 -3
- package/dist/{run-XXnwwGOT.d.ts → run-C8FBAC8o.d.cts} +21 -2
- package/dist/{run-XXnwwGOT.d.cts → run-C8FBAC8o.d.ts} +21 -2
- package/dist/{run-until-BK56WG4P.js → run-until-HEQOUVU6.js} +2 -2
- package/dist/run-until-HEQOUVU6.js.map +1 -0
- package/dist/{run-until-L5KQD3PV.cjs → run-until-U2B5FJJI.cjs} +2 -2
- package/dist/run-until-U2B5FJJI.cjs.map +1 -0
- package/dist/sandbox/bwrap.d.cts +15 -1
- package/dist/sandbox/bwrap.d.ts +15 -1
- package/dist/sandbox/index.cjs +39 -24
- package/dist/sandbox/index.cjs.map +1 -1
- package/dist/sandbox/index.d.cts +1 -1
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.js +24 -10
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/provision.d.cts +1 -1
- package/dist/sandbox/provision.d.ts +1 -1
- package/dist/server/errors-envelope.cjs +14 -14
- package/dist/server/errors-envelope.d.cts +3 -3
- package/dist/server/errors-envelope.d.ts +3 -3
- package/dist/server/errors-envelope.js +3 -3
- package/dist/session-transcript-7FWTO4BK.js +5 -0
- package/dist/{session-transcript-X3UMSVL2.js.map → session-transcript-7FWTO4BK.js.map} +1 -1
- package/dist/session-transcript-FYRKWRWV.cjs +50 -0
- package/dist/{session-transcript-SLQRKQ72.cjs.map → session-transcript-FYRKWRWV.cjs.map} +1 -1
- package/dist/skills.cjs +7 -7
- package/dist/skills.js +5 -5
- package/dist/stream-object-3R3HZPQN.cjs +20 -0
- package/dist/{stream-object-3HEUGMQY.cjs.map → stream-object-3R3HZPQN.cjs.map} +1 -1
- package/dist/stream-object-NPJXDZXO.js +7 -0
- package/dist/{stream-object-VWYW7FJ2.js.map → stream-object-NPJXDZXO.js.map} +1 -1
- package/dist/subagents-loader-5KQVYUNS.js +6 -0
- package/dist/{subagents-loader-QUIK6GMV.js.map → subagents-loader-5KQVYUNS.js.map} +1 -1
- package/dist/subagents-loader-FDXPBBRA.cjs +15 -0
- package/dist/{subagents-loader-F52ARQ62.cjs.map → subagents-loader-FDXPBBRA.cjs.map} +1 -1
- package/dist/subagents-loader.cjs +15 -15
- package/dist/subagents-loader.cjs.map +1 -1
- package/dist/subagents-loader.d.cts +2 -2
- package/dist/subagents-loader.d.ts +2 -2
- package/dist/subagents-loader.js +14 -14
- package/dist/subagents-loader.js.map +1 -1
- package/dist/subscription/index.cjs +3 -3
- package/dist/subscription/index.js +2 -2
- package/dist/task-store.cjs +7 -7
- package/dist/task-store.js +4 -4
- package/dist/types/run-events.d.ts +20 -1
- package/dist/types/session-record.d.ts +1 -1
- package/dist/types/usage.d.ts +1 -1
- package/dist/workflow.cjs +27 -27
- package/dist/workflow.js +6 -6
- package/docs/error-codes.md +22 -0
- package/docs/harness-capability-map.md +22 -0
- package/package.json +1 -1
- package/dist/agent-MSR3DHO4.js +0 -46
- package/dist/agent-OOXJJD6A.cjs +0 -55
- package/dist/agent-session-store-EGTTYSKS.js +0 -6
- package/dist/agent-session-store-RHTLZ5OX.cjs +0 -23
- package/dist/chunk-23HI77BZ.js.map +0 -1
- package/dist/chunk-33B2BSME.cjs.map +0 -1
- package/dist/chunk-5KOW3GLE.js.map +0 -1
- package/dist/chunk-5XPKYDK7.js.map +0 -1
- package/dist/chunk-7GFX45DD.js.map +0 -1
- package/dist/chunk-AKMPQJPX.js.map +0 -1
- package/dist/chunk-BURYFNOM.cjs.map +0 -1
- package/dist/chunk-BVGJXMSB.cjs.map +0 -1
- package/dist/chunk-EYUZZXHZ.js.map +0 -1
- package/dist/chunk-KRPEPZQY.js.map +0 -1
- package/dist/chunk-LNTQRD23.cjs.map +0 -1
- package/dist/chunk-N4JNY5DT.cjs.map +0 -1
- package/dist/chunk-NJVV5OAV.cjs.map +0 -1
- package/dist/chunk-ONVIALVV.js.map +0 -1
- package/dist/chunk-QMIG7TKG.cjs.map +0 -1
- package/dist/chunk-RNCN2TTP.js.map +0 -1
- package/dist/chunk-SEWAPWAF.cjs.map +0 -1
- package/dist/chunk-T6KFGMNY.cjs.map +0 -1
- package/dist/chunk-UIPTINIF.js.map +0 -1
- package/dist/chunk-V7CA3CX5.cjs.map +0 -1
- package/dist/chunk-WPZTYOUX.cjs.map +0 -1
- package/dist/chunk-X627TO3A.js.map +0 -1
- package/dist/chunk-ZRQZOJ3N.js.map +0 -1
- package/dist/compact-session-AZU2LEAE.js +0 -18
- package/dist/compact-session-TRCEYCPG.cjs +0 -55
- package/dist/context-DNFT4B5D.cjs +0 -22
- package/dist/context-LYE6TJL5.js +0 -5
- package/dist/fs-session-store-I6GUIFRO.js +0 -10
- package/dist/fs-session-store-KRZZIG3O.cjs +0 -19
- package/dist/generate-object-DLHT5RXH.js +0 -7
- package/dist/generate-object-QILSGTEJ.cjs +0 -20
- package/dist/index-manager-LEMQ73A7.cjs +0 -20
- package/dist/index-manager-SXF3FAQV.js +0 -11
- package/dist/judge-call-AIT3EULV.cjs +0 -22
- package/dist/judge-call-NPRU7JIQ.js +0 -5
- package/dist/registry-AXQXPLFH.js +0 -9
- package/dist/registry-VKDFTK6L.cjs +0 -46
- package/dist/run-until-BK56WG4P.js.map +0 -1
- package/dist/run-until-L5KQD3PV.cjs.map +0 -1
- package/dist/session-transcript-SLQRKQ72.cjs +0 -50
- package/dist/session-transcript-X3UMSVL2.js +0 -5
- package/dist/stream-object-3HEUGMQY.cjs +0 -20
- package/dist/stream-object-VWYW7FJ2.js +0 -7
- package/dist/subagents-loader-F52ARQ62.cjs +0 -15
- package/dist/subagents-loader-QUIK6GMV.js +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/runtime/retry/default-retriable.ts","../src/errors.ts"],"names":[],"mappings":";;;AAUO,SAAS,wBAAwB,IAAA,EAAuB;AAC7D,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,YAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,cAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,sBAAA;AACH,MAAA,OAAO,IAAA;AAAA,IACT;AACE,MAAA,OAAO,KAAA;AAAA;AAEb;;;ACsDA,IAAM,2BAAA,uBAAkC,GAAA,CAAY;AAAA,EAClD,YAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA,mBAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,oBAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAUM,SAAS,+BAA+B,IAAA,EAAkD;AAC/F,EAAA,IAAI,IAAA,KAAS,MAAA,IAAa,2BAAA,CAA4B,GAAA,CAAI,IAAI,CAAA,EAAG;AAC/D,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,SAAA;AACT;AAmCO,IAAM,iBAAA,GAAN,cAAgC,KAAA,CAAM;AAAA,EACzB,IAAA,GAAe,mBAAA;AAAA,EACxB,WAAA;AAAA,EACA,IAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EAET,WAAA,CACE,OAAA,EACA,OAAA,GAMI,EAAC,EACL;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,QAAQ,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAM,GAAI,MAAS,CAAA;AACjF,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,KAAA;AAC1C,IAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,EAAW,IAAA,CAAK,OAAO,OAAA,CAAQ,IAAA;AACpD,IAAA,IAAI,OAAA,CAAQ,cAAA,KAAmB,MAAA,EAAW,IAAA,CAAK,iBAAiB,OAAA,CAAQ,cAAA;AACxE,IAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AAAA,EAC9D;AACF;AAOO,IAAM,mBAAA,GAAN,cAAkC,iBAAA,CAAkB;AAAA,EACvC,IAAA,GAAe,qBAAA;AAAA,EAEjC,WAAA,CACE,OAAA,EACA,OAAA,GAAwE,EAAC,EACzE;AACA,IAAA,KAAA,CAAM,SAAS,EAAE,GAAG,OAAA,EAAS,WAAA,EAAa,OAAO,CAAA;AAAA,EACnD;AACF;AAOO,IAAM,cAAA,GAAN,cAA6B,iBAAA,CAAkB;AAAA,EAClC,IAAA,GAAe,gBAAA;AAAA,EAEjC,WAAA,CACE,OAAA,EACA,OAAA,GAAwE,EAAC,EACzE;AACA,IAAA,KAAA,CAAM,SAAS,EAAE,GAAG,OAAA,EAAS,WAAA,EAAa,MAAM,CAAA;AAAA,EAClD;AACF;AAOO,IAAM,kBAAA,GAAN,cAAiC,iBAAA,CAAkB;AAAA,EACtC,IAAA,GAAe,oBAAA;AAAA,EAEjC,WAAA,CACE,OAAA,EACA,OAAA,GAAwE,EAAC,EACzE;AACA,IAAA,KAAA,CAAM,SAAS,EAAE,GAAG,OAAA,EAAS,WAAA,EAAa,OAAO,CAAA;AAAA,EACnD;AACF;AAQO,IAAM,4BAAA,GAAN,cAA2C,kBAAA,CAAmB;AAAA,EACjD,IAAA,GAAe,8BAAA;AAAA,EACxB,QAAA;AAAA,EACA,OAAA;AAAA,EAET,WAAA,CACE,SACA,OAAA,EAOA;AACA,IAAA,KAAA,CAAM,SAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AACxB,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,OAAA;AAAA,EACzB;AACF;AAOO,IAAM,YAAA,GAAN,cAA2B,iBAAA,CAAkB;AAAA,EAChC,IAAA,GAAe,cAAA;AAAA,EAEjC,WAAA,CACE,OAAA,EACA,OAAA,GAAwE,EAAC,EACzE;AACA,IAAA,KAAA,CAAM,SAAS,EAAE,GAAG,OAAA,EAAS,WAAA,EAAa,MAAM,CAAA;AAAA,EAClD;AACF;AAOO,IAAM,iBAAA,GAAN,cAAgC,iBAAA,CAAkB;AAAA,EACrC,IAAA,GAAe,mBAAA;AAAA,EAEjC,WAAA,CACE,OAAA,EACA,OAAA,GAAwE,EAAC,EACzE;AACA,IAAA,KAAA,CAAM,SAAS,EAAE,GAAG,OAAA,EAAS,WAAA,EAAa,OAAO,CAAA;AAAA,EACnD;AACF;AAsBO,IAAM,aAAA,GAAN,cAA4B,iBAAA,CAAkB;AAAA,EACjC,IAAA,GAAe,eAAA;AAAA,EACxB,QAAA;AAAA,EACA,GAAA;AAAA;AAAA,EAEA,SAAA;AAAA;AAAA,EAEA,cAAA;AAAA,EAET,WAAA,CACE,SACA,OAAA,EAUA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS;AAAA,MACb,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,UAAU,OAAA,CAAQ,QAAA;AAAA;AAAA;AAAA;AAAA,MAIlB,WAAA,EAAa,OAAA,CAAQ,SAAA,IAAa,uBAAA,CAAwB,QAAQ,IAAI;AAAA,KACvE,CAAA;AACD,IAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AAC5D,IAAA,IAAI,OAAA,CAAQ,GAAA,KAAQ,MAAA,EAAW,IAAA,CAAK,MAAM,OAAA,CAAQ,GAAA;AAClD,IAAA,IAAI,OAAA,CAAQ,SAAA,KAAc,MAAA,EAAW,IAAA,CAAK,YAAY,OAAA,CAAQ,SAAA;AAC9D,IAAA,IAAI,OAAA,CAAQ,cAAA,KAAmB,MAAA,EAAW,IAAA,CAAK,iBAAiB,OAAA,CAAQ,cAAA;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,SAAA,GAAqB;AACvB,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAI,YAAA,GAAmC;AACrC,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,UAAA,KAAe,MAAA,EAAW,OAAO,MAAA;AACpD,IAAA,OAAO,IAAA,CAAK,SAAS,UAAA,GAAa,GAAA;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAI,aAAA,GAAyB;AAC3B,IAAA,MAAM,GAAA,GAAM,KAAK,QAAA,EAAU,GAAA;AAC3B,IAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,MAAA;AAC9B,IAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,cAAc,GAAG,CAAA;AAErD,IAAA,IAAI;AACF,MAAA,OAAO,aAAA,CAAc,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,IAC1C,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,aAAA,CAAc,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAA,GAAkC;AAChC,IAAA,MAAM,IAAA,GAAgC;AAAA,MACpC,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,aAAa,IAAA,CAAK;AAAA,KACpB;AACA,IAAA,iBAAA,CAAkB,MAAM,IAAI,CAAA;AAC5B,IAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,IAAA,CAAK,QAAQ,CAAA;AAC/C,IAAA,IAAI,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,QAAA,GAAW,QAAA;AAC5C,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,iBAAA,CAAkB,MAA+B,GAAA,EAA0B;AAClF,EAAA,IAAI,GAAA,CAAI,IAAA,KAAS,MAAA,EAAW,IAAA,CAAK,OAAO,GAAA,CAAI,IAAA;AAC5C,EAAA,IAAI,GAAA,CAAI,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,WAAW,GAAA,CAAI,QAAA;AACpD,EAAA,IAAI,GAAA,CAAI,SAAA,KAAc,MAAA,EAAW,IAAA,CAAK,YAAY,GAAA,CAAI,SAAA;AACtD,EAAA,IAAI,GAAA,CAAI,cAAA,KAAmB,MAAA,EAAW,IAAA,CAAK,iBAAiB,GAAA,CAAI,cAAA;AAChE,EAAA,IAAI,IAAI,GAAA,KAAQ,MAAA,OAAgB,GAAA,GAAM,aAAA,CAAc,IAAI,GAAG,CAAA;AAC7D;AAEA,SAAS,iBAAiB,IAAA,EAA4D;AACpF,EAAA,IAAI,IAAA,KAAS,QAAW,OAAO,MAAA;AAC/B,EAAA,MAAM,EAAE,GAAA,EAAK,GAAG,IAAA,EAAK,GAAI,IAAA;AACzB,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,wBAAA,KAA6B,GAAA;AAC1D,EAAA,IAAI,QAAA,IAAY,QAAQ,MAAA,EAAW;AACjC,IAAA,MAAM,WAAA,GACJ,OAAO,GAAA,KAAQ,QAAA,GAAW,aAAA,CAAc,GAAG,CAAA,GAAI,aAAA,CAAc,aAAA,CAAc,GAAG,CAAC,CAAA;AACjF,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,GAAA,EAAK,WAAA,EAAY;AAAA,EACrC;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,cAAc,KAAA,EAAwB;AAC7C,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,EAC7B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB;AACF;AAuBO,SAAS,iBAAiB,GAAA,EAAuB;AACtD,EAAA,OAAO,GAAA,YAAe,iBAAA,IAAqB,GAAA,CAAI,WAAA,KAAgB,IAAA;AACjE;AAYO,IAAM,4BAAA,GAAN,cAA2C,iBAAA,CAAkB;AAAA,EAChD,IAAA,GAAe,8BAAA;AAAA,EACxB,SAAA;AAAA,EAET,WAAA,CACE,OAAA,EACA,SAAA,EACA,OAAA,GAA8C,EAAC,EAC/C;AACA,IAAA,KAAA,CAAM,OAAA,EAAS;AAAA,MACb,GAAG,OAAA;AAAA,MACH,WAAA,EAAa,KAAA;AAAA,MACb,IAAA,EAAM,QAAQ,IAAA,IAAQ;AAAA,KACvB,CAAA;AACD,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF;AAaO,IAAM,4BAAA,GAAN,cAA2C,iBAAA,CAAkB;AAAA,EAChD,IAAA,GAAe,8BAAA;AAAA,EACxB,QAAA;AAAA,EACA,WAAA;AAAA,EAET,WAAA,CACE,SACA,OAAA,EAOA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS;AAAA,MACb,GAAG,OAAA;AAAA,MACH,WAAA,EAAa,IAAA;AAAA,MACb,IAAA,EAAM,QAAQ,IAAA,IAAQ;AAAA,KACvB,CAAA;AACD,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AACxB,IAAA,IAAA,CAAK,cAAc,OAAA,CAAQ,WAAA;AAAA,EAC7B;AACF;AAqBO,IAAM,kBAAA,GAAN,cAAiC,iBAAA,CAAkB;AAAA,EACtC,IAAA,GAAe,oBAAA;AAAA,EACxB,SAAA;AAAA,EAET,WAAA,CACE,SACA,OAAA,EAMA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS;AAAA,MACb,WAAA,EAAa,OAAA,CAAQ,IAAA,KAAS,cAAA,IAAkB,QAAQ,IAAA,KAAS,SAAA;AAAA,MACjE,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,GAAI,QAAQ,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAM,GAAI,EAAC;AAAA,MAC9D,GAAI,QAAQ,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAS,GAAI;AAAC,KACxE,CAAA;AACD,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,SAAA;AAAA,EAC3B;AACF;AASO,IAAM,kBAAA,GAAN,cAAiC,iBAAA,CAAkB;AAAA,EACtC,IAAA,GAAe,oBAAA;AAAA,EACxB,MAAA;AAAA,EAET,WAAA,CAAY,OAAA,EAAiB,MAAA,EAAgB,OAAA,GAA+B,EAAC,EAAG;AAC9E,IAAA,KAAA,CAAM,OAAA,EAAS;AAAA,MACb,GAAG,OAAA;AAAA,MACH,WAAA,EAAa,KAAA;AAAA,MACb,IAAA,EAAM;AAAA,KACP,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AACF;AAQO,IAAM,iBAAA,GAAN,cAAgC,iBAAA,CAAkB;AAAA,EACrC,IAAA,GAAe,mBAAA;AAAA,EACxB,MAAA;AAAA,EAET,WAAA,CAAY,MAAA,EAAgB,OAAA,GAA+B,EAAC,EAAG;AAC7D,IAAA,KAAA,CAAM,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAA,EAAI;AAAA,MACjC,GAAG,OAAA;AAAA,MACH,WAAA,EAAa,KAAA;AAAA,MACb,IAAA,EAAM;AAAA,KACP,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AACF;AAQO,IAAM,6BAAA,GAAN,cAA4C,iBAAA,CAAkB;AAAA,EACjD,IAAA,GAAe,+BAAA;AAAA,EACxB,SAAA;AAAA,EAET,WAAA,CAAY,SAAA,EAAmB,OAAA,GAA+B,EAAC,EAAG;AAChE,IAAA,KAAA;AAAA,MACE,mBAAmB,SAAS,CAAA,4DAAA,CAAA;AAAA,MAC5B;AAAA,QACE,GAAG,OAAA;AAAA,QACH,WAAA,EAAa,KAAA;AAAA,QACb,IAAA,EAAM;AAAA;AACR,KACF;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF;AASO,IAAM,mBAAA,GAAN,cAAkC,iBAAA,CAAkB;AAAA,EACvC,IAAA,GAAe,qBAAA;AAAA,EACxB,UAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EAET,YAAY,IAAA,EAOT;AACD,IAAA,KAAA;AAAA,MACE,WAAW,IAAA,CAAK,UAAU,CAAA,sBAAA,EAAyB,IAAA,CAAK,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAC,CAAA,UAAA,EAAa,KAAK,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA;AAAA,MACvI;AAAA,QACE,GAAI,KAAK,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM,GAAI,EAAC;AAAA,QACxD,WAAA,EAAa,KAAA;AAAA,QACb,IAAA,EAAM;AAAA;AACR,KACF;AACA,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AAAA,EACnB;AACF;AAgBO,IAAM,kBAAA,GAAN,cAAiC,iBAAA,CAAkB;AAAA,EACtC,IAAA,GAAe,oBAAA;AAAA,EACxB,OAAA;AAAA,EAET,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,CAAA,OAAA,EAAU,OAAO,CAAA,8DAAA,CAAA,EAAkE;AAAA,MACvF,WAAA,EAAa,KAAA;AAAA,MACb,IAAA,EAAM;AAAA,KACP,CAAA;AACD,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF;AAEO,IAAM,+BAAA,GAAN,cAA8C,iBAAA,CAAkB;AAAA,EACnD,IAAA,GAAe,iCAAA;AAAA,EACxB,SAAA;AAAA,EAET,WAAA,CAAY,SAAA,EAAmB,OAAA,GAA+B,EAAC,EAAG;AAChE,IAAA,KAAA;AAAA,MACE,qBAAqB,SAAS,CAAA,4DAAA,CAAA;AAAA,MAC9B;AAAA,QACE,GAAG,OAAA;AAAA,QACH,WAAA,EAAa,KAAA;AAAA,QACb,IAAA,EAAM;AAAA;AACR,KACF;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF","file":"chunk-VQ33XLC6.js","sourcesContent":["/**\n * Default retryability verdict for an `AgentRunError` code.\n *\n * Extracted from `errors.ts` (G8 LoC budget — SRP). The parameter is typed\n * `string` (not the `AgentRunErrorCode` union) deliberately: this is a leaf\n * with NO import back into `errors.ts`, so it cannot form an import cycle. The\n * `default` branch makes the behavior identical to the typed switch.\n *\n * @internal\n */\nexport function defaultRetriableForCode(code: string): boolean {\n switch (code) {\n case \"rate_limit\":\n case \"timeout\":\n case \"server_error\":\n case \"network\":\n case \"provider_unreachable\":\n return true;\n default:\n return false;\n }\n}\n","import { defaultRetriableForCode } from \"./internal/runtime/retry/default-retriable.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\nimport type { RunOperation } from \"./types/run.js\";\n\n/**\n * Finite, machine-readable error codes for provider-originated errors\n * (ADR D66). Consumers can `switch (err.metadata?.code)` exhaustively\n * — adding a new variant is an explicit decision + test coverage.\n *\n * @public\n */\nexport type ErrorCode =\n | \"rate_limit\"\n | \"auth_failed\"\n | \"invalid_request\"\n | \"timeout\"\n | \"server_error\"\n | \"context_too_long\"\n | \"content_filtered\"\n | \"model_unavailable\"\n | \"network\"\n | \"quota_exceeded\"\n | \"unknown\";\n\n/**\n * Codes used by {@link AgentRunError} (Production-Readiness #3, ADR D311).\n *\n * Superset of {@link ErrorCode} extended with codes that do NOT originate\n * from a provider HTTP response:\n *\n * - `quota_exceeded` — billing limit hit (provider 402 or signalled error)\n * - `tool_runtime_error` — custom tool handler threw inside dispatch\n * - `aborted` — caller's `AbortSignal` fired (Phase 4)\n * - `invalid_model` — model id rejected by provider (400 \"model not found\")\n * - `safety_blocked` — provider safety filter blocked req or resp\n * - `provider_unreachable` — DNS/TCP/timeout/5xx at transport boundary\n *\n * The `& {}` tail keeps the literal-union ergonomics (autocomplete) while\n * accepting any string for forward compatibility with constructor calls\n * that pass arbitrary code values (legacy callers).\n *\n * @public\n */\n/**\n * T1.1 — closed literal union for `AgentRunError.code`. The previous\n * `(string & {})` escape hatch let arbitrary strings slip into the type\n * surface and defeated exhaustive `switch (code)` discrimination. This is\n * the canonical closed form. `AgentRunErrorCode` is re-aliased below for\n * source-level back-compat.\n *\n * Adding a new code: append the literal here AND audit every `switch (err.code)`\n * in callers. Type-checker enforces the audit via the `default: assertNever(code)`\n * convention.\n *\n * @public\n */\nexport type KnownAgentRunErrorCode =\n | ErrorCode\n | \"quota_exceeded\"\n | \"tool_runtime_error\"\n | \"aborted\"\n | \"invalid_model\"\n | \"safety_blocked\"\n | \"provider_unreachable\";\n\n/**\n * Back-compat alias of {@link KnownAgentRunErrorCode}. Pre-T1.1 callers that\n * imported `AgentRunErrorCode` keep working; new code SHOULD prefer\n * `KnownAgentRunErrorCode` to make the closed-union intent explicit.\n *\n * @public\n */\nexport type AgentRunErrorCode = KnownAgentRunErrorCode;\n\n/** Snapshot of every known code at runtime — used by the boundary coercer. */\nconst KNOWN_AGENT_RUN_ERROR_CODES = new Set<string>([\n \"rate_limit\",\n \"auth_failed\",\n \"invalid_request\",\n \"timeout\",\n \"server_error\",\n \"context_too_long\",\n \"content_filtered\",\n \"model_unavailable\",\n \"network\",\n \"unknown\",\n \"quota_exceeded\",\n \"tool_runtime_error\",\n \"aborted\",\n \"invalid_model\",\n \"safety_blocked\",\n \"provider_unreachable\",\n]);\n\n/**\n * T1.1 boundary helper — coerce an arbitrary string (typically arriving from\n * a downstream `RunErrorDetail.code` or a deserialized cloud response) into a\n * `KnownAgentRunErrorCode`. Unknown strings collapse to `\"unknown\"` so the\n * closed type contract holds without forcing every caller to switch.\n *\n * @internal\n */\nexport function coerceToKnownAgentRunErrorCode(code: string | undefined): KnownAgentRunErrorCode {\n if (code !== undefined && KNOWN_AGENT_RUN_ERROR_CODES.has(code)) {\n return code as KnownAgentRunErrorCode;\n }\n return \"unknown\";\n}\n\n/**\n * Structured context for errors that originated from a provider HTTP\n * call (ADR D65). Lets callers retry with the right backoff (`retryAfter`),\n * surface actionable diagnostics (`provider`, `endpoint`), and inspect the\n * raw response body when needed (`raw`, capped at ~2KB by the mapper).\n *\n * @public\n */\nexport interface ErrorMetadata {\n /** Provider canonical name (e.g., `\"anthropic\"`, `\"openai\"`, `\"openrouter\"`, `\"gemini\"`). */\n provider: string;\n /** HTTP endpoint that failed (e.g., `\"/v1/messages\"`, `\"/v1/chat/completions\"`). */\n endpoint: string;\n /** Machine-readable error code (finite enum). */\n code: ErrorCode;\n /** HTTP status code if applicable. */\n statusCode?: number;\n /** Seconds to wait before retry, per provider's `retry-after` header (numeric form only). */\n retryAfter?: number;\n /** Raw response body for debugging (truncated to ~2KB by the mapper). */\n raw?: unknown;\n}\n\n/**\n * Base class for all errors thrown by `@theokit/sdk`.\n *\n * Use `isRetryable` to drive retry/backoff logic. `code` and `protoErrorCode`\n * are populated for server-originated errors when available. `metadata`\n * (ADR D65) carries structured `{ provider, endpoint, code, ... }` when\n * the error originated from a provider HTTP call.\n *\n * @public\n */\nexport class TheokitAgentError extends Error {\n override readonly name: string = \"TheokitAgentError\";\n readonly isRetryable: boolean;\n readonly code?: string;\n readonly protoErrorCode?: string;\n readonly metadata?: ErrorMetadata;\n\n constructor(\n message: string,\n options: {\n isRetryable?: boolean;\n code?: string;\n protoErrorCode?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n } = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.isRetryable = options.isRetryable ?? false;\n if (options.code !== undefined) this.code = options.code;\n if (options.protoErrorCode !== undefined) this.protoErrorCode = options.protoErrorCode;\n if (options.metadata !== undefined) this.metadata = options.metadata;\n }\n}\n\n/**\n * Invalid API key, not logged in, insufficient permissions.\n *\n * @public\n */\nexport class AuthenticationError extends TheokitAgentError {\n override readonly name: string = \"AuthenticationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Too many requests or usage limits exceeded.\n *\n * @public\n */\nexport class RateLimitError extends TheokitAgentError {\n override readonly name: string = \"RateLimitError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Invalid model, bad request parameters, malformed options.\n *\n * @public\n */\nexport class ConfigurationError extends TheokitAgentError {\n override readonly name: string = \"ConfigurationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown when creating a cloud agent for a repo whose SCM provider is not\n * connected. Use `helpUrl` to point the user at the right reconnect flow.\n *\n * @public\n */\nexport class IntegrationNotConnectedError extends ConfigurationError {\n override readonly name: string = \"IntegrationNotConnectedError\";\n readonly provider: string;\n readonly helpUrl: string;\n\n constructor(\n message: string,\n options: {\n provider: string;\n helpUrl: string;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, options);\n this.provider = options.provider;\n this.helpUrl = options.helpUrl;\n }\n}\n\n/**\n * Service unavailable, timeout, transport-level failure.\n *\n * @public\n */\nexport class NetworkError extends TheokitAgentError {\n override readonly name: string = \"NetworkError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Catch-all for unclassified server or runtime errors.\n *\n * @public\n */\nexport class UnknownAgentError extends TheokitAgentError {\n override readonly name: string = \"UnknownAgentError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown by `Agent.prompt` (and helpers that go through `run.wait()`) when\n * the option `{ throwOnError: true }` is set and the run terminates with\n * `status: 'error'`. Carries the structured `RunResult.error` fields so\n * callers can `catch` once and branch on `code` / `provider` instead of\n * unwrapping the run.\n *\n * Extends {@link TheokitAgentError} per ADR D65 — no new hierarchy.\n *\n * @example\n * try {\n * await Agent.prompt(msg, { apiKey, model, throwOnError: true });\n * } catch (err) {\n * if (err instanceof AgentRunError && err.code === 'auth_failed') {\n * // bad key\n * }\n * }\n *\n * @public\n */\nexport class AgentRunError extends TheokitAgentError {\n override readonly name: string = \"AgentRunError\";\n readonly provider?: string;\n readonly raw?: string;\n /** Provider's request id (`x-request-id` / `request-id` header). Useful for support tickets. */\n readonly requestId?: string;\n /** SDK conversation id this error was raised inside. */\n readonly conversationId?: string;\n\n constructor(\n message: string,\n options: {\n code: AgentRunErrorCode;\n provider?: string;\n raw?: string;\n requestId?: string;\n conversationId?: string;\n retriable?: boolean;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n code: options.code,\n cause: options.cause,\n metadata: options.metadata,\n // D311: most AgentRunErrors are not retriable (auth, validation, abort).\n // Provider mappers (D314) override per-status — explicit `retriable` wins\n // over the implicit default when supplied.\n isRetryable: options.retriable ?? defaultRetriableForCode(options.code),\n });\n if (options.provider !== undefined) this.provider = options.provider;\n if (options.raw !== undefined) this.raw = options.raw;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.conversationId !== undefined) this.conversationId = options.conversationId;\n }\n\n /**\n * Production-Readiness #3 (ADR D311): alias for `isRetryable` exposed as\n * `retriable` to match the handoff contract. Future v2 will deprecate\n * `isRetryable` in favor of this.\n */\n get retriable(): boolean {\n return this.isRetryable;\n }\n\n /**\n * D312: provider's `Retry-After` header in **milliseconds**. Mappers store\n * the header value (seconds) in `metadata.retryAfter`; this getter\n * multiplies by 1000 so the result composes with `Date.now()`/`setTimeout`.\n *\n * Returns `undefined` when no hint was provided. `0` is a legitimate value\n * — use `=== undefined` check rather than truthy check.\n */\n get retryAfterMs(): number | undefined {\n if (this.metadata?.retryAfter === undefined) return undefined;\n return this.metadata.retryAfter * 1000;\n }\n\n /**\n * D313 + T1.5: alias for `metadata.raw`. Provider response body for\n * debugging. T1.5 wraps the value in `redactSecrets` at the getter\n * boundary so secret-shaped substrings (`sk-...`, Bearer JWTs, etc.) are\n * stripped before reaching the caller. Available but NEVER serialized\n * into `.message` (anti-leak invariant).\n */\n get providerError(): unknown {\n const raw = this.metadata?.raw;\n if (raw === undefined) return undefined;\n if (typeof raw === \"string\") return redactSecrets(raw);\n // Non-string raw (object/buffer) — stringify then redact.\n try {\n return redactSecrets(JSON.stringify(raw));\n } catch {\n return redactSecrets(String(raw));\n }\n }\n\n /**\n * T1.5 — sanitized JSON form. `metadata.raw` is OMITTED by default; opt\n * in via `THEOKIT_DEBUG_RAW_ERRORS=1` to surface the (redacted) raw\n * payload for diagnostics. Every other field stays accessible.\n *\n * The single env-var gate is read each call so operators can toggle at\n * runtime without restarting the process.\n */\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n name: this.name,\n message: this.message,\n isRetryable: this.isRetryable,\n };\n addOptionalFields(json, this);\n const safeMeta = sanitizeMetadata(this.metadata);\n if (safeMeta !== undefined) json.metadata = safeMeta;\n return json;\n }\n}\n\nfunction addOptionalFields(json: Record<string, unknown>, err: AgentRunError): void {\n if (err.code !== undefined) json.code = err.code;\n if (err.provider !== undefined) json.provider = err.provider;\n if (err.requestId !== undefined) json.requestId = err.requestId;\n if (err.conversationId !== undefined) json.conversationId = err.conversationId;\n if (err.raw !== undefined) json.raw = redactSecrets(err.raw);\n}\n\nfunction sanitizeMetadata(meta: ErrorMetadata | undefined): ErrorMetadata | undefined {\n if (meta === undefined) return undefined;\n const { raw, ...rest } = meta;\n const debugRaw = process.env.THEOKIT_DEBUG_RAW_ERRORS === \"1\";\n if (debugRaw && raw !== undefined) {\n const redactedRaw =\n typeof raw === \"string\" ? redactSecrets(raw) : redactSecrets(safeStringify(raw));\n return { ...rest, raw: redactedRaw } as ErrorMetadata;\n }\n return rest as ErrorMetadata;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\n/**\n * Is this error transient (worth retrying)?\n *\n * Returns the SDK's own retryability verdict: every {@link TheokitAgentError}\n * subclass computes `isRetryable` at construction (rate-limit / network /\n * credential-pool-exhausted are retryable; auth / configuration / unsupported\n * are not), so this predicate is a single source of truth rather than a\n * re-derivation. Non-SDK errors return `false` conservatively — wrap a foreign\n * error in the appropriate SDK error first if you want it considered transient.\n * It never inspects `err.message`.\n *\n * @example\n * try {\n * await agent.send(message, { throwOnError: true });\n * } catch (err) {\n * if (isTransientError(err)) return retryWithBackoff();\n * throw err;\n * }\n *\n * @public\n */\nexport function isTransientError(err: unknown): boolean {\n return err instanceof TheokitAgentError && err.isRetryable === true;\n}\n\n/**\n * Thrown when a {@link Run} or agent operation is not available on the current\n * runtime. Check first with `run.supports(operation)`.\n *\n * Extends {@link TheokitAgentError} (so error-catching code that branches on\n * `instanceof TheokitAgentError` continues to work) but is never retryable —\n * an unsupported operation will not become supported on retry.\n *\n * @public\n */\nexport class UnsupportedRunOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedRunOperationError\";\n readonly operation: RunOperation;\n\n constructor(\n message: string,\n operation: RunOperation,\n options: { code?: string; cause?: unknown } = {},\n ) {\n super(message, {\n ...options,\n isRetryable: false,\n code: options.code ?? \"unsupported_run_operation\",\n });\n this.operation = operation;\n }\n}\n\n/**\n * Thrown when every credential in a per-provider pool is in cooldown\n * and no healthy key is available (ADR D133). The caller's\n * {@link import(\"./internal/llm/fallback-client.js\").FallbackLlmClient}\n * catches this and tries the next provider in the fallback chain.\n *\n * `metadata.nextRetryAt` (epoch ms) tells callers when the soonest\n * pool entry resumes — useful for manual retry scheduling.\n *\n * @public\n */\nexport class CredentialPoolExhaustedError extends TheokitAgentError {\n override readonly name: string = \"CredentialPoolExhaustedError\";\n readonly provider: string;\n readonly nextRetryAt: number | undefined;\n\n constructor(\n message: string,\n options: {\n provider: string;\n nextRetryAt?: number;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n ...options,\n isRetryable: true,\n code: options.code ?? \"credential_pool_exhausted\",\n });\n this.provider = options.provider;\n this.nextRetryAt = options.nextRetryAt;\n }\n}\n\n/**\n * Finite error codes specific to memory adapter operations (ADR D141).\n *\n * @public\n */\nexport type MemoryAdapterErrorCode =\n | \"auth_failed\"\n | \"rate_limited\"\n | \"not_found\"\n | \"network\"\n | \"invalid_input\"\n | \"unknown\";\n\n/**\n * Error raised by `@theokit-memory-*` adapters. Carries `adapterId`\n * so callers can branch on which provider failed (ADR D141).\n *\n * @public\n */\nexport class MemoryAdapterError extends TheokitAgentError {\n override readonly name: string = \"MemoryAdapterError\";\n readonly adapterId: string;\n\n constructor(\n message: string,\n options: {\n adapterId: string;\n code: MemoryAdapterErrorCode;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n isRetryable: options.code === \"rate_limited\" || options.code === \"network\",\n code: options.code,\n ...(options.cause !== undefined ? { cause: options.cause } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n this.adapterId = options.adapterId;\n }\n}\n\n/**\n * Thrown when a user-supplied task ID violates the grammar\n * `^[a-z0-9][a-z0-9_-]*$` (D368) OR starts with a reserved adapter\n * prefix (`wf-` / `b-` / `cron-`, EC-5).\n *\n * @public\n */\nexport class InvalidTaskIdError extends TheokitAgentError {\n override readonly name: string = \"InvalidTaskIdError\";\n readonly taskId: string;\n\n constructor(message: string, taskId: string, options: { cause?: unknown } = {}) {\n super(message, {\n ...options,\n isRetryable: false,\n code: \"invalid_task_id\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `Task.subscribe(id)` is called for a task that has been\n * evicted, never submitted, or evicted after retention (D373).\n *\n * @public\n */\nexport class TaskNotFoundError extends TheokitAgentError {\n override readonly name: string = \"TaskNotFoundError\";\n readonly taskId: string;\n\n constructor(taskId: string, options: { cause?: unknown } = {}) {\n super(`Task not found: ${taskId}`, {\n ...options,\n isRetryable: false,\n code: \"task_not_found\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `CloudAgent` is asked to wrap a task (D370). Cloud\n * task observability is deferred until Theo PaaS GA.\n *\n * @public\n */\nexport class UnsupportedTaskOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedTaskOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Task operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D370)`,\n {\n ...options,\n isRetryable: false,\n code: \"task_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n\n/**\n * Thrown by `Budget` enforcement (ADR D386) when a `mode: \"block\"`\n * budget would be exceeded by the upcoming LLM call. Caller pega\n * tipado para retry-after-window-reset or surface to the user.\n *\n * @public\n */\nexport class BudgetExceededError extends TheokitAgentError {\n override readonly name: string = \"BudgetExceededError\";\n readonly budgetName: string;\n readonly window: import(\"./types/budget.js\").BudgetWindow;\n readonly spentUsd: number;\n readonly limitUsd: number;\n readonly mode: import(\"./types/budget.js\").BudgetMode;\n\n constructor(args: {\n budgetName: string;\n window: import(\"./types/budget.js\").BudgetWindow;\n spentUsd: number;\n limitUsd: number;\n mode: import(\"./types/budget.js\").BudgetMode;\n cause?: unknown;\n }) {\n super(\n `Budget \"${args.budgetName}\" exceeded for window ${args.window}: spent $${args.spentUsd.toFixed(4)} > limit $${args.limitUsd.toFixed(4)}`,\n {\n ...(args.cause !== undefined ? { cause: args.cause } : {}),\n isRetryable: false,\n code: \"budget_exceeded\",\n },\n );\n this.budgetName = args.budgetName;\n this.window = args.window;\n this.spentUsd = args.spentUsd;\n this.limitUsd = args.limitUsd;\n this.mode = args.mode;\n }\n}\n\n/**\n * Thrown when `CloudAgent.send({ budget })` is invoked (D388). Cloud\n * budget surface waits for Theo PaaS GA.\n *\n * @public\n */\n/**\n * T1.6 — Thrown when a consumer calls `agent.send()` or any method\n * on an agent that has already been `dispose()`d. Pre-T1.6 this was\n * a generic `new Error(\"Agent has been disposed\")` — consumers\n * couldn't catch it without string-matching the message.\n *\n * @public\n */\nexport class AgentDisposedError extends TheokitAgentError {\n override readonly name: string = \"AgentDisposedError\";\n readonly agentId: string;\n\n constructor(agentId: string) {\n super(`Agent \"${agentId}\" has been disposed. Create a new agent or use Agent.resume().`, {\n isRetryable: false,\n code: \"agent_disposed\",\n });\n this.agentId = agentId;\n }\n}\n\nexport class UnsupportedBudgetOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedBudgetOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Budget operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D388)`,\n {\n ...options,\n isRetryable: false,\n code: \"budget_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/runtime/retry/default-retriable.ts","../src/errors.ts"],"names":[],"mappings":"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","file":"chunk-MRKSSN36.js","sourcesContent":["/**\n * Default retryability verdict for an `AgentRunError` code.\n *\n * Extracted from `errors.ts` (G8 LoC budget — SRP). The parameter is typed\n * `string` (not the `AgentRunErrorCode` union) deliberately: this is a leaf\n * with NO import back into `errors.ts`, so it cannot form an import cycle. The\n * `default` branch makes the behavior identical to the typed switch.\n *\n * @internal\n */\nexport function defaultRetriableForCode(code: string): boolean {\n switch (code) {\n case \"rate_limit\":\n case \"timeout\":\n case \"server_error\":\n case \"network\":\n case \"provider_unreachable\":\n return true;\n default:\n return false;\n }\n}\n","import { defaultRetriableForCode } from \"./internal/runtime/retry/default-retriable.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\nimport type { RunOperation } from \"./types/run.js\";\n\n/**\n * Finite, machine-readable error codes for provider-originated errors\n * (ADR D66). Consumers can `switch (err.metadata?.code)` exhaustively\n * — adding a new variant is an explicit decision + test coverage.\n *\n * @public\n */\nexport type ErrorCode =\n | \"rate_limit\"\n | \"auth_failed\"\n | \"invalid_request\"\n | \"timeout\"\n | \"server_error\"\n | \"context_too_long\"\n | \"content_filtered\"\n | \"model_unavailable\"\n | \"network\"\n | \"quota_exceeded\"\n | \"unknown\";\n\n/**\n * Codes used by {@link AgentRunError} (Production-Readiness #3, ADR D311).\n *\n * Superset of {@link ErrorCode} extended with codes that do NOT originate\n * from a provider HTTP response:\n *\n * - `quota_exceeded` — billing limit hit (provider 402 or signalled error)\n * - `tool_runtime_error` — custom tool handler threw inside dispatch\n * - `aborted` — caller's `AbortSignal` fired (Phase 4)\n * - `invalid_model` — model id rejected by provider (400 \"model not found\")\n * - `safety_blocked` — provider safety filter blocked req or resp\n * - `provider_unreachable` — DNS/TCP/timeout/5xx at transport boundary\n *\n * The `& {}` tail keeps the literal-union ergonomics (autocomplete) while\n * accepting any string for forward compatibility with constructor calls\n * that pass arbitrary code values (legacy callers).\n *\n * @public\n */\n/**\n * T1.1 — closed literal union for `AgentRunError.code`. The previous\n * `(string & {})` escape hatch let arbitrary strings slip into the type\n * surface and defeated exhaustive `switch (code)` discrimination. This is\n * the canonical closed form. `AgentRunErrorCode` is re-aliased below for\n * source-level back-compat.\n *\n * Adding a new code: append the literal here AND audit every `switch (err.code)`\n * in callers. Type-checker enforces the audit via the `default: assertNever(code)`\n * convention.\n *\n * @public\n */\nexport type KnownAgentRunErrorCode =\n | ErrorCode\n | \"quota_exceeded\"\n | \"tool_runtime_error\"\n | \"aborted\"\n | \"invalid_model\"\n | \"safety_blocked\"\n | \"provider_unreachable\";\n\n/**\n * Back-compat alias of {@link KnownAgentRunErrorCode}. Pre-T1.1 callers that\n * imported `AgentRunErrorCode` keep working; new code SHOULD prefer\n * `KnownAgentRunErrorCode` to make the closed-union intent explicit.\n *\n * @public\n */\nexport type AgentRunErrorCode = KnownAgentRunErrorCode;\n\n/** Snapshot of every known code at runtime — used by the boundary coercer. */\nconst KNOWN_AGENT_RUN_ERROR_CODES = new Set<string>([\n \"rate_limit\",\n \"auth_failed\",\n \"invalid_request\",\n \"timeout\",\n \"server_error\",\n \"context_too_long\",\n \"content_filtered\",\n \"model_unavailable\",\n \"network\",\n \"unknown\",\n \"quota_exceeded\",\n \"tool_runtime_error\",\n \"aborted\",\n \"invalid_model\",\n \"safety_blocked\",\n \"provider_unreachable\",\n]);\n\n/**\n * T1.1 boundary helper — coerce an arbitrary string (typically arriving from\n * a downstream `RunErrorDetail.code` or a deserialized cloud response) into a\n * `KnownAgentRunErrorCode`. Unknown strings collapse to `\"unknown\"` so the\n * closed type contract holds without forcing every caller to switch.\n *\n * @internal\n */\nexport function coerceToKnownAgentRunErrorCode(code: string | undefined): KnownAgentRunErrorCode {\n if (code !== undefined && KNOWN_AGENT_RUN_ERROR_CODES.has(code)) {\n return code as KnownAgentRunErrorCode;\n }\n return \"unknown\";\n}\n\n/**\n * Structured context for errors that originated from a provider HTTP\n * call (ADR D65). Lets callers retry with the right backoff (`retryAfter`),\n * surface actionable diagnostics (`provider`, `endpoint`), and inspect the\n * raw response body when needed (`raw`, capped at ~2KB by the mapper).\n *\n * @public\n */\nexport interface ErrorMetadata {\n /** Provider canonical name (e.g., `\"anthropic\"`, `\"openai\"`, `\"openrouter\"`, `\"gemini\"`). */\n provider: string;\n /** HTTP endpoint that failed (e.g., `\"/v1/messages\"`, `\"/v1/chat/completions\"`). */\n endpoint: string;\n /** Machine-readable error code (finite enum). */\n code: ErrorCode;\n /** HTTP status code if applicable. */\n statusCode?: number;\n /** Seconds to wait before retry, per provider's `retry-after` header (numeric form only). */\n retryAfter?: number;\n /** Raw response body for debugging (truncated to ~2KB by the mapper). */\n raw?: unknown;\n}\n\n/**\n * Base class for all errors thrown by `@theokit/sdk`.\n *\n * Use `isRetryable` to drive retry/backoff logic. `code` and `protoErrorCode`\n * are populated for server-originated errors when available. `metadata`\n * (ADR D65) carries structured `{ provider, endpoint, code, ... }` when\n * the error originated from a provider HTTP call.\n *\n * @public\n */\nexport class TheokitAgentError extends Error {\n override readonly name: string = \"TheokitAgentError\";\n readonly isRetryable: boolean;\n readonly code?: string;\n readonly protoErrorCode?: string;\n readonly metadata?: ErrorMetadata;\n\n constructor(\n message: string,\n options: {\n isRetryable?: boolean;\n code?: string;\n protoErrorCode?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n } = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.isRetryable = options.isRetryable ?? false;\n if (options.code !== undefined) this.code = options.code;\n if (options.protoErrorCode !== undefined) this.protoErrorCode = options.protoErrorCode;\n if (options.metadata !== undefined) this.metadata = options.metadata;\n }\n}\n\n/**\n * Invalid API key, not logged in, insufficient permissions.\n *\n * @public\n */\nexport class AuthenticationError extends TheokitAgentError {\n override readonly name: string = \"AuthenticationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Too many requests or usage limits exceeded.\n *\n * @public\n */\nexport class RateLimitError extends TheokitAgentError {\n override readonly name: string = \"RateLimitError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Invalid model, bad request parameters, malformed options.\n *\n * @public\n */\nexport class ConfigurationError extends TheokitAgentError {\n override readonly name: string = \"ConfigurationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown when creating a cloud agent for a repo whose SCM provider is not\n * connected. Use `helpUrl` to point the user at the right reconnect flow.\n *\n * @public\n */\nexport class IntegrationNotConnectedError extends ConfigurationError {\n override readonly name: string = \"IntegrationNotConnectedError\";\n readonly provider: string;\n readonly helpUrl: string;\n\n constructor(\n message: string,\n options: {\n provider: string;\n helpUrl: string;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, options);\n this.provider = options.provider;\n this.helpUrl = options.helpUrl;\n }\n}\n\n/**\n * Service unavailable, timeout, transport-level failure.\n *\n * @public\n */\nexport class NetworkError extends TheokitAgentError {\n override readonly name: string = \"NetworkError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Catch-all for unclassified server or runtime errors.\n *\n * @public\n */\nexport class UnknownAgentError extends TheokitAgentError {\n override readonly name: string = \"UnknownAgentError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown by `Agent.prompt` (and helpers that go through `run.wait()`) when\n * the option `{ throwOnError: true }` is set and the run terminates with\n * `status: 'error'`. Carries the structured `RunResult.error` fields so\n * callers can `catch` once and branch on `code` / `provider` instead of\n * unwrapping the run.\n *\n * Extends {@link TheokitAgentError} per ADR D65 — no new hierarchy.\n *\n * @example\n * try {\n * await Agent.prompt(msg, { apiKey, model, throwOnError: true });\n * } catch (err) {\n * if (err instanceof AgentRunError && err.code === 'auth_failed') {\n * // bad key\n * }\n * }\n *\n * @public\n */\nexport class AgentRunError extends TheokitAgentError {\n override readonly name: string = \"AgentRunError\";\n readonly provider?: string;\n readonly raw?: string;\n /** Provider's request id (`x-request-id` / `request-id` header). Useful for support tickets. */\n readonly requestId?: string;\n /** SDK conversation id this error was raised inside. */\n readonly conversationId?: string;\n\n constructor(\n message: string,\n options: {\n code: AgentRunErrorCode;\n provider?: string;\n raw?: string;\n requestId?: string;\n conversationId?: string;\n retriable?: boolean;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n code: options.code,\n cause: options.cause,\n metadata: options.metadata,\n // D311: most AgentRunErrors are not retriable (auth, validation, abort).\n // Provider mappers (D314) override per-status — explicit `retriable` wins\n // over the implicit default when supplied.\n isRetryable: options.retriable ?? defaultRetriableForCode(options.code),\n });\n if (options.provider !== undefined) this.provider = options.provider;\n if (options.raw !== undefined) this.raw = options.raw;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.conversationId !== undefined) this.conversationId = options.conversationId;\n }\n\n /**\n * Production-Readiness #3 (ADR D311): alias for `isRetryable` exposed as\n * `retriable` to match the handoff contract. Future v2 will deprecate\n * `isRetryable` in favor of this.\n */\n get retriable(): boolean {\n return this.isRetryable;\n }\n\n /**\n * D312: provider's `Retry-After` header in **milliseconds**. Mappers store\n * the header value (seconds) in `metadata.retryAfter`; this getter\n * multiplies by 1000 so the result composes with `Date.now()`/`setTimeout`.\n *\n * Returns `undefined` when no hint was provided. `0` is a legitimate value\n * — use `=== undefined` check rather than truthy check.\n */\n get retryAfterMs(): number | undefined {\n if (this.metadata?.retryAfter === undefined) return undefined;\n return this.metadata.retryAfter * 1000;\n }\n\n /**\n * D313 + T1.5: alias for `metadata.raw`. Provider response body for\n * debugging. T1.5 wraps the value in `redactSecrets` at the getter\n * boundary so secret-shaped substrings (`sk-...`, Bearer JWTs, etc.) are\n * stripped before reaching the caller. Available but NEVER serialized\n * into `.message` (anti-leak invariant).\n */\n get providerError(): unknown {\n const raw = this.metadata?.raw;\n if (raw === undefined) return undefined;\n if (typeof raw === \"string\") return redactSecrets(raw);\n // Non-string raw (object/buffer) — stringify then redact.\n try {\n return redactSecrets(JSON.stringify(raw));\n } catch {\n return redactSecrets(String(raw));\n }\n }\n\n /**\n * T1.5 — sanitized JSON form. `metadata.raw` is OMITTED by default; opt\n * in via `THEOKIT_DEBUG_RAW_ERRORS=1` to surface the (redacted) raw\n * payload for diagnostics. Every other field stays accessible.\n *\n * The single env-var gate is read each call so operators can toggle at\n * runtime without restarting the process.\n */\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n name: this.name,\n message: this.message,\n isRetryable: this.isRetryable,\n };\n addOptionalFields(json, this);\n const safeMeta = sanitizeMetadata(this.metadata);\n if (safeMeta !== undefined) json.metadata = safeMeta;\n return json;\n }\n}\n\nfunction addOptionalFields(json: Record<string, unknown>, err: AgentRunError): void {\n if (err.code !== undefined) json.code = err.code;\n if (err.provider !== undefined) json.provider = err.provider;\n if (err.requestId !== undefined) json.requestId = err.requestId;\n if (err.conversationId !== undefined) json.conversationId = err.conversationId;\n if (err.raw !== undefined) json.raw = redactSecrets(err.raw);\n}\n\nfunction sanitizeMetadata(meta: ErrorMetadata | undefined): ErrorMetadata | undefined {\n if (meta === undefined) return undefined;\n const { raw, ...rest } = meta;\n const debugRaw = process.env.THEOKIT_DEBUG_RAW_ERRORS === \"1\";\n if (debugRaw && raw !== undefined) {\n const redactedRaw =\n typeof raw === \"string\" ? redactSecrets(raw) : redactSecrets(safeStringify(raw));\n return { ...rest, raw: redactedRaw } as ErrorMetadata;\n }\n return rest as ErrorMetadata;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\n/**\n * Is this error transient (worth retrying)?\n *\n * Returns the SDK's own retryability verdict: every {@link TheokitAgentError}\n * subclass computes `isRetryable` at construction (rate-limit / network /\n * credential-pool-exhausted are retryable; auth / configuration / unsupported\n * are not), so this predicate is a single source of truth rather than a\n * re-derivation. Non-SDK errors return `false` conservatively — wrap a foreign\n * error in the appropriate SDK error first if you want it considered transient.\n * It never inspects `err.message`.\n *\n * @example\n * try {\n * await agent.send(message, { throwOnError: true });\n * } catch (err) {\n * if (isTransientError(err)) return retryWithBackoff();\n * throw err;\n * }\n *\n * @public\n */\nexport function isTransientError(err: unknown): boolean {\n return err instanceof TheokitAgentError && err.isRetryable === true;\n}\n\n/**\n * Thrown when a {@link Run} or agent operation is not available on the current\n * runtime. Check first with `run.supports(operation)`.\n *\n * Extends {@link TheokitAgentError} (so error-catching code that branches on\n * `instanceof TheokitAgentError` continues to work) but is never retryable —\n * an unsupported operation will not become supported on retry.\n *\n * @public\n */\nexport class UnsupportedRunOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedRunOperationError\";\n readonly operation: RunOperation;\n\n constructor(\n message: string,\n operation: RunOperation,\n options: { code?: string; cause?: unknown } = {},\n ) {\n super(message, {\n ...options,\n isRetryable: false,\n code: options.code ?? \"unsupported_run_operation\",\n });\n this.operation = operation;\n }\n}\n\n/**\n * Thrown when every credential in a per-provider pool is in cooldown\n * and no healthy key is available (ADR D133). The caller's\n * {@link import(\"./internal/llm/fallback-client.js\").FallbackLlmClient}\n * catches this and tries the next provider in the fallback chain.\n *\n * `metadata.nextRetryAt` (epoch ms) tells callers when the soonest\n * pool entry resumes — useful for manual retry scheduling.\n *\n * @public\n */\nexport class CredentialPoolExhaustedError extends TheokitAgentError {\n override readonly name: string = \"CredentialPoolExhaustedError\";\n readonly provider: string;\n readonly nextRetryAt: number | undefined;\n\n constructor(\n message: string,\n options: {\n provider: string;\n nextRetryAt?: number;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n ...options,\n isRetryable: true,\n code: options.code ?? \"credential_pool_exhausted\",\n });\n this.provider = options.provider;\n this.nextRetryAt = options.nextRetryAt;\n }\n}\n\n/**\n * Finite error codes specific to memory adapter operations (ADR D141).\n *\n * @public\n */\nexport type MemoryAdapterErrorCode =\n | \"auth_failed\"\n | \"rate_limited\"\n | \"not_found\"\n | \"network\"\n | \"invalid_input\"\n | \"unknown\";\n\n/**\n * Error raised by `@theokit-memory-*` adapters. Carries `adapterId`\n * so callers can branch on which provider failed (ADR D141).\n *\n * @public\n */\nexport class MemoryAdapterError extends TheokitAgentError {\n override readonly name: string = \"MemoryAdapterError\";\n readonly adapterId: string;\n\n constructor(\n message: string,\n options: {\n adapterId: string;\n code: MemoryAdapterErrorCode;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n isRetryable: options.code === \"rate_limited\" || options.code === \"network\",\n code: options.code,\n ...(options.cause !== undefined ? { cause: options.cause } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n this.adapterId = options.adapterId;\n }\n}\n\n/**\n * Thrown when a user-supplied task ID violates the grammar\n * `^[a-z0-9][a-z0-9_-]*$` (D368) OR starts with a reserved adapter\n * prefix (`wf-` / `b-` / `cron-`, EC-5).\n *\n * @public\n */\nexport class InvalidTaskIdError extends TheokitAgentError {\n override readonly name: string = \"InvalidTaskIdError\";\n readonly taskId: string;\n\n constructor(message: string, taskId: string, options: { cause?: unknown } = {}) {\n super(message, {\n ...options,\n isRetryable: false,\n code: \"invalid_task_id\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `Task.subscribe(id)` is called for a task that has been\n * evicted, never submitted, or evicted after retention (D373).\n *\n * @public\n */\nexport class TaskNotFoundError extends TheokitAgentError {\n override readonly name: string = \"TaskNotFoundError\";\n readonly taskId: string;\n\n constructor(taskId: string, options: { cause?: unknown } = {}) {\n super(`Task not found: ${taskId}`, {\n ...options,\n isRetryable: false,\n code: \"task_not_found\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `CloudAgent` is asked to wrap a task (D370). Cloud\n * task observability is deferred until Theo PaaS GA.\n *\n * @public\n */\nexport class UnsupportedTaskOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedTaskOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Task operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D370)`,\n {\n ...options,\n isRetryable: false,\n code: \"task_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n\n/**\n * Thrown by `Budget` enforcement (ADR D386) when a `mode: \"block\"`\n * budget would be exceeded by the upcoming LLM call. The caller catches a\n * typed error to retry after the window resets, or surfaces it to the user.\n *\n * @public\n */\nexport class BudgetExceededError extends TheokitAgentError {\n override readonly name: string = \"BudgetExceededError\";\n readonly budgetName: string;\n readonly window: import(\"./types/budget.js\").BudgetWindow;\n readonly spentUsd: number;\n readonly limitUsd: number;\n readonly mode: import(\"./types/budget.js\").BudgetMode;\n\n constructor(args: {\n budgetName: string;\n window: import(\"./types/budget.js\").BudgetWindow;\n spentUsd: number;\n limitUsd: number;\n mode: import(\"./types/budget.js\").BudgetMode;\n cause?: unknown;\n }) {\n super(\n `Budget \"${args.budgetName}\" exceeded for window ${args.window}: spent $${args.spentUsd.toFixed(4)} > limit $${args.limitUsd.toFixed(4)}`,\n {\n ...(args.cause !== undefined ? { cause: args.cause } : {}),\n isRetryable: false,\n code: \"budget_exceeded\",\n },\n );\n this.budgetName = args.budgetName;\n this.window = args.window;\n this.spentUsd = args.spentUsd;\n this.limitUsd = args.limitUsd;\n this.mode = args.mode;\n }\n}\n\n/**\n * Thrown when `CloudAgent.send({ budget })` is invoked (D388). Cloud\n * budget surface waits for Theo PaaS GA.\n *\n * @public\n */\n/**\n * T1.6 — Thrown when a consumer calls `agent.send()` or any method\n * on an agent that has already been `dispose()`d. Pre-T1.6 this was\n * a generic `new Error(\"Agent has been disposed\")` — consumers\n * couldn't catch it without string-matching the message.\n *\n * @public\n */\nexport class AgentDisposedError extends TheokitAgentError {\n override readonly name: string = \"AgentDisposedError\";\n readonly agentId: string;\n\n constructor(agentId: string) {\n super(`Agent \"${agentId}\" has been disposed. Create a new agent or use Agent.resume().`, {\n isRetryable: false,\n code: \"agent_disposed\",\n });\n this.agentId = agentId;\n }\n}\n\nexport class UnsupportedBudgetOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedBudgetOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Budget operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D388)`,\n {\n ...options,\n isRetryable: false,\n code: \"budget_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkZHPET3LZ_cjs = require('./chunk-ZHPET3LZ.cjs');
|
|
4
4
|
var crypto = require('crypto');
|
|
5
5
|
var promises = require('fs/promises');
|
|
6
6
|
var path = require('path');
|
|
@@ -23,17 +23,24 @@ async function warnOnNetworkFsOnce(dirPath, label) {
|
|
|
23
23
|
const info = await promises.statfs(dirPath);
|
|
24
24
|
const fsName = detectNetworkFsName(info.type);
|
|
25
25
|
if (fsName === null) return;
|
|
26
|
-
|
|
26
|
+
chunkZHPET3LZ_cjs.diag(
|
|
27
27
|
`[theokit-sdk] ${label}: detected network fs (${fsName}) at ${dirPath} \u2014 rename() atomicity guarantees may be weaker than expected.
|
|
28
28
|
`
|
|
29
29
|
);
|
|
30
30
|
} catch {
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
function atomicWriteTempPath(filePath, pid, suffix) {
|
|
34
|
+
return `${filePath}.${String(pid)}.${suffix}.tmp`;
|
|
35
|
+
}
|
|
36
|
+
var TEMP_PATTERN = /^(.+)\.\d+\.[0-9a-f]{16}\.tmp$/;
|
|
37
|
+
function atomicWriteTempTarget(name) {
|
|
38
|
+
return TEMP_PATTERN.exec(name)?.[1];
|
|
39
|
+
}
|
|
33
40
|
async function replaceFileAtomic(filePath, content, options) {
|
|
34
41
|
await warnOnNetworkFsOnce(path.dirname(filePath), "atomic-write");
|
|
35
42
|
const suffix = crypto.randomBytes(8).toString("hex");
|
|
36
|
-
const tmp =
|
|
43
|
+
const tmp = atomicWriteTempPath(filePath, process.pid, suffix);
|
|
37
44
|
const handle = await promises.open(tmp, options?.exclusive === true ? "wx" : "w", options?.mode ?? 384);
|
|
38
45
|
try {
|
|
39
46
|
await handle.writeFile(content, "utf8");
|
|
@@ -67,7 +74,8 @@ async function atomicWriteText(filePath, content) {
|
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
exports.atomicWriteJson = atomicWriteJson;
|
|
77
|
+
exports.atomicWriteTempTarget = atomicWriteTempTarget;
|
|
70
78
|
exports.atomicWriteText = atomicWriteText;
|
|
71
79
|
exports.replaceFileAtomic = replaceFileAtomic;
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
73
|
-
//# sourceMappingURL=chunk-
|
|
80
|
+
//# sourceMappingURL=chunk-NETYW4V3.cjs.map
|
|
81
|
+
//# sourceMappingURL=chunk-NETYW4V3.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/persistence/atomic-write.ts"],"names":["statfs","diag","dirname","randomBytes","open","rename","unlink","mkdir"],"mappings":"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","file":"chunk-NETYW4V3.cjs","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { mkdir, open, rename, statfs, unlink } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { diag } from \"../diagnostics.js\";\n\n// T5.8 — Linux filesystem magic numbers (from `<linux/magic.h>`).\n// Used by `detectNetworkFsName` to identify the parent directory's\n// filesystem type from a `statfs()` return value. The four entries\n// below cover the network/FUSE cases where `rename()` is best-effort\n// rather than strictly atomic; everything else is treated as local.\nconst NETWORK_FS_MAGIC: ReadonlyMap<number, string> = new Map([\n [0x6969, \"nfs\"],\n [0x517b, \"smb\"],\n [0xff534d42, \"cifs\"],\n [0x65735546, \"fuse\"],\n]);\n\n/**\n * T5.8 — Map a `statfs().type` magic number to a network-FS label, or\n * `null` for local filesystems. Pure function — exported via the\n * `__TESTING__` seam so unit tests can drive the parse logic without\n * needing a network mount.\n *\n * @internal\n */\nfunction detectNetworkFsName(typeMagic: number): string | null {\n return NETWORK_FS_MAGIC.get(typeMagic) ?? null;\n}\n\nconst warnedNfsDirs = new Set<string>();\n\n/**\n * T5.8 — Best-effort one-shot stderr warning when `dirPath` lives on a\n * network/FUSE filesystem. Silent no-op on local filesystems, on\n * statfs failure (Windows / Node < 18.15 / EACCES), or after the\n * first warning per (dir + label) pair. Mirrors the `sqlite-wal.ts`\n * warn-once-per-label pattern (D63).\n *\n * @internal\n */\nasync function warnOnNetworkFsOnce(dirPath: string, label: string): Promise<void> {\n const key = `${dirPath}\\0${label}`;\n if (warnedNfsDirs.has(key)) return;\n warnedNfsDirs.add(key);\n try {\n const info = await statfs(dirPath);\n const fsName = detectNetworkFsName(info.type);\n if (fsName === null) return;\n diag(\n `[theokit-sdk] ${label}: detected network fs (${fsName}) at ${dirPath} — ` +\n \"rename() atomicity guarantees may be weaker than expected.\\n\",\n );\n } catch {\n // statfs unavailable (Windows / Node < 18.15) or unreadable —\n // silent fallback. The warning is purely informational.\n }\n}\n\n/**\n * T5.8 — Test seam exposing the pure detection function so unit tests\n * can assert magic-number coverage without spinning up a network FS.\n * NOT included in the public barrel.\n *\n * @internal\n */\nexport function __TESTING__detectNetworkFsName(typeMagic: number): string | null {\n return detectNetworkFsName(typeMagic);\n}\n\n/**\n * T5.8 — Test seam: clear the per-directory warn-once registry between\n * tests so warning-emission tests stay deterministic.\n *\n * @internal\n */\nexport function __TESTING__resetNfsWarnings(): void {\n warnedNfsDirs.clear();\n}\n\n/**\n * M107 — temp-file creation control, shared by `replaceFileAtomic`,\n * `atomicWriteJson` e `atomicWriteText`.\n *\n * Both fields are OPTIONAL and the default is byte-identical to the behavior\n * before M107. See `replaceFileAtomic` for why the mode reassertion\n * is conditional.\n *\n * @internal\n */\nexport interface AtomicWriteFileOptions {\n /**\n * Permission bits of the created file. Default: `0o600`, the previous fixed\n * literal — filtered by the `umask`, as it always was. When provided, the mode is\n * reasserted on the descriptor, so the `umask` cannot silently\n * clearing bits the caller asked for.\n */\n mode?: number;\n /**\n * Create the temp file with `wx` (exclusive creation) instead of `w`. Default:\n * `false` — the previous flag. With `true`, a pre-existing temp file becomes\n * `EEXIST` instead of being truncated.\n */\n exclusive?: boolean;\n}\n\n/** The one place the temp-path format is written. `atomicWriteTempTarget` reverses it. */\nfunction atomicWriteTempPath(filePath: string, pid: number, suffix: string): string {\n return `${filePath}.${String(pid)}.${suffix}.tmp`;\n}\n\n/** Reverses {@link atomicWriteTempPath}: `<file>.<pid>.<hex>.tmp` → `<file>`. */\nconst TEMP_PATTERN = /^(.+)\\.\\d+\\.[0-9a-f]{16}\\.tmp$/;\n\n/**\n * U-9 — the file a leftover temp was replacing, or `undefined` if this is not one of ours.\n *\n * A crash between the open and the rename leaves `<file>.<pid>.<hex>.tmp` behind, and nothing here\n * collects it: this module creates temps and has no opinion about sweeping them. A consumer that\n * wants to has to know the format — which lived only in the implementation, so one copied it out of\n * a compiled chunk as a regex. That copy would have gone on reporting \"nothing to collect\" the day\n * the format changed, which is the quietest possible way for a cleanup to stop working.\n *\n * Deliberately strict: the pid must be digits and the suffix exactly 16 hex characters. Matching any\n * `.tmp` would claim editors' swap files and other tools' scratch, on a path whose purpose is\n * deleting them.\n */\nexport function atomicWriteTempTarget(name: string): string | undefined {\n return TEMP_PATTERN.exec(name)?.[1];\n}\n\n/**\n * Atomic file replacement: write content to a per-call unique tmp path,\n * fsync, then rename over the target. Crash mid-write leaves either the old\n * file intact or the new file complete — never a half-written file.\n *\n * The tmp suffix is `<pid>.<rand>.tmp` so parallel processes (and concurrent\n * burst writes within one process) never collide on the same tmp path — a\n * race that would manifest as `ENOENT` on `rename` after the rival process\n * already moved its tmp into place.\n *\n * Mirrors peer-project's `replaceFileAtomic` from\n * `reference/peer-project/packages/memory-host-sdk/src/host/fs-utils.ts` with\n * the multi-writer robustness fix.\n *\n * ## M107 — `options` is optional, and the default is byte-identical\n *\n * The third parameter is additive: every earlier caller still compiles and\n * writing exactly the same bytes, with the same mode, to the same path.\n *\n * The mode reassertion (`handle.chmod`) is **conditional on `mode !== undefined`**,\n * and that is not cosmetic. `open`'s mode argument is filtered by the `umask`,\n * which only CLEARS bits — measured in this codebase before the change:\n *\n * ```\n * umask 0o002 -> 0o600 umask 0o022 -> 0o600 umask 0o200 -> 0o400\n * ```\n *\n * An unconditional `chmod` would take the third case from `0o400` to `0o600` — a\n * an on-disk change for every caller that asked for nothing, including external\n * consumers. When the caller DOES ask for a mode, however, letting the `umask` decide\n * silently is the defect this parameter exists to close; hence the reassertion.\n *\n * It goes on the DESCRIPTOR, before the `rename`, never after: chmod-ing the final\n * final one would leave a window where it carries the `umask`'s mode — the anti-pattern\n * from `opencode/packages/core/src/fs-util.ts:110-114`. The chosen shape (mode as\n * `open` argument) is that of `codex-rs/network-proxy/src/certs.rs:687,783-791`.\n *\n * @internal\n */\nexport async function replaceFileAtomic(\n filePath: string,\n content: string,\n options?: AtomicWriteFileOptions,\n): Promise<void> {\n // T5.8 — warn once per parent directory if it lives on a network /\n // FUSE filesystem where `rename()` atomicity is best-effort. The\n // write proceeds unchanged; the warning is purely informational so\n // operators can spot the case in stderr / log aggregators.\n await warnOnNetworkFsOnce(dirname(filePath), \"atomic-write\");\n // T5.7 — crypto-random tmp suffix (CSPRNG, 64 bits of entropy)\n // replaces the predictable `Math.random().toString(36)` source. An\n // attacker observing the process can no longer predict the next\n // tmp path and pre-stage a hostile file to be renamed into place.\n const suffix = randomBytes(8).toString(\"hex\");\n const tmp = atomicWriteTempPath(filePath, process.pid, suffix);\n // T5.7 — mode 0o600 on the tmp file (owner read+write only). The\n // tmp file holds the FULL in-flight content (credential snapshots,\n // OAuth tokens) before the rename. World-readable default would\n // expose secrets during the ms-window between open and rename\n // (TOCTOU). On modern Linux the post-rename target inherits the\n // tmp's permission bits, so the final file is also 0o600.\n const handle = await open(tmp, options?.exclusive === true ? \"wx\" : \"w\", options?.mode ?? 0o600);\n try {\n await handle.writeFile(content, \"utf8\");\n await handle.sync();\n // Conditional by measurement, not by taste — see this function's docblock.\n if (options?.mode !== undefined) await handle.chmod(options.mode);\n } finally {\n await handle.close();\n }\n try {\n await rename(tmp, filePath);\n } catch (cause) {\n // Cleanup tmp on rename failure so we don't leak stale .tmp files.\n await unlink(tmp).catch(() => undefined);\n throw cause;\n }\n}\n\n/**\n * Options for `atomicWriteJson`.\n *\n * @internal\n */\nexport interface AtomicWriteJsonOptions extends AtomicWriteFileOptions {\n /** Indent passed to `JSON.stringify`. Default: 2. */\n indent?: number;\n /** Whether to append a trailing newline (POSIX convention). Default: true. */\n trailingNewline?: boolean;\n}\n\n/**\n * Typed JSON atomic write helper.\n *\n * Serializes `data` to JSON, then delegates to `replaceFileAtomic`. The\n * parent directory is auto-created (recursive `mkdir`) to make this helper\n * safe for callers who haven't ensured the directory exists (EC-4 in the\n * persistence-state-hardening plan).\n *\n * Throws `TypeError` on circular refs or `undefined` data (propagates from\n * `JSON.stringify`).\n *\n * @internal\n */\nexport async function atomicWriteJson<T>(\n filePath: string,\n data: T,\n options?: AtomicWriteJsonOptions,\n): Promise<void> {\n const indent = options?.indent ?? 2;\n const trailingNewline = options?.trailingNewline ?? true;\n const json = JSON.stringify(data, null, indent);\n if (json === undefined) {\n throw new TypeError(\"atomicWriteJson: cannot serialize undefined\");\n }\n const content = trailingNewline ? `${json}\\n` : json;\n await mkdir(dirname(filePath), { recursive: true });\n await replaceFileAtomic(filePath, content, options);\n}\n\n/**\n * Atomic text write. Same crash-safety guarantees as `replaceFileAtomic` +\n * auto-mkdir of the parent directory. Used by `theokit-migrate-config`\n * (T4.1, EC-2 MUST FIX) so a crash mid-migration leaves previous MD files\n * intact rather than corrupting them.\n *\n * @internal\n */\nexport async function atomicWriteText(filePath: string, content: string): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n await replaceFileAtomic(filePath, content);\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkYULF6FPB_cjs = require('./chunk-YULF6FPB.cjs');
|
|
4
|
+
var chunkZHPET3LZ_cjs = require('./chunk-ZHPET3LZ.cjs');
|
|
5
5
|
|
|
6
6
|
// src/internal/runtime/compression/compression-helpers.ts
|
|
7
7
|
function selectCompressionWindow(messages, preserveLast = 6) {
|
|
@@ -40,7 +40,7 @@ Anything that MUST NOT be forgotten (preserve verbatim: error messages, exact va
|
|
|
40
40
|
File paths touched or referenced (verbatim).`;
|
|
41
41
|
function assertMarker(marker) {
|
|
42
42
|
if (marker === "") {
|
|
43
|
-
throw new
|
|
43
|
+
throw new chunkYULF6FPB_cjs.TheokitAgentError("compaction marker must be non-empty", {
|
|
44
44
|
code: "invalid_argument"
|
|
45
45
|
});
|
|
46
46
|
}
|
|
@@ -73,8 +73,8 @@ async function runSummarize(summarize, head, template, failSafe) {
|
|
|
73
73
|
return await summarize(head, template);
|
|
74
74
|
} catch (err) {
|
|
75
75
|
if (!failSafe) throw err;
|
|
76
|
-
|
|
77
|
-
`[compaction] summarizer failed \u2014 proceeding uncompacted: ${
|
|
76
|
+
chunkZHPET3LZ_cjs.diag(
|
|
77
|
+
`[compaction] summarizer failed \u2014 proceeding uncompacted: ${chunkZHPET3LZ_cjs.redactSecrets(err instanceof Error ? err.message : String(err))}
|
|
78
78
|
`
|
|
79
79
|
);
|
|
80
80
|
return FAILSAFE_ABORT;
|
|
@@ -117,9 +117,9 @@ function filterFromLatestCheckpoint(messages, options = {}) {
|
|
|
117
117
|
return [...messages];
|
|
118
118
|
}
|
|
119
119
|
function isContextOverflowError(err) {
|
|
120
|
-
return err instanceof
|
|
120
|
+
return err instanceof chunkYULF6FPB_cjs.TheokitAgentError && (err.code === "context_too_long" || err.metadata?.code === "context_too_long");
|
|
121
121
|
}
|
|
122
|
-
var ContextWindowMarginError = class extends
|
|
122
|
+
var ContextWindowMarginError = class extends chunkYULF6FPB_cjs.TheokitAgentError {
|
|
123
123
|
constructor(margin) {
|
|
124
124
|
super(
|
|
125
125
|
`context-window margin must be in (0, 1], got ${String(margin)}. A margin above 1 grows the assumed window and delays compaction past the real limit.`,
|
|
@@ -167,5 +167,5 @@ exports.filterFromLatestCheckpoint = filterFromLatestCheckpoint;
|
|
|
167
167
|
exports.isContextOverflowError = isContextOverflowError;
|
|
168
168
|
exports.resolveEffectiveContextWindow = resolveEffectiveContextWindow;
|
|
169
169
|
exports.shouldCompact = shouldCompact;
|
|
170
|
-
//# sourceMappingURL=chunk-
|
|
171
|
-
//# sourceMappingURL=chunk-
|
|
170
|
+
//# sourceMappingURL=chunk-NNNUQELM.cjs.map
|
|
171
|
+
//# sourceMappingURL=chunk-NNNUQELM.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/runtime/compression/compression-helpers.ts","../src/compaction.ts"],"names":["TheokitAgentError","diag","redactSecrets"],"mappings":"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","file":"chunk-OVGNXGCK.cjs","sourcesContent":["/**\n * Compression helpers (T2.3, ADR D92).\n *\n * Scaffold for future compression LLM integration:\n * - `selectCompressionWindow` — splits messages into compress/preserve halves\n * - `assertCompressionReduced` — 10% reduction floor to detect \"compression placebo\"\n *\n * The compression LLM call itself is out of scope for this plan (requires\n * an auxiliary-model ADR). These helpers are used by `Agent.send` when a\n * future iteration adds compression.\n *\n * @internal\n */\n\nexport interface CompressionWindow<M> {\n toCompress: M[];\n toPreserve: M[];\n}\n\n/**\n * Split `messages` into the half to compress (older) and the half to\n * preserve verbatim (recent). When `messages.length <= preserveLast`,\n * everything is preserved.\n *\n * @internal\n */\nexport function selectCompressionWindow<M>(\n messages: readonly M[],\n preserveLast = 6,\n): CompressionWindow<M> {\n if (messages.length <= preserveLast) {\n return { toCompress: [], toPreserve: [...messages] };\n }\n return {\n toCompress: messages.slice(0, -preserveLast),\n toPreserve: messages.slice(-preserveLast),\n };\n}\n\nexport interface CompressionCheck {\n reduced: boolean;\n reductionPct: number;\n reason?: string;\n}\n\n/**\n * Check that compression actually reduced token count by at least `minPct`\n * (default 10%). Returns `{ reduced: false }` for spirals-in-formation\n * (compression LLM outputs that grow or barely shrink).\n *\n * @internal\n */\nexport function assertCompressionReduced(\n before: number,\n after: number,\n minPct = 10,\n): CompressionCheck {\n if (before <= 0) {\n return { reduced: false, reductionPct: 0, reason: \"before count was zero\" };\n }\n const reductionPct = ((before - after) / before) * 100;\n if (reductionPct >= minPct) {\n return { reduced: true, reductionPct };\n }\n return {\n reduced: false,\n reductionPct,\n reason: `compression reduced ${reductionPct.toFixed(1)}% (< ${minPct}% min). Spiral likely.`,\n };\n}\n","/**\n * Public compaction / context-management helpers (M2-1, extended V3-3).\n *\n * Promotes the SDK's compaction capability to a public surface so consumers can\n * compact a transcript, mark/filter conversation checkpoints, and detect\n * context-overflow — without reaching into `internal/`.\n *\n * Two recent-window modes (V3-3):\n * - `keepRecent` (turn-count, default) — keeps the last N turns verbatim and\n * always preserves leading system PROMPTS; reuses the internal\n * `selectCompressionWindow` (no second algorithm).\n * - `keepTokens` (token-budget) — keeps the trailing turns whose accumulated\n * `estimateTokens` fits the budget (theocode `splitTranscript` semantics). In\n * this mode leading system prompts are NOT special-cased (D6).\n *\n * Summarization is delegated to a caller-supplied callback (which receives the\n * older window + the summary template). With `failSafe`, a thrown summarizer\n * returns the ORIGINAL transcript + a structured warn (compaction is an\n * optimization, never a cause of data loss); without it, the error propagates.\n *\n * Public from the `@theokit/sdk/compaction` sub-path.\n */\n\nimport { TheokitAgentError } from \"./errors.js\";\nimport { diag } from \"./internal/diagnostics.js\";\nimport { selectCompressionWindow } from \"./internal/runtime/compression/compression-helpers.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\n\n/**\n * Minimal message shape for compaction/compression input. THE canonical public origin (leaf type —\n * rollup-plugin-dts cannot re-export types from internal modules into entry bundles; M42 lesson).\n *\n * @public\n */\nexport interface CompressibleMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n}\n\n/**\n * Sentinel prefix marking a conversation checkpoint turn. A visible, structured,\n * prose-unlikely token (no invisible/control bytes — safe to persist and to read\n * in source). Only {@link buildCheckpoint} should produce content beginning with it.\n */\nexport const CHECKPOINT_MARKER = \"[[theokit:checkpoint]] \";\n\n/**\n * The 7-section summary template handed to the `summarize` callback (theocode\n * parity shape). Every header is always present so the summarizer cannot silently\n * drop a category; the model is told to preserve file paths, commands, and error\n * text verbatim. Override per-call via {@link CompactTranscriptOptions.summaryTemplate}.\n */\nexport const SUMMARY_TEMPLATE = `Summarize the conversation so far into these sections (keep every header even if empty):\n\n## Goal\nWhat the user is ultimately trying to achieve.\n\n## Constraints\nHard requirements, conventions, and rules stated.\n\n## Progress\nWhat has been done so far.\n\n## Decisions\nChoices made and their rationale.\n\n## Next\nThe immediate next steps.\n\n## Critical\nAnything that MUST NOT be forgotten (preserve verbatim: error messages, exact values).\n\n## Files\nFile paths touched or referenced (verbatim).`;\n\n/** Reject an empty marker — it would match every turn via `startsWith(\"\")` (EC-3). */\nfunction assertMarker(marker: string): void {\n if (marker === \"\") {\n throw new TheokitAgentError(\"compaction marker must be non-empty\", {\n code: \"invalid_argument\",\n });\n }\n}\n\n/** True for a real system prompt — a `system` turn that is NOT a checkpoint marker. */\nfunction isSystemPrompt(message: CompressibleMessage, marker: string): boolean {\n return message.role === \"system\" && !message.content.startsWith(marker);\n}\n\n/** Carried split: leading system prompts (preserved), the older window, the verbatim tail. */\ninterface TranscriptSplit {\n systemPrompts: CompressibleMessage[];\n head: CompressibleMessage[];\n recent: CompressibleMessage[];\n}\n\n/**\n * Token-budget split (theocode `splitTranscript`): walk from the END accumulating\n * `estimateTokens` until `keepTokens` is exceeded; everything older is the head.\n * Always keeps ≥ 1 recent turn. No system-prompt special-casing (D6).\n */\nfunction selectByTokenBudget(\n messages: CompressibleMessage[],\n keepTokens: number,\n): { head: CompressibleMessage[]; recent: CompressibleMessage[] } {\n let acc = 0;\n let splitIndex = messages.length;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n acc += estimateTokens(messages[i]?.content ?? \"\");\n if (acc > keepTokens && i < messages.length - 1) {\n splitIndex = i + 1;\n break;\n }\n splitIndex = i;\n }\n return { head: messages.slice(0, splitIndex), recent: messages.slice(splitIndex) };\n}\n\n/** Turn-count split (M2): preserve leading system prompts; window the rest by `keepRecent`. */\nfunction splitByRecent(\n messages: CompressibleMessage[],\n keepRecent: number,\n marker: string,\n): TranscriptSplit {\n const systemPrompts = messages.filter((m) => isSystemPrompt(m, marker));\n const rest = messages.filter((m) => !isSystemPrompt(m, marker));\n const { toCompress, toPreserve } = selectCompressionWindow(rest, keepRecent);\n return { systemPrompts, head: toCompress, recent: toPreserve };\n}\n\n/** Options for {@link compactTranscript}. */\nexport interface CompactTranscriptOptions {\n /** Trailing turns preserved verbatim by COUNT (default 6). Ignored when `keepTokens` is set. */\n keepRecent?: number;\n /**\n * Trailing turns preserved verbatim by TOKEN BUDGET (theocode mode). When set,\n * takes precedence over `keepRecent` and disables system-prompt preservation (D6).\n */\n keepTokens?: number;\n /** Checkpoint marker (default {@link CHECKPOINT_MARKER}). Must be non-empty. */\n marker?: string;\n /** Summary template passed to `summarize` (default {@link SUMMARY_TEMPLATE}). */\n summaryTemplate?: string;\n /** Summarize the older window into one turn; if omitted, the older window is dropped. */\n summarize?: (older: CompressibleMessage[], template: string) => Promise<CompressibleMessage>;\n /**\n * When true, a thrown `summarize` returns the ORIGINAL transcript + a structured\n * warn (compaction never loses data). Default false: the error propagates.\n */\n failSafe?: boolean;\n}\n\n/** Sentinel returned by {@link runSummarize} when fail-safe swallowed a throw. */\nconst FAILSAFE_ABORT = Symbol(\"failsafe-abort\");\n\n/** Run the summarizer; on throw, either propagate or (fail-safe) warn + signal abort. */\nasync function runSummarize(\n summarize: NonNullable<CompactTranscriptOptions[\"summarize\"]>,\n head: CompressibleMessage[],\n template: string,\n failSafe: boolean,\n): Promise<CompressibleMessage | typeof FAILSAFE_ABORT> {\n try {\n return await summarize(head, template);\n } catch (err) {\n if (!failSafe) throw err;\n // Unbreakable Rule 8 — never fail silently. The breadcrumb points at the root\n // cause when a summarizer fails every turn and context grows unchecked. The\n // summarizer is caller-supplied, so its error text is routed through\n // `redactSecrets` (ADR D68 — no unredacted output sink in src/).\n // theokit#147 — through the interceptable channel. A summarizer failing every turn is exactly\n // the breadcrumb a TUI host wants in its own panel, not smeared across its alternate screen.\n diag(\n `[compaction] summarizer failed — proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}\\n`,\n );\n return FAILSAFE_ABORT;\n }\n}\n\n/**\n * Compact a transcript. In `keepRecent` mode (default) the last `keepRecent` turns\n * are kept verbatim and leading system PROMPTS preserved; in `keepTokens` mode the\n * trailing turns within the token budget are kept (no system special-casing, D6).\n * The older window is summarized (via `summarize`, receiving the template) or\n * dropped. Never mutates the input.\n */\nexport async function compactTranscript(\n messages: CompressibleMessage[],\n options: CompactTranscriptOptions = {},\n): Promise<CompressibleMessage[]> {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n assertMarker(marker);\n const split =\n options.keepTokens != null\n ? { systemPrompts: [], ...selectByTokenBudget(messages, options.keepTokens) }\n : splitByRecent(messages, options.keepRecent ?? 6, marker);\n if (split.head.length === 0) {\n return [...messages];\n }\n if (!options.summarize) {\n return [...split.systemPrompts, ...split.recent];\n }\n const template = options.summaryTemplate ?? SUMMARY_TEMPLATE;\n const summary = await runSummarize(\n options.summarize,\n split.head,\n template,\n options.failSafe ?? false,\n );\n if (summary === FAILSAFE_ABORT) {\n return [...messages];\n }\n return [...split.systemPrompts, summary, ...split.recent];\n}\n\n/**\n * Build a checkpoint marker turn (a `system` turn whose content starts with\n * `marker`, default {@link CHECKPOINT_MARKER}). `marker` must be non-empty.\n */\nexport function buildCheckpoint(\n label?: string,\n marker: string = CHECKPOINT_MARKER,\n): CompressibleMessage {\n assertMarker(marker);\n return { role: \"system\", content: marker + (label ?? \"\") };\n}\n\n/** Options for {@link filterFromLatestCheckpoint}. */\nexport interface FilterCheckpointOptions {\n /** Marker to scan for (default {@link CHECKPOINT_MARKER}). */\n marker?: string;\n /**\n * `'after'` (default, M2) returns turns AFTER the latest marker (exclusive);\n * `'from'` (theocode) returns turns FROM the latest marker (inclusive).\n */\n include?: \"after\" | \"from\";\n}\n\n/**\n * Return the turns relative to the most recent checkpoint marker (all turns if\n * none). `include: 'after'` (default) excludes the checkpoint; `'from'` includes\n * it (the summary stands in for the pruned head). Never mutates the input.\n */\nexport function filterFromLatestCheckpoint(\n messages: CompressibleMessage[],\n options: FilterCheckpointOptions = {},\n): CompressibleMessage[] {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n const offset = options.include === \"from\" ? 0 : 1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.content.startsWith(marker)) {\n return messages.slice(i + offset);\n }\n }\n return [...messages];\n}\n\n/**\n * True iff `err` is a {@link TheokitAgentError} (or subclass) reporting a\n * context-window-exceeded condition (the typed `context_too_long` code). Reads\n * both `code` (set by provider mappers) and `metadata.code` (the preferred field)\n * — never a brittle message regex.\n */\nexport function isContextOverflowError(err: unknown): boolean {\n return (\n err instanceof TheokitAgentError &&\n (err.code === \"context_too_long\" || err.metadata?.code === \"context_too_long\")\n );\n}\n\n/**\n * M77 — the margin is outside `(0, 1]`. Typed, because a margin > 1 would GROW the assumed window,\n * which is the unsafe direction: `shouldCompact` is monotonically decreasing in `contextWindow`, so\n * overestimating it makes the trigger fire too late and the context overflow.\n */\nexport class ContextWindowMarginError extends TheokitAgentError {\n constructor(readonly margin: number) {\n super(\n `context-window margin must be in (0, 1], got ${String(margin)}. ` +\n `A margin above 1 grows the assumed window and delays compaction past the real limit.`,\n { code: \"invalid_context_window_margin\" },\n );\n }\n}\n\n/**\n * M77 — default safety margin on the context window.\n *\n * `0.95` is not a guess: it is the single reference's value. Codex ships\n * `effective_context_window_percent: 95` (`models-manager/src/model_info.rs:158`) and never budgets\n * against 100% of a window. Being MULTIPLICATIVE, it stays conservative at any window size, which a\n * fixed subtraction would not.\n */\nexport const CONTEXT_WINDOW_MARGIN = 0.95;\n\n/**\n * M77 — the floor used ONLY when neither the catalog nor the caller knows the window.\n *\n * Honest about its own weakness. This number has **one** source (the M77 milestone text); the search\n * for a second one failed, because the reference has no fallback at all — Codex returns `Option` and\n * its callers early-return (`core/src/session/turn_context.rs:213`, `core/src/compact_remote.rs:374`).\n *\n * It is conservative only UPWARD. For a model whose real window is larger, budgeting against 128k\n * compacts early — wasteful but safe. For a model whose real window is SMALLER (an 8k or 32k model\n * absent from the catalog), it compacts too late and the context still overflows. That residual risk\n * is real and is why {@link resolveEffectiveContextWindow} never lets this floor compete with a known\n * catalog value, and why the `compaction_fallback` event exists: a surface can show that the budget is\n * a guess instead of the user finding out when the provider rejects the request.\n */\nexport const CONTEXT_WINDOW_FLOOR = 128_000;\n\n/** Where the effective window came from — carried into the M77 structured event. */\nexport type ContextWindowSource = \"override\" | \"catalog\" | \"fallback\";\n\n/** Input to {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindowInput {\n /** Caller-supplied window, in tokens. Clamped by `catalog` when both are present. */\n readonly override?: number | undefined;\n /** The model's window from the catalog, in tokens. Absent when the model is unknown. */\n readonly catalog?: number | undefined;\n /** Safety margin in `(0, 1]`. Codex uses 0.95 (`model_info.rs:158`). */\n readonly margin: number;\n /** Conservative floor used ONLY when neither `override` nor `catalog` is available. */\n readonly floor?: number | undefined;\n}\n\n/** Result of {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindow {\n /** The window to budget against, after clamp and margin. */\n readonly window: number;\n /** Which input won — `\"fallback\"` means neither override nor catalog was available. */\n readonly source: ContextWindowSource;\n /** `true` when an `override` above the catalog window was clamped down to it. */\n readonly clamped: boolean;\n}\n\n/**\n * Resolve the window to budget against — the fail-SAFE replacement for reading the catalog directly.\n *\n * Today `post-run-lifecycle.ts` reads `getCatalogModelInfo(model)?.limit?.context` and, when that is\n * `undefined`, auto-compaction simply never fires. That is fail-OPEN: the context grows until the\n * provider rejects the request. (The comment there calls it \"fail-safe\" — M77 corrects it.)\n *\n * Three techniques, two of them borrowed from the single reference:\n *\n * 1. **Override, CLAMPED by the catalog** — Codex `models-manager/src/model_info.rs:26-31` lets\n * config override the window but limits it with `context_window.min(max_context_window)`.\n * Without the clamp, declaring 999k on a 200k model reopens the overflow through another door.\n * 2. **Multiplicative margin** — Codex `model_info.rs:158` (`effective_context_window_percent: 95`)\n * never budgets against 100% of the window. Being multiplicative, it is conservative for ANY\n * window size.\n * 3. **Floor, only when nothing is known** — deliberately NOT a blanket default. A fixed floor is\n * conservative only upward: applied to a small model it would inflate the assumed window and\n * reproduce the very fail-open this function exists to close. Hence the floor never competes\n * with a known catalog value.\n *\n * Pure — no catalog lookup, no I/O. The caller supplies the numbers, mirroring `shouldCompact`.\n */\n/**\n * Absolute cap on a declared context window, applied when no catalog entry exists to compare against.\n *\n * **10M**, not 2M. The first version used 2M on the rationale that it sat \"comfortably above the\n * largest published window\" — adversarial review measured the opposite: Llama 4 Scout publishes\n * **10M**, and it arrives precisely via OpenRouter, the provider **without** a catalog, which is the\n * case this cap exists to cover. The user would have silently lost 80% of the declared window.\n *\n * The cap still serves what motivates it — one extra zero on 400k gives 4M, which passes; two zeros\n * give 40M, which does not. A limit that rejects legitimate configuration is worse than no limit,\n * because failing OPEN is visible when it happens and silently losing 80% is not.\n */\nexport const ABSOLUTE_CONTEXT_WINDOW_CAP = 10_000_000;\n\nexport function resolveEffectiveContextWindow(\n input: EffectiveContextWindowInput,\n): EffectiveContextWindow {\n if (!(input.margin > 0) || input.margin > 1) {\n throw new ContextWindowMarginError(input.margin);\n }\n\n const withMargin = (raw: number): number => Math.floor(raw * input.margin);\n\n if (input.override !== undefined) {\n // The catalog is the preferred cap; without it the ABSOLUTE cap applies.\n //\n // M95 (adversarial review of M94) — the previous version clamped **only** when a catalog entry\n // existed, and the whole reason the `contextWindow` key exists is the model that has NO entry\n // (OpenRouter has zero). So the clamp was missing in exactly the case that justifies the\n // feature, while the documentation — including an already-published CHANGELOG — stated without\n // qualification that \"declaring 10M does not blow past the provider\".\n //\n // The concrete scenario is one extra zero: `context_window = 4000000`. The only guard was a\n // `.positive().int()`, which sets no upper bound. The agent would never compact until the\n // provider refused the turn — the silent fail-OPEN that M77 exists to prevent.\n const cap = input.catalog ?? ABSOLUTE_CONTEXT_WINDOW_CAP;\n const clamped = input.override > cap;\n return { window: withMargin(clamped ? cap : input.override), source: \"override\", clamped };\n }\n\n if (input.catalog !== undefined) {\n return { window: withMargin(input.catalog), source: \"catalog\", clamped: false };\n }\n\n return { window: withMargin(input.floor ?? 0), source: \"fallback\", clamped: false };\n}\n\n/** Input to {@link shouldCompact}: an estimate, the model's window, and reserved headroom. */\nexport interface ShouldCompactInput {\n /** Estimated token count of the next request (e.g. from {@link estimateTokens}). */\n readonly estimated: number;\n /** The model's total context window, in tokens. */\n readonly contextWindow: number;\n /** Tokens to reserve as headroom (output + safety margin). */\n readonly buffer: number;\n /**\n * Tokens reserved for the model's response generation, SEPARATE from `buffer`.\n * Default 0 — omitting it preserves the legacy\n * `estimated >= contextWindow - buffer` result.\n */\n readonly maxOutput?: number;\n}\n\n/**\n * Tokenizer-free token estimate via the conventional ~4-chars-per-token\n * heuristic: `ceil(text.length / 4)`. `\"\"` → 0; any non-empty text → ≥ 1.\n * A cheap PRE-CALL gate for {@link shouldCompact} — NOT exact tokenization\n * (a consumer needing exactness supplies their own tokenizer). Uses UTF-16\n * `.length` (code units), so multibyte text is approximate.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Decide BEFORE sending whether to compact: `true` when the `estimated` token\n * count leaves less than `buffer` headroom in the `contextWindow`\n * (`estimated >= contextWindow - buffer`). A `buffer >= contextWindow`\n * (non-positive threshold) always returns `true`. Pure — the caller supplies\n * the window (e.g. from `resolveModelCapabilities`), keeping this decoupled\n * from the per-model catalog.\n */\nexport function shouldCompact(input: ShouldCompactInput): boolean {\n return input.estimated >= input.contextWindow - input.buffer - (input.maxOutput ?? 0);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/runtime/compression/compression-helpers.ts","../src/compaction.ts"],"names":["TheokitAgentError","diag","redactSecrets"],"mappings":"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","file":"chunk-NNNUQELM.cjs","sourcesContent":["/**\n * Compression helpers (T2.3, ADR D92).\n *\n * Scaffold for future compression LLM integration:\n * - `selectCompressionWindow` — splits messages into compress/preserve halves\n * - `assertCompressionReduced` — 10% reduction floor to detect \"compression placebo\"\n *\n * The compression LLM call itself is out of scope for this plan (requires\n * an auxiliary-model ADR). These helpers are used by `Agent.send` when a\n * future iteration adds compression.\n *\n * @internal\n */\n\nexport interface CompressionWindow<M> {\n toCompress: M[];\n toPreserve: M[];\n}\n\n/**\n * Split `messages` into the half to compress (older) and the half to\n * preserve verbatim (recent). When `messages.length <= preserveLast`,\n * everything is preserved.\n *\n * @internal\n */\nexport function selectCompressionWindow<M>(\n messages: readonly M[],\n preserveLast = 6,\n): CompressionWindow<M> {\n if (messages.length <= preserveLast) {\n return { toCompress: [], toPreserve: [...messages] };\n }\n return {\n toCompress: messages.slice(0, -preserveLast),\n toPreserve: messages.slice(-preserveLast),\n };\n}\n\nexport interface CompressionCheck {\n reduced: boolean;\n reductionPct: number;\n reason?: string;\n}\n\n/**\n * Check that compression actually reduced token count by at least `minPct`\n * (default 10%). Returns `{ reduced: false }` for spirals-in-formation\n * (compression LLM outputs that grow or barely shrink).\n *\n * @internal\n */\nexport function assertCompressionReduced(\n before: number,\n after: number,\n minPct = 10,\n): CompressionCheck {\n if (before <= 0) {\n return { reduced: false, reductionPct: 0, reason: \"before count was zero\" };\n }\n const reductionPct = ((before - after) / before) * 100;\n if (reductionPct >= minPct) {\n return { reduced: true, reductionPct };\n }\n return {\n reduced: false,\n reductionPct,\n reason: `compression reduced ${reductionPct.toFixed(1)}% (< ${minPct}% min). Spiral likely.`,\n };\n}\n","/**\n * Public compaction / context-management helpers (M2-1, extended V3-3).\n *\n * Promotes the SDK's compaction capability to a public surface so consumers can\n * compact a transcript, mark/filter conversation checkpoints, and detect\n * context-overflow — without reaching into `internal/`.\n *\n * Two recent-window modes (V3-3):\n * - `keepRecent` (turn-count, default) — keeps the last N turns verbatim and\n * always preserves leading system PROMPTS; reuses the internal\n * `selectCompressionWindow` (no second algorithm).\n * - `keepTokens` (token-budget) — keeps the trailing turns whose accumulated\n * `estimateTokens` fits the budget (theocode `splitTranscript` semantics). In\n * this mode leading system prompts are NOT special-cased (D6).\n *\n * Summarization is delegated to a caller-supplied callback (which receives the\n * older window + the summary template). With `failSafe`, a thrown summarizer\n * returns the ORIGINAL transcript + a structured warn (compaction is an\n * optimization, never a cause of data loss); without it, the error propagates.\n *\n * Public from the `@theokit/sdk/compaction` sub-path.\n */\n\nimport { TheokitAgentError } from \"./errors.js\";\nimport { diag } from \"./internal/diagnostics.js\";\nimport { selectCompressionWindow } from \"./internal/runtime/compression/compression-helpers.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\n\n/**\n * Minimal message shape for compaction/compression input. THE canonical public origin (leaf type —\n * rollup-plugin-dts cannot re-export types from internal modules into entry bundles; M42 lesson).\n *\n * @public\n */\nexport interface CompressibleMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n}\n\n/**\n * Sentinel prefix marking a conversation checkpoint turn. A visible, structured,\n * prose-unlikely token (no invisible/control bytes — safe to persist and to read\n * in source). Only {@link buildCheckpoint} should produce content beginning with it.\n */\nexport const CHECKPOINT_MARKER = \"[[theokit:checkpoint]] \";\n\n/**\n * The 7-section summary template handed to the `summarize` callback (theocode\n * parity shape). Every header is always present so the summarizer cannot silently\n * drop a category; the model is told to preserve file paths, commands, and error\n * text verbatim. Override per-call via {@link CompactTranscriptOptions.summaryTemplate}.\n */\nexport const SUMMARY_TEMPLATE = `Summarize the conversation so far into these sections (keep every header even if empty):\n\n## Goal\nWhat the user is ultimately trying to achieve.\n\n## Constraints\nHard requirements, conventions, and rules stated.\n\n## Progress\nWhat has been done so far.\n\n## Decisions\nChoices made and their rationale.\n\n## Next\nThe immediate next steps.\n\n## Critical\nAnything that MUST NOT be forgotten (preserve verbatim: error messages, exact values).\n\n## Files\nFile paths touched or referenced (verbatim).`;\n\n/** Reject an empty marker — it would match every turn via `startsWith(\"\")` (EC-3). */\nfunction assertMarker(marker: string): void {\n if (marker === \"\") {\n throw new TheokitAgentError(\"compaction marker must be non-empty\", {\n code: \"invalid_argument\",\n });\n }\n}\n\n/** True for a real system prompt — a `system` turn that is NOT a checkpoint marker. */\nfunction isSystemPrompt(message: CompressibleMessage, marker: string): boolean {\n return message.role === \"system\" && !message.content.startsWith(marker);\n}\n\n/** Carried split: leading system prompts (preserved), the older window, the verbatim tail. */\ninterface TranscriptSplit {\n systemPrompts: CompressibleMessage[];\n head: CompressibleMessage[];\n recent: CompressibleMessage[];\n}\n\n/**\n * Token-budget split (theocode `splitTranscript`): walk from the END accumulating\n * `estimateTokens` until `keepTokens` is exceeded; everything older is the head.\n * Always keeps ≥ 1 recent turn. No system-prompt special-casing (D6).\n */\nfunction selectByTokenBudget(\n messages: CompressibleMessage[],\n keepTokens: number,\n): { head: CompressibleMessage[]; recent: CompressibleMessage[] } {\n let acc = 0;\n let splitIndex = messages.length;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n acc += estimateTokens(messages[i]?.content ?? \"\");\n if (acc > keepTokens && i < messages.length - 1) {\n splitIndex = i + 1;\n break;\n }\n splitIndex = i;\n }\n return { head: messages.slice(0, splitIndex), recent: messages.slice(splitIndex) };\n}\n\n/** Turn-count split (M2): preserve leading system prompts; window the rest by `keepRecent`. */\nfunction splitByRecent(\n messages: CompressibleMessage[],\n keepRecent: number,\n marker: string,\n): TranscriptSplit {\n const systemPrompts = messages.filter((m) => isSystemPrompt(m, marker));\n const rest = messages.filter((m) => !isSystemPrompt(m, marker));\n const { toCompress, toPreserve } = selectCompressionWindow(rest, keepRecent);\n return { systemPrompts, head: toCompress, recent: toPreserve };\n}\n\n/** Options for {@link compactTranscript}. */\nexport interface CompactTranscriptOptions {\n /** Trailing turns preserved verbatim by COUNT (default 6). Ignored when `keepTokens` is set. */\n keepRecent?: number;\n /**\n * Trailing turns preserved verbatim by TOKEN BUDGET (theocode mode). When set,\n * takes precedence over `keepRecent` and disables system-prompt preservation (D6).\n */\n keepTokens?: number;\n /** Checkpoint marker (default {@link CHECKPOINT_MARKER}). Must be non-empty. */\n marker?: string;\n /** Summary template passed to `summarize` (default {@link SUMMARY_TEMPLATE}). */\n summaryTemplate?: string;\n /** Summarize the older window into one turn; if omitted, the older window is dropped. */\n summarize?: (older: CompressibleMessage[], template: string) => Promise<CompressibleMessage>;\n /**\n * When true, a thrown `summarize` returns the ORIGINAL transcript + a structured\n * warn (compaction never loses data). Default false: the error propagates.\n */\n failSafe?: boolean;\n}\n\n/** Sentinel returned by {@link runSummarize} when fail-safe swallowed a throw. */\nconst FAILSAFE_ABORT = Symbol(\"failsafe-abort\");\n\n/** Run the summarizer; on throw, either propagate or (fail-safe) warn + signal abort. */\nasync function runSummarize(\n summarize: NonNullable<CompactTranscriptOptions[\"summarize\"]>,\n head: CompressibleMessage[],\n template: string,\n failSafe: boolean,\n): Promise<CompressibleMessage | typeof FAILSAFE_ABORT> {\n try {\n return await summarize(head, template);\n } catch (err) {\n if (!failSafe) throw err;\n // Unbreakable Rule 8 — never fail silently. The breadcrumb points at the root\n // cause when a summarizer fails every turn and context grows unchecked. The\n // summarizer is caller-supplied, so its error text is routed through\n // `redactSecrets` (ADR D68 — no unredacted output sink in src/).\n // theokit#147 — through the interceptable channel. A summarizer failing every turn is exactly\n // the breadcrumb a TUI host wants in its own panel, not smeared across its alternate screen.\n diag(\n `[compaction] summarizer failed — proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}\\n`,\n );\n return FAILSAFE_ABORT;\n }\n}\n\n/**\n * Compact a transcript. In `keepRecent` mode (default) the last `keepRecent` turns\n * are kept verbatim and leading system PROMPTS preserved; in `keepTokens` mode the\n * trailing turns within the token budget are kept (no system special-casing, D6).\n * The older window is summarized (via `summarize`, receiving the template) or\n * dropped. Never mutates the input.\n */\nexport async function compactTranscript(\n messages: CompressibleMessage[],\n options: CompactTranscriptOptions = {},\n): Promise<CompressibleMessage[]> {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n assertMarker(marker);\n const split =\n options.keepTokens != null\n ? { systemPrompts: [], ...selectByTokenBudget(messages, options.keepTokens) }\n : splitByRecent(messages, options.keepRecent ?? 6, marker);\n if (split.head.length === 0) {\n return [...messages];\n }\n if (!options.summarize) {\n return [...split.systemPrompts, ...split.recent];\n }\n const template = options.summaryTemplate ?? SUMMARY_TEMPLATE;\n const summary = await runSummarize(\n options.summarize,\n split.head,\n template,\n options.failSafe ?? false,\n );\n if (summary === FAILSAFE_ABORT) {\n return [...messages];\n }\n return [...split.systemPrompts, summary, ...split.recent];\n}\n\n/**\n * Build a checkpoint marker turn (a `system` turn whose content starts with\n * `marker`, default {@link CHECKPOINT_MARKER}). `marker` must be non-empty.\n */\nexport function buildCheckpoint(\n label?: string,\n marker: string = CHECKPOINT_MARKER,\n): CompressibleMessage {\n assertMarker(marker);\n return { role: \"system\", content: marker + (label ?? \"\") };\n}\n\n/** Options for {@link filterFromLatestCheckpoint}. */\nexport interface FilterCheckpointOptions {\n /** Marker to scan for (default {@link CHECKPOINT_MARKER}). */\n marker?: string;\n /**\n * `'after'` (default, M2) returns turns AFTER the latest marker (exclusive);\n * `'from'` (theocode) returns turns FROM the latest marker (inclusive).\n */\n include?: \"after\" | \"from\";\n}\n\n/**\n * Return the turns relative to the most recent checkpoint marker (all turns if\n * none). `include: 'after'` (default) excludes the checkpoint; `'from'` includes\n * it (the summary stands in for the pruned head). Never mutates the input.\n */\nexport function filterFromLatestCheckpoint(\n messages: CompressibleMessage[],\n options: FilterCheckpointOptions = {},\n): CompressibleMessage[] {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n const offset = options.include === \"from\" ? 0 : 1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.content.startsWith(marker)) {\n return messages.slice(i + offset);\n }\n }\n return [...messages];\n}\n\n/**\n * True iff `err` is a {@link TheokitAgentError} (or subclass) reporting a\n * context-window-exceeded condition (the typed `context_too_long` code). Reads\n * both `code` (set by provider mappers) and `metadata.code` (the preferred field)\n * — never a brittle message regex.\n */\nexport function isContextOverflowError(err: unknown): boolean {\n return (\n err instanceof TheokitAgentError &&\n (err.code === \"context_too_long\" || err.metadata?.code === \"context_too_long\")\n );\n}\n\n/**\n * M77 — the margin is outside `(0, 1]`. Typed, because a margin > 1 would GROW the assumed window,\n * which is the unsafe direction: `shouldCompact` is monotonically decreasing in `contextWindow`, so\n * overestimating it makes the trigger fire too late and the context overflow.\n */\nexport class ContextWindowMarginError extends TheokitAgentError {\n constructor(readonly margin: number) {\n super(\n `context-window margin must be in (0, 1], got ${String(margin)}. ` +\n `A margin above 1 grows the assumed window and delays compaction past the real limit.`,\n { code: \"invalid_context_window_margin\" },\n );\n }\n}\n\n/**\n * M77 — default safety margin on the context window.\n *\n * `0.95` is not a guess: it is the single reference's value. Codex ships\n * `effective_context_window_percent: 95` (`models-manager/src/model_info.rs:158`) and never budgets\n * against 100% of a window. Being MULTIPLICATIVE, it stays conservative at any window size, which a\n * fixed subtraction would not.\n */\nexport const CONTEXT_WINDOW_MARGIN = 0.95;\n\n/**\n * M77 — the floor used ONLY when neither the catalog nor the caller knows the window.\n *\n * Honest about its own weakness. This number has **one** source (the M77 milestone text); the search\n * for a second one failed, because the reference has no fallback at all — Codex returns `Option` and\n * its callers early-return (`core/src/session/turn_context.rs:213`, `core/src/compact_remote.rs:374`).\n *\n * It is conservative only UPWARD. For a model whose real window is larger, budgeting against 128k\n * compacts early — wasteful but safe. For a model whose real window is SMALLER (an 8k or 32k model\n * absent from the catalog), it compacts too late and the context still overflows. That residual risk\n * is real and is why {@link resolveEffectiveContextWindow} never lets this floor compete with a known\n * catalog value, and why the `compaction_fallback` event exists: a surface can show that the budget is\n * a guess instead of the user finding out when the provider rejects the request.\n */\nexport const CONTEXT_WINDOW_FLOOR = 128_000;\n\n/** Where the effective window came from — carried into the M77 structured event. */\nexport type ContextWindowSource = \"override\" | \"catalog\" | \"fallback\";\n\n/** Input to {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindowInput {\n /** Caller-supplied window, in tokens. Clamped by `catalog` when both are present. */\n readonly override?: number | undefined;\n /** The model's window from the catalog, in tokens. Absent when the model is unknown. */\n readonly catalog?: number | undefined;\n /** Safety margin in `(0, 1]`. Codex uses 0.95 (`model_info.rs:158`). */\n readonly margin: number;\n /** Conservative floor used ONLY when neither `override` nor `catalog` is available. */\n readonly floor?: number | undefined;\n}\n\n/** Result of {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindow {\n /** The window to budget against, after clamp and margin. */\n readonly window: number;\n /** Which input won — `\"fallback\"` means neither override nor catalog was available. */\n readonly source: ContextWindowSource;\n /** `true` when an `override` above the catalog window was clamped down to it. */\n readonly clamped: boolean;\n}\n\n/**\n * Resolve the window to budget against — the fail-SAFE replacement for reading the catalog directly.\n *\n * Today `post-run-lifecycle.ts` reads `getCatalogModelInfo(model)?.limit?.context` and, when that is\n * `undefined`, auto-compaction simply never fires. That is fail-OPEN: the context grows until the\n * provider rejects the request. (The comment there calls it \"fail-safe\" — M77 corrects it.)\n *\n * Three techniques, two of them borrowed from the single reference:\n *\n * 1. **Override, CLAMPED by the catalog** — Codex `models-manager/src/model_info.rs:26-31` lets\n * config override the window but limits it with `context_window.min(max_context_window)`.\n * Without the clamp, declaring 999k on a 200k model reopens the overflow through another door.\n * 2. **Multiplicative margin** — Codex `model_info.rs:158` (`effective_context_window_percent: 95`)\n * never budgets against 100% of the window. Being multiplicative, it is conservative for ANY\n * window size.\n * 3. **Floor, only when nothing is known** — deliberately NOT a blanket default. A fixed floor is\n * conservative only upward: applied to a small model it would inflate the assumed window and\n * reproduce the very fail-open this function exists to close. Hence the floor never competes\n * with a known catalog value.\n *\n * Pure — no catalog lookup, no I/O. The caller supplies the numbers, mirroring `shouldCompact`.\n */\n/**\n * Absolute cap on a declared context window, applied when no catalog entry exists to compare against.\n *\n * **10M**, not 2M. The first version used 2M on the rationale that it sat \"comfortably above the\n * largest published window\" — adversarial review measured the opposite: Llama 4 Scout publishes\n * **10M**, and it arrives precisely via OpenRouter, the provider **without** a catalog, which is the\n * case this cap exists to cover. The user would have silently lost 80% of the declared window.\n *\n * The cap still serves what motivates it — one extra zero on 400k gives 4M, which passes; two zeros\n * give 40M, which does not. A limit that rejects legitimate configuration is worse than no limit,\n * because failing OPEN is visible when it happens and silently losing 80% is not.\n */\nexport const ABSOLUTE_CONTEXT_WINDOW_CAP = 10_000_000;\n\nexport function resolveEffectiveContextWindow(\n input: EffectiveContextWindowInput,\n): EffectiveContextWindow {\n if (!(input.margin > 0) || input.margin > 1) {\n throw new ContextWindowMarginError(input.margin);\n }\n\n const withMargin = (raw: number): number => Math.floor(raw * input.margin);\n\n if (input.override !== undefined) {\n // The catalog is the preferred cap; without it the ABSOLUTE cap applies.\n //\n // M95 (adversarial review of M94) — the previous version clamped **only** when a catalog entry\n // existed, and the whole reason the `contextWindow` key exists is the model that has NO entry\n // (OpenRouter has zero). So the clamp was missing in exactly the case that justifies the\n // feature, while the documentation — including an already-published CHANGELOG — stated without\n // qualification that \"declaring 10M does not blow past the provider\".\n //\n // The concrete scenario is one extra zero: `context_window = 4000000`. The only guard was a\n // `.positive().int()`, which sets no upper bound. The agent would never compact until the\n // provider refused the turn — the silent fail-OPEN that M77 exists to prevent.\n const cap = input.catalog ?? ABSOLUTE_CONTEXT_WINDOW_CAP;\n const clamped = input.override > cap;\n return { window: withMargin(clamped ? cap : input.override), source: \"override\", clamped };\n }\n\n if (input.catalog !== undefined) {\n return { window: withMargin(input.catalog), source: \"catalog\", clamped: false };\n }\n\n return { window: withMargin(input.floor ?? 0), source: \"fallback\", clamped: false };\n}\n\n/** Input to {@link shouldCompact}: an estimate, the model's window, and reserved headroom. */\nexport interface ShouldCompactInput {\n /** Estimated token count of the next request (e.g. from {@link estimateTokens}). */\n readonly estimated: number;\n /** The model's total context window, in tokens. */\n readonly contextWindow: number;\n /** Tokens to reserve as headroom (output + safety margin). */\n readonly buffer: number;\n /**\n * Tokens reserved for the model's response generation, SEPARATE from `buffer`.\n * Default 0 — omitting it preserves the legacy\n * `estimated >= contextWindow - buffer` result.\n */\n readonly maxOutput?: number;\n}\n\n/**\n * Tokenizer-free token estimate via the conventional ~4-chars-per-token\n * heuristic: `ceil(text.length / 4)`. `\"\"` → 0; any non-empty text → ≥ 1.\n * A cheap PRE-CALL gate for {@link shouldCompact} — NOT exact tokenization\n * (a consumer needing exactness supplies their own tokenizer). Uses UTF-16\n * `.length` (code units), so multibyte text is approximate.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Decide BEFORE sending whether to compact: `true` when the `estimated` token\n * count leaves less than `buffer` headroom in the `contextWindow`\n * (`estimated >= contextWindow - buffer`). A `buffer >= contextWindow`\n * (non-positive threshold) always returns `true`. Pure — the caller supplies\n * the window (e.g. from `resolveModelCapabilities`), keeping this decoupled\n * from the per-model catalog.\n */\nexport function shouldCompact(input: ShouldCompactInput): boolean {\n return input.estimated >= input.contextWindow - input.buffer - (input.maxOutput ?? 0);\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { atomicWriteText } from './chunk-
|
|
2
|
-
import { InvalidTaskIdError } from './chunk-
|
|
3
|
-
import { diag } from './chunk-
|
|
1
|
+
import { atomicWriteText } from './chunk-VQFSEKU5.js';
|
|
2
|
+
import { InvalidTaskIdError } from './chunk-MRKSSN36.js';
|
|
3
|
+
import { diag } from './chunk-PBML2FHN.js';
|
|
4
4
|
import { mkdirSync, readdirSync } from 'fs';
|
|
5
5
|
import { readFile, unlink } from 'fs/promises';
|
|
6
6
|
import { join } from 'path';
|
|
@@ -188,5 +188,5 @@ function getTaskStoreFor(options) {
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
export { InMemoryTaskStore, JsonFileTaskStore, getTaskStoreFor, isValidTaskId };
|
|
191
|
-
//# sourceMappingURL=chunk-
|
|
192
|
-
//# sourceMappingURL=chunk-
|
|
191
|
+
//# sourceMappingURL=chunk-NOM2YWFP.js.map
|
|
192
|
+
//# sourceMappingURL=chunk-NOM2YWFP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/task.ts","../src/internal/task/store.ts"],"names":[],"mappings":"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","file":"chunk-BM7VYZED.js","sourcesContent":["/**\n * Public type contract for the Task observability registry (ADRs D361-D374).\n *\n * Tasks are an opt-in observability layer over async work in the SDK\n * (`Agent.send`, `Agent.batch`, `Workflow.run`, `Cron` fires). They have\n * a closed 5-state lifecycle (D362), discriminated events (D366), and a\n * pluggable store (D364). The `Task` facade in `task.ts` is the public\n * surface; consumers import these types from `@theokit/sdk`.\n *\n * @public\n */\n\n/**\n * Closed enum of the 5 lifecycle states (D362).\n *\n * Transitions are acyclic:\n * queued → running → (finished | error | cancelled)\n * queued → cancelled (direct, no run started)\n */\nexport type TaskState = \"queued\" | \"running\" | \"finished\" | \"error\" | \"cancelled\";\n\n/** Discriminator of the runtime that produced a task (D374). */\nexport type TaskKind = \"run\" | \"batch\" | \"workflow\" | \"cron\" | \"custom\";\n\n/** Discriminated union of task lifecycle events (D366). */\nexport type TaskEvent =\n | {\n readonly type: \"submitted\";\n readonly taskId: string;\n readonly kind: TaskKind;\n readonly submittedAt: number;\n readonly meta?: Record<string, unknown>;\n /** D372 — flag set on the first yielded event when the ring buffer was at cap. */\n readonly truncated?: boolean;\n }\n | { readonly type: \"started\"; readonly taskId: string; readonly startedAt: number }\n | {\n readonly type: \"progress\";\n readonly taskId: string;\n readonly at: number;\n readonly payload: unknown;\n }\n | {\n readonly type: \"finished\";\n readonly taskId: string;\n readonly finishedAt: number;\n readonly result: unknown;\n }\n | {\n readonly type: \"errored\";\n readonly taskId: string;\n readonly erroredAt: number;\n readonly error: { readonly code: string; readonly message: string };\n }\n | {\n readonly type: \"cancelled\";\n readonly taskId: string;\n readonly cancelledAt: number;\n readonly reason?: string;\n };\n\n/** Public read-only view of a task entry in the registry. */\nexport interface TaskHandle {\n readonly id: string;\n readonly kind: TaskKind;\n readonly state: TaskState;\n readonly submittedAt: number;\n readonly startedAt?: number;\n readonly finishedAt?: number;\n readonly cancelledAt?: number;\n readonly erroredAt?: number;\n readonly result?: unknown;\n readonly error?: { readonly code: string; readonly message: string };\n readonly meta?: Record<string, unknown>;\n /**\n * EC-7 — cross-process best-effort cancel flag. Set by CLI\n * `theokit tasks cancel` via JsonFileTaskStore. The owning process\n * polls at checkpoints and honors via AbortController. Always\n * `undefined` for in-process cancel paths (which go directly through\n * AbortController).\n */\n readonly cancelRequested?: boolean;\n}\n\n/** Query filter for `Task.list`. */\nexport interface TaskFilter {\n readonly state?: TaskState | readonly TaskState[];\n readonly kind?: TaskKind | readonly TaskKind[];\n readonly submittedAfter?: number;\n readonly submittedBefore?: number;\n /** Defaults to 100. JsonFileTaskStore hard-caps loaded entries at 256 (D364). */\n readonly limit?: number;\n}\n\n/** Options for `Task.submit`. */\nexport interface TaskSubmitOptions {\n /**\n * Optional user-supplied ID. Must match grammar `^[a-z0-9][a-z0-9_-]*$`\n * and MUST NOT start with the reserved prefixes `wf-` / `b-` / `cron-`\n * (D368, EC-5). When omitted, `crypto.randomUUID()` is used.\n */\n readonly id?: string;\n readonly meta?: Record<string, unknown>;\n /**\n * Optional caller-provided AbortSignal. If already aborted at submit\n * time, the registry short-circuits to `cancelled` without acquiring\n * a semaphore slot (EC-4).\n */\n readonly signal?: AbortSignal;\n /**\n * SE2 — an opt-in {@link import(\"./run-events.js\").RunEventSink}. The task's\n * lifecycle is forwarded to it as typed `task_started` / `task_updated` /\n * `task_completed` RunEvents, so a caller that spawned the task can observe it\n * through the same `onRunEvent` channel as the rest of the run. Best-effort (a\n * throwing sink never breaks the task). The dedicated `Task.subscribe(id)`\n * channel is unaffected.\n */\n readonly onRunEvent?: import(\"./run-events.js\").RunEventSink;\n}\n\n/** Options shape for `TaskStore` factory (D364). */\nexport type TaskStoreOptions =\n | { readonly backend: \"memory\" }\n | { readonly backend: \"json\"; readonly dir: string };\n\n/** Result of `Task.cancel` (D365 — idempotent). */\nexport interface TaskCancelResult {\n readonly cancelled: boolean;\n readonly alreadyTerminal: boolean;\n}\n\n/**\n * Grammar for user-supplied task IDs (D368).\n * `crypto.randomUUID()` outputs do NOT match this (UUIDs have dashes\n * AND uppercase letters in their canonical form on some Node versions),\n * but the registry normalizes auto-generated IDs to lowercase before\n * insertion, so they pass the same regex.\n */\nconst TASK_ID_GRAMMAR = /^[a-z0-9][a-z0-9_-]*$/;\n\n/** Reserved prefixes for adapter-generated IDs (D368, EC-5). */\nconst RESERVED_PREFIXES = [\"wf-\", \"b-\", \"cron-\"] as const;\n\n/**\n * Validates a task ID against the public grammar + reserved prefixes.\n * Throws `InvalidTaskIdError` from `../errors.js` on rejection.\n *\n * Adapter callers (workflow/batch/cron) MUST set `allowReserved: true`\n * to register their own IDs; user-facing surfaces (`Task.submit`,\n * `agent.send({ task: { id } })`) leave it false.\n */\nexport function isValidTaskId(id: string, allowReserved: boolean): boolean {\n if (!TASK_ID_GRAMMAR.test(id)) return false;\n if (allowReserved) return true;\n for (const prefix of RESERVED_PREFIXES) {\n if (id.startsWith(prefix)) return false;\n }\n return true;\n}\n\n/** Re-exported for adapter implementations + tests. */\nexport const TASK_RESERVED_PREFIXES: readonly string[] = RESERVED_PREFIXES;\n","/**\n * `TaskStore` interface + 2 implementations (ADR D364).\n *\n * - `InMemoryTaskStore` — default, transient, single-process.\n * - `JsonFileTaskStore` — opt-in, one JSON file per task under a\n * dedicated dir; single-process invariant (EC-15 documented).\n *\n * Edge cases absorbed:\n * - EC-1: constructor auto-creates dir (mkdirSync recursive idempotent).\n * - EC-2: every method validates the task id against the public\n * grammar (D368) BEFORE doing any path I/O — path-traversal defense.\n * - EC-6: `list()` returns `[]` on ENOENT (fresh install path).\n * - EC-8: `list()` skips `.tmp.*` orphan files left by interrupted\n * atomic writes.\n * - EC-14 (DOCUMENT): `list()` JSDoc documents the 256-row hard cap\n * and the `submittedBefore` paging idiom.\n * - EC-15 (DOCUMENT): `JsonFileTaskStore` JSDoc documents the\n * single-process invariant; v0.2 SQLite covers cross-process.\n *\n * @internal\n */\n\nimport { mkdirSync, readdirSync } from \"node:fs\";\nimport { readFile, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { InvalidTaskIdError } from \"../../errors.js\";\nimport {\n isValidTaskId,\n type TaskFilter,\n type TaskHandle,\n type TaskState,\n type TaskStoreOptions,\n} from \"../../types/task.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { atomicWriteText } from \"../persistence/atomic-write.js\";\n\nconst JSON_LOAD_CAP = 256;\nconst DEFAULT_LIST_LIMIT = 100;\n\n/** Storage interface used by `TaskRegistry`. */\nexport interface TaskStore {\n insert(handle: TaskHandle): Promise<void>;\n update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined>;\n get(id: string): Promise<TaskHandle | undefined>;\n /**\n * Returns at most `filter.limit ?? 100` matching handles. JsonFile\n * backend hard-caps loaded entries at 256 — callers needing larger\n * pages must use `submittedBefore` to walk the timeline.\n */\n list(filter: TaskFilter): Promise<TaskHandle[]>;\n delete(id: string): Promise<boolean>;\n /** Removes terminal handles whose terminal-timestamp is older than `epochMs`. */\n evictTerminalOlderThan(epochMs: number): Promise<number>;\n}\n\nfunction assertValidIdForStore(id: string): void {\n if (!isValidTaskId(id, /* allowReserved */ true)) {\n throw new InvalidTaskIdError(`store rejects invalid task id: ${id}`, id);\n }\n}\n\nfunction terminalTimestamp(h: TaskHandle): number | undefined {\n if (h.state === \"finished\") return h.finishedAt;\n if (h.state === \"error\") return h.erroredAt;\n if (h.state === \"cancelled\") return h.cancelledAt;\n return undefined;\n}\n\nfunction isTerminal(state: TaskState): boolean {\n return state === \"finished\" || state === \"error\" || state === \"cancelled\";\n}\n\nfunction matchesState(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.state === undefined) return true;\n const states = Array.isArray(filter.state) ? filter.state : [filter.state];\n return states.includes(h.state);\n}\nfunction matchesKind(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.kind === undefined) return true;\n const kinds = Array.isArray(filter.kind) ? filter.kind : [filter.kind];\n return kinds.includes(h.kind);\n}\nfunction matchesTime(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.submittedAfter !== undefined && h.submittedAt <= filter.submittedAfter) return false;\n if (filter.submittedBefore !== undefined && h.submittedAt >= filter.submittedBefore) return false;\n return true;\n}\nfunction matchesFilter(h: TaskHandle, filter: TaskFilter): boolean {\n return matchesState(h, filter) && matchesKind(h, filter) && matchesTime(h, filter);\n}\n\nfunction applyFilter(values: Iterable<TaskHandle>, filter: TaskFilter): TaskHandle[] {\n const limit = filter.limit ?? DEFAULT_LIST_LIMIT;\n const out: TaskHandle[] = [];\n for (const h of values) {\n if (matchesFilter(h, filter)) {\n out.push(h);\n if (out.length >= limit) break;\n }\n }\n return out;\n}\n\n/* ─── InMemory ─── */\n\nexport class InMemoryTaskStore implements TaskStore {\n private readonly map = new Map<string, TaskHandle>();\n\n async insert(handle: TaskHandle): Promise<void> {\n assertValidIdForStore(handle.id);\n this.map.set(handle.id, handle);\n }\n\n async update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n const existing = this.map.get(id);\n if (existing === undefined) return undefined;\n const next = mutate(existing);\n this.map.set(id, next);\n return next;\n }\n\n async get(id: string): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n return this.map.get(id);\n }\n\n async list(filter: TaskFilter): Promise<TaskHandle[]> {\n return applyFilter(this.map.values(), filter);\n }\n\n async delete(id: string): Promise<boolean> {\n assertValidIdForStore(id);\n return this.map.delete(id);\n }\n\n async evictTerminalOlderThan(epochMs: number): Promise<number> {\n let count = 0;\n for (const [id, h] of this.map.entries()) {\n if (!isTerminal(h.state)) continue;\n const ts = terminalTimestamp(h);\n if (ts !== undefined && ts < epochMs) {\n this.map.delete(id);\n count++;\n }\n }\n return count;\n }\n}\n\n/* ─── JsonFile (opt-in) ───\n *\n * IMPORTANT (EC-15): `JsonFileTaskStore` is **single-process**.\n * Concurrent writers from multiple Node processes against the same\n * directory may corrupt entries (atomic-write protects per-file, but\n * the `list()` scan + `update()` read-modify-write cycle is not\n * serialised across processes). Use only when the `TaskRegistry`\n * runs in exactly one process. v0.2 will add a SQLite backend with\n * the same interface for cross-process scenarios (D364 + D61).\n */\nexport class JsonFileTaskStore implements TaskStore {\n constructor(private readonly dir: string) {\n // EC-1: idempotent mkdir; ignore EEXIST.\n try {\n mkdirSync(dir, { recursive: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n }\n }\n\n private filePath(id: string): string {\n return join(this.dir, `${id}.json`);\n }\n\n async insert(handle: TaskHandle): Promise<void> {\n assertValidIdForStore(handle.id);\n await atomicWriteText(this.filePath(handle.id), JSON.stringify(handle));\n }\n\n async update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n const existing = await this.get(id);\n if (existing === undefined) return undefined;\n const next = mutate(existing);\n await atomicWriteText(this.filePath(id), JSON.stringify(next));\n return next;\n }\n\n async get(id: string): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n try {\n const raw = await readFile(this.filePath(id), \"utf8\");\n return JSON.parse(raw) as TaskHandle;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") return undefined;\n // Corrupt JSON or other I/O error — log + degrade gracefully (D50/EC-7 cache pattern).\n diag(`[task-store] failed to read ${id}: ${(err as Error).message}\\n`);\n return undefined;\n }\n }\n\n async list(filter: TaskFilter): Promise<TaskHandle[]> {\n let entries: string[];\n try {\n entries = readdirSync(this.dir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return []; // EC-6\n throw err;\n }\n // EC-8: skip orphan .tmp files left by interrupted atomic writes.\n const candidates = entries\n .filter((name) => name.endsWith(\".json\") && !name.includes(\".tmp\"))\n .slice(0, JSON_LOAD_CAP);\n\n const loaded = await Promise.all(\n candidates.map(async (name) => {\n const id = name.slice(0, -\".json\".length);\n if (!isValidTaskId(id, true)) return undefined;\n return this.get(id);\n }),\n );\n const handles = loaded.filter((h): h is TaskHandle => h !== undefined);\n return applyFilter(handles, filter);\n }\n\n async delete(id: string): Promise<boolean> {\n assertValidIdForStore(id);\n try {\n await unlink(this.filePath(id));\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw err;\n }\n }\n\n async evictTerminalOlderThan(epochMs: number): Promise<number> {\n const handles = await this.list({ state: [\"finished\", \"error\", \"cancelled\"], limit: 256 });\n let count = 0;\n for (const h of handles) {\n const ts = terminalTimestamp(h);\n if (ts !== undefined && ts < epochMs) {\n if (await this.delete(h.id)) count++;\n }\n }\n return count;\n }\n}\n\n/** Factory used by `TaskRegistry.configure` (D364). */\nexport function getTaskStoreFor(options: TaskStoreOptions): TaskStore {\n if (options.backend === \"memory\") return new InMemoryTaskStore();\n return new JsonFileTaskStore(options.dir);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/task.ts","../src/internal/task/store.ts"],"names":[],"mappings":"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","file":"chunk-NOM2YWFP.js","sourcesContent":["/**\n * Public type contract for the Task observability registry (ADRs D361-D374).\n *\n * Tasks are an opt-in observability layer over async work in the SDK\n * (`Agent.send`, `Agent.batch`, `Workflow.run`, `Cron` fires). They have\n * a closed 5-state lifecycle (D362), discriminated events (D366), and a\n * pluggable store (D364). The `Task` facade in `task.ts` is the public\n * surface; consumers import these types from `@theokit/sdk`.\n *\n * @public\n */\n\n/**\n * Closed enum of the 5 lifecycle states (D362).\n *\n * Transitions are acyclic:\n * queued → running → (finished | error | cancelled)\n * queued → cancelled (direct, no run started)\n */\nexport type TaskState = \"queued\" | \"running\" | \"finished\" | \"error\" | \"cancelled\";\n\n/** Discriminator of the runtime that produced a task (D374). */\nexport type TaskKind = \"run\" | \"batch\" | \"workflow\" | \"cron\" | \"custom\";\n\n/** Discriminated union of task lifecycle events (D366). */\nexport type TaskEvent =\n | {\n readonly type: \"submitted\";\n readonly taskId: string;\n readonly kind: TaskKind;\n readonly submittedAt: number;\n readonly meta?: Record<string, unknown>;\n /** D372 — flag set on the first yielded event when the ring buffer was at cap. */\n readonly truncated?: boolean;\n }\n | { readonly type: \"started\"; readonly taskId: string; readonly startedAt: number }\n | {\n readonly type: \"progress\";\n readonly taskId: string;\n readonly at: number;\n readonly payload: unknown;\n }\n | {\n readonly type: \"finished\";\n readonly taskId: string;\n readonly finishedAt: number;\n readonly result: unknown;\n }\n | {\n readonly type: \"errored\";\n readonly taskId: string;\n readonly erroredAt: number;\n readonly error: { readonly code: string; readonly message: string };\n }\n | {\n readonly type: \"cancelled\";\n readonly taskId: string;\n readonly cancelledAt: number;\n readonly reason?: string;\n };\n\n/** Public read-only view of a task entry in the registry. */\nexport interface TaskHandle {\n readonly id: string;\n readonly kind: TaskKind;\n readonly state: TaskState;\n readonly submittedAt: number;\n readonly startedAt?: number;\n readonly finishedAt?: number;\n readonly cancelledAt?: number;\n readonly erroredAt?: number;\n readonly result?: unknown;\n readonly error?: { readonly code: string; readonly message: string };\n readonly meta?: Record<string, unknown>;\n /**\n * EC-7 — cross-process best-effort cancel flag. Set by CLI\n * `theokit tasks cancel` via JsonFileTaskStore. The owning process\n * polls at checkpoints and honors via AbortController. Always\n * `undefined` for in-process cancel paths (which go directly through\n * AbortController).\n */\n readonly cancelRequested?: boolean;\n}\n\n/** Query filter for `Task.list`. */\nexport interface TaskFilter {\n readonly state?: TaskState | readonly TaskState[];\n readonly kind?: TaskKind | readonly TaskKind[];\n readonly submittedAfter?: number;\n readonly submittedBefore?: number;\n /** Defaults to 100. JsonFileTaskStore hard-caps loaded entries at 256 (D364). */\n readonly limit?: number;\n}\n\n/** Options for `Task.submit`. */\nexport interface TaskSubmitOptions {\n /**\n * Optional user-supplied ID. Must match grammar `^[a-z0-9][a-z0-9_-]*$`\n * and MUST NOT start with the reserved prefixes `wf-` / `b-` / `cron-`\n * (D368, EC-5). When omitted, `crypto.randomUUID()` is used.\n */\n readonly id?: string;\n readonly meta?: Record<string, unknown>;\n /**\n * Optional caller-provided AbortSignal. If already aborted at submit\n * time, the registry short-circuits to `cancelled` without acquiring\n * a semaphore slot (EC-4).\n */\n readonly signal?: AbortSignal;\n /**\n * SE2 — an opt-in {@link import(\"./run-events.js\").RunEventSink}. The task's\n * lifecycle is forwarded to it as typed `task_started` / `task_updated` /\n * `task_completed` RunEvents, so a caller that spawned the task can observe it\n * through the same `onRunEvent` channel as the rest of the run. Best-effort (a\n * throwing sink never breaks the task). The dedicated `Task.subscribe(id)`\n * channel is unaffected.\n */\n readonly onRunEvent?: import(\"./run-events.js\").RunEventSink;\n}\n\n/** Options shape for `TaskStore` factory (D364). */\nexport type TaskStoreOptions =\n | { readonly backend: \"memory\" }\n | { readonly backend: \"json\"; readonly dir: string };\n\n/** Result of `Task.cancel` (D365 — idempotent). */\nexport interface TaskCancelResult {\n readonly cancelled: boolean;\n readonly alreadyTerminal: boolean;\n}\n\n/**\n * Grammar for user-supplied task IDs (D368).\n * `crypto.randomUUID()` outputs do NOT match this (UUIDs have dashes\n * AND uppercase letters in their canonical form on some Node versions),\n * but the registry normalizes auto-generated IDs to lowercase before\n * insertion, so they pass the same regex.\n */\nconst TASK_ID_GRAMMAR = /^[a-z0-9][a-z0-9_-]*$/;\n\n/** Reserved prefixes for adapter-generated IDs (D368, EC-5). */\nconst RESERVED_PREFIXES = [\"wf-\", \"b-\", \"cron-\"] as const;\n\n/**\n * Validates a task ID against the public grammar + reserved prefixes.\n * Throws `InvalidTaskIdError` from `../errors.js` on rejection.\n *\n * Adapter callers (workflow/batch/cron) MUST set `allowReserved: true`\n * to register their own IDs; user-facing surfaces (`Task.submit`,\n * `agent.send({ task: { id } })`) leave it false.\n */\nexport function isValidTaskId(id: string, allowReserved: boolean): boolean {\n if (!TASK_ID_GRAMMAR.test(id)) return false;\n if (allowReserved) return true;\n for (const prefix of RESERVED_PREFIXES) {\n if (id.startsWith(prefix)) return false;\n }\n return true;\n}\n\n/** Re-exported for adapter implementations + tests. */\nexport const TASK_RESERVED_PREFIXES: readonly string[] = RESERVED_PREFIXES;\n","/**\n * `TaskStore` interface + 2 implementations (ADR D364).\n *\n * - `InMemoryTaskStore` — default, transient, single-process.\n * - `JsonFileTaskStore` — opt-in, one JSON file per task under a\n * dedicated dir; single-process invariant (EC-15 documented).\n *\n * Edge cases absorbed:\n * - EC-1: constructor auto-creates dir (mkdirSync recursive idempotent).\n * - EC-2: every method validates the task id against the public\n * grammar (D368) BEFORE doing any path I/O — path-traversal defense.\n * - EC-6: `list()` returns `[]` on ENOENT (fresh install path).\n * - EC-8: `list()` skips `.tmp.*` orphan files left by interrupted\n * atomic writes.\n * - EC-14 (DOCUMENT): `list()` JSDoc documents the 256-row hard cap\n * and the `submittedBefore` paging idiom.\n * - EC-15 (DOCUMENT): `JsonFileTaskStore` JSDoc documents the\n * single-process invariant; v0.2 SQLite covers cross-process.\n *\n * @internal\n */\n\nimport { mkdirSync, readdirSync } from \"node:fs\";\nimport { readFile, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { InvalidTaskIdError } from \"../../errors.js\";\nimport {\n isValidTaskId,\n type TaskFilter,\n type TaskHandle,\n type TaskState,\n type TaskStoreOptions,\n} from \"../../types/task.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { atomicWriteText } from \"../persistence/atomic-write.js\";\n\nconst JSON_LOAD_CAP = 256;\nconst DEFAULT_LIST_LIMIT = 100;\n\n/** Storage interface used by `TaskRegistry`. */\nexport interface TaskStore {\n insert(handle: TaskHandle): Promise<void>;\n update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined>;\n get(id: string): Promise<TaskHandle | undefined>;\n /**\n * Returns at most `filter.limit ?? 100` matching handles. JsonFile\n * backend hard-caps loaded entries at 256 — callers needing larger\n * pages must use `submittedBefore` to walk the timeline.\n */\n list(filter: TaskFilter): Promise<TaskHandle[]>;\n delete(id: string): Promise<boolean>;\n /** Removes terminal handles whose terminal-timestamp is older than `epochMs`. */\n evictTerminalOlderThan(epochMs: number): Promise<number>;\n}\n\nfunction assertValidIdForStore(id: string): void {\n if (!isValidTaskId(id, /* allowReserved */ true)) {\n throw new InvalidTaskIdError(`store rejects invalid task id: ${id}`, id);\n }\n}\n\nfunction terminalTimestamp(h: TaskHandle): number | undefined {\n if (h.state === \"finished\") return h.finishedAt;\n if (h.state === \"error\") return h.erroredAt;\n if (h.state === \"cancelled\") return h.cancelledAt;\n return undefined;\n}\n\nfunction isTerminal(state: TaskState): boolean {\n return state === \"finished\" || state === \"error\" || state === \"cancelled\";\n}\n\nfunction matchesState(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.state === undefined) return true;\n const states = Array.isArray(filter.state) ? filter.state : [filter.state];\n return states.includes(h.state);\n}\nfunction matchesKind(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.kind === undefined) return true;\n const kinds = Array.isArray(filter.kind) ? filter.kind : [filter.kind];\n return kinds.includes(h.kind);\n}\nfunction matchesTime(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.submittedAfter !== undefined && h.submittedAt <= filter.submittedAfter) return false;\n if (filter.submittedBefore !== undefined && h.submittedAt >= filter.submittedBefore) return false;\n return true;\n}\nfunction matchesFilter(h: TaskHandle, filter: TaskFilter): boolean {\n return matchesState(h, filter) && matchesKind(h, filter) && matchesTime(h, filter);\n}\n\nfunction applyFilter(values: Iterable<TaskHandle>, filter: TaskFilter): TaskHandle[] {\n const limit = filter.limit ?? DEFAULT_LIST_LIMIT;\n const out: TaskHandle[] = [];\n for (const h of values) {\n if (matchesFilter(h, filter)) {\n out.push(h);\n if (out.length >= limit) break;\n }\n }\n return out;\n}\n\n/* ─── InMemory ─── */\n\nexport class InMemoryTaskStore implements TaskStore {\n private readonly map = new Map<string, TaskHandle>();\n\n async insert(handle: TaskHandle): Promise<void> {\n assertValidIdForStore(handle.id);\n this.map.set(handle.id, handle);\n }\n\n async update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n const existing = this.map.get(id);\n if (existing === undefined) return undefined;\n const next = mutate(existing);\n this.map.set(id, next);\n return next;\n }\n\n async get(id: string): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n return this.map.get(id);\n }\n\n async list(filter: TaskFilter): Promise<TaskHandle[]> {\n return applyFilter(this.map.values(), filter);\n }\n\n async delete(id: string): Promise<boolean> {\n assertValidIdForStore(id);\n return this.map.delete(id);\n }\n\n async evictTerminalOlderThan(epochMs: number): Promise<number> {\n let count = 0;\n for (const [id, h] of this.map.entries()) {\n if (!isTerminal(h.state)) continue;\n const ts = terminalTimestamp(h);\n if (ts !== undefined && ts < epochMs) {\n this.map.delete(id);\n count++;\n }\n }\n return count;\n }\n}\n\n/* ─── JsonFile (opt-in) ───\n *\n * IMPORTANT (EC-15): `JsonFileTaskStore` is **single-process**.\n * Concurrent writers from multiple Node processes against the same\n * directory may corrupt entries (atomic-write protects per-file, but\n * the `list()` scan + `update()` read-modify-write cycle is not\n * serialised across processes). Use only when the `TaskRegistry`\n * runs in exactly one process. v0.2 will add a SQLite backend with\n * the same interface for cross-process scenarios (D364 + D61).\n */\nexport class JsonFileTaskStore implements TaskStore {\n constructor(private readonly dir: string) {\n // EC-1: idempotent mkdir; ignore EEXIST.\n try {\n mkdirSync(dir, { recursive: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n }\n }\n\n private filePath(id: string): string {\n return join(this.dir, `${id}.json`);\n }\n\n async insert(handle: TaskHandle): Promise<void> {\n assertValidIdForStore(handle.id);\n await atomicWriteText(this.filePath(handle.id), JSON.stringify(handle));\n }\n\n async update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n const existing = await this.get(id);\n if (existing === undefined) return undefined;\n const next = mutate(existing);\n await atomicWriteText(this.filePath(id), JSON.stringify(next));\n return next;\n }\n\n async get(id: string): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n try {\n const raw = await readFile(this.filePath(id), \"utf8\");\n return JSON.parse(raw) as TaskHandle;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") return undefined;\n // Corrupt JSON or other I/O error — log + degrade gracefully (D50/EC-7 cache pattern).\n diag(`[task-store] failed to read ${id}: ${(err as Error).message}\\n`);\n return undefined;\n }\n }\n\n async list(filter: TaskFilter): Promise<TaskHandle[]> {\n let entries: string[];\n try {\n entries = readdirSync(this.dir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return []; // EC-6\n throw err;\n }\n // EC-8: skip orphan .tmp files left by interrupted atomic writes.\n const candidates = entries\n .filter((name) => name.endsWith(\".json\") && !name.includes(\".tmp\"))\n .slice(0, JSON_LOAD_CAP);\n\n const loaded = await Promise.all(\n candidates.map(async (name) => {\n const id = name.slice(0, -\".json\".length);\n if (!isValidTaskId(id, true)) return undefined;\n return this.get(id);\n }),\n );\n const handles = loaded.filter((h): h is TaskHandle => h !== undefined);\n return applyFilter(handles, filter);\n }\n\n async delete(id: string): Promise<boolean> {\n assertValidIdForStore(id);\n try {\n await unlink(this.filePath(id));\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw err;\n }\n }\n\n async evictTerminalOlderThan(epochMs: number): Promise<number> {\n const handles = await this.list({ state: [\"finished\", \"error\", \"cancelled\"], limit: 256 });\n let count = 0;\n for (const h of handles) {\n const ts = terminalTimestamp(h);\n if (ts !== undefined && ts < epochMs) {\n if (await this.delete(h.id)) count++;\n }\n }\n return count;\n }\n}\n\n/** Factory used by `TaskRegistry.configure` (D364). */\nexport function getTaskStoreFor(options: TaskStoreOptions): TaskStore {\n if (options.backend === \"memory\") return new InMemoryTaskStore();\n return new JsonFileTaskStore(options.dir);\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkJA4FEA5Z_cjs = require('./chunk-JA4FEA5Z.cjs');
|
|
4
|
+
var chunkWCXOKGOQ_cjs = require('./chunk-WCXOKGOQ.cjs');
|
|
5
|
+
var chunk6W4U2G3J_cjs = require('./chunk-6W4U2G3J.cjs');
|
|
6
6
|
var promises = require('fs/promises');
|
|
7
7
|
var path = require('path');
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ async function acquireShared(path) {
|
|
|
13
13
|
existing.refs++;
|
|
14
14
|
return createProxy(path);
|
|
15
15
|
}
|
|
16
|
-
const lease = await
|
|
16
|
+
const lease = await chunkJA4FEA5Z_cjs.acquireSessionWriter(path);
|
|
17
17
|
sharedLeases.set(path, { lease, refs: 1 });
|
|
18
18
|
return createProxy(path);
|
|
19
19
|
}
|
|
@@ -50,14 +50,14 @@ var FsSessionStore = class {
|
|
|
50
50
|
this.#cwd = options.cwd;
|
|
51
51
|
}
|
|
52
52
|
async readRecords(agentId) {
|
|
53
|
-
return
|
|
53
|
+
return chunkWCXOKGOQ_cjs.readTranscript(chunkWCXOKGOQ_cjs.transcriptPath(this.#baseDir, this.#cwd, agentId));
|
|
54
54
|
}
|
|
55
55
|
async appendRecords(agentId, records) {
|
|
56
56
|
if (records.length === 0) return;
|
|
57
|
-
const path$1 =
|
|
57
|
+
const path$1 = chunkWCXOKGOQ_cjs.transcriptPath(this.#baseDir, this.#cwd, agentId);
|
|
58
58
|
await promises.mkdir(path.dirname(path$1), { recursive: true });
|
|
59
|
-
await
|
|
60
|
-
for (const record of records)
|
|
59
|
+
await chunk6W4U2G3J_cjs.withFileLock(path$1, async () => {
|
|
60
|
+
for (const record of records) chunk6W4U2G3J_cjs.appendJsonl(path$1, record);
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
@@ -76,7 +76,7 @@ var FsSessionStore = class {
|
|
|
76
76
|
*/
|
|
77
77
|
async acquire(agentId) {
|
|
78
78
|
if (this.#leases.has(agentId)) return;
|
|
79
|
-
const path$1 =
|
|
79
|
+
const path$1 = chunkWCXOKGOQ_cjs.transcriptPath(this.#baseDir, this.#cwd, agentId);
|
|
80
80
|
await promises.mkdir(path.dirname(path$1), { recursive: true });
|
|
81
81
|
this.#leases.set(agentId, await acquireShared(path$1));
|
|
82
82
|
}
|
|
@@ -108,5 +108,5 @@ var FsSessionStore = class {
|
|
|
108
108
|
};
|
|
109
109
|
|
|
110
110
|
exports.FsSessionStore = FsSessionStore;
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
112
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-NRA36JKG.cjs.map
|
|
112
|
+
//# sourceMappingURL=chunk-NRA36JKG.cjs.map
|