@theokit/sdk 4.53.0 → 4.54.0
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 +1096 -8
- package/LICENSE +2 -2
- package/README.md +14 -9
- package/bin/theokit-migrate-config.mjs +11 -2
- package/dist/a2a/agent-mailbox.d.cts +27 -0
- package/dist/a2a/agent-mailbox.d.ts +27 -0
- package/dist/a2a/index.cjs +9 -4
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +7 -2
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/message-bus.d.cts +39 -0
- package/dist/a2a/message-bus.d.ts +39 -0
- package/dist/a2a/subagent.d.cts +68 -7
- package/dist/a2a/subagent.d.ts +68 -7
- package/dist/a2a/types.d.cts +26 -0
- package/dist/a2a/types.d.ts +26 -0
- package/dist/{agent-BiCINq25.d.ts → agent-CIUgz7cN.d.cts} +211 -858
- package/dist/{agent-Zta1kvGH.d.cts → agent-DSec-E0c.d.ts} +211 -858
- package/dist/agent-NOEGF4GI.cjs +61 -0
- package/dist/{agent-JX5SBYDE.cjs.map → agent-NOEGF4GI.cjs.map} +1 -1
- package/dist/agent-VGD5WL4N.js +52 -0
- package/dist/{agent-ZAGG6ZBS.js.map → agent-VGD5WL4N.js.map} +1 -1
- package/dist/agent-builder.d.ts +19 -0
- package/dist/agent-session-store-P6V3FINW.js +7 -0
- package/dist/{agent-session-store-JMU7ASDB.js.map → agent-session-store-P6V3FINW.js.map} +1 -1
- package/dist/agent-session-store-ZJ3JSRS4.cjs +24 -0
- package/dist/{agent-session-store-EPX2WQI4.cjs.map → agent-session-store-ZJ3JSRS4.cjs.map} +1 -1
- package/dist/agent.d.ts +25 -7
- package/dist/auth/index.cjs +53 -36
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.d.cts +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.js +27 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/{batch-NLIS4QTW.js → batch-2TGJMNCJ.js} +14 -13
- package/dist/batch-2TGJMNCJ.js.map +1 -0
- package/dist/{batch-WQ3AJCDV.cjs → batch-ND32UKZS.cjs} +31 -30
- package/dist/batch-ND32UKZS.cjs.map +1 -0
- package/dist/{chunk-TR4V2LHV.cjs → chunk-2ADR2GSO.cjs} +8 -8
- package/dist/chunk-2ADR2GSO.cjs.map +1 -0
- package/dist/{chunk-7HQVDLFI.cjs → chunk-2C72DXQF.cjs} +65 -27
- package/dist/chunk-2C72DXQF.cjs.map +1 -0
- package/dist/{chunk-DEZ75ET5.js → chunk-2D34UTDC.js} +21 -5
- package/dist/chunk-2D34UTDC.js.map +1 -0
- package/dist/{chunk-XGYI2KQH.js → chunk-2QKTVKH3.js} +4 -4
- package/dist/{chunk-XGYI2KQH.js.map → chunk-2QKTVKH3.js.map} +1 -1
- package/dist/{chunk-BBZYXVLZ.cjs → chunk-2ZPEDVLM.cjs} +2 -2
- package/dist/chunk-2ZPEDVLM.cjs.map +1 -0
- package/dist/{chunk-DHVNJYTO.js → chunk-3E77SX4H.js} +4 -4
- package/dist/{chunk-DHVNJYTO.js.map → chunk-3E77SX4H.js.map} +1 -1
- package/dist/{chunk-VYHJZVL5.cjs → chunk-3EE6LVWT.cjs} +2 -2
- package/dist/chunk-3EE6LVWT.cjs.map +1 -0
- package/dist/chunk-3KGLRRFC.cjs +18 -0
- package/dist/chunk-3KGLRRFC.cjs.map +1 -0
- package/dist/{chunk-5NBUH3NO.js → chunk-3OR54XG4.js} +2 -2
- package/dist/{chunk-C6Y6CWYD.cjs.map → chunk-3OR54XG4.js.map} +1 -1
- package/dist/{chunk-FUASIT3E.cjs → chunk-3YJNUKYN.cjs} +15 -15
- package/dist/{chunk-FUASIT3E.cjs.map → chunk-3YJNUKYN.cjs.map} +1 -1
- package/dist/{chunk-R7TKOQMJ.js → chunk-44JAAH4X.js} +3 -3
- package/dist/chunk-44JAAH4X.js.map +1 -0
- package/dist/{chunk-XRI6DXPZ.js → chunk-44MBDIHG.js} +4 -4
- package/dist/chunk-44MBDIHG.js.map +1 -0
- package/dist/{chunk-BXVSBYGW.js → chunk-4ERPXIVB.js} +5 -5
- package/dist/{chunk-BXVSBYGW.js.map → chunk-4ERPXIVB.js.map} +1 -1
- package/dist/{chunk-T6QUCG7L.cjs → chunk-4I55V454.cjs} +4 -4
- package/dist/chunk-4I55V454.cjs.map +1 -0
- package/dist/{chunk-B4YA6BRS.cjs → chunk-4O5TGQBW.cjs} +30 -7
- package/dist/chunk-4O5TGQBW.cjs.map +1 -0
- package/dist/{chunk-4JBHSLQO.cjs → chunk-4OTIXDMU.cjs} +2 -2
- package/dist/{chunk-4JBHSLQO.cjs.map → chunk-4OTIXDMU.cjs.map} +1 -1
- package/dist/{chunk-C6Y6CWYD.cjs → chunk-52NKC5HT.cjs} +2 -2
- package/dist/chunk-52NKC5HT.cjs.map +1 -0
- package/dist/{chunk-3YYDHUNH.cjs → chunk-53CBTBWO.cjs} +11 -11
- package/dist/{chunk-3YYDHUNH.cjs.map → chunk-53CBTBWO.cjs.map} +1 -1
- package/dist/{chunk-2QMK627M.cjs → chunk-5BJV5UPY.cjs} +27 -27
- package/dist/chunk-5BJV5UPY.cjs.map +1 -0
- package/dist/{chunk-OZXPA3ME.js → chunk-5JLFFPCH.js} +4 -4
- package/dist/{chunk-OZXPA3ME.js.map → chunk-5JLFFPCH.js.map} +1 -1
- package/dist/{chunk-34XOCZJO.js → chunk-5PHVENFV.js} +3 -3
- package/dist/chunk-5PHVENFV.js.map +1 -0
- package/dist/{chunk-EQMLJ52C.cjs → chunk-5UOVYM3P.cjs} +36 -31
- package/dist/chunk-5UOVYM3P.cjs.map +1 -0
- package/dist/{chunk-33L2NVTJ.cjs → chunk-5USCYPPI.cjs} +15 -15
- package/dist/chunk-5USCYPPI.cjs.map +1 -0
- package/dist/{chunk-I732VEDW.js → chunk-AEOZTXVW.js} +3 -3
- package/dist/{chunk-I732VEDW.js.map → chunk-AEOZTXVW.js.map} +1 -1
- package/dist/{chunk-5XXUYU3M.js → chunk-AG5JPQIY.js} +3 -3
- package/dist/{chunk-5XXUYU3M.js.map → chunk-AG5JPQIY.js.map} +1 -1
- package/dist/{chunk-3SHW7XKK.js → chunk-AGSBJD2L.js} +27 -29
- package/dist/chunk-AGSBJD2L.js.map +1 -0
- package/dist/{chunk-KZBB4YKU.js → chunk-AQLGBKNT.js} +3 -3
- package/dist/chunk-AQLGBKNT.js.map +1 -0
- package/dist/{chunk-7W7ZWMLQ.js → chunk-AWO27VRZ.js} +3 -3
- package/dist/chunk-AWO27VRZ.js.map +1 -0
- package/dist/{chunk-VYCKUKPA.cjs → chunk-B2J4ZMZL.cjs} +3 -2
- package/dist/chunk-B2J4ZMZL.cjs.map +1 -0
- package/dist/{chunk-UJ3SXRZZ.js → chunk-BMAZLQQ4.js} +3 -3
- package/dist/{chunk-UJ3SXRZZ.js.map → chunk-BMAZLQQ4.js.map} +1 -1
- package/dist/{chunk-NUEL6RCZ.cjs → chunk-BVZW2B5V.cjs} +4 -4
- package/dist/chunk-BVZW2B5V.cjs.map +1 -0
- package/dist/{chunk-W4FV7JBH.js → chunk-CQ2TQ32Y.js} +4 -4
- package/dist/chunk-CQ2TQ32Y.js.map +1 -0
- package/dist/{chunk-NFATC6ZF.cjs → chunk-CQGYNZ3K.cjs} +4 -4
- package/dist/{chunk-NFATC6ZF.cjs.map → chunk-CQGYNZ3K.cjs.map} +1 -1
- package/dist/{chunk-3R4ZCQAZ.cjs → chunk-CTCGWIUD.cjs} +5 -5
- package/dist/{chunk-3R4ZCQAZ.cjs.map → chunk-CTCGWIUD.cjs.map} +1 -1
- package/dist/{chunk-HTK54K2J.js → chunk-CV7XMBHP.js} +4 -4
- package/dist/chunk-CV7XMBHP.js.map +1 -0
- package/dist/{chunk-NOS7PTKP.js → chunk-DAPSQZT4.js} +15 -10
- package/dist/chunk-DAPSQZT4.js.map +1 -0
- package/dist/{chunk-E3OCRJU6.cjs → chunk-DQKERTND.cjs} +11 -11
- package/dist/{chunk-E3OCRJU6.cjs.map → chunk-DQKERTND.cjs.map} +1 -1
- package/dist/{chunk-I5OTK2RP.js → chunk-DUIF54UP.js} +6 -6
- package/dist/chunk-DUIF54UP.js.map +1 -0
- package/dist/{chunk-C4EU627W.js → chunk-DZBSJX6J.js} +4 -4
- package/dist/{chunk-C4EU627W.js.map → chunk-DZBSJX6J.js.map} +1 -1
- package/dist/{chunk-ADVZIC43.cjs → chunk-EI2Q7SJ5.cjs} +12 -12
- package/dist/chunk-EI2Q7SJ5.cjs.map +1 -0
- package/dist/{chunk-UCFONJBG.js → chunk-EPSICJLZ.js} +2 -2
- package/dist/{chunk-UCFONJBG.js.map → chunk-EPSICJLZ.js.map} +1 -1
- package/dist/{chunk-RAACTJ7C.cjs → chunk-F3YZMOAU.cjs} +8 -8
- package/dist/{chunk-RAACTJ7C.cjs.map → chunk-F3YZMOAU.cjs.map} +1 -1
- package/dist/{chunk-KIX45IKP.js → chunk-F7AQV62G.js} +5 -4
- package/dist/chunk-F7AQV62G.js.map +1 -0
- package/dist/{chunk-2YWWPCGX.js → chunk-FXEUP75G.js} +10 -12
- package/dist/chunk-FXEUP75G.js.map +1 -0
- package/dist/{chunk-2RW7K6FN.cjs → chunk-GHX4P3V2.cjs} +2 -2
- package/dist/chunk-GHX4P3V2.cjs.map +1 -0
- package/dist/{chunk-634YVZLU.js → chunk-GJ6RK75E.js} +5 -5
- package/dist/chunk-GJ6RK75E.js.map +1 -0
- package/dist/{chunk-Z5U2JGEK.cjs → chunk-GNT35C5U.cjs} +13 -13
- package/dist/chunk-GNT35C5U.cjs.map +1 -0
- package/dist/{chunk-4NAKHID5.js → chunk-GTKFV7O5.js} +2 -2
- package/dist/chunk-GTKFV7O5.js.map +1 -0
- package/dist/{chunk-BWGXYOBZ.cjs → chunk-GWC3HADL.cjs} +4 -4
- package/dist/{chunk-BWGXYOBZ.cjs.map → chunk-GWC3HADL.cjs.map} +1 -1
- package/dist/{chunk-OXNYIMZZ.js → chunk-H73MEMQB.js} +2 -2
- package/dist/chunk-H73MEMQB.js.map +1 -0
- package/dist/{chunk-RTLUZKDL.cjs → chunk-HJBMA5MB.cjs} +11 -11
- package/dist/{chunk-RTLUZKDL.cjs.map → chunk-HJBMA5MB.cjs.map} +1 -1
- package/dist/{chunk-AM2CNBKE.js → chunk-HKCKOAIO.js} +2 -2
- package/dist/chunk-HKCKOAIO.js.map +1 -0
- package/dist/{chunk-PVBANCWU.cjs → chunk-HY57ULY2.cjs} +5 -5
- package/dist/{chunk-PVBANCWU.cjs.map → chunk-HY57ULY2.cjs.map} +1 -1
- package/dist/{chunk-CAH3G4IS.js → chunk-HY66GLM6.js} +2 -2
- package/dist/chunk-HY66GLM6.js.map +1 -0
- package/dist/{chunk-2CFEET3Y.cjs → chunk-I6TGFUCO.cjs} +4 -4
- package/dist/chunk-I6TGFUCO.cjs.map +1 -0
- package/dist/{chunk-HI4ZW62S.js → chunk-IDCKSLYH.js} +4 -4
- package/dist/chunk-IDCKSLYH.js.map +1 -0
- package/dist/{chunk-KNZU4YO5.cjs → chunk-ILCGLTSA.cjs} +4 -4
- package/dist/{chunk-KNZU4YO5.cjs.map → chunk-ILCGLTSA.cjs.map} +1 -1
- package/dist/{chunk-44IISBRZ.cjs → chunk-IWBGCBR6.cjs} +4 -4
- package/dist/{chunk-44IISBRZ.cjs.map → chunk-IWBGCBR6.cjs.map} +1 -1
- package/dist/{chunk-R3CKCRK3.cjs → chunk-J24VJOH3.cjs} +22 -6
- package/dist/chunk-J24VJOH3.cjs.map +1 -0
- package/dist/{chunk-ECPL5RV6.cjs → chunk-JHPGF3FP.cjs} +8 -8
- package/dist/{chunk-ECPL5RV6.cjs.map → chunk-JHPGF3FP.cjs.map} +1 -1
- package/dist/{chunk-SXSPMRSV.cjs → chunk-JTB5Q42C.cjs} +21 -19
- package/dist/chunk-JTB5Q42C.cjs.map +1 -0
- package/dist/{chunk-2YGIBOUH.cjs → chunk-K3FW2XZD.cjs} +9 -9
- package/dist/chunk-K3FW2XZD.cjs.map +1 -0
- package/dist/{chunk-6DCTL32L.cjs → chunk-NGESVVJN.cjs} +17 -17
- package/dist/chunk-NGESVVJN.cjs.map +1 -0
- package/dist/{chunk-MV4TOCUK.js → chunk-NLTVXLGT.js} +3 -3
- package/dist/{chunk-MV4TOCUK.js.map → chunk-NLTVXLGT.js.map} +1 -1
- package/dist/chunk-NUKRL3I6.cjs +23 -0
- package/dist/chunk-NUKRL3I6.cjs.map +1 -0
- package/dist/{chunk-ZSJPRPN7.js → chunk-OC4NTGMN.js} +3 -3
- package/dist/{chunk-ZSJPRPN7.js.map → chunk-OC4NTGMN.js.map} +1 -1
- package/dist/{chunk-K42QGAKM.cjs → chunk-P6A3M6VD.cjs} +10 -10
- package/dist/{chunk-K42QGAKM.cjs.map → chunk-P6A3M6VD.cjs.map} +1 -1
- package/dist/{chunk-OKLYRPKL.cjs → chunk-Q47R5E2X.cjs} +8 -8
- package/dist/chunk-Q47R5E2X.cjs.map +1 -0
- package/dist/{chunk-2XLKLVVR.js → chunk-Q5EWJPRY.js} +2 -2
- package/dist/chunk-Q5EWJPRY.js.map +1 -0
- package/dist/{chunk-XWCTBGYK.js → chunk-QARJGQSA.js} +16 -7
- package/dist/chunk-QARJGQSA.js.map +1 -0
- package/dist/{chunk-EUBGGYPH.cjs → chunk-QDED6YO6.cjs} +5 -5
- package/dist/{chunk-EUBGGYPH.cjs.map → chunk-QDED6YO6.cjs.map} +1 -1
- package/dist/{chunk-VK7MAV65.cjs → chunk-QKLOP4VC.cjs} +2 -2
- package/dist/{chunk-VK7MAV65.cjs.map → chunk-QKLOP4VC.cjs.map} +1 -1
- package/dist/{chunk-PLUCC4N5.js → chunk-QRSUA2CV.js} +3 -3
- package/dist/{chunk-PLUCC4N5.js.map → chunk-QRSUA2CV.js.map} +1 -1
- package/dist/{chunk-YTO5BRBD.cjs → chunk-R3UPQFKK.cjs} +21 -12
- package/dist/chunk-R3UPQFKK.cjs.map +1 -0
- package/dist/{chunk-X2FR4OIT.js → chunk-R7WIIPUR.js} +2 -2
- package/dist/chunk-R7WIIPUR.js.map +1 -0
- package/dist/{chunk-BC5EUG7R.cjs → chunk-RM7Y65IG.cjs} +18 -20
- package/dist/chunk-RM7Y65IG.cjs.map +1 -0
- package/dist/{chunk-RP5HQVLD.js → chunk-RNB4APBZ.js} +30 -7
- package/dist/chunk-RNB4APBZ.js.map +1 -0
- package/dist/{chunk-V45L2OYP.cjs → chunk-ROYPRJH4.cjs} +9 -9
- package/dist/{chunk-V45L2OYP.cjs.map → chunk-ROYPRJH4.cjs.map} +1 -1
- package/dist/{chunk-JJZ4NIAG.js → chunk-RUDY2GTT.js} +61 -24
- package/dist/chunk-RUDY2GTT.js.map +1 -0
- package/dist/{chunk-QLAWEGTZ.cjs → chunk-SKXBJ2NU.cjs} +7 -7
- package/dist/chunk-SKXBJ2NU.cjs.map +1 -0
- package/dist/chunk-SSQZA3DZ.js +15 -0
- package/dist/chunk-SSQZA3DZ.js.map +1 -0
- package/dist/{chunk-7TB5U7RK.js → chunk-SUKXXLWD.js} +6 -6
- package/dist/chunk-SUKXXLWD.js.map +1 -0
- package/dist/{chunk-N43XLTHZ.js → chunk-T73NA43R.js} +3 -3
- package/dist/{chunk-N43XLTHZ.js.map → chunk-T73NA43R.js.map} +1 -1
- package/dist/chunk-T7O6K6PX.js +20 -0
- package/dist/chunk-T7O6K6PX.js.map +1 -0
- package/dist/{chunk-4X3SBHPK.js → chunk-T7XEKOVW.js} +18 -17
- package/dist/chunk-T7XEKOVW.js.map +1 -0
- package/dist/{chunk-NZOR3N4E.js → chunk-TPTZA6NI.js} +293 -126
- package/dist/chunk-TPTZA6NI.js.map +1 -0
- package/dist/{chunk-QN5N3ZVT.cjs → chunk-TTHBHAJI.cjs} +44 -46
- package/dist/chunk-TTHBHAJI.cjs.map +1 -0
- package/dist/{chunk-CZHPR2G7.cjs → chunk-U2AC6JUP.cjs} +8 -8
- package/dist/chunk-U2AC6JUP.cjs.map +1 -0
- package/dist/{chunk-ITQ4NO4P.js → chunk-UC3HT2S4.js} +3 -3
- package/dist/{chunk-ITQ4NO4P.js.map → chunk-UC3HT2S4.js.map} +1 -1
- package/dist/{chunk-2VFZQEDW.cjs → chunk-UFAO4T7Z.cjs} +565 -399
- package/dist/chunk-UFAO4T7Z.cjs.map +1 -0
- package/dist/{chunk-DM6Y5B2G.cjs → chunk-UNDROG5N.cjs} +201 -154
- package/dist/chunk-UNDROG5N.cjs.map +1 -0
- package/dist/{chunk-L7EGRCKJ.js → chunk-UPRJR6IP.js} +4 -4
- package/dist/chunk-UPRJR6IP.js.map +1 -0
- package/dist/{chunk-23VZBRDQ.js → chunk-UQGQFBRL.js} +3 -3
- package/dist/chunk-UQGQFBRL.js.map +1 -0
- package/dist/{chunk-2Y5NO2SY.js → chunk-VDEWG5TV.js} +88 -43
- package/dist/chunk-VDEWG5TV.js.map +1 -0
- package/dist/{chunk-CHVSMEKM.js → chunk-VF7EWVDG.js} +3 -3
- package/dist/chunk-VF7EWVDG.js.map +1 -0
- package/dist/{chunk-PNVDQL5Y.cjs → chunk-VTYY7XL5.cjs} +2 -2
- package/dist/chunk-VTYY7XL5.cjs.map +1 -0
- package/dist/{chunk-E6T264NS.js → chunk-WKRSH2VR.js} +3 -3
- package/dist/{chunk-E6T264NS.js.map → chunk-WKRSH2VR.js.map} +1 -1
- package/dist/{chunk-4QEC4CCS.js → chunk-WTMU7J4U.js} +2 -2
- package/dist/{chunk-4QEC4CCS.js.map → chunk-WTMU7J4U.js.map} +1 -1
- package/dist/{chunk-EFXJ5C7X.js → chunk-XN7NOENA.js} +6 -6
- package/dist/chunk-XN7NOENA.js.map +1 -0
- package/dist/{chunk-AMYY3JHQ.cjs → chunk-XSX2UU6Y.cjs} +10 -9
- package/dist/chunk-XSX2UU6Y.cjs.map +1 -0
- package/dist/{chunk-6PTCKXD3.js → chunk-XV4IZNV4.js} +9 -9
- package/dist/chunk-XV4IZNV4.js.map +1 -0
- package/dist/{chunk-FBZMSLDC.cjs → chunk-XWL6O3SW.cjs} +4 -4
- package/dist/chunk-XWL6O3SW.cjs.map +1 -0
- package/dist/{chunk-OIBHY6JQ.js → chunk-YMA4S2WO.js} +4 -4
- package/dist/{chunk-OIBHY6JQ.js.map → chunk-YMA4S2WO.js.map} +1 -1
- package/dist/{chunk-T5ZWI3MC.cjs → chunk-YPJ5NH5N.cjs} +11 -11
- package/dist/chunk-YPJ5NH5N.cjs.map +1 -0
- package/dist/{chunk-YLQQX5W2.cjs → chunk-ZF2LDKQQ.cjs} +2 -2
- package/dist/chunk-ZF2LDKQQ.cjs.map +1 -0
- package/dist/{chunk-L5YO6PWL.cjs → chunk-ZNW6V4Y6.cjs} +2 -2
- package/dist/chunk-ZNW6V4Y6.cjs.map +1 -0
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/theokit-client.d.cts +36 -0
- package/dist/client/theokit-client.d.ts +36 -0
- package/dist/client/types.d.cts +30 -0
- package/dist/client/types.d.ts +30 -0
- package/dist/compact-session-K5LXTBPJ.js +22 -0
- package/dist/{compact-session-EJ36VH5I.js.map → compact-session-K5LXTBPJ.js.map} +1 -1
- package/dist/compact-session-YCT6JMBX.cjs +59 -0
- package/dist/{compact-session-6GKIS4SD.cjs.map → compact-session-YCT6JMBX.cjs.map} +1 -1
- package/dist/compaction.cjs +17 -16
- package/dist/compaction.d.cts +13 -13
- package/dist/compaction.d.ts +13 -13
- package/dist/compaction.js +4 -3
- package/dist/concurrency.cjs +7 -6
- package/dist/concurrency.cjs.map +1 -1
- package/dist/concurrency.js +5 -4
- package/dist/concurrency.js.map +1 -1
- package/dist/context/index.cjs +7 -7
- package/dist/context/index.js +3 -3
- package/dist/context-FDOON2DB.js +6 -0
- package/dist/{context-DCECDKWN.js.map → context-FDOON2DB.js.map} +1 -1
- package/dist/context-VMIE4BMD.cjs +23 -0
- package/dist/{context-4HGPCOH6.cjs.map → context-VMIE4BMD.cjs.map} +1 -1
- package/dist/cron-CRwy2JBF.d.ts +240 -0
- package/dist/cron-DxxeQ-sK.d.cts +240 -0
- package/dist/cron.cjs +44 -42
- package/dist/cron.d.cts +5 -3
- package/dist/cron.d.ts +5 -3
- package/dist/cron.js +43 -41
- package/dist/define-tool.d.ts +14 -6
- package/dist/{errors-CHllybaU.d.ts → errors-BgJH9PHi.d.cts} +39 -24
- package/dist/{errors-BSoXcl3F.d.cts → errors-C5fJUqLk.d.ts} +39 -24
- package/dist/errors.cjs +22 -21
- package/dist/errors.d.cts +2 -2
- package/dist/errors.d.ts +2 -2
- package/dist/errors.js +3 -2
- package/dist/eval.cjs +62 -59
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.d.cts +38 -0
- package/dist/eval.d.ts +38 -0
- package/dist/eval.js +52 -49
- package/dist/eval.js.map +1 -1
- package/dist/event-bus.d.ts +16 -0
- package/dist/{executor-3CGPLVJL.js → executor-BMEHFOXZ.js} +8 -7
- package/dist/executor-BMEHFOXZ.js.map +1 -0
- package/dist/{executor-4SW7QGZ4.cjs → executor-ZERJ3DGN.cjs} +25 -24
- package/dist/executor-ZERJ3DGN.cjs.map +1 -0
- package/dist/filesystem/index.cjs +8 -7
- package/dist/filesystem/index.cjs.map +1 -1
- package/dist/filesystem/index.js +4 -3
- package/dist/filesystem/index.js.map +1 -1
- package/dist/filesystem/local-filesystem.d.cts +18 -0
- package/dist/filesystem/local-filesystem.d.ts +18 -0
- package/dist/filesystem/types.d.cts +12 -0
- package/dist/filesystem/types.d.ts +12 -0
- package/dist/fs-session-store-3MOJQGP2.cjs +20 -0
- package/dist/{fs-session-store-VXXDIBGM.cjs.map → fs-session-store-3MOJQGP2.cjs.map} +1 -1
- package/dist/fs-session-store-IN7JTTXD.js +11 -0
- package/dist/{fs-session-store-LIKYT24K.js.map → fs-session-store-IN7JTTXD.js.map} +1 -1
- package/dist/generate-object-N5MDZUJI.js +8 -0
- package/dist/{generate-object-TVQCW2IZ.js.map → generate-object-N5MDZUJI.js.map} +1 -1
- package/dist/generate-object-PGSP5U7N.cjs +21 -0
- package/dist/{generate-object-E465DX5I.cjs.map → generate-object-PGSP5U7N.cjs.map} +1 -1
- package/dist/generate-object.d.ts +20 -0
- package/dist/index-manager-NG5YENWO.cjs +22 -0
- package/dist/{index-manager-HGGL4DD5.cjs.map → index-manager-NG5YENWO.cjs.map} +1 -1
- package/dist/index-manager-ZMRJ6ZII.js +13 -0
- package/dist/{index-manager-EA6FGIQG.js.map → index-manager-ZMRJ6ZII.js.map} +1 -1
- package/dist/index.cjs +176 -154
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +761 -57
- package/dist/index.d.ts +761 -57
- package/dist/index.js +62 -59
- package/dist/index.js.map +1 -1
- package/dist/{inject-session-HO7FYVCX.js → inject-session-DDR6X6PC.js} +9 -8
- package/dist/inject-session-DDR6X6PC.js.map +1 -0
- package/dist/inject-session-XLO3KTBM.cjs +29 -0
- package/dist/inject-session-XLO3KTBM.cjs.map +1 -0
- package/dist/internal/auth/auth-types.d.ts +84 -2
- package/dist/internal/auth/credential-store.d.ts +34 -6
- package/dist/internal/auth/oauth-device.d.ts +2 -3
- package/dist/internal/auth/resolve-credential.d.ts +40 -0
- package/dist/internal/budget/tracker/budget.d.ts +12 -14
- package/dist/internal/budget/usage-accumulator.d.ts +15 -0
- package/dist/internal/llm/anthropic-shared.d.ts +8 -4
- package/dist/internal/llm/model-identifier.d.ts +26 -0
- package/dist/internal/llm/openai.d.ts +8 -0
- package/dist/internal/llm/router.d.ts +8 -0
- package/dist/internal/llm/types.d.ts +12 -1
- package/dist/internal/local-agent/mcp-pool.d.ts +2 -4
- package/dist/internal/local-agent/real-local-run-provider.d.ts +8 -3
- package/dist/internal/local-agent/real-local-run-tools.d.ts +8 -0
- package/dist/internal/mcp/oauth.d.ts +19 -1
- package/dist/internal/mcp/token-storage.d.ts +52 -1
- package/dist/internal/memory/adapters/index.cjs +12 -11
- package/dist/internal/memory/adapters/index.d.cts +3 -1
- package/dist/internal/memory/adapters/index.d.ts +3 -1
- package/dist/internal/memory/adapters/index.js +9 -8
- package/dist/internal/memory/adapters/openai-compatible.d.cts +45 -0
- package/dist/internal/memory/adapters/openai-compatible.d.ts +45 -0
- package/dist/internal/memory/embedding-cache.d.ts +42 -1
- package/dist/internal/memory/escape-like-pattern.d.ts +22 -0
- package/dist/internal/memory/sqlite-vec-loader.d.ts +1 -3
- package/dist/internal/memory/storage/markdown-store.d.ts +0 -5
- package/dist/internal/persistence/atomic-write.d.cts +93 -0
- package/dist/internal/persistence/atomic-write.d.ts +93 -0
- package/dist/internal/persistence/cwd-mutex.d.cts +34 -0
- package/dist/internal/persistence/cwd-mutex.d.ts +34 -0
- package/dist/internal/persistence/exclusive-create.d.cts +31 -0
- package/dist/internal/persistence/exclusive-create.d.ts +31 -0
- package/dist/internal/persistence/file-lock.d.cts +41 -1
- package/dist/internal/persistence/file-lock.d.ts +41 -1
- package/dist/internal/persistence/fs-session-store.d.cts +3 -0
- package/dist/internal/persistence/fs-session-store.d.ts +3 -0
- package/dist/internal/persistence/fts5-sanitize.d.cts +29 -1
- package/dist/internal/persistence/fts5-sanitize.d.ts +29 -1
- package/dist/internal/persistence/index.cjs +40 -39
- package/dist/internal/persistence/index.cjs.map +1 -1
- package/dist/internal/persistence/index.d.cts +6 -1
- package/dist/internal/persistence/index.d.ts +6 -1
- package/dist/internal/persistence/index.js +9 -8
- package/dist/internal/persistence/index.js.map +1 -1
- package/dist/internal/persistence/paths.d.cts +54 -1
- package/dist/internal/persistence/paths.d.ts +54 -1
- package/dist/internal/persistence/persistence-schema.d.cts +9 -1
- package/dist/internal/persistence/persistence-schema.d.ts +9 -1
- package/dist/internal/persistence/schema-version.d.cts +215 -1
- package/dist/internal/persistence/schema-version.d.ts +215 -1
- package/dist/internal/persistence/session-dir.d.cts +1 -0
- package/dist/internal/persistence/session-dir.d.ts +1 -0
- package/dist/internal/persistence/session-writer.d.cts +20 -7
- package/dist/internal/persistence/session-writer.d.ts +20 -7
- package/dist/internal/persistence/sqlite-cas.d.cts +37 -1
- package/dist/internal/persistence/sqlite-cas.d.ts +37 -1
- package/dist/internal/persistence/sqlite-open.d.cts +14 -0
- package/dist/internal/persistence/sqlite-open.d.ts +14 -0
- package/dist/internal/persistence/sqlite-wal.d.cts +53 -0
- package/dist/internal/persistence/sqlite-wal.d.ts +53 -0
- package/dist/internal/persistence/transcript-ops.d.cts +7 -1
- package/dist/internal/persistence/transcript-ops.d.ts +7 -1
- package/dist/internal/plugins/types.d.cts +1 -1
- package/dist/internal/plugins/types.d.ts +1 -1
- package/dist/internal/providers/builtin/cerebras.d.ts +2 -2
- package/dist/internal/providers/builtin/deepinfra.d.ts +1 -1
- package/dist/internal/providers/builtin/openai-chatgpt.d.ts +12 -0
- package/dist/internal/providers/catalog-loader.d.ts +8 -0
- package/dist/internal/providers/catalog-schema.d.ts +55 -0
- package/dist/internal/providers/catalog-source-models-dev.d.ts +37 -1
- package/dist/internal/runtime/concurrency/delegation-depth.d.ts +27 -0
- package/dist/internal/runtime/concurrency/subagent-credentials.d.ts +33 -1
- package/dist/internal/runtime/context/context-discovery-runner.d.ts +44 -0
- package/dist/internal/runtime/context/context-discovery.d.ts +58 -0
- package/dist/internal/runtime/context/context-rules-frontmatter.d.ts +70 -1
- package/dist/internal/runtime/fixtures/fixture-mode.d.ts +15 -1
- package/dist/internal/runtime/lifecycle/env-policy.d.ts +1 -3
- package/dist/internal/runtime/lifecycle/post-run-lifecycle.d.ts +15 -0
- package/dist/internal/runtime/registry/agent-registry-store.d.ts +12 -0
- package/dist/internal/runtime/registry/live-agent-registry.d.ts +37 -0
- package/dist/internal/scorers/llm-judge.d.ts +6 -1
- package/dist/internal/security/index.cjs +14 -13
- package/dist/internal/security/index.d.cts +4 -1
- package/dist/internal/security/index.d.ts +4 -1
- package/dist/internal/security/index.js +4 -3
- package/dist/internal/security/path-guard.d.cts +107 -0
- package/dist/internal/security/path-guard.d.ts +107 -0
- package/dist/internal/security/redact.d.cts +71 -0
- package/dist/internal/security/redact.d.ts +71 -0
- package/dist/internal/session/agent-session.d.ts +15 -4
- package/dist/internal/session/compact-session.d.ts +2 -2
- package/dist/internal/session/session-cache.d.ts +5 -0
- package/dist/internal/task/store.d.ts +91 -5
- package/dist/internal/telemetry/span-names.d.ts +0 -1
- package/dist/internal/telemetry/tracer.d.ts +38 -0
- package/dist/job-queue.d.ts +18 -0
- package/dist/judge-call-DWHAJATE.js +6 -0
- package/dist/{judge-call-QMKGC2ZK.js.map → judge-call-DWHAJATE.js.map} +1 -1
- package/dist/judge-call-EGYRC2RE.cjs +23 -0
- package/dist/{judge-call-GVIJWQVE.cjs.map → judge-call-EGYRC2RE.cjs.map} +1 -1
- package/dist/mcp-auth.cjs +41 -25
- package/dist/mcp-auth.cjs.map +1 -1
- package/dist/mcp-auth.js +34 -18
- package/dist/mcp-auth.js.map +1 -1
- package/dist/models.cjs +43 -28
- package/dist/models.cjs.map +1 -1
- package/dist/models.js +26 -11
- package/dist/models.js.map +1 -1
- package/dist/oauth-transaction-store-BT4GLTLK.cjs +36 -0
- package/dist/{oauth-transaction-store-7CKHPQRN.cjs.map → oauth-transaction-store-BT4GLTLK.cjs.map} +1 -1
- package/dist/oauth-transaction-store-W52KVHQ4.js +3 -0
- package/dist/{oauth-transaction-store-W74I6EFD.js.map → oauth-transaction-store-W52KVHQ4.js.map} +1 -1
- package/dist/path-safety.cjs +11 -10
- package/dist/path-safety.js +4 -3
- package/dist/permission-engine.d.ts +55 -0
- package/dist/persistence.cjs +43 -42
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.js +13 -12
- package/dist/persistence.js.map +1 -1
- package/dist/project.cjs +9 -8
- package/dist/project.cjs.map +1 -1
- package/dist/project.js +5 -4
- package/dist/project.js.map +1 -1
- package/dist/providers.cjs +23 -0
- package/dist/providers.cjs.map +1 -0
- package/dist/providers.d.cts +29 -0
- package/dist/providers.d.ts +29 -0
- package/dist/providers.js +10 -0
- package/dist/providers.js.map +1 -0
- package/dist/registry-VFKX7WOP.cjs +47 -0
- package/dist/{registry-UBY26R4I.cjs.map → registry-VFKX7WOP.cjs.map} +1 -1
- package/dist/registry-VFP3WWQP.js +10 -0
- package/dist/{registry-GC7BQMSV.js.map → registry-VFP3WWQP.js.map} +1 -1
- package/dist/retry.cjs +5 -4
- package/dist/retry.js +4 -3
- package/dist/{run-C8FBAC8o.d.ts → run-BYSHf58D.d.cts} +185 -33
- package/dist/{run-C8FBAC8o.d.cts → run-BYSHf58D.d.ts} +185 -33
- package/dist/{run-to-completion-JDPIUKSH.js → run-to-completion-DRO77625.js} +3 -3
- package/dist/{run-to-completion-JDPIUKSH.js.map → run-to-completion-DRO77625.js.map} +1 -1
- package/dist/{run-to-completion-J73I6IY4.cjs → run-to-completion-X4OWM673.cjs} +13 -13
- package/dist/{run-to-completion-J73I6IY4.cjs.map → run-to-completion-X4OWM673.cjs.map} +1 -1
- package/dist/sandbox/bwrap.d.cts +27 -14
- package/dist/sandbox/bwrap.d.ts +27 -14
- package/dist/sandbox/index.cjs +21 -20
- package/dist/sandbox/index.cjs.map +1 -1
- package/dist/sandbox/index.js +6 -5
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/linux-sandbox.d.cts +72 -0
- package/dist/sandbox/linux-sandbox.d.ts +72 -0
- package/dist/sandbox/local-sandbox.d.cts +41 -0
- package/dist/sandbox/local-sandbox.d.ts +41 -0
- package/dist/sandbox/seccomp.d.cts +6 -0
- package/dist/sandbox/seccomp.d.ts +6 -0
- package/dist/sandbox/types.d.cts +64 -0
- package/dist/sandbox/types.d.ts +64 -0
- package/dist/scorers.d.ts +38 -7
- package/dist/sdk-agent-D8qJVkuV.d.ts +860 -0
- package/dist/sdk-agent-DEoKhA8a.d.cts +860 -0
- package/dist/server/auth/errors.d.cts +1 -1
- package/dist/server/auth/errors.d.ts +1 -1
- package/dist/server/auth/index.cjs +29 -21
- package/dist/server/auth/index.cjs.map +1 -1
- package/dist/server/auth/index.d.cts +25 -15
- package/dist/server/auth/index.d.ts +25 -15
- package/dist/server/auth/index.js +15 -7
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/auth/oauth-transaction-store.d.cts +13 -1
- package/dist/server/auth/oauth-transaction-store.d.ts +13 -1
- package/dist/server/auth/orchestrator.d.cts +1 -1
- package/dist/server/auth/orchestrator.d.ts +1 -1
- package/dist/server/auth/types.d.cts +1 -1
- package/dist/server/auth/types.d.ts +1 -1
- package/dist/server/auth/validate-return-to.d.cts +21 -11
- package/dist/server/auth/validate-return-to.d.ts +21 -11
- package/dist/server/errors-envelope.cjs +15 -14
- package/dist/server/errors-envelope.cjs.map +1 -1
- package/dist/server/errors-envelope.d.cts +4 -4
- package/dist/server/errors-envelope.d.ts +4 -4
- package/dist/server/errors-envelope.js +4 -3
- package/dist/server/errors-envelope.js.map +1 -1
- package/dist/session-transcript-AKDYYGXQ.js +6 -0
- package/dist/{session-transcript-SKIRBEJE.js.map → session-transcript-AKDYYGXQ.js.map} +1 -1
- package/dist/session-transcript-JXHFTB7G.cjs +51 -0
- package/dist/{session-transcript-TNAJ4O3M.cjs.map → session-transcript-JXHFTB7G.cjs.map} +1 -1
- package/dist/skills.cjs +8 -7
- package/dist/skills.js +6 -5
- package/dist/stream-object-BUCF5PHO.cjs +21 -0
- package/dist/{stream-object-T4DAMNVB.cjs.map → stream-object-BUCF5PHO.cjs.map} +1 -1
- package/dist/stream-object-L57K4OFS.js +8 -0
- package/dist/{stream-object-QMNR3YFF.js.map → stream-object-L57K4OFS.js.map} +1 -1
- package/dist/{stream-to-completion-DFJ5T3BK.js → stream-to-completion-QV5HCL3J.js} +3 -3
- package/dist/{stream-to-completion-DFJ5T3BK.js.map → stream-to-completion-QV5HCL3J.js.map} +1 -1
- package/dist/{stream-to-completion-H2MHISSK.cjs → stream-to-completion-SRISU5AB.cjs} +10 -10
- package/dist/{stream-to-completion-H2MHISSK.cjs.map → stream-to-completion-SRISU5AB.cjs.map} +1 -1
- package/dist/subagents-loader-AZIXJ7D3.cjs +16 -0
- package/dist/{subagents-loader-3CXBQWWY.cjs.map → subagents-loader-AZIXJ7D3.cjs.map} +1 -1
- package/dist/subagents-loader-J54ESLDV.js +7 -0
- package/dist/{subagents-loader-WN2SB6PV.js.map → subagents-loader-J54ESLDV.js.map} +1 -1
- package/dist/subagents-loader.cjs +7 -6
- package/dist/subagents-loader.cjs.map +1 -1
- package/dist/subagents-loader.d.cts +3 -2
- package/dist/subagents-loader.d.ts +3 -2
- package/dist/subagents-loader.js +5 -4
- package/dist/subagents-loader.js.map +1 -1
- package/dist/subscription/define-subscription.d.cts +1 -1
- package/dist/subscription/define-subscription.d.ts +1 -1
- package/dist/subscription/index.cjs +22 -9
- package/dist/subscription/index.cjs.map +1 -1
- package/dist/subscription/index.d.cts +1 -1
- package/dist/subscription/index.d.ts +1 -1
- package/dist/subscription/index.js +21 -8
- package/dist/subscription/index.js.map +1 -1
- package/dist/subscription/internal/adapter-types.d.cts +1 -1
- package/dist/subscription/internal/adapter-types.d.ts +1 -1
- package/dist/subscription/internal/server-integration.d.cts +1 -1
- package/dist/subscription/internal/server-integration.d.ts +1 -1
- package/dist/subscription/internal/sse-encoder.d.cts +1 -1
- package/dist/subscription/internal/sse-encoder.d.ts +1 -1
- package/dist/subscription/internal/sse-parser.d.cts +1 -1
- package/dist/subscription/internal/sse-parser.d.ts +1 -1
- package/dist/subscription/internal/subscription-runtime.d.cts +1 -1
- package/dist/subscription/internal/subscription-runtime.d.ts +1 -1
- package/dist/subscription/internal/ws-adapter-node.d.cts +1 -1
- package/dist/subscription/internal/ws-adapter-node.d.ts +1 -1
- package/dist/subscription/theokit-subscribe.d.cts +14 -1
- package/dist/subscription/theokit-subscribe.d.ts +14 -1
- package/dist/subscription/types.d.cts +19 -1
- package/dist/subscription/types.d.ts +19 -1
- package/dist/task-store.cjs +8 -7
- package/dist/task-store.js +5 -4
- package/dist/types/agent-prims.d.ts +14 -0
- package/dist/types/agent.d.ts +69 -17
- package/dist/types/batch.d.ts +7 -1
- package/dist/types/conversation.d.ts +18 -5
- package/dist/types/goal-events.d.ts +4 -8
- package/dist/types/memory-adapter.d.ts +12 -1
- package/dist/types/plugin.d.ts +101 -0
- package/dist/types/provider-profile.d.ts +21 -2
- package/dist/types/run-events.d.ts +28 -1
- package/dist/types/run.d.ts +35 -23
- package/dist/types/sdk-agent.d.ts +14 -0
- package/dist/types/session-record.d.ts +18 -1
- package/dist/types/task.d.ts +15 -1
- package/dist/types/theokit.d.ts +10 -1
- package/dist/types/updates.d.ts +35 -4
- package/dist/types/workflow.d.ts +155 -0
- package/dist/workflow.cjs +29 -28
- package/dist/workflow.d.cts +666 -17
- package/dist/workflow.d.ts +666 -17
- package/dist/workflow.js +8 -7
- package/docs/error-codes.md +208 -172
- package/docs/harness-capability-map.md +1357 -304
- package/package.json +21 -8
- package/bin/init-claude.mjs +0 -68
- package/claude-template/AGENTS.md +0 -157
- package/claude-template/CLAUDE.md +0 -66
- package/claude-template/dot-claude/rules/theokit-conventions.md +0 -32
- package/claude-template/dot-claude/settings.json +0 -16
- package/claude-template/dot-claude/skills/theokit-agent-core/SKILL.md +0 -209
- package/claude-template/dot-claude/skills/theokit-auth/SKILL.md +0 -102
- package/claude-template/dot-claude/skills/theokit-budget/SKILL.md +0 -176
- package/claude-template/dot-claude/skills/theokit-client/SKILL.md +0 -58
- package/claude-template/dot-claude/skills/theokit-compaction/SKILL.md +0 -102
- package/claude-template/dot-claude/skills/theokit-concurrency/SKILL.md +0 -68
- package/claude-template/dot-claude/skills/theokit-config/SKILL.md +0 -139
- package/claude-template/dot-claude/skills/theokit-cron/SKILL.md +0 -148
- package/claude-template/dot-claude/skills/theokit-di/SKILL.md +0 -233
- package/claude-template/dot-claude/skills/theokit-di-agent/SKILL.md +0 -294
- package/claude-template/dot-claude/skills/theokit-errors/SKILL.md +0 -172
- package/claude-template/dot-claude/skills/theokit-eval/SKILL.md +0 -179
- package/claude-template/dot-claude/skills/theokit-filesystem/SKILL.md +0 -74
- package/claude-template/dot-claude/skills/theokit-gateways/SKILL.md +0 -209
- package/claude-template/dot-claude/skills/theokit-memory/SKILL.md +0 -176
- package/claude-template/dot-claude/skills/theokit-messages/SKILL.md +0 -58
- package/claude-template/dot-claude/skills/theokit-models/SKILL.md +0 -79
- package/claude-template/dot-claude/skills/theokit-path-safety/SKILL.md +0 -60
- package/claude-template/dot-claude/skills/theokit-persistence/SKILL.md +0 -85
- package/claude-template/dot-claude/skills/theokit-project/SKILL.md +0 -55
- package/claude-template/dot-claude/skills/theokit-retry/SKILL.md +0 -50
- package/claude-template/dot-claude/skills/theokit-sandbox/SKILL.md +0 -93
- package/claude-template/dot-claude/skills/theokit-sanitize/SKILL.md +0 -66
- package/claude-template/dot-claude/skills/theokit-skills/SKILL.md +0 -68
- package/claude-template/dot-claude/skills/theokit-streaming/SKILL.md +0 -156
- package/claude-template/dot-claude/skills/theokit-subagents/SKILL.md +0 -109
- package/claude-template/dot-claude/skills/theokit-subscriptions/SKILL.md +0 -148
- package/claude-template/dot-claude/skills/theokit-task-store/SKILL.md +0 -75
- package/claude-template/dot-claude/skills/theokit-tools/SKILL.md +0 -170
- package/claude-template/dot-claude/skills/theokit-workflows/SKILL.md +0 -218
- package/dist/agent-JX5SBYDE.cjs +0 -59
- package/dist/agent-ZAGG6ZBS.js +0 -50
- package/dist/agent-session-store-EPX2WQI4.cjs +0 -23
- package/dist/agent-session-store-JMU7ASDB.js +0 -6
- package/dist/batch-NLIS4QTW.js.map +0 -1
- package/dist/batch-WQ3AJCDV.cjs.map +0 -1
- package/dist/chunk-23VZBRDQ.js.map +0 -1
- package/dist/chunk-2CFEET3Y.cjs.map +0 -1
- package/dist/chunk-2QMK627M.cjs.map +0 -1
- package/dist/chunk-2RW7K6FN.cjs.map +0 -1
- package/dist/chunk-2VFZQEDW.cjs.map +0 -1
- package/dist/chunk-2XLKLVVR.js.map +0 -1
- package/dist/chunk-2Y5NO2SY.js.map +0 -1
- package/dist/chunk-2YGIBOUH.cjs.map +0 -1
- package/dist/chunk-2YWWPCGX.js.map +0 -1
- package/dist/chunk-33L2NVTJ.cjs.map +0 -1
- package/dist/chunk-34XOCZJO.js.map +0 -1
- package/dist/chunk-3SHW7XKK.js.map +0 -1
- package/dist/chunk-4NAKHID5.js.map +0 -1
- package/dist/chunk-4X3SBHPK.js.map +0 -1
- package/dist/chunk-5NBUH3NO.js.map +0 -1
- package/dist/chunk-634YVZLU.js.map +0 -1
- package/dist/chunk-6DCTL32L.cjs.map +0 -1
- package/dist/chunk-6PTCKXD3.js.map +0 -1
- package/dist/chunk-7HQVDLFI.cjs.map +0 -1
- package/dist/chunk-7TB5U7RK.js.map +0 -1
- package/dist/chunk-7W7ZWMLQ.js.map +0 -1
- package/dist/chunk-ADVZIC43.cjs.map +0 -1
- package/dist/chunk-AM2CNBKE.js.map +0 -1
- package/dist/chunk-AMYY3JHQ.cjs.map +0 -1
- package/dist/chunk-B4YA6BRS.cjs.map +0 -1
- package/dist/chunk-BBZYXVLZ.cjs.map +0 -1
- package/dist/chunk-BC5EUG7R.cjs.map +0 -1
- package/dist/chunk-CAH3G4IS.js.map +0 -1
- package/dist/chunk-CHVSMEKM.js.map +0 -1
- package/dist/chunk-CZHPR2G7.cjs.map +0 -1
- package/dist/chunk-DEZ75ET5.js.map +0 -1
- package/dist/chunk-DM6Y5B2G.cjs.map +0 -1
- package/dist/chunk-EFXJ5C7X.js.map +0 -1
- package/dist/chunk-EQMLJ52C.cjs.map +0 -1
- package/dist/chunk-FBZMSLDC.cjs.map +0 -1
- package/dist/chunk-HI4ZW62S.js.map +0 -1
- package/dist/chunk-HTK54K2J.js.map +0 -1
- package/dist/chunk-I5OTK2RP.js.map +0 -1
- package/dist/chunk-JJZ4NIAG.js.map +0 -1
- package/dist/chunk-KIX45IKP.js.map +0 -1
- package/dist/chunk-KZBB4YKU.js.map +0 -1
- package/dist/chunk-L5YO6PWL.cjs.map +0 -1
- package/dist/chunk-L7EGRCKJ.js.map +0 -1
- package/dist/chunk-NOS7PTKP.js.map +0 -1
- package/dist/chunk-NUEL6RCZ.cjs.map +0 -1
- package/dist/chunk-NZOR3N4E.js.map +0 -1
- package/dist/chunk-OKLYRPKL.cjs.map +0 -1
- package/dist/chunk-OXNYIMZZ.js.map +0 -1
- package/dist/chunk-PNVDQL5Y.cjs.map +0 -1
- package/dist/chunk-QLAWEGTZ.cjs.map +0 -1
- package/dist/chunk-QN5N3ZVT.cjs.map +0 -1
- package/dist/chunk-R3CKCRK3.cjs.map +0 -1
- package/dist/chunk-R7TKOQMJ.js.map +0 -1
- package/dist/chunk-RP5HQVLD.js.map +0 -1
- package/dist/chunk-SXSPMRSV.cjs.map +0 -1
- package/dist/chunk-T5ZWI3MC.cjs.map +0 -1
- package/dist/chunk-T6QUCG7L.cjs.map +0 -1
- package/dist/chunk-TR4V2LHV.cjs.map +0 -1
- package/dist/chunk-VYCKUKPA.cjs.map +0 -1
- package/dist/chunk-VYHJZVL5.cjs.map +0 -1
- package/dist/chunk-W4FV7JBH.js.map +0 -1
- package/dist/chunk-X2FR4OIT.js.map +0 -1
- package/dist/chunk-XRI6DXPZ.js.map +0 -1
- package/dist/chunk-XWCTBGYK.js.map +0 -1
- package/dist/chunk-YLQQX5W2.cjs.map +0 -1
- package/dist/chunk-YTO5BRBD.cjs.map +0 -1
- package/dist/chunk-Z5U2JGEK.cjs.map +0 -1
- package/dist/compact-session-6GKIS4SD.cjs +0 -58
- package/dist/compact-session-EJ36VH5I.js +0 -21
- package/dist/context-4HGPCOH6.cjs +0 -22
- package/dist/context-DCECDKWN.js +0 -5
- package/dist/cron-DgHJnMAK.d.cts +0 -631
- package/dist/cron-DyWQsEG6.d.ts +0 -631
- package/dist/executor-3CGPLVJL.js.map +0 -1
- package/dist/executor-4SW7QGZ4.cjs.map +0 -1
- package/dist/fs-session-store-LIKYT24K.js +0 -10
- package/dist/fs-session-store-VXXDIBGM.cjs +0 -19
- package/dist/generate-object-E465DX5I.cjs +0 -20
- package/dist/generate-object-TVQCW2IZ.js +0 -7
- package/dist/index-manager-EA6FGIQG.js +0 -12
- package/dist/index-manager-HGGL4DD5.cjs +0 -21
- package/dist/inject-session-67SF65FC.cjs +0 -28
- package/dist/inject-session-67SF65FC.cjs.map +0 -1
- package/dist/inject-session-HO7FYVCX.js.map +0 -1
- package/dist/judge-call-GVIJWQVE.cjs +0 -22
- package/dist/judge-call-QMKGC2ZK.js +0 -5
- package/dist/oauth-transaction-store-7CKHPQRN.cjs +0 -32
- package/dist/oauth-transaction-store-W74I6EFD.js +0 -3
- package/dist/registry-GC7BQMSV.js +0 -9
- package/dist/registry-UBY26R4I.cjs +0 -46
- package/dist/session-transcript-SKIRBEJE.js +0 -5
- package/dist/session-transcript-TNAJ4O3M.cjs +0 -50
- package/dist/stream-object-QMNR3YFF.js +0 -7
- package/dist/stream-object-T4DAMNVB.cjs +0 -20
- package/dist/subagents-loader-3CXBQWWY.cjs +0 -15
- package/dist/subagents-loader-WN2SB6PV.js +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,1093 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.54.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0258f3c: Two `theokit` flags that were advertised in `--help` and read by nothing now behave.
|
|
8
|
+
|
|
9
|
+
`tasks cancel --reason <r>` records the reason: `TaskHandle` gains a `cancelReason` field, written
|
|
10
|
+
alongside `cancelledAt` for a queued task and alongside `cancelRequested` for a running one. A task
|
|
11
|
+
that is already terminal is left untouched, reason or not.
|
|
12
|
+
|
|
13
|
+
**Breaking:** `theokit init --here` is removed. It never scaffolded into the current directory, and
|
|
14
|
+
the writer cannot honour it — the tree is built in a temp directory and moved into place with `rm` +
|
|
15
|
+
`rename`, so a destination equal to `cwd` would mean deleting the directory the process is running
|
|
16
|
+
in. An unknown-option error is immediate and clear where silence was not.
|
|
17
|
+
|
|
18
|
+
- d485b4e: Fix three unresolved type references in the published declaration file (#335).
|
|
19
|
+
|
|
20
|
+
`MemoryProviderFactory` is now exported from the package root. It is the shape a
|
|
21
|
+
consumer must satisfy to write a memory plugin — the public `Plugin` union names
|
|
22
|
+
it in the `createProvider` position — but it carried the internal-visibility
|
|
23
|
+
JSDoc tag, so `stripInternal` deleted the declaration while the union went on
|
|
24
|
+
referencing it. The shipped `.d.ts` named a type it did not declare.
|
|
25
|
+
|
|
26
|
+
`AgentBuilderDeps` and the blast-radius symbol used as a computed key in
|
|
27
|
+
`WithBlastRadius<T>` had the same defect on other surfaces and are now emitted.
|
|
28
|
+
Neither is added to the public API — they only needed to exist in the declaration
|
|
29
|
+
file that references them.
|
|
30
|
+
|
|
31
|
+
None of this is visible under `skipLibCheck`, which is why it shipped. Consumers
|
|
32
|
+
running type-aware lint saw every type reached through those references degrade
|
|
33
|
+
to `error`, producing `no-unsafe-*` reports on correct SDK calls.
|
|
34
|
+
|
|
35
|
+
- 181967f: New `RunEvent` member: `mcp_server_ready`, carrying the server name and the tool names it listed.
|
|
36
|
+
|
|
37
|
+
`mcp_server_failed` already reached consumers, so a broken MCP server was visible. A server that came
|
|
38
|
+
up was not — the resolved tool table never leaves the agent loop's internals, and no event carried an
|
|
39
|
+
inventory. A consumer could list what was configured and what broke, and could not tell a server that
|
|
40
|
+
came up with twelve tools from one that came up with none.
|
|
41
|
+
|
|
42
|
+
Emitted from the same function as its failure sibling, on the other branch. An event rather than a
|
|
43
|
+
getter because the state is scoped to the run: with `mcpLifecycle: "run"` a server may not exist by
|
|
44
|
+
the time anyone asks. Tool names are the server's own, not the sanitized `mcp_<server>_<tool>` form
|
|
45
|
+
the model sees.
|
|
46
|
+
|
|
47
|
+
Requested by `usetheokit/theokit#426`.
|
|
48
|
+
|
|
49
|
+
- f33b52b: `MemoryAdapter.isAvailable()` now disables an adapter that returns `false`, as its mandatory
|
|
50
|
+
presence always implied.
|
|
51
|
+
|
|
52
|
+
Nothing called it. Every third-party adapter implements it as "is there a non-empty apiKey", so an
|
|
53
|
+
implementer reasonably read `false` as "disable me" — and it disabled nothing: the client is built
|
|
54
|
+
lazily, so `mem0Memory({ apiKey: "" })` started normally and surfaced mid-conversation as
|
|
55
|
+
`auth_failed`, at the point where a memory write is happening rather than where the operator could
|
|
56
|
+
still fix it.
|
|
57
|
+
|
|
58
|
+
An unavailable adapter is now skipped with a diagnostic naming it, so a missing key degrades to
|
|
59
|
+
no-memory and a multi-adapter setup falls back to the ones that work. When every registered adapter
|
|
60
|
+
declines, `write` and `recall` fail with a message saying exactly that — distinct from the message
|
|
61
|
+
for no adapter registered at all.
|
|
62
|
+
|
|
63
|
+
- 398e7a0: `ModelSelection.url` — a model can name the endpoint it should reach.
|
|
64
|
+
|
|
65
|
+
The base URL came only from a process-wide env var (`OLLAMA_HOST`, `OPENAI_API_BASE_URL`) or the
|
|
66
|
+
provider profile's shipped default, so every `ollama/*` model in a process shared one host. An app
|
|
67
|
+
could not run a small model on localhost and a large one on a GPU box, and could not talk to two
|
|
68
|
+
OpenAI-compatible servers at once. The information had nowhere to travel: `ProviderRouterOptions`
|
|
69
|
+
carried no URL field at all (usetheokit/theokit-sdk#332).
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
model: { id: "ollama/llama3.3:70b", url: "http://gpu-box:11434" }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Precedence is `ModelSelection.url` → the provider's base-URL env var → `profile.baseUrl`. The model
|
|
76
|
+
outranks the env var deliberately: with the env var winning, whoever set it for one model would keep
|
|
77
|
+
hijacking every other one, which is the same bug wearing a hat.
|
|
78
|
+
|
|
79
|
+
Leaving `url` unset changes nothing — `ollama/qwen2.5:3b` still resolves to `http://localhost:11434`
|
|
80
|
+
from the profile, with no key and no setup.
|
|
81
|
+
|
|
82
|
+
Applied to both transports separately, because they do not share the override: `OllamaNativeClient`
|
|
83
|
+
(the native `/api/chat` path Ollama tool calling requires) and the OpenAI-compatible client, which
|
|
84
|
+
covers `lmstudio` and `llamacpp`. The tests assert the URL the stubbed `fetch` actually received
|
|
85
|
+
rather than the options object handed to the client — an options-level assertion passes with the
|
|
86
|
+
precedence inverted.
|
|
87
|
+
|
|
88
|
+
- 8d1feaa: `PostAssistantReplyContext` now carries `usedTools`, and `@theokit/sdk-cache` stops caching
|
|
89
|
+
tool-using turns in plugin mode.
|
|
90
|
+
|
|
91
|
+
The cache's D266/EC-10 guard exists because replaying an answer produced by a `write_file` / HTTP
|
|
92
|
+
POST / payment call re-serves the text without the side effect having happened. The
|
|
93
|
+
`post_assistant_reply` hook had no tool signal to key on and passed a literal `false`, so the guard
|
|
94
|
+
never fired on the path that runs automatically — only a hand-written `cache.remember(..., {
|
|
95
|
+
usedTools: true })` reached it.
|
|
96
|
+
|
|
97
|
+
The runtime derives the flag from the run's replayed event stream. A hook handler written against
|
|
98
|
+
the previous shape keeps working; code that CONSTRUCTS a `PostAssistantReplyContext` (test doubles,
|
|
99
|
+
custom emitters) now has to supply the field.
|
|
100
|
+
|
|
101
|
+
- 9a27a72: Exposes the provider registry: `listProviders()` and `getProviderProfile(name)`.
|
|
102
|
+
|
|
103
|
+
The registry was `@internal`, so the SDK was the only thing that could answer "which providers
|
|
104
|
+
exist, and what does each one need?". `theokit` consequently kept its own hand-written list of
|
|
105
|
+
three — against the 46 registered here — and an agent declaring `ollama/qwen2.5:3b` routed to
|
|
106
|
+
whichever API key happened to be set rather than to Ollama (usetheokit/theokit#326).
|
|
107
|
+
|
|
108
|
+
A second table that nothing forces to agree with the first is not a cache, it is a future bug.
|
|
109
|
+
These two functions exist so there is one table, and the framework can stop guessing.
|
|
110
|
+
|
|
111
|
+
Both register the builtins before answering. Registration is lazy — it happens when an agent is
|
|
112
|
+
created, a run is routed, or a provider is defined — so a caller asking early would otherwise get
|
|
113
|
+
an empty registry and reasonably conclude the SDK knows nothing. Local providers (`ollama`,
|
|
114
|
+
`lmstudio`, `llamacpp`) come back with `authType: "none"`, which is what lets a consumer tell "no
|
|
115
|
+
credential needed" apart from "credential missing" without hardcoding names.
|
|
116
|
+
|
|
117
|
+
- f692988: The reference docs no longer ship inside the package. `node_modules/@theokit/sdk/docs/` is gone, along with the `harness-capability-map.md` and `error-codes.md` files it carried — the `docs` entry was removed from the published `files` list and the build step that generated it was removed with it.
|
|
118
|
+
|
|
119
|
+
The exported TypeScript types are now the only reference surface, and they remain the canonical contract: every public primitive carries its import path, signature and JSDoc example, surfaced by your editor. Nothing about the runtime API changed.
|
|
120
|
+
|
|
121
|
+
The scaffolded agent context still ships, unchanged, under `claude-template/`.
|
|
122
|
+
|
|
123
|
+
- 4556488: **`local.sessionDir` replaces `local.baseDir`** (#301). "Base directory" read as the directory the agent works in, in an interface whose `cwd` is the option that actually means that — so `baseDir: "./"` ran without error and wrote session transcripts into the caller's repository root. `baseDir` still works and still resolves to the same place; it emits a deprecation diagnostic, and `sessionDir` wins if both are set.
|
|
124
|
+
|
|
125
|
+
**`isValidTaskId` and `TASK_RESERVED_PREFIXES` now exist at runtime** (#279). The bundled `.d.ts` had declared both as values since 4.51.1 while `dist/index.js` exported neither, so `import { isValidTaskId } from "@theokit/sdk"` typechecked clean and threw at the call site.
|
|
126
|
+
|
|
127
|
+
**Thirteen `@theokit/sdk/persistence`, `@theokit/sdk/path-safety` and `@theokit/sdk/mcp-auth` symbols now arrive typed** (#280). Those re-exports resolved to no declaration at all, because each symbol carried `@internal` and `stripInternal` deletes it — while the public barrel went on naming it. They imported and ran, untyped: `atomicWriteText` in particular hid that it is `async`, so a caller could skip the `await` and watch a write report success before the bytes landed.
|
|
128
|
+
|
|
129
|
+
**`OTelSpan` and `TelemetryHandle` are exported** from the root entry. Types only; nothing is added to the bundle.
|
|
130
|
+
|
|
131
|
+
- 566615c: BREAKING: `npx theokit-init-claude` and the bundled `claude-template/` are gone. The
|
|
132
|
+
agent skills they scaffolded now live in [`@theokit/skills`](https://www.npmjs.com/package/@theokit/skills):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npx @theokit/skills
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The thirty per-module skills were authored here and copied into that package by a sync
|
|
139
|
+
script, so they existed twice and the copy was the worse of the two — the script
|
|
140
|
+
stripped YAML frontmatter, and the frontmatter is where the `paths:` globs live that
|
|
141
|
+
make a skill load only when you are editing something it covers. They are authored
|
|
142
|
+
there now, with the globs intact.
|
|
143
|
+
|
|
144
|
+
Three things a consumer gets that the old scaffold did not offer. It installs for
|
|
145
|
+
every tool rather than Claude Code alone: `.agents/skills/` is read by OpenAI Codex,
|
|
146
|
+
Gemini CLI, GitHub Copilot, Zed and Devin Desktop, and `.claude/skills/` by Claude
|
|
147
|
+
Code. It links instead of copying when it is a real dependency, so the skills follow
|
|
148
|
+
your lockfile rather than freezing at scaffold time. And `--check` fails in CI when
|
|
149
|
+
what is installed has drifted, which is the only thing that stops an instruction file
|
|
150
|
+
from quietly going stale — a stale one is followed exactly as diligently as a current
|
|
151
|
+
one.
|
|
152
|
+
|
|
153
|
+
The SDK tarball drops 328 KB. Nothing in `dist/` referenced the template; it was
|
|
154
|
+
scaffold material, never runtime.
|
|
155
|
+
|
|
156
|
+
- 4397a90: `Theokit.subscribe` accepts an injected `fetch` and `WebSocket`.
|
|
157
|
+
|
|
158
|
+
Both were read off `globalThis` at call time, so the only way to exercise the SSE or WebSocket path —
|
|
159
|
+
in our own tests or in a consumer's — was to replace a global for the duration of the call. That is a
|
|
160
|
+
process-wide mutation to test one function, and it makes the transports untestable in any environment
|
|
161
|
+
where patching globals is not acceptable: a worker, a sandbox, an embedded runtime, or a suite running
|
|
162
|
+
files in parallel.
|
|
163
|
+
|
|
164
|
+
`SubscribeOptions` now takes optional `fetch` and `WebSocket`, each falling back to the global when
|
|
165
|
+
absent, so existing callers are unaffected. The SSE path, the WebSocket path and the automatic
|
|
166
|
+
transport selection all resolve through the same seam.
|
|
167
|
+
|
|
168
|
+
One case still requires replacing the global rather than injecting: asserting the error a caller gets
|
|
169
|
+
when no `WebSocket` exists at all. Node 22 ships a real global `WebSocket`, and a fallback cannot
|
|
170
|
+
express absence — only removal can. That single test says so where it stands.
|
|
171
|
+
|
|
172
|
+
- 7c7b21a: `theokit init` gains four templates — `chatbot`, `multi-agent`, `rag-agent` and
|
|
173
|
+
`workflow-automation` — and its `telegram-bot` template now installs and
|
|
174
|
+
compiles. It imported `createAgentFactory`, which the SE36 rename replaced with
|
|
175
|
+
`AgentFactory.create`, and pinned `@theokit/gateway` to the SDK's own version, so
|
|
176
|
+
a scaffolded project failed at `pnpm install` before any code ran.
|
|
177
|
+
|
|
178
|
+
`@theokit/cli` exports the `eval.config.ts` contract its README tells you to use:
|
|
179
|
+
`EvalConfig`, `DatasetEntry`, `Scorer` and `Score`.
|
|
180
|
+
|
|
181
|
+
`@theokit/sdk` exports `Workflow`, `fn` and `agentStep` from the package root.
|
|
182
|
+
`CronCreateOptions.workflow` types against the copy in the cron chunk, while the
|
|
183
|
+
`./workflow` subpath emits its own declaration of the same class — so a workflow
|
|
184
|
+
built the documented way was rejected by `Cron.create` on a private-field
|
|
185
|
+
mismatch. Importing both from the root now gives one identity.
|
|
186
|
+
|
|
187
|
+
### Patch Changes
|
|
188
|
+
|
|
189
|
+
- 1cb6607: Adding a published sub-entry to the SDK now fails fast and names every file still missing, and the
|
|
190
|
+
ACP smoke test actually sends the request its name promises.
|
|
191
|
+
|
|
192
|
+
Thirty-four sub-entries are published, and adding one required editing four files that nothing forced
|
|
193
|
+
to agree: the package's `exports`, the bundler's entry list, the declaration-build include, and the
|
|
194
|
+
declaration-mirroring script's target list. Only the first omission failed quickly. Skipping the last
|
|
195
|
+
two broke nothing visible — output was emitted, typechecking passed, the whole suite passed — and the
|
|
196
|
+
only gate that noticed ran at pre-push, about ten minutes in, where the error surfaces on whoever
|
|
197
|
+
pushes next rather than on whoever caused it. A consistency check now derives the expected set from
|
|
198
|
+
`exports`, the file that decides what is actually published, and reports every place that disagrees.
|
|
199
|
+
It runs at the front of the validation chain, not at the end of it.
|
|
200
|
+
|
|
201
|
+
Separately, the ACP smoke test was named for initializing a session, prompting, cancelling and
|
|
202
|
+
shutting down, and its docblock promised a response with a stop reason. It never sent a prompt. Two
|
|
203
|
+
defects in one: a name that tells the reader a path is covered, and a real gap on the protocol's main
|
|
204
|
+
path. It now sends the request over the wire and asserts the stop reason it gets back — verified by
|
|
205
|
+
mutating the handler to return a different reason and watching the test fail.
|
|
206
|
+
|
|
207
|
+
- 034da4d: A model id could stall the process for minutes. The Anthropic price lookup normalised dots with
|
|
208
|
+
`/(\d+)\.(\d+)/g`, which on a long run of digits containing no dot consumes to the end of the
|
|
209
|
+
string at every start position and backtracks — quadratic in a value the caller supplies.
|
|
210
|
+
|
|
211
|
+
Measured: 12,500 digits took 762 ms; 25,000 took 3 seconds; 200,000 took **154 seconds** with one
|
|
212
|
+
CPU pinned. For an SDK built to run inside a server handling other people's requests, that is a
|
|
213
|
+
denial of service reachable from a single field.
|
|
214
|
+
|
|
215
|
+
The same input now takes about 4 milliseconds. The pattern matches one dot between two digits
|
|
216
|
+
using lookarounds, so there is nothing for the engine to backtrack over.
|
|
217
|
+
|
|
218
|
+
One behaviour difference, and it is checked rather than assumed: a model id with two dots between
|
|
219
|
+
digits (`1.2.3`) normalised to `1-2.3` before and `1-2-3` now, because the old pattern swallowed
|
|
220
|
+
the middle digit into its first match. No id in the provider catalog has two — measured across all
|
|
221
|
+
34, of which 14 have exactly one.
|
|
222
|
+
|
|
223
|
+
Separately, reading a transcript's tail called `statSync(path)` and then `openSync(path)`, and the
|
|
224
|
+
size from the first call drove every read offset against the descriptor from the second. It now
|
|
225
|
+
sizes the descriptor it reads.
|
|
226
|
+
|
|
227
|
+
- 803e3ef: `MessageBus.send` discarded the handler's promise. `MessageHandler` may return one and `request`
|
|
228
|
+
awaits it; only `send` dropped it, so a rejecting handler became an unhandled rejection — fatal
|
|
229
|
+
under Node's default `--unhandled-rejections=throw` — while `await bus.send(...)` resolved cleanly
|
|
230
|
+
and the sender learned nothing.
|
|
231
|
+
|
|
232
|
+
Fire-and-forget means the sender does not wait for the result. It does not mean nobody is told when
|
|
233
|
+
delivery fails. The rejection is now caught and reported, naming the target agent and the reason,
|
|
234
|
+
and `send` stays non-blocking.
|
|
235
|
+
|
|
236
|
+
`AgentMailbox.send` forwards into this path and is fixed with it.
|
|
237
|
+
|
|
238
|
+
- ce6a591: Fix `ReferenceError: process is not defined` in the browser, which blanked every page of any app built on `theokit@0.48.x` (usetheokit/theokit#317).
|
|
239
|
+
|
|
240
|
+
`errors.ts` is imported by the client bindings framework consumers ship to the front end, and it pulls in the redaction and retry modules with it. Two of them read a bare `process.env` — one at module scope, in `internal/security/redact.ts` — so the read threw while the module graph was still evaluating, before a single component rendered. The page went blank with one console error naming no cause.
|
|
241
|
+
|
|
242
|
+
Environment reads on that path now go through `readEnv()`, which resolves `globalThis.process?.env?.[name]`: unchanged on the server, `undefined` in a browser, and still replaced at build time by bundlers that inline `process.env.X`. Redaction stays **enabled** when the flag cannot be read, since unreadable must mean unset rather than disabled.
|
|
243
|
+
|
|
244
|
+
`diagFailure` no longer relies on a `try/catch` swallowing the same ReferenceError to reach its fallback.
|
|
245
|
+
|
|
246
|
+
`tests/security/browser-safe-env.test.ts` walks the import graph reachable from `errors.ts` and fails on any bare `process` in it — a stronger guard than the two modules that happened to break this time.
|
|
247
|
+
|
|
248
|
+
- aea04f4: Fifteen tests that quietly reported success on machines missing a native dependency now report as
|
|
249
|
+
skipped.
|
|
250
|
+
|
|
251
|
+
Each was shaped `if (!(await probe())) return;` as the first line of the test body. A guard written
|
|
252
|
+
that way returns before any assertion runs, and the runner counts the case as passed — so a machine
|
|
253
|
+
without `better-sqlite3`, without the vector stack, or running as root was indistinguishable from one
|
|
254
|
+
where every assertion held. The skip was invisible in the count, which is the only place anyone would
|
|
255
|
+
have looked.
|
|
256
|
+
|
|
257
|
+
Measured on the same six guards in one package, forced on:
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
old shape 31 passed, 0 skipped
|
|
261
|
+
new shape 25 passed, 6 skipped
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Across all three packages the conversion moves fifteen cases from a silent pass to a reported skip.
|
|
265
|
+
|
|
266
|
+
A full triage of every occurrence of this shape was done before changing anything, because the shape
|
|
267
|
+
alone does not identify the defect. Of thirty-three occurrences, fifteen were silent skips; the other
|
|
268
|
+
eighteen are legitimate and untouched — seven are type narrowings placed immediately after an
|
|
269
|
+
assertion that has already reported the failure, and eleven are ordinary control flow inside
|
|
270
|
+
callbacks, loops and handlers.
|
|
271
|
+
|
|
272
|
+
- 1471fd7: The `tests/chaos` and `tests/load` families no longer report resilience coverage they do not have.
|
|
273
|
+
|
|
274
|
+
Every file in both directories exercised `node:fs`, `node:http` and `node:child_process` without
|
|
275
|
+
importing a single line of SDK source, and two of their assertions could not fail at all:
|
|
276
|
+
`result.code !== undefined || result.signal !== null` is always true when `code` is `number | null`,
|
|
277
|
+
and `typeof process.uptime === "function"` cannot be false in a process alive enough to run the
|
|
278
|
+
assertion. The directory names promised that OOM, SIGKILL-mid-stream, filesystem partition and
|
|
279
|
+
generator leaks were covered against the product. They were not.
|
|
280
|
+
|
|
281
|
+
The OOM test now asserts what it observes: that the heap-capped child aborts rather than exiting
|
|
282
|
+
cleanly, and that its allocation loop never printed `survived`. Measured — V8's out-of-memory is a
|
|
283
|
+
fatal process abort, not a catchable exception, so the child's own `catch`/`exit(7)` never runs and
|
|
284
|
+
the assertion does not pretend otherwise. Verified to go red when the heap cap is raised so the child
|
|
285
|
+
survives.
|
|
286
|
+
|
|
287
|
+
The generator-leak test is rewritten against real SDK code. It previously asked
|
|
288
|
+
`FinalizationRegistry` whether a generator had been collected, behind a `globalThis.gc` guard nothing
|
|
289
|
+
in the repository satisfied, so it reported a pass without executing its assertion for its entire
|
|
290
|
+
life; supplying the flag makes it fail, and no window can fix that, because the specification gives
|
|
291
|
+
`FinalizationRegistry` no timing guarantee at all. It now asserts cleanup through the task event
|
|
292
|
+
stream's own subscriber count — deterministic, no GC and no timers — and it is verified by mutation:
|
|
293
|
+
removing the iterator's `return()` turns it red.
|
|
294
|
+
|
|
295
|
+
That rewrite also corrects the premise it was built on. Breaking out of a `for await` loop does not
|
|
296
|
+
leak a generator; the iteration protocol calls `.return()` on your behalf, on `break` and on `throw`
|
|
297
|
+
alike. Only an iterator taken by hand and abandoned escapes cleanup, and that is the shape now
|
|
298
|
+
asserted.
|
|
299
|
+
|
|
300
|
+
The scaffolds that remain unwired each carry a todo naming the SDK path they stand in for, an owner
|
|
301
|
+
and a sunset date, and each directory carries a README stating plainly what it does and does not
|
|
302
|
+
cover.
|
|
303
|
+
|
|
304
|
+
- 521f8c7: A disposed `CloudAgent` now refuses `send()`, as `LocalAgent` already did.
|
|
305
|
+
|
|
306
|
+
`CloudAgent` tracked a `disposed` flag but consulted it only to make `dispose()` idempotent — `send()`
|
|
307
|
+
never checked it. So after disposing a cloud agent, sending still started a real run and resolved with
|
|
308
|
+
a live `CloudRun`, while the identical call on a local agent rejected. A caller reaching a torn-down
|
|
309
|
+
handle through a stale reference, a retry, or an `await using` scope that had already exited got work
|
|
310
|
+
started on an agent they believed was released.
|
|
311
|
+
|
|
312
|
+
`send()` now throws `AgentDisposedError` (code `agent_disposed`) before constructing anything, matching
|
|
313
|
+
`LocalAgent`. `dispose()` keeps its own idempotence, so `await using` double-dispatch is unaffected.
|
|
314
|
+
|
|
315
|
+
Thrown rather than returned as a failed run: the error is not retryable and a disposed handle never
|
|
316
|
+
becomes un-disposed, so a rejected run would invite retry loops around a condition that cannot clear.
|
|
317
|
+
|
|
318
|
+
- d0c800c: A real cloud run now reports a `RunStatus` the public type actually declares
|
|
319
|
+
(#341). The SSE transport cast the server's terminal token straight into
|
|
320
|
+
`RunStatus`, and the server sends `FINISHED` while `RunStatus` is lowercase — so
|
|
321
|
+
`result.status === "finished"` never fired on a successful cloud run, and
|
|
322
|
+
`throwOnError`, which keys on `"error"`, never fired on a failed one. Silently,
|
|
323
|
+
on the primary cloud path.
|
|
324
|
+
|
|
325
|
+
Server tokens are now mapped case-insensitively onto `RunStatus`, and an
|
|
326
|
+
unrecognised one fails the run with an actionable message instead of defaulting
|
|
327
|
+
to `"finished"`. `EXPIRED` settles as `"error"`: a run that expired did not
|
|
328
|
+
finish. The wire-level `SDKStatusMessage.status` stays uppercase — that is its
|
|
329
|
+
declared union — but is validated rather than cast.
|
|
330
|
+
|
|
331
|
+
- 969b36e: `Cron.create()` now accepts zero-padded fields and refuses malformed ranges, matching the scheduler
|
|
332
|
+
that actually runs the job.
|
|
333
|
+
|
|
334
|
+
The validator parsed each field shape differently. Literals and steps carried a `String(n) === field`
|
|
335
|
+
round-trip; ranges did not. So `"5abc * * * *"` was refused while `"1-5abc * * * *"` was accepted —
|
|
336
|
+
the same malformed input, two answers, decided by which shape the user happened to write it in. The
|
|
337
|
+
accepted ones did not become working jobs: they were refused later by croner at fire time, where the
|
|
338
|
+
failure is a scheduling error nobody is watching rather than a rejected call the caller can fix.
|
|
339
|
+
|
|
340
|
+
The round-trip also refused `"07 * * * *"`, because `String(7) !== "07"`. Measured against croner 9,
|
|
341
|
+
the scheduler this SDK fires jobs with: it accepts `"07 * * * *"` and fires it at :07, accepts
|
|
342
|
+
`"01-05"` and `"*/05"`, and refuses `"5abc"`, `"1-5abc"`, `"1abc-5"`, `"0x5"`, `"5.9"`, `"+5"` and
|
|
343
|
+
`"1e1"` as illegal characters. Validating stricter than the engine rejects schedules that would have
|
|
344
|
+
run correctly; validating looser only defers the failure. Both directions were wrong, in different
|
|
345
|
+
field shapes, for the same reason.
|
|
346
|
+
|
|
347
|
+
One digits-only predicate now decides every shape, reproducing croner's answer on each case above.
|
|
348
|
+
Zero-padded expressions that were previously rejected are accepted; malformed ranges that were
|
|
349
|
+
previously accepted are rejected at `Cron.create()` with `ConfigurationError` / `invalid_cron`, which
|
|
350
|
+
is where the caller can still do something about it.
|
|
351
|
+
|
|
352
|
+
Also removes a defensive branch in the same validator that no caller could reach: its only caller ran
|
|
353
|
+
with exactly five fields against a five-entry table, so the "field index out of range" guard stayed at
|
|
354
|
+
zero executions through 37 tests written specifically to enter it.
|
|
355
|
+
|
|
356
|
+
- ba8ebeb: Remove four unused internal exports surfaced once the dead-code gate stopped
|
|
357
|
+
skipping `src/internal/` — `isSqliteVecLoaded`, `listNotes` (with its `NoteFile`
|
|
358
|
+
type), `MemoryFileEntry`, and the derived `SpanName` union. None had a caller;
|
|
359
|
+
all four lived behind `@internal`, so no public export changes.
|
|
360
|
+
|
|
361
|
+
Two docblocks corrected in the process. `session-loader` claimed to return
|
|
362
|
+
`MemoryFileEntry`-shaped records against a two-field type where the interface had
|
|
363
|
+
four, with the path field named differently. `span-names` described the removed
|
|
364
|
+
union as the mechanism preventing span-name drift; the `as const` map is what
|
|
365
|
+
does that, and emitters read keys off it.
|
|
366
|
+
|
|
367
|
+
The HITL approval middleware is now documented as not wired — it is constructed
|
|
368
|
+
nowhere outside its own test file — with the timeout-versus-denial semantics
|
|
369
|
+
pinned by characterization tests. Behaviour unchanged.
|
|
370
|
+
|
|
371
|
+
- d610c2a: Device login now reports a non-JSON response as a typed error instead of a raw `SyntaxError`.
|
|
372
|
+
|
|
373
|
+
Every failure in the OAuth device flows is supposed to reach the caller as an `AuthCallbackError`
|
|
374
|
+
carrying a code the CLI can branch on. Three of the four entry points broke that contract: they
|
|
375
|
+
parsed the response with `res.json()`, so an endpoint answering with HTML — a captive portal, a
|
|
376
|
+
corporate proxy's sign-in page, a load balancer's error page — rejected with a `SyntaxError` that no
|
|
377
|
+
`catch` in the module handled. It escaped untyped past callers prepared only for `AuthCallbackError`.
|
|
378
|
+
|
|
379
|
+
Affected: `requestDeviceCode`, `requestOpenAIUsercode`, and the two-step poll inside
|
|
380
|
+
`openaiDeviceLogin`. The RFC 8628 poll loop was already safe and is unchanged.
|
|
381
|
+
|
|
382
|
+
The message now quotes the body (truncated), because "not JSON" and "not JSON, and it looks like a
|
|
383
|
+
proxy login page" are different diagnoses for whoever is holding the terminal — and sending someone
|
|
384
|
+
to debug the provider when the fault is their own network is the expensive kind of wrong.
|
|
385
|
+
|
|
386
|
+
- e3f2a82: Public-API documentation reviewed file by file, and corrected wherever it disagreed
|
|
387
|
+
with the code. The docblocks ship in the `.d.ts`, so these read as behaviour changes
|
|
388
|
+
in an editor even though no behaviour changed.
|
|
389
|
+
|
|
390
|
+
The corrections that change what a caller would do:
|
|
391
|
+
|
|
392
|
+
- **`sdk-cache` documented its own premise backwards.** The header example labelled a
|
|
393
|
+
semantic hit as if it avoided the provider call. `asPlugin()` returns the cached
|
|
394
|
+
answer as `recalledContext`, which the agent loop injects as a `<memory-context>`
|
|
395
|
+
block _before_ the prompt — the request still goes to the provider. The two modes
|
|
396
|
+
are now labelled separately, with a table saying which one short-circuits and which
|
|
397
|
+
one seeds.
|
|
398
|
+
- **`sdk-handoff`'s five error classes said "throw".** Under the plugin wiring the
|
|
399
|
+
handler never throws; every failure becomes a tool result `{"ok":false,…}` handed
|
|
400
|
+
back to the model. Each class now says where it is actually observable. The header
|
|
401
|
+
also told readers to `import { Handoff } from "@theokit/sdk"`, from which it was
|
|
402
|
+
extracted.
|
|
403
|
+
- **`sdk-budget`'s `charge()` claimed idempotency across concurrent calls.** The mutex
|
|
404
|
+
serialises, it does not deduplicate: two identical calls record twice. Related, and
|
|
405
|
+
newly documented: with `maxUsd` set, a model missing from the pricing table denies
|
|
406
|
+
every request rather than passing it — and the table matches by exact string, so
|
|
407
|
+
`"openai/gpt-4o"` does not match `"gpt-4o"`.
|
|
408
|
+
- **The three `memory-*` adapters advertised an env-var fallback they do not read**,
|
|
409
|
+
and their peer dependencies are required rather than optional. Their behavioural
|
|
410
|
+
differences are now stated where they break the "interchangeable adapter"
|
|
411
|
+
assumption — honcho ignores `k` and always throws on `delete`; mem0 recalls across
|
|
412
|
+
sessions by design; supermemory ignores `sessionId` entirely.
|
|
413
|
+
- **`sdk-memory`'s `truncated` flag was documented as its own inverse**, and its
|
|
414
|
+
dreaming sweep claimed a mutex it never takes against the writer it names.
|
|
415
|
+
- **`sdk-tools`** corrected `run_vitest`'s unreachable `no_vitest` code, `truncation`'s
|
|
416
|
+
replacement-character claim, and two return shapes missing a live error code.
|
|
417
|
+
- **`acp`/`cli`** corrected sixteen statements including a named error class that is
|
|
418
|
+
not the one raised, a handler documented as calling `fork()` that refuses
|
|
419
|
+
unconditionally, handlers described as pure that mint ids and mutate a store, a
|
|
420
|
+
config loader credited to Zod in a package that does not import it, and a `--force`
|
|
421
|
+
scaffold described as atomic that deletes the destination before the rename.
|
|
422
|
+
|
|
423
|
+
Undocumented public symbols were documented across every package, with each claim
|
|
424
|
+
checked against the implementation rather than inferred from the name.
|
|
425
|
+
|
|
426
|
+
- e368fc1: Every published declaration file now compiles without `skipLibCheck` (#345). The
|
|
427
|
+
DTS rollup emitted symbols as a re-export from a chunk while omitting them from
|
|
428
|
+
that chunk's `import`, and dropped type-only imports from external packages —
|
|
429
|
+
leaving 51 unresolved references across ten of the twelve packages. Nothing broke
|
|
430
|
+
at runtime, and `tsc` stayed green for anyone with `skipLibCheck` on, but a
|
|
431
|
+
consumer running type-aware lint saw every type reached through one degrade to
|
|
432
|
+
`error`.
|
|
433
|
+
|
|
434
|
+
The declarations are repaired at build time from the compiler's own diagnostics.
|
|
435
|
+
No source or API change.
|
|
436
|
+
|
|
437
|
+
- 3ac2b08: `LiveAgentRegistry` is no longer offered as a constructible value by the published
|
|
438
|
+
declaration. The source exports it type-only — the runtime singleton is reached
|
|
439
|
+
via `Agent.registry` — but the DTS rollup emitted `declare class` and re-exported
|
|
440
|
+
it as a value, while `dist/index.js` never exported it at all. A consumer writing
|
|
441
|
+
`new LiveAgentRegistry()` typechecked and failed at runtime.
|
|
442
|
+
- 29ebaa1: Three places where a value was reported that nobody had actually selected.
|
|
443
|
+
|
|
444
|
+
**An empty `POSTHOG_API_KEY` no longer masks a valid `POSTHOG_PROJECT_API_KEY`.** The adapter read
|
|
445
|
+
`POSTHOG_API_KEY ?? POSTHOG_PROJECT_API_KEY`, and `??` treats `""` as present. Leaving a variable
|
|
446
|
+
blank in a `.env` or a CI config is the ordinary way to say "unset", so a blank primary key silently
|
|
447
|
+
disabled telemetry while a working key sat in the sibling variable — and telemetry going quiet is the
|
|
448
|
+
one failure that reports itself as nothing at all. Empty and whitespace-only values now fall through.
|
|
449
|
+
The same trap on `POSTHOG_HOST` is closed with it.
|
|
450
|
+
|
|
451
|
+
**The provider inspector reports the model the route resolves to.** `extractModelName` documented
|
|
452
|
+
itself as surfacing the name from the prefix split and instead returned a hard-coded default, so a
|
|
453
|
+
route configured as `anthropic:claude-opus-4` with no explicit `route.model` reported
|
|
454
|
+
`claude-3-7-sonnet`. That field exists to let a caller confirm which model a route resolves to; a
|
|
455
|
+
wrong answer there is worse than no answer, because it is indistinguishable from a right one. The
|
|
456
|
+
name is now derived from the model id the route actually carries, and the default-model lookup that
|
|
457
|
+
produced the literal is deleted rather than left as a decoy.
|
|
458
|
+
|
|
459
|
+
**An errored ACP run no longer reaches the client as `end_turn`.** The stop-reason mapping fell
|
|
460
|
+
through to `end_turn` for any run status it did not recognise, so a failure was reported over the
|
|
461
|
+
wire as an ordinary completed turn — invisible to every ACP client, which is the swallowed-error
|
|
462
|
+
shape the project's error-handling rules forbid by name. The protocol's `StopReason` has no error
|
|
463
|
+
value, so an unmapped status now surfaces through the JSON-RPC error channel the handler already uses
|
|
464
|
+
for every other failure, with a message naming the status that was not mapped. A dead branch
|
|
465
|
+
returning `end_turn` twice is removed in the same pass.
|
|
466
|
+
|
|
467
|
+
- 0bc18f6: Adds negative-case tests over two modules whose typed errors were never entered by any test.
|
|
468
|
+
|
|
469
|
+
A sweep of the SDK found 340 `throw new *Error` sites with roughly a third never executed. The error
|
|
470
|
+
hierarchy exists so callers can branch on a typed code, and the project's own testing rule requires a
|
|
471
|
+
negative case to assert the specific error and message rather than merely that something threw — so
|
|
472
|
+
an untested throw site is a contract nobody has checked.
|
|
473
|
+
|
|
474
|
+
The hook-source loader is now fully covered on its failure paths: an unreadable hooks file, malformed
|
|
475
|
+
JSON, a non-object root, a non-array event group, and an invalid command shape. Each asserts the
|
|
476
|
+
class, the code and a message substring. One pre-existing test that asserted only
|
|
477
|
+
`.rejects.toThrow(/hook/i)` is upgraded to the same standard — matching a regular expression against
|
|
478
|
+
a message is not the same as identifying which guard fired.
|
|
479
|
+
|
|
480
|
+
Agent-helper resolution gains the same treatment on four of its five uncovered throw sites. The
|
|
481
|
+
fifth is left untested on purpose and recorded: its condition cannot be false for any caller, because
|
|
482
|
+
a sibling predicate that feeds it returns a constant. Writing a test for it would require mocking
|
|
483
|
+
that predicate away in order to reach a line real callers cannot, which is the decoy pattern this
|
|
484
|
+
project has already removed three times.
|
|
485
|
+
|
|
486
|
+
- b5b5e77: `humanizeModelName` stripped trailing slashes with a pattern that backtracks. On a model id ending
|
|
487
|
+
in a long run of slashes, the engine consumed to the end of the string at every start position:
|
|
488
|
+
25,000 slashes took half a second, 100,000 took **31 seconds** with one CPU pinned — to render a
|
|
489
|
+
label.
|
|
490
|
+
|
|
491
|
+
The trim is now a single linear pass. Behaviour is unchanged: a trailing slash is still stripped,
|
|
492
|
+
several are still stripped, and an id without one is untouched.
|
|
493
|
+
|
|
494
|
+
- 14ccb69: A run that exhausts its iteration budget now says so (#338 item 4). It reported
|
|
495
|
+
`status: "error"` with an empty result and no error detail — byte-for-byte the
|
|
496
|
+
shape a provider rejection produces, so a caller could not tell "the model ran out
|
|
497
|
+
of turns" from "the provider refused the request". `RunResult.error` now carries
|
|
498
|
+
`code: "iteration_limit_reached"`, the limit that was hit, and the name of the
|
|
499
|
+
option that raises it.
|
|
500
|
+
|
|
501
|
+
`LocalOptions` documents two behaviours that were reported as surprises: a `shell`
|
|
502
|
+
tool is registered on every local agent even when you pass `tools: []`, and a
|
|
503
|
+
finished run writes a transcript with the full prompt and reply to
|
|
504
|
+
`.theokit/memory/sessions/` under the workspace. Behaviour unchanged; both now
|
|
505
|
+
appear where a consumer meets them.
|
|
506
|
+
|
|
507
|
+
- fbf6721: Remove three unused error classes from the internal iteration-budget module
|
|
508
|
+
(`IterationBudgetExhaustedError`, `CompressionExhaustedError`,
|
|
509
|
+
`CompressionIneffectiveError`). They were never thrown: the budget reports
|
|
510
|
+
exhaustion by return value (`recordCompression()` answers
|
|
511
|
+
`{ allowed: false, reason }`), which is the shape the agent loop actually reads.
|
|
512
|
+
They were left over from an earlier exception-based design and advertised a
|
|
513
|
+
contract the module does not honour. No public export changes — all three lived
|
|
514
|
+
behind `@internal`.
|
|
515
|
+
- 240ae12: `LocalSandbox` now appends the `...(truncated)` marker when a command's output exceeds
|
|
516
|
+
`maxOutputBytes`, as `ExecuteResult` has always documented.
|
|
517
|
+
|
|
518
|
+
Node caps `execFile`'s buffer AT `maxBuffer`, so for ASCII output the string came back exactly at
|
|
519
|
+
the cap — never _greater_ — and the length test that gated the marker never fired. Callers were
|
|
520
|
+
told to branch on a marker that was never written, and every derived helper (`readFile`, `glob`,
|
|
521
|
+
`grep`, `listDir`) returned a silent prefix. Since a cut command reports `exitCode: 1` like any
|
|
522
|
+
other failure, the marker is the only thing that distinguishes lost output from a failed command.
|
|
523
|
+
|
|
524
|
+
`LinuxSandbox` routes through the same `execute` and is fixed with it.
|
|
525
|
+
|
|
526
|
+
- da98560: A malformed API key for a named provider is now refused when the agent is created, instead of failing
|
|
527
|
+
later wherever the key is first used.
|
|
528
|
+
|
|
529
|
+
The strict shape check existed and could never run. Deciding whether a key was headed for a provider
|
|
530
|
+
reused the predicate that decides whether a local runtime is available — and that one always answers
|
|
531
|
+
yes, because the SDK ships a local provider as a builtin. So the answer was no for every possible
|
|
532
|
+
input: the strict branch and the provider-prefix check were unreachable, and a key that could not
|
|
533
|
+
possibly work was accepted at the boundary.
|
|
534
|
+
|
|
535
|
+
The two questions are now answered separately. Whether to drive the real local runtime is still
|
|
536
|
+
decided where it always was. Whether a key reaches a provider that authenticates with it is decided by
|
|
537
|
+
that provider's own declared authentication type, so a provider that ignores keys entirely — the local
|
|
538
|
+
ones — accepts any shape, exactly as before.
|
|
539
|
+
|
|
540
|
+
Both unknowns stay permissive on purpose: an unrecognised model identifier or an unregistered provider
|
|
541
|
+
skips strictness. Rejecting a valid key blocks someone outright, while accepting a malformed one for a
|
|
542
|
+
provider we cannot identify only restores the previous behaviour for that case.
|
|
543
|
+
|
|
544
|
+
**This can newly reject keys that previously reached agent creation.** A short placeholder key paired
|
|
545
|
+
with a real provider prefix is the case to look for — two test suites in this repository were relying
|
|
546
|
+
on exactly that. Keys for local providers, fixture keys, and any setup with a base-URL override are
|
|
547
|
+
unaffected.
|
|
548
|
+
|
|
549
|
+
Also removes an authentication error that could not be raised: its condition depended on the same
|
|
550
|
+
always-true predicate, and the check that now does its job is the strict one above.
|
|
551
|
+
|
|
552
|
+
- 510ee70: The MCP OAuth token store now honours `THEOKIT_HOME`. When the variable is set, the store lives at `$THEOKIT_HOME/mcp-tokens.json`; when it is not, it stays exactly where it was, at `~/.theokit/mcp-tokens.json`.
|
|
553
|
+
|
|
554
|
+
`internal/mcp/token-storage.ts` was the only module on the credential path that ignored the variable this SDK isolates state with, and the consequence was not confined to configuration preference. `vitest.setup.ts` isolates every test in `@theokit/sdk` by pointing `THEOKIT_HOME` at a fresh tmpdir; it backs `HOME` up and never sets it. A home-anchored module that ignored `THEOKIT_HOME` therefore resolved to the developer's real `~` while the suite believed it was isolated — and it did resolve there: a default-config run of the suite deposited four refresh-token entries (`test-srv`, `srv-2`, `srv-race`, `srv-roundtrip`) into `~/.theokit/mcp-tokens.json` at mode 0600, written by the OAuth golden tests. Every key in that file was verified to be a test fixture rather than a real credential, and this predates the per-call path resolution shipped earlier — the old module constant resolved to the same real home.
|
|
555
|
+
|
|
556
|
+
A suite that is wrong about its own isolation is a false green about the property the rest of its greens rest on, which is why this shipped as a defect rather than as a preference.
|
|
557
|
+
|
|
558
|
+
**This is the code catching up to a contract the SDK already published, not a new policy.** `src/project-env.ts:47-49` documents `THEOKIT_HOME` as _"Locates the SDK home — sessions, and the credential store beneath it"_, and lists it as a sovereign key precisely because it governs where credentials live. The public contract already said the token store sits under the variable. This module was the half that disagreed, so what changes here is not the promise — it is the code finally keeping it.
|
|
559
|
+
|
|
560
|
+
**The resolver adopted is `transcriptRoot()`'s, not `getTheokitHome(cwd)`'s.** The transcript is the sibling with the matching shape: home-anchored default, `THEOKIT_HOME` override, trimmed and empty-guarded — and its own docstring records that before M94 it ignored the variable, so "whoever set it had their state split in two silently", which is this defect verbatim. M94 ADR-2 already accepted that migration for identically-shaped state. `getTheokitHome(cwd)` falls back to `<cwd>/.theokit` instead, so adopting it would have moved the token file of everyone who does **not** set the variable — and to a _different place per working directory_, making whether you are logged in a property of which folder you launched from. That is a regression for every user, not a migration.
|
|
561
|
+
|
|
562
|
+
**The migration this does carry, stated rather than buried.** A user who already holds `~/.theokit/mcp-tokens.json` **and** sets `THEOKIT_HOME` stops seeing those tokens: `getTokens` returns `undefined`, the caller surfaces it as "not logged in", and the OAuth flow re-runs. Nothing is deleted and nothing is overwritten — the old file stays where it is and is found again the moment the variable is unset. No migration step is performed on the user's behalf, because silently relocating a credential file is a worse failure than a re-auth, and a store that moved a token without being asked would be indistinguishable from one that lost it. Users who do not set `THEOKIT_HOME` — the default — see no change at all.
|
|
563
|
+
|
|
564
|
+
**Two further consequences for those who do set it**, both on the directory-permission path rather than on path resolution.
|
|
565
|
+
|
|
566
|
+
The store no longer re-permissions a `THEOKIT_HOME` it did not create. `ensurePrivateStoreDir` chmods the store directory 0700, and that was written unconditional on purpose: `mkdir`'s mode applies only at creation, so a machine that ran an older build already has a loose `~/.theokit`, and a fix reaching only fresh installs misses the population that has the problem. But that reasoning names its own population — directories _this SDK_ created. Once `THEOKIT_HOME` is honoured, an unconditional chmod also reaches a root the operator chose and shares with sessions, transcripts, personality and credential-pool state, which `paths.ts` documents as a multi-tenant deployment knob and which no other consumer of the variable imposes a mode on. Measured: it silently demoted a 0775 `$THEOKIT_HOME` to 0700. The retro-fix now keeps its population and loses the one it never had; a directory the SDK creates is still born 0700 wherever it points.
|
|
567
|
+
|
|
568
|
+
The consequence of not repairing it is that `getTokens` **refuses** — a typed `CredentialError` naming the directory and the `chmod 700` that fixes it — rather than returning `undefined`, when `$THEOKIT_HOME` is group- or world-writable. That is the intended end state, and the two alternatives are worse: silently tightening the operator's root breaks a deployment to protect them from a choice they may have made deliberately, and silently returning the token hands the caller a refresh token that any local user could already have swapped. One asymmetry is left unfixed and is not hidden: the write path has no matching gate, so `setTokens` writes into such a directory and the next `getTokens` refuses it.
|
|
569
|
+
|
|
570
|
+
An empty or whitespace-only `THEOKIT_HOME` falls through to the home-anchored default. That guard is load-bearing in a way the sibling `HOME` guard is not: without it, `THEOKIT_HOME=""` resolves the store to a **cwd-relative** `mcp-tokens.json` and `THEOKIT_HOME=" "` to a directory literally named three spaces. Neither falls back to anything — both are new locations invented from an unusable value.
|
|
571
|
+
|
|
572
|
+
Pinned in both directions, per `rules/testing.md § 4.2`: one test asserts the store follows the override and leaves the home default untouched, one asserts the read path looks there too (the file is placed by hand rather than through `setTokens`, so a roundtrip cannot pass by having both halves agree on the wrong path), and two assert that an unusable value leaves the home default in place. Verified by mutation, six mutants and six deaths: removing the override branch, relaxing the empty guard, dropping the `.trim()`, hard-coding the old path back into the warning, chmodding unconditionally, and dropping the chmod entirely each kill a test named for the property it breaks. A seventh — guarding the chmod on "we just created it" as well — killed nothing, because a umask only clears bits and 0700 carries none in the group/other range, so `mkdir(0700)` is private under every umask. That clause was deleted rather than pinned with a test written to justify it.
|
|
573
|
+
|
|
574
|
+
The keytar-absent fallback warning now names the **resolved** store path instead of the literal `~/.theokit/mcp-tokens.json`. That literal was correct until this change; afterwards it would have sent anyone who sets `THEOKIT_HOME` to look at a file the store no longer writes, and a diagnostic that names the wrong location costs more than one that names none — the reader stops looking once they find it empty.
|
|
575
|
+
|
|
576
|
+
- 1362583: The MCP OAuth token store now resolves its path when an operation runs — reading the same environment variable `os.homedir()` reads on that platform (`USERPROFILE` on Windows, `HOME` elsewhere), with `os.homedir()` itself as the fallback — instead of binding a path once when the module is first imported.
|
|
577
|
+
|
|
578
|
+
`internal/mcp/token-storage.ts` held `const FILE_PATH = join(homedir(), ".theokit", "mcp-tokens.json")` at module scope. A constant at module scope captures ambient global state at import, so the store kept reading and writing under whichever `HOME` was set at that moment and never noticed a later change. It made the module's correctness a property of _when_ it was imported, which is not a property a credential store should have.
|
|
579
|
+
|
|
580
|
+
Reading the environment first is not a stylistic preference, and **the variable read is per platform because `os.homedir()` itself is**: on POSIX it prefers `$HOME`, on Windows it reads `USERPROFILE` and never consults `HOME`. Mirroring that split keeps this a binding-time fix rather than a behaviour change. In a normal process on either platform the resolved path is identical to what shipped before.
|
|
581
|
+
|
|
582
|
+
They diverge in exactly one place — inside a worker thread, `process.env` is a JS-level copy while `os.homedir()` is a native call reading the real process environment, so a home moved inside a worker is invisible to `homedir()`.
|
|
583
|
+
|
|
584
|
+
An empty or whitespace-only value falls through to `homedir()`. Being precise about what that buys, because an earlier draft of this note overstated it: on POSIX it is close to a no-op, since `homedir()` returns the same empty value, and an empty home resolves the store to a CWD-relative `.theokit/mcp-tokens.json` either way. It earns its place on Windows and for a worker whose environment copy was blanked.
|
|
585
|
+
|
|
586
|
+
**The Windows OS is untested; the platform branch is not.** Every POSIX-mode test in `mcp-token-store-modes.test.ts` is guarded by `it.skipIf(!POSIX)` so it does not run on Windows, and CI runs ubuntu only, so nothing here exercises real Windows chmod semantics or libuv's `USERPROFILE` lookup. The branch SELECTION does run everywhere: one test spies `process.platform` and asserts the store follows `USERPROFILE` rather than `HOME`. The split itself is reasoned from `os.homedir()`'s documented per-platform source, not from a run on Windows.
|
|
587
|
+
|
|
588
|
+
The path is resolved once per operation and passed down, including into the directory-permission step. Resolving it per use would let a read and the write that follows it disagree if `HOME` moved in between, or lock down one directory while the token lands in another.
|
|
589
|
+
|
|
590
|
+
**Behaviour change, both directions.** A process that moves `HOME` after importing the SDK now has its tokens follow the new home. On the write path that is the safer reading — the alternative writes credentials to a location the caller no longer considers theirs. On the read path it has a cost worth naming: tokens stored under the previous home are no longer found, so `getTokens` returns `undefined` and the caller sees "not logged in" rather than an error. Following the current home is still the right trade for a credential store, but it converts a stale-write risk into a silent-re-auth one, and both sides are stated here rather than only the favourable one.
|
|
591
|
+
|
|
592
|
+
`THEOKIT_HOME` is deliberately not honoured by this store. `transcriptRoot()` does honour it and M94 ADR-2 accepted that migration for the sibling module; doing the same for credentials changes what existing token holders see, which is a product decision rather than a prerequisite for making this module independent of the execution model.
|
|
593
|
+
|
|
594
|
+
Found while measuring whether mutation testing is viable on this package: the directory-permission tests passed only because `vitest.config.ts` pins the `forks` pool with `fileParallelism: false`. A tool that controls test execution refused to start against that baseline. The suite now carries a regression test that holds under the default config **and** under `--pool=threads`.
|
|
595
|
+
|
|
596
|
+
- 2cdadcc: The memory index's `LIKE` fallback — used when FTS5 cannot tokenise a query, which is the normal
|
|
597
|
+
path for CJK text — escaped `%` and `_` but not the backslash that its own `ESCAPE '\'` clause
|
|
598
|
+
depends on. A query containing a backslash produced a pattern where the inserted escape was
|
|
599
|
+
consumed escaping the user's backslash, leaving the next wildcard live:
|
|
600
|
+
|
|
601
|
+
```
|
|
602
|
+
search for x\%y
|
|
603
|
+
old pattern %x\\%y% the % is unescaped — matches anything between "x\" and "y"
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
So a literal search silently became a scan, returning rows the caller never asked for. Escaping the
|
|
607
|
+
backslash first fixes it, and the rule now lives in one function with the ordering argument written
|
|
608
|
+
next to it.
|
|
609
|
+
|
|
610
|
+
Separately, `ContextManager` called `stat()` on each source file and discarded the result before
|
|
611
|
+
reading it. `readFile` already fails when the file is gone, so the extra lookup added nothing but a
|
|
612
|
+
window in which the path could resolve to a different file between the two calls. It is gone.
|
|
613
|
+
|
|
614
|
+
- 1c94ad3: The "Missing API key" refusal now names the provider credential you actually have
|
|
615
|
+
(#338 item 5). With `OPENROUTER_API_KEY` exported and `THEOKIT_API_KEY` unset,
|
|
616
|
+
the old three-word message named neither — while the SDK consults that exact
|
|
617
|
+
variable a moment later to decide whether to drive a real runtime, so the
|
|
618
|
+
environment looks configured to whoever set it up. Reported as three hours of
|
|
619
|
+
diagnosis on the wrong cause.
|
|
620
|
+
|
|
621
|
+
Resolution is unchanged: a provider key is still not adopted from the
|
|
622
|
+
environment, because with two of them exported there is no non-arbitrary answer
|
|
623
|
+
to which one was meant. The message says where to put it instead. Names the
|
|
624
|
+
variables, never their values.
|
|
625
|
+
|
|
626
|
+
- 3ad398d: `ModelSelection.url` names the endpoint a specific model lives at, and it was handed to every
|
|
627
|
+
provider in a fallback chain. A fallback therefore inherited the primary's host and could never
|
|
628
|
+
reach its own — so a configured failover silently retried the same dead endpoint instead of moving
|
|
629
|
+
on.
|
|
630
|
+
|
|
631
|
+
Measured against two servers with the primary refusing every request: with `model.url` set, the
|
|
632
|
+
primary received 6 requests and the fallback 0. Pointing each provider with its own
|
|
633
|
+
`*_API_BASE_URL` instead gave 3 and 1.
|
|
634
|
+
|
|
635
|
+
The per-call URL now reaches only the provider the model id names. Each fallback resolves its own
|
|
636
|
+
endpoint from its profile and its own `*_API_BASE_URL`, which is what makes a fallback a different
|
|
637
|
+
destination rather than a retry.
|
|
638
|
+
|
|
639
|
+
- a8cf443: `ModelSelection.url` names the endpoint a call should reach, and it reached only two of the four
|
|
640
|
+
transport branches. On `anthropic_messages`, `bedrock` and the Responses API it was silently
|
|
641
|
+
dropped: a run explicitly aimed at a local host went to the vendor instead, with the caller's key,
|
|
642
|
+
and nothing said so.
|
|
643
|
+
|
|
644
|
+
Measured on the anthropic branch: the local server recorded zero requests and the run failed with
|
|
645
|
+
`Anthropic API error: auth_failed (HTTP 401)` — a 401 from `api.anthropic.com`, after the caller
|
|
646
|
+
had named a different host.
|
|
647
|
+
|
|
648
|
+
All four branches now honour it, and it outranks the process-wide `*_API_BASE_URL` on each, which
|
|
649
|
+
is the contract the field's own documentation states. Nothing changes when it is absent.
|
|
650
|
+
|
|
651
|
+
- aadc9dd: Seventeen more negative-case tests now identify which failure they caught, and a registry test suite
|
|
652
|
+
stops sleeping to make timestamps differ.
|
|
653
|
+
|
|
654
|
+
Most of those assertions turned out to be under-asserting rather than untestable: twelve of them sat
|
|
655
|
+
on errors that were **already typed**, and simply checked that something threw. They now name the
|
|
656
|
+
class, the stable code and a message fragment — which means a change that swaps one failure for
|
|
657
|
+
another is caught, where before any error at all satisfied the test.
|
|
658
|
+
|
|
659
|
+
Four remain matched on a message fragment because the underlying error genuinely has no type yet, and
|
|
660
|
+
one of those is filed separately: a public entry point throwing a plain error gives callers nothing to
|
|
661
|
+
branch on but a string that changes whenever someone improves the wording.
|
|
662
|
+
|
|
663
|
+
Four more were reclassified out of scope after reading the source rather than the name: they raise
|
|
664
|
+
errors owned by Node, by the schema library, or by a database driver, and pinning a third-party class
|
|
665
|
+
buys little.
|
|
666
|
+
|
|
667
|
+
Separately, the live-agent-registry tests slept thirteen times — some to force last-used timestamps
|
|
668
|
+
apart so eviction ordering could be asserted, others to let fire-and-forget cleanup finish. Both are
|
|
669
|
+
now driven by the test clock, a mechanism this same file already used elsewhere and which needed no
|
|
670
|
+
production change. The file runs in a fraction of the time and no longer depends on how busy the
|
|
671
|
+
machine is.
|
|
672
|
+
|
|
673
|
+
- a1cae95: Removes an unreachable `ollama` arm from the provider base-URL resolver. `OLLAMA_HOST` is unaffected
|
|
674
|
+
and keeps working exactly as before.
|
|
675
|
+
|
|
676
|
+
The router's base-URL env switch carried a `case "ollama"` returning `process.env.OLLAMA_HOST`. It
|
|
677
|
+
never ran. Ollama is served by its own native client, which the transport selector returns before the
|
|
678
|
+
OpenAI-compatible branch — the only place that switch is consulted — so the arm was unreachable from
|
|
679
|
+
the first line of the function containing it. Measured two ways: line coverage over the router and
|
|
680
|
+
provider suites puts the arm at 0 entries while all four siblings are entered, and a probe that
|
|
681
|
+
replaced its body with a throw was never triggered by any test, plugin profile or alias.
|
|
682
|
+
|
|
683
|
+
The one construction that could reach it is a provider profile whose `name` getter returns a
|
|
684
|
+
different value on successive reads — a profile contradicting itself. Run against the old code, that
|
|
685
|
+
path shows what the line actually did: it pointed the **OpenAI-compatible** transport at the Ollama
|
|
686
|
+
host, producing `…/v1/chat/completions` against an Ollama daemon. That is the failure mode ADR D191
|
|
687
|
+
exists to prevent — models emitting raw tool JSON as plain text. So this is not merely an inert line
|
|
688
|
+
being tidied away; it is a latent bug being removed on the only path that reached it.
|
|
689
|
+
|
|
690
|
+
The line also cost real time as a decoy: it reads exactly like the mechanism implementing
|
|
691
|
+
`OLLAMA_HOST` and is not. A repair pass mutated it, measured a green suite, and concluded the real
|
|
692
|
+
override was untested. The real one lives on the native branch and is now pinned by a test asserting
|
|
693
|
+
that an ollama request reaches `/api/chat` at the configured host, so the routing this removal
|
|
694
|
+
depends on cannot change unnoticed.
|
|
695
|
+
|
|
696
|
+
- 8226bc6: Fourteen negative-case tests now identify which guard fired, and a scheduled job keeps test-order
|
|
697
|
+
independence honest.
|
|
698
|
+
|
|
699
|
+
Assertions that only checked "something threw" now assert the error class, its stable code and a
|
|
700
|
+
message substring — for concurrency validation, retry configuration, path traversal, filename
|
|
701
|
+
validation and credential loading. Each conversion was verified by mutating the production error's
|
|
702
|
+
code and watching the corresponding test fail, so the assertions are pinned to the real constants
|
|
703
|
+
rather than to a copy of them.
|
|
704
|
+
|
|
705
|
+
Forty-five remaining sites are deliberately left alone and grouped with reasons: ten raise validation
|
|
706
|
+
errors owned by a third-party schema library, thirteen surface Node's own errors, and twenty-two are
|
|
707
|
+
plain untyped errors in our code where there is no class or code to assert yet.
|
|
708
|
+
|
|
709
|
+
Separately, the suite runs one file at a time, and a comment in the configuration said that was
|
|
710
|
+
covering up a leak. Measured: with file-level parallelism restored the suite is fully green, twice
|
|
711
|
+
over — the two leaks that comment named have since been fixed. Restoring _within-file_ concurrency
|
|
712
|
+
plus randomised order does still fail, reproducibly, in one file that shares a mutable counter
|
|
713
|
+
between its cases; that is filed on its own and is not fixed here.
|
|
714
|
+
|
|
715
|
+
The default gate is unchanged. A separate weekly job runs the suite in shuffled order so the
|
|
716
|
+
remaining coupling keeps surfacing instead of staying suppressed by the serial default.
|
|
717
|
+
|
|
718
|
+
Also documented for contributors: what makes a wait trustworthy, and why a premise that justifies
|
|
719
|
+
deleting something needs checking in a way that a premise justifying keeping something does not.
|
|
720
|
+
|
|
721
|
+
- e699569: **The repository moved to the official `usetheokit` organization.** Every `repository`, `bugs` and `homepage` field now points there, along with the README, `CONTRIBUTING.md`, `SECURITY.md` and the issue templates. Existing clones and any URL already published keep working — GitHub redirects a transferred repository permanently — so this is a correctness fix for the metadata npm renders, not a break.
|
|
722
|
+
|
|
723
|
+
**The Apache-2.0 text every package ships was replaced with the official one.** The copy distributed until now had paragraph 4(d) truncated: it read "except as required for describing the origin of the Work and reproducing the content of the NOTICE file", dropping "reasonable and customary use" from the licensed clause. §4(d) governs what a redistributor must do with attribution notices, and the omission narrowed it.
|
|
724
|
+
|
|
725
|
+
That matters more than a typo would. The manifests declare the SPDX identifier `Apache-2.0`, which is an assertion that the terms are _the_ Apache-2.0 terms — a licence scanner resolves the identifier and never reads the file. A consumer's compliance review, which does read the file, would find a body that no longer matches the identifier and has no name of its own. Every `LICENSE` in this repository is now byte-identical to the canonical text, with the appendix filled in.
|
|
726
|
+
|
|
727
|
+
Nothing else about the terms changed: the licence is the same licence it has always been meant to be, and no package changes what it grants.
|
|
728
|
+
|
|
729
|
+
- 6950332: A `PermissionRule` argument matcher written as a predicate was invoked with `undefined` when the
|
|
730
|
+
call supplied no such argument. The string and RegExp forms already treated a missing argument as
|
|
731
|
+
"does not match"; the predicate branch returned before that guard.
|
|
732
|
+
|
|
733
|
+
Both directions were wrong, and the first is a permission escape: an allow rule like
|
|
734
|
+
`(v) => v !== "prod"` returns `true` for `undefined`, so a call that supplied nothing produced an
|
|
735
|
+
explicit allow — a matcher written to narrow, widening. A deny rule like `(v) => v.includes("rm")`
|
|
736
|
+
raised `TypeError` out of the permission gate instead of denying.
|
|
737
|
+
|
|
738
|
+
A rule that declares an argument is a rule about that argument. A call that omitted it no longer
|
|
739
|
+
satisfies the rule, whatever form the matcher takes.
|
|
740
|
+
|
|
741
|
+
- 9e6828e: When the API key's own prefix or an explicit `providers.routes` entry overrides the provider named
|
|
742
|
+
in the model id, the SDK now says so once per process, naming both the provider asked for and the
|
|
743
|
+
one used.
|
|
744
|
+
|
|
745
|
+
The precedence itself is unchanged and deliberate: an explicitly-passed key is ground truth about
|
|
746
|
+
which endpoint will actually be reached, so a `sk-or-` key beats an `openai/...` prefix. What was
|
|
747
|
+
missing was the sentence. A caller writing `model: { id: "custom/model" }` and receiving
|
|
748
|
+
`openai API error: auth_failed` had no way to learn their prefix had been overruled, because the
|
|
749
|
+
error names only the winner.
|
|
750
|
+
|
|
751
|
+
Nothing is emitted when the model id carries no prefix, or when the prefix is what was used.
|
|
752
|
+
|
|
753
|
+
- e3f2a82: Every symbol these packages declare in `exports` now reaches the `.d.ts` they publish.
|
|
754
|
+
|
|
755
|
+
Sixty-six declarations across twenty-three published files did not compile, and four entry
|
|
756
|
+
points silently omitted names their own barrel exports — `@theokit/sdk/internal/security`
|
|
757
|
+
dropped seven at once. Runtime was never affected; this is types-only. A consumer with
|
|
758
|
+
`skipLibCheck` on saw nothing, and a consumer running type-aware lint saw every type reached
|
|
759
|
+
through one of them degrade to `error`.
|
|
760
|
+
|
|
761
|
+
The cause was `stripInternal`, which deletes a declaration when the literal `@internal`
|
|
762
|
+
appears in ANY leading comment range of it. The tag was being used here to mean "outside the
|
|
763
|
+
semver contract" — `internal/persistence/sqlite-open.ts` said so in those words, on a subpath
|
|
764
|
+
the manifest publishes and a back-compat test pins. The compiler reads it as "erase this", and
|
|
765
|
+
the two meanings only diverge in the published artifact. It now says the semver exemption in
|
|
766
|
+
prose, and the tag is gone from the symbols that are published.
|
|
767
|
+
|
|
768
|
+
Two further mechanisms had the same cause and a wider blast radius. A tag in a BARREL header
|
|
769
|
+
deleted the first `export … from` beneath it; a tag in a MODULE header deleted the following
|
|
770
|
+
`import`, so `import { z } from "zod"` vanished and every type it bound became
|
|
771
|
+
`Cannot find name`. Nothing was added to any `exports` map and no `export` line changed — a
|
|
772
|
+
deleted import was never privacy, only a broken declaration.
|
|
773
|
+
|
|
774
|
+
`@theokit/sdk-handoff`'s `./internal` entry left `SDKAgent` and `CustomTool` unbound, from a
|
|
775
|
+
different defect: the declaration repair only ever looked at `exports["."]`, so it fixed each
|
|
776
|
+
package's main entry and shipped the rest unrepaired. It now covers every declared subpath, and
|
|
777
|
+
binds the side-effect import form (`import '@theokit/sdk';`) the rollup emits with the names
|
|
778
|
+
stripped out.
|
|
779
|
+
|
|
780
|
+
Three gates were widened or added so this cannot return silently: the declaration typecheck
|
|
781
|
+
now covers all 45 published entries rather than 12, a new export-parity check fails when a
|
|
782
|
+
source barrel exports a name the emit omits, and public-API documentation coverage is gated at
|
|
783
|
+
100%.
|
|
784
|
+
|
|
785
|
+
Two consequences worth naming rather than discovering. `coerceToKnownAgentRunErrorCode` — the
|
|
786
|
+
boundary helper the 4.x release notes point at as the migration path off the open
|
|
787
|
+
`AgentRunErrorCode` union — was tagged internal and therefore absent from the published types; it
|
|
788
|
+
is now exported and documented, which is a small addition to the public surface. And
|
|
789
|
+
`packages/sdk/typedoc.json` sets `excludeInternal: true`, so the generated API reference gains the
|
|
790
|
+
~57 symbols whose tags were removed. That is the intended direction: those symbols are published,
|
|
791
|
+
and the reference now says so.
|
|
792
|
+
|
|
793
|
+
- ac08996: `sanitizeIdentifier` now reports every rejection as `ConfigurationError` with code
|
|
794
|
+
`invalid_identifier`.
|
|
795
|
+
|
|
796
|
+
It used to throw two classes and the input chose which: a NUL, C0 control char or DEL produced
|
|
797
|
+
`PathTraversalError` (code `path_traversal`), everything else produced `invalid_identifier`. A
|
|
798
|
+
caller branching on the documented code — the shape an HTTP handler uses to answer 400 — rethrew
|
|
799
|
+
for exactly the input class an attacker controls, so a rejection surfaced as a 500 and the 400/500
|
|
800
|
+
split became an oracle for which branch was reached. The input was rejected either way; this was
|
|
801
|
+
never a traversal bypass.
|
|
802
|
+
|
|
803
|
+
The message still names the offending byte (`<nul-byte>`, `<control-char-0x1f>`), which is the part
|
|
804
|
+
the second class existed for. `@theokit/sdk/workflow` validates step ids through this function and
|
|
805
|
+
inherits the fix.
|
|
806
|
+
|
|
807
|
+
- 96b28ba: Test-harness repairs: an unmeasurable socket probe now reports as skipped instead of passing, and a
|
|
808
|
+
fixed sleep is replaced by polling the real value.
|
|
809
|
+
|
|
810
|
+
The CLOSE_WAIT socket monitor returned a bare `null` when it could not measure — off Linux, or when
|
|
811
|
+
`ss` was unavailable — and the caller treated that as a pass. An environment where the probe could
|
|
812
|
+
not run was therefore indistinguishable from one where the assertion held. It now returns an explicit
|
|
813
|
+
unavailable result with a reason, the caller reports the case as skipped and names that reason, and
|
|
814
|
+
the assertion helper refuses an unavailable result rather than quietly doing nothing.
|
|
815
|
+
|
|
816
|
+
The same test slept a fixed 500ms to let the operating system finish tearing sockets down. The OS
|
|
817
|
+
decides that timing, not the test process, so the wait is now a poll against the real count with a
|
|
818
|
+
deadline. The threshold moves to the value the harness's own docblock documents; the number at the
|
|
819
|
+
call site had never matched it and never explained itself.
|
|
820
|
+
|
|
821
|
+
A shared polling helper replaces three more fixed sleeps in the semaphore tests, where the queue
|
|
822
|
+
depth is a real signal that can be waited on, and absorbs one hand-rolled poll loop that had already
|
|
823
|
+
been written by hand elsewhere.
|
|
824
|
+
|
|
825
|
+
Every change is verified by mutation rather than by construction: mutating the production semaphore's
|
|
826
|
+
pending-count turns the converted tests red, and three mutants of the socket monitor each kill the
|
|
827
|
+
test named for them.
|
|
828
|
+
|
|
829
|
+
Honest limit, recorded in the test and tracked separately: the CLOSE_WAIT assertion still cannot
|
|
830
|
+
detect a real leak. Removing the driver's own socket cleanup entirely leaves the count at zero,
|
|
831
|
+
because Node completes the FIN handshake on its own and the fixture server closes idle sockets. This
|
|
832
|
+
change makes the test honest about what it cannot measure; it does not give it detection power.
|
|
833
|
+
|
|
834
|
+
- f53ee6a: A stream cut mid-flight now delivers the text that already arrived, instead of dropping it.
|
|
835
|
+
|
|
836
|
+
Measured on a 200-chunk answer severed just before its terminator: the provider sent 1490 characters
|
|
837
|
+
and the consumer received none. Truncated streams are routine — proxy timeouts, load-balancer idle
|
|
838
|
+
limits, mobile links — and every one of them turned a mostly-complete answer into nothing, the more
|
|
839
|
+
so the longer the answer. The run is still reported as errored; what the caller gets back is the
|
|
840
|
+
choice of whether a partial answer is usable.
|
|
841
|
+
|
|
842
|
+
A body read that fails mid-stream is also routed through the transport-error mapper, so it reads
|
|
843
|
+
`openai transport failure on /v1/chat/completions: terminated` and carries `code:
|
|
844
|
+
"transport_failure"` instead of undici's bare `terminated` with no code. `RunResult.usage` is
|
|
845
|
+
documented as absent for such a run: the counts arrive with the terminating frame a severed
|
|
846
|
+
connection never delivers.
|
|
847
|
+
|
|
848
|
+
- 1af99fa: `maxDelegationDepth` now bounds the delegation chain it always claimed to.
|
|
849
|
+
|
|
850
|
+
The check ran once at tool-construction time against a `parentDepth` argument nothing in the SDK
|
|
851
|
+
incremented, so under the documented `SubAgent.create(spec)` call it could never fire and a
|
|
852
|
+
subagent whose tools include another subagent recursed unbounded. Depth is now counted at dispatch
|
|
853
|
+
and travels with the run, so nesting is bounded without threading a counter by hand.
|
|
854
|
+
|
|
855
|
+
A caller that does thread `parentDepth` keeps its existing behaviour — the threaded value offsets
|
|
856
|
+
the chain depth, and an already-impossible spec is still refused at construction.
|
|
857
|
+
|
|
858
|
+
- 8f8d3eb: Breaking out of a subscription now closes the underlying connection instead of leaving it open.
|
|
859
|
+
|
|
860
|
+
`Theokit.subscribe`'s SSE transport released its stream reader on exit but never cancelled it. Per
|
|
861
|
+
the Streams specification those are different operations: releasing detaches the reader and leaves
|
|
862
|
+
the stream — and therefore the `fetch` response and its socket — open until something else cancels it
|
|
863
|
+
or reads it to completion. So the ordinary consumer shape, breaking out of the loop early, left a
|
|
864
|
+
connection dangling every time. The WebSocket transport already closed its socket correctly; only the
|
|
865
|
+
SSE half was affected.
|
|
866
|
+
|
|
867
|
+
The reader is now cancelled on early exit, best-effort and skipped on natural completion, where the
|
|
868
|
+
stream is already finished and cancelling would only risk surfacing a spurious rejection.
|
|
869
|
+
|
|
870
|
+
This is the leak a load test in this repo has claimed to detect for some time and never could. That
|
|
871
|
+
test drove raw sockets with no SDK code in the path at all, and passed whether or not anything
|
|
872
|
+
cleaned up — measured by deleting its own cleanup call and watching the count stay at zero, twice.
|
|
873
|
+
Its claim is now withdrawn in the test itself and in that directory's README, and the real property
|
|
874
|
+
is asserted where the code actually lives: a test that drives the SSE and WebSocket transports
|
|
875
|
+
through injected mocks, with no network and no operating-system probing, and that fails when either
|
|
876
|
+
transport stops cleaning up.
|
|
877
|
+
|
|
878
|
+
Also included: the plugin manager's seven manifest-validation errors now each have a test asserting
|
|
879
|
+
the specific error class, code and message, plus cases each guard must accept — a guard tested only
|
|
880
|
+
on what it rejects cannot be told apart from one that rejects everything.
|
|
881
|
+
|
|
882
|
+
- 883f473: Seventeen module docblocks that opened with `@theokit/...` are rewritten to open with a sentence.
|
|
883
|
+
|
|
884
|
+
A JSDoc block whose first line begins with `@` has no description: TypeScript parses the whole block
|
|
885
|
+
as that tag's value, so `getDocumentationComment()` returns nothing and editor tooltips, TypeDoc and
|
|
886
|
+
this repo's doc-coverage instrument all report the symbol as undocumented while the source plainly
|
|
887
|
+
documents it. The affected files are the `server/auth` and `subscription` surfaces; the same words
|
|
888
|
+
now appear in an order the tooling can read.
|
|
889
|
+
|
|
890
|
+
A new `quality:doc-tag-first` gate fails the build on the shape, so it cannot come back.
|
|
891
|
+
|
|
892
|
+
- 36e5879: The task-registry tests wait for the state they need instead of sleeping.
|
|
893
|
+
|
|
894
|
+
Twelve waits in that suite were fixed sleeps between 10ms and 200ms, each chosen to be "long enough"
|
|
895
|
+
for the registry's fire-and-forget work to reach a state. The state is observable — the registry can
|
|
896
|
+
be asked for it — so the sleep was guessing at something the test could simply read. Under load those
|
|
897
|
+
guesses stop being long enough, which is how a suite acquires flakes that only appear on a busy
|
|
898
|
+
machine or a slow runner.
|
|
899
|
+
|
|
900
|
+
Each now polls the real state with a deadline. A passing run is never slower than the sleep it
|
|
901
|
+
replaced, because it returns the moment the state arrives; a state that genuinely never arrives fails
|
|
902
|
+
with the state it was waiting for, rather than an assertion on stale data.
|
|
903
|
+
|
|
904
|
+
The shared polling helper was widened to accept an asynchronous condition rather than growing a
|
|
905
|
+
second near-identical copy for the case where the value has to be awaited.
|
|
906
|
+
|
|
907
|
+
- b68704b: `JsonFileTaskStore.list()` no longer hides tasks past the 256th file.
|
|
908
|
+
|
|
909
|
+
The 256-entry cap was applied to the raw directory listing, before `state`, `kind` and the
|
|
910
|
+
`submittedBefore` / `submittedAfter` window were considered — so past 256 task files the visible
|
|
911
|
+
set was an arbitrary, readdir-ordered subset, `submittedBefore` narrowed within that subset instead
|
|
912
|
+
of paging beyond it, and `evictTerminalOlderThan()` left eligible handles behind however many times
|
|
913
|
+
it was called.
|
|
914
|
+
|
|
915
|
+
The cap is now a bound on concurrent file reads, which is the cost it was meant to control, and
|
|
916
|
+
results come back newest-first so `submittedBefore` works as a cursor. Eviction sweeps the whole
|
|
917
|
+
directory: one call now means everything eligible is gone.
|
|
918
|
+
|
|
919
|
+
- 9ab1f0d: The test suite runs its files in parallel again.
|
|
920
|
+
|
|
921
|
+
It had been pinned to one file at a time, with a comment explaining that the serialisation was holding
|
|
922
|
+
back two leaks: tests mutating the home directory environment variable, and a process-wide registry
|
|
923
|
+
accumulating entries across tests. Both were fixed elsewhere, and nobody went back to ask whether the
|
|
924
|
+
constraint still had a reason. It did not — what actually prevents the home-directory race is that
|
|
925
|
+
each file already gets its own subprocess, which is a separate setting and unchanged here.
|
|
926
|
+
|
|
927
|
+
One genuine coupling had to be removed first: a contract test kept a file-level counter that three of
|
|
928
|
+
its cases each expected a specific value from, which only holds if they run in declaration order. Each
|
|
929
|
+
case now owns its own identifier, so nothing is shared to race over.
|
|
930
|
+
|
|
931
|
+
Within-file concurrency stays capped at one, deliberately. The more aggressive configuration —
|
|
932
|
+
concurrent cases plus randomised order — remains a separate periodic probe rather than part of the
|
|
933
|
+
gate, and a test now pins that split so it cannot drift quietly.
|
|
934
|
+
|
|
935
|
+
- 464c390: Repairs four quality gates that were measuring something other than what they claimed.
|
|
936
|
+
|
|
937
|
+
**The Portuguese-language lint no longer scans files git does not track.** It walked the tree with
|
|
938
|
+
`readdir` and skipped only dot-directories, so it flagged untracked files CI never sees — going red
|
|
939
|
+
on a developer's machine while CI stayed green — and simultaneously missed `.github/workflows/`,
|
|
940
|
+
which CI very much does have. A red that CI cannot reproduce is what teaches people to reach for
|
|
941
|
+
`--no-verify`. The scan is now driven by `git ls-files`, which fixes both halves at once: untracked
|
|
942
|
+
files disappear by construction, and tracked dot-directories come into scope. Portuguese text the
|
|
943
|
+
lint could not previously see in the CI workflow is translated as part of the change.
|
|
944
|
+
|
|
945
|
+
**The pre-push Biome gate has the same repair.** `biome check .` walked everything on disk;
|
|
946
|
+
`biome.json`'s `vcs.useIgnoreFile` skips gitignored files but not untracked-but-unignored ones, which
|
|
947
|
+
is exactly the class that broke the gate. Measured: the tracked-only scan and the walk-everything
|
|
948
|
+
scan process the same 1686 files on a clean tree, so scoping to tracked files costs no coverage.
|
|
949
|
+
|
|
950
|
+
**The pre-commit typecheck no longer typechecks all fifteen packages on every commit.** It is scoped
|
|
951
|
+
to the packages the diff actually touches, with a guard the item this came from insisted on: the run
|
|
952
|
+
reports how many packages it selected, and a selection of zero fails loudly instead of exiting 0.
|
|
953
|
+
That silent-zero case is real — a stale or unfetched ref makes the scoped filter select nothing while
|
|
954
|
+
turbo reports success — and swapping an expensive honest gate for a cheap silent one would have
|
|
955
|
+
reproduced the defect being repaired. The full unscoped verdict still runs at pre-push and in CI.
|
|
956
|
+
|
|
957
|
+
**Dead Vitest 4 settings are removed rather than migrated.** The config carried a `poolOptions` block
|
|
958
|
+
that Vitest 4 no longer reads, printing a deprecation warning on every run. Migrating those keys
|
|
959
|
+
would not have revived the knob they configured: `fileParallelism: false` overwrites the worker count
|
|
960
|
+
unconditionally, so the `SDK_TEST_MAX_FORKS` environment variable was inert by two independent paths.
|
|
961
|
+
The block and the variable are deleted, `fileParallelism: false` is kept (test-order safety currently
|
|
962
|
+
depends on it), and Vitest 4's actual replacement for the isolation setting is declared explicitly.
|
|
963
|
+
|
|
964
|
+
- c7385d2: Test runs no longer claim every core on the host.
|
|
965
|
+
|
|
966
|
+
None of the package configs capped `maxWorkers`, so vitest's default applied: `os.availableParallelism()`,
|
|
967
|
+
one fork per core, each booting a full test environment. The repo's `test` script is
|
|
968
|
+
`turbo run test --filter='./packages/*'`, so that default is paid once per package _concurrently_ —
|
|
969
|
+
nproc forks times turbo's concurrency, on nproc cores. Measured on a 12-thread machine during an
|
|
970
|
+
unrelated investigation, two vitest pools alone were enough to reach load average 33.89 with the
|
|
971
|
+
desktop unusable; a full fan-out is several times that.
|
|
972
|
+
|
|
973
|
+
`@theokit/sdk` is the interesting case. B-104 recorded on 2026-08-19 that the `poolOptions.forks.*`
|
|
974
|
+
block was 100% dead in Vitest 4, deleted it, and noted that `fileParallelism: false` was forcing
|
|
975
|
+
`maxWorkers` to 1 unconditionally, so a fork-count knob could not act. B-059 then flipped
|
|
976
|
+
`fileParallelism` to `true` on 2026-08-20, which made the knob able to act again — and nothing
|
|
977
|
+
reintroduced one, so the package silently went back to the uncapped default. That comment has been
|
|
978
|
+
corrected along with the config; it claimed no knob existed, which is no longer true.
|
|
979
|
+
|
|
980
|
+
The cap leaves 4 cores free (`Math.max(2, cpus().length - 4)`), scaling with the runner rather than
|
|
981
|
+
hard-coding one machine's core count. It costs no wall-clock: measured in `theokit-ui`, the full
|
|
982
|
+
suite ran 73.96s at 4 workers against 74.36s at 12, so the parallelism above the cap was already
|
|
983
|
+
noise. Verified as resolved config rather than as file contents — `createVitest` reports
|
|
984
|
+
`maxWorkers: 8` on a 12-thread host, which is the formula, not the default.
|
|
985
|
+
|
|
986
|
+
This changes no published behaviour; it is test tooling only. Refs usetheokit/theokit-ui#51.
|
|
987
|
+
|
|
988
|
+
- 9f5cc20: A test run can no longer write into the developer's real home directory.
|
|
989
|
+
|
|
990
|
+
The shared test setup gave every test an isolated `THEOKIT_HOME` in a fresh temporary directory, and
|
|
991
|
+
backed up `HOME` alongside it — but never actually set `HOME`. So any module reading `HOME` or
|
|
992
|
+
`os.homedir()` directly, instead of consulting `THEOKIT_HOME`, resolved to the real home and wrote
|
|
993
|
+
there. That was not hypothetical: the MCP token store did exactly this, and a real `~/.theokit`
|
|
994
|
+
credential file was observed accumulating test fixtures and changing timestamps across an afternoon
|
|
995
|
+
of runs.
|
|
996
|
+
|
|
997
|
+
That one module was fixed previously. This closes the gap itself, so the next module that reads the
|
|
998
|
+
home directory without going through `THEOKIT_HOME` cannot repeat it. Isolation is now enforced by
|
|
999
|
+
the setup rather than by each module remembering, which is the difference between a property and a
|
|
1000
|
+
convention.
|
|
1001
|
+
|
|
1002
|
+
Verified the way the problem was originally found: the golden MCP suite was run with `HOME` pointed
|
|
1003
|
+
at a throwaway sentinel directory, and nothing was written to it.
|
|
1004
|
+
|
|
1005
|
+
Also included: the dependency-boundary check now cruises the test tree as well as the source tree,
|
|
1006
|
+
and the code-quality gate refuses to report success when it audited no languages at all — previously
|
|
1007
|
+
a gate with nothing enabled returned a pass, which is indistinguishable from a clean run.
|
|
1008
|
+
|
|
1009
|
+
- 5fac0f6: Test-suite hygiene: scratch directories are cleaned up, the working directory is no longer mutated
|
|
1010
|
+
process-wide, and the agent registry starts empty in every test.
|
|
1011
|
+
|
|
1012
|
+
Fifty-nine test files created temporary directories and never removed them, so a full run left its
|
|
1013
|
+
debris behind on every machine that executed it. Each now removes its directory when the test
|
|
1014
|
+
finishes, through the same retry-hardened helper the workspace fixture already used — the retries
|
|
1015
|
+
matter because a directory holding a file another handle has open cannot be removed on the first
|
|
1016
|
+
attempt.
|
|
1017
|
+
|
|
1018
|
+
Three tests changed the process's working directory to exercise code that reads it. `process.chdir`
|
|
1019
|
+
is process-wide, so a test doing that mutates the environment of every other test sharing the worker,
|
|
1020
|
+
and the two production paths involved hardcode the current directory with no override to pass. They
|
|
1021
|
+
now replace the reader rather than the process state. A lint test bans any future live `chdir` under
|
|
1022
|
+
the test tree, so this does not return for a fourth time.
|
|
1023
|
+
|
|
1024
|
+
The agent registry is a process-wide map that does not follow the per-test home directory, so entries
|
|
1025
|
+
accumulated across tests and individual files had taken to clearing it by hand — which only works for
|
|
1026
|
+
the files that remember. It is now cleared by the shared setup, unconditionally.
|
|
1027
|
+
|
|
1028
|
+
One test file was removed rather than repaired: it exercised a locally-declared copy of a concurrency
|
|
1029
|
+
helper instead of the real one, so nothing it asserted could fail when production changed. Its one
|
|
1030
|
+
genuinely distinct assertion — that three tasks overlap under a barrier — moved to a test that drives
|
|
1031
|
+
the real function, and was verified by stubbing that function to return nothing and watching four
|
|
1032
|
+
tests die.
|
|
1033
|
+
|
|
1034
|
+
- e685ccb: The model catalog was fetched with `res.text()` and written to the cache with no size limit. The
|
|
1035
|
+
default source is trusted, but `THEOKIT_MODELS_URL` lets an operator point the fetch anywhere, and
|
|
1036
|
+
a host serving a multi-gigabyte document would have been materialised in memory and then written
|
|
1037
|
+
to disk.
|
|
1038
|
+
|
|
1039
|
+
The fetch now refuses anything over 32 MiB — roughly 40x the real catalog. The declared
|
|
1040
|
+
`content-length` is checked before the body is read, and the received size is checked after,
|
|
1041
|
+
because a server that omits or misstates the header is exactly the one worth bounding.
|
|
1042
|
+
|
|
1043
|
+
A refused catalog is handled the way every other refresh failure already is: the SDK keeps serving
|
|
1044
|
+
the data it had, and says so.
|
|
1045
|
+
|
|
1046
|
+
- 7fd8c7e: Removes two guards no caller could reach, makes `Batch`'s `concurrency` option actually bound
|
|
1047
|
+
`onResult`, and stops three `Agent` APIs from accepting documented options they discarded.
|
|
1048
|
+
|
|
1049
|
+
**`concurrency` now bounds `onResult`.** The semaphore slot was released before the result callback
|
|
1050
|
+
ran, so a batch configured with `concurrency: 2` could have any number of `onResult` callbacks in
|
|
1051
|
+
flight at once. Callers using that option to protect a rate-limited downstream — the reason to set it
|
|
1052
|
+
at all — were not protected. The callback now runs inside the slot it belongs to. A test that had
|
|
1053
|
+
pinned the old behaviour as a contract is inverted, because it documented the bug as a promise.
|
|
1054
|
+
|
|
1055
|
+
**Three `Agent` APIs honour their options or stop accepting them.** `Agent.get` and `Agent.listRuns`
|
|
1056
|
+
took a `cwd` and ignored it, so they answered about the wrong workspace; `Agent.list` took
|
|
1057
|
+
`includeArchived`, `limit` and `cursor` and ignored all three. Each is now wired, with pagination
|
|
1058
|
+
opt-in so the default ordering is unchanged. Two options are removed rather than half-implemented:
|
|
1059
|
+
`prUrl`, which would need the on-disk registry to retain per-repo URLs, and `ListRunsOptions.runtime`,
|
|
1060
|
+
which is redundant once an `agentId` pins the runtime. Silently discarding a documented option is
|
|
1061
|
+
worse than not offering it, because the caller has no way to detect it.
|
|
1062
|
+
|
|
1063
|
+
**One unreachable guard is deleted.** The Vertex client's fetch wrapper branched on `URL` and
|
|
1064
|
+
`Request` input forms its only caller never produces, and on a URL condition that caller always
|
|
1065
|
+
satisfies. It is removed rather than annotated: a defensive branch nothing can reach is a decoy that
|
|
1066
|
+
reads like working machinery, and this project has spent real time on several of them.
|
|
1067
|
+
|
|
1068
|
+
- 60010b4: Provider-reported token usage is validated before it reaches `run.usage`, the cost calculation and
|
|
1069
|
+
`@theokit/sdk-budget`.
|
|
1070
|
+
|
|
1071
|
+
A negative count used to be billed as a negative cost and moved a budget gate downward; a numeric
|
|
1072
|
+
string was concatenated rather than summed, producing `"0100050"` where a total was intended. Both
|
|
1073
|
+
now drop with a diagnostic naming the field, and a numeric string parses. Fractional counts are
|
|
1074
|
+
floored rather than discarded.
|
|
1075
|
+
|
|
1076
|
+
Magnitude is deliberately not checked: any ceiling here would be invented, rejecting a legitimate
|
|
1077
|
+
large batch while still passing anything just under it. That is a budget policy, and
|
|
1078
|
+
`@theokit/sdk-budget` is where a cap belongs.
|
|
1079
|
+
|
|
1080
|
+
- 25b7eee: `Workflow` is now one type across `@theokit/sdk` and `@theokit/sdk/workflow`.
|
|
1081
|
+
|
|
1082
|
+
The two entries were built by different declaration pipelines and each emitted its own
|
|
1083
|
+
`declare class Workflow`. A class with a private field is compared nominally, so the documented
|
|
1084
|
+
combination — `import { Workflow } from "@theokit/sdk/workflow"` passed to `Cron.create` from the
|
|
1085
|
+
root — was rejected with "types have separate declarations of a private property '\_options'".
|
|
1086
|
+
Nothing in-tree crosses that boundary, because in-tree code imports from `src/`.
|
|
1087
|
+
|
|
1088
|
+
Both entries now resolve to a single declaration, and a new `quality:dts-identity` gate fails the
|
|
1089
|
+
build if any exported class is ever declared twice across published entries again.
|
|
1090
|
+
|
|
3
1091
|
## 4.53.0
|
|
4
1092
|
|
|
5
1093
|
### Minor Changes
|
|
@@ -473,7 +1561,7 @@
|
|
|
473
1561
|
|
|
474
1562
|
The profile shipped `originator: "codex_cli_rs"` — the value the official Codex CLI sends for itself.
|
|
475
1563
|
Presenting another vendor's client name is a false statement of identity, and it diverged from the
|
|
476
|
-
prior art
|
|
1564
|
+
prior art: third-party clients send their own name against the same endpoint,
|
|
477
1565
|
which also shows the route is not restricted to the official client.
|
|
478
1566
|
|
|
479
1567
|
A test pinned the old value as the contract, which is how it survived review — correcting the
|
|
@@ -1077,7 +2165,7 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
|
|
|
1077
2165
|
|
|
1078
2166
|
### Minor Changes
|
|
1079
2167
|
|
|
1080
|
-
- Data-provider fleet (agent-builder M45): 9 new first-party builtins on a data-only `openAiCompatibleProfile` base — `google` (DIRECT Gemini via the OpenAI-compat endpoint, `GOOGLE_API_KEY`/`GEMINI_API_KEY`; distinct from the `gemini` OpenRouter passthrough), `mistral`, `groq`, `cohere` (via `api.cohere.ai/compatibility/v1`), `deepinfra`, `together` (alias `togetherai`), `xai` (alias `grok`), `perplexity`, `cerebras` — each ~10 lines with source-cited values. Two defects fixed: the chat_completions URL-join no longer doubles version segments (`…/v1/v1/chat/completions` — every version-suffixed catalog baseUrl was broken for streaming) via version-segment detection + a data-only `ProviderProfile.chatCompletionsPath` escape (existing builtins byte-identical, contract-asserted), and Google is finally reachable (the `google-gemini` catalog entry was silently skipped by an alias collision). The `anthropic_messages` transport now consumes `extraHeaders` + the provider `transform` (mirror of the M41 chat_completions wiring) and the anthropic builtin ships `anthropic-beta: interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14` (the sanctioned behavior delta); openrouter gains theokit's own attribution headers (`HTTP-Referer: https://usetheo.dev`, `X-Title: theokit`); cerebras sends `X-Cerebras-3rd-Party-Integration: theokit`. A table-driven contract suite asserts identity + the EXACT wire URL and headers per provider.
|
|
2168
|
+
- Data-provider fleet (agent-builder M45): 9 new first-party builtins on a data-only `openAiCompatibleProfile` base — `google` (DIRECT Gemini via the OpenAI-compat endpoint, `GOOGLE_API_KEY`/`GEMINI_API_KEY`; distinct from the `gemini` OpenRouter passthrough), `mistral`, `groq`, `cohere` (via `api.cohere.ai/compatibility/v1`), `deepinfra`, `together` (alias `togetherai`), `xai` (alias `grok`), `perplexity`, `cerebras` — each ~10 lines with source-cited values. Two defects fixed: the chat_completions URL-join no longer doubles version segments (`…/v1/v1/chat/completions` — every version-suffixed catalog baseUrl was broken for streaming) via version-segment detection + a data-only `ProviderProfile.chatCompletionsPath` escape (existing builtins byte-identical, contract-asserted), and Google is finally reachable (the `google-gemini` catalog entry was silently skipped by an alias collision). The `anthropic_messages` transport now consumes `extraHeaders` + the provider `transform` (mirror of the M41 chat_completions wiring) and the anthropic builtin ships `anthropic-beta: interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14` (the sanctioned behavior delta); openrouter gains theokit's own attribution headers (`HTTP-Referer: https://usetheo.dev`, `X-Title: theokit`); cerebras sends `X-Cerebras-3rd-Party-Integration: theokit`. A table-driven contract suite asserts identity + the EXACT wire URL and headers per provider.
|
|
1081
2169
|
|
|
1082
2170
|
## 4.13.1
|
|
1083
2171
|
|
|
@@ -1089,7 +2177,7 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
|
|
|
1089
2177
|
|
|
1090
2178
|
### Minor Changes
|
|
1091
2179
|
|
|
1092
|
-
- Model catalog enrichment (agent-builder M44): the vendored `provider-catalog.json` now carries OPTIONAL per-model data (`models` block — models.dev shape verbatim: `cost{input,output,cache_read,cache_write}` USD-per-1M, `limit{context,input,output}`, `modalities`, `tool_call`/`reasoning`/`structured_output`/`cache_control`, `release_date`, `status`), loaded into an internal model-info index keyed `provider/model` (entry id + aliases). Fully additive: entries without `models` behave byte-identically, `ProviderProfile` is untouched, the 10 builtins + all 43 catalog entries keep resolving, and a malformed model sub-entry drops that model with WARN keeping the provider. DRY reconciliation: `resolveModelCapabilities` is now catalog-backed (the hand-curated EXACT map migrated into the catalog and was deleted — parity-tested over the full old-map snapshot), and `getPricingEntry` gains a step-5 catalog fallback on total LiteLLM miss (provenance `pricingVersion:"catalog-vendored"`; the LiteLLM snapshot keeps absolute precedence — and the new drift advisory caught a real stale rate: `openai/o3` corrected 10/40 → 2/8). New on `@theokit/sdk/models`: `getModelInfo(modelId)` (the enriched per-model view) and `refreshModelCatalog({url?, force?})` — an EXPLICIT opt-in models.dev refresh with a 1h-TTL atomic disk cache under `~/.theokit/cache/models-dev/`, kill-switch `THEOKIT_DISABLE_MODELS_FETCH`, and the vendored catalog as offline fallback; startup and requests never touch the network.
|
|
2180
|
+
- Model catalog enrichment (agent-builder M44): the vendored `provider-catalog.json` now carries OPTIONAL per-model data (`models` block — models.dev shape verbatim: `cost{input,output,cache_read,cache_write}` USD-per-1M, `limit{context,input,output}`, `modalities`, `tool_call`/`reasoning`/`structured_output`/`cache_control`, `release_date`, `status`), loaded into an internal model-info index keyed `provider/model` (entry id + aliases). Fully additive: entries without `models` behave byte-identically, `ProviderProfile` is untouched, the 10 builtins + all 43 catalog entries keep resolving, and a malformed model sub-entry drops that model with WARN keeping the provider. DRY reconciliation: `resolveModelCapabilities` is now catalog-backed (the hand-curated EXACT map migrated into the catalog and was deleted — parity-tested over the full old-map snapshot), and `getPricingEntry` gains a step-5 catalog fallback on total LiteLLM miss (provenance `pricingVersion:"catalog-vendored"`; the LiteLLM snapshot keeps absolute precedence — and the new drift advisory caught a real stale rate: `openai/o3` corrected 10/40 → 2/8). New on `@theokit/sdk/models`: `getModelInfo(modelId)` (the enriched per-model view) and `refreshModelCatalog({url?, force?})` — an EXPLICIT opt-in models.dev refresh with a 1h-TTL atomic disk cache under `~/.theokit/cache/models-dev/`, kill-switch `THEOKIT_DISABLE_MODELS_FETCH`, and the vendored catalog as offline fallback; startup and requests never touch the network. Maintenance: `scripts/refresh-catalog.mjs` regenerates the curated vendored subset (30 models, +36KB).
|
|
1093
2181
|
|
|
1094
2182
|
## 4.12.2
|
|
1095
2183
|
|
|
@@ -1107,19 +2195,19 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
|
|
|
1107
2195
|
|
|
1108
2196
|
### Minor Changes
|
|
1109
2197
|
|
|
1110
|
-
- Codex provider as a builtin (agent-builder M43): a new first-class `openai-chatgpt` builtin `ProviderProfile` routes `openai-chatgpt/<model>` ids to the ChatGPT "Codex" backend (`https://chatgpt.com/backend-api/codex`, `responses_api`). Its `transform.fetch` resolves the LIVE credential from the ambient store per HTTP request — a freshly-refreshed Bearer + a dynamic `ChatGPT-Account-Id` header — so a mid-turn token expiry refreshes transparently with NO agent rebuild, and a not-logged-in request fails fast (no placeholder on the wire). The ambient store is `~/.theokit/auth.json` with a `THEOKIT_HOME` override so a consumer points it at its own store. Two account_id lifecycle fixes ship alongside: `ensureFreshCredential` now PRESERVES a stored `account_id` across refresh (OpenAI's refresh JWTs carry no top-level `account_id`), and `openaiDeviceLogin` JWT-extracts `chatgpt_account_id` at login.
|
|
2198
|
+
- Codex provider as a builtin (agent-builder M43): a new first-class `openai-chatgpt` builtin `ProviderProfile` routes `openai-chatgpt/<model>` ids to the ChatGPT "Codex" backend (`https://chatgpt.com/backend-api/codex`, `responses_api`). Its `transform.fetch` resolves the LIVE credential from the ambient store per HTTP request — a freshly-refreshed Bearer + a dynamic `ChatGPT-Account-Id` header — so a mid-turn token expiry refreshes transparently with NO agent rebuild, and a not-logged-in request fails fast (no placeholder on the wire). The ambient store is `~/.theokit/auth.json` with a `THEOKIT_HOME` override so a consumer points it at its own store. Two account_id lifecycle fixes ship alongside: `ensureFreshCredential` now PRESERVES a stored `account_id` across refresh (OpenAI's refresh JWTs carry no top-level `account_id`), and `openaiDeviceLogin` JWT-extracts `chatgpt_account_id` at login. Consumers add a provider in one SDK file; the Codex backend needs zero provider logic in the app.
|
|
1111
2199
|
|
|
1112
2200
|
## 4.11.1
|
|
1113
2201
|
|
|
1114
2202
|
### Patch Changes
|
|
1115
2203
|
|
|
1116
|
-
- Auth subsystem review fixes (agent-builder M42), grounded in
|
|
2204
|
+
- Auth subsystem review fixes (agent-builder M42), grounded in the provider-auth model: (1) an oauth provider that resolves NO credential now fails fast with a `ConfigurationError` (the `MissingCredentialError` analog) instead of putting the `__oauth_lazy_token__` placeholder on the wire — a placeholder is never sent; (2) `resolveCredential` no longer attributes a provider-less or mismatched-provider stored key to the requested provider (fail-closed — prevents cross-vendor key exposure, e.g. an Anthropic key POSTed to api.openai.com). The credential store/engine mechanics are unchanged.
|
|
1117
2205
|
|
|
1118
2206
|
## 4.11.0
|
|
1119
2207
|
|
|
1120
2208
|
### Minor Changes
|
|
1121
2209
|
|
|
1122
|
-
- Auth subsystem (agent-builder M42): a new `@theokit/sdk/auth` sub-entry ships a credential store + OAuth engine, promoted DOWN from agent-builder's hardened M37 code, generalized to `provider: string` + a caller-supplied `CredentialStoreConfig` (no hardcoded client IDs). Public surface (`import { … } from "@theokit/sdk/auth"`): `resolveCredential(name)` returns a fresh (transparently-refreshed) `ResolvedCredential`; the credential store (`writeCredential`/`readAuthFile`/`readStoredOAuth`/`authFilePath`/`credentialHome`/`CredentialError`), the OAuth engine (`exchangeCode`/`refreshOAuthTokens`/`ensureFreshCredential`/`persistOAuthTokens`), the device flows (`deviceLogin`/`openaiDeviceLogin`/`requestDeviceCode`/`pollDeviceToken`/`requestOpenAIUsercode`/`parseJwtClaims`/`extractAccountId`), and the contract types (`CredentialStoreConfig`, `ResolvedCredential`, `StoredOAuthCredential`, `OAuthProviderConfig`, `OAuthTokens`, `HttpDeps`, `DeviceOAuthConfig`, `OpenAIDeviceConfig`, …). It sits at a dedicated sub-entry (DTS via tsc) — the same isolation as `@theokit/sdk/messages` / `/subscription` / `/sanitize` — because rollup-plugin-dts cannot bundle the modules into the main barrel. The credential store does an atomic O_EXCL + rename + fsync write at mode 0600 with 0700/0600 mode gates; the OAuth engine implements RFC 8628 device-grant + the OpenAI two-step headless flow + token exchange/refresh with in-flight-refresh coalescing (keyed by store path, rejected promise evicted — single-use refresh tokens are never double-spent) and a no-token-in-error discipline. The router's lazy-sentinel path now covers `oauth_device_code` / `oauth_external` so an oauth provider builds a client whose M41 `transform.fetch(ctx)` owns the fresh bearer at stream time — a mid-turn expiry refreshes without rebuilding the agent, and plain (api-key/env) profiles resolve byte-for-byte unchanged.
|
|
2210
|
+
- Auth subsystem (agent-builder M42): a new `@theokit/sdk/auth` sub-entry ships a credential store + OAuth engine, promoted DOWN from agent-builder's hardened M37 code, generalized to `provider: string` + a caller-supplied `CredentialStoreConfig` (no hardcoded client IDs). Public surface (`import { … } from "@theokit/sdk/auth"`): `resolveCredential(name)` returns a fresh (transparently-refreshed) `ResolvedCredential`; the credential store (`writeCredential`/`readAuthFile`/`readStoredOAuth`/`authFilePath`/`credentialHome`/`CredentialError`), the OAuth engine (`exchangeCode`/`refreshOAuthTokens`/`ensureFreshCredential`/`persistOAuthTokens`), the device flows (`deviceLogin`/`openaiDeviceLogin`/`requestDeviceCode`/`pollDeviceToken`/`requestOpenAIUsercode`/`parseJwtClaims`/`extractAccountId`), and the contract types (`CredentialStoreConfig`, `ResolvedCredential`, `StoredOAuthCredential`, `OAuthProviderConfig`, `OAuthTokens`, `HttpDeps`, `DeviceOAuthConfig`, `OpenAIDeviceConfig`, …). It sits at a dedicated sub-entry (DTS via tsc) — the same isolation as `@theokit/sdk/messages` / `/subscription` / `/sanitize` — because rollup-plugin-dts cannot bundle the modules into the main barrel. The credential store does an atomic O_EXCL + rename + fsync write at mode 0600 with 0700/0600 mode gates; the OAuth engine implements RFC 8628 device-grant + the OpenAI two-step headless flow + token exchange/refresh with in-flight-refresh coalescing (keyed by store path, rejected promise evicted — single-use refresh tokens are never double-spent) and a no-token-in-error discipline. The router's lazy-sentinel path now covers `oauth_device_code` / `oauth_external` so an oauth provider builds a client whose M41 `transform.fetch(ctx)` owns the fresh bearer at stream time — a mid-turn expiry refreshes without rebuilding the agent, and plain (api-key/env) profiles resolve byte-for-byte unchanged.
|
|
1123
2211
|
|
|
1124
2212
|
## 4.10.1
|
|
1125
2213
|
|
|
@@ -1131,7 +2219,7 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
|
|
|
1131
2219
|
|
|
1132
2220
|
### Minor Changes
|
|
1133
2221
|
|
|
1134
|
-
- Provider `transform` seam (agent-builder M41): `ProviderProfile` gains an optional `transform` (dynamic `headers(ctx)` + refresh-aware `fetch(ctx)`), fed through `selectTransport` into the `chat_completions` + `responses_api` transports — a provider can now own its per-request auth/headers. A profile without `transform` takes the static path byte-for-byte.
|
|
2222
|
+
- Provider `transform` seam (agent-builder M41): `ProviderProfile` gains an optional `transform` (dynamic `headers(ctx)` + refresh-aware `fetch(ctx)`), fed through `selectTransport` into the `chat_completions` + `responses_api` transports — a provider can now own its per-request auth/headers. A profile without `transform` takes the static path byte-for-byte.
|
|
1135
2223
|
|
|
1136
2224
|
## 4.9.1
|
|
1137
2225
|
|
|
@@ -1143,7 +2231,7 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
|
|
|
1143
2231
|
|
|
1144
2232
|
### Minor Changes
|
|
1145
2233
|
|
|
1146
|
-
- `responses_api` transport (agent-builder M40): a `ResponsesApiClient` for the OpenAI Responses API (ChatGPT Codex backend + any responses provider). The `responses_api` apiMode was declared but had no transport (`selectTransport` threw); this ships it — body build + SSE state machine, consuming `baseUrl` + `extraHeaders`.
|
|
2234
|
+
- `responses_api` transport (agent-builder M40): a `ResponsesApiClient` for the OpenAI Responses API (ChatGPT Codex backend + any responses provider). The `responses_api` apiMode was declared but had no transport (`selectTransport` threw); this ships it — body build + SSE state machine, consuming `baseUrl` + `extraHeaders`. Recorded fixtures serve as golden tests.
|
|
1147
2235
|
|
|
1148
2236
|
## 4.8.0
|
|
1149
2237
|
|