@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/dist/mcp-auth.js
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
|
-
import { atomicWriteJson } from './chunk-
|
|
2
|
-
import { assertSecureModes } from './chunk-
|
|
3
|
-
import { ConfigurationError } from './chunk-
|
|
4
|
-
import
|
|
1
|
+
import { atomicWriteJson } from './chunk-VF7EWVDG.js';
|
|
2
|
+
import { assertSecureModes } from './chunk-UQGQFBRL.js';
|
|
3
|
+
import { ConfigurationError } from './chunk-IDCKSLYH.js';
|
|
4
|
+
import './chunk-T7XEKOVW.js';
|
|
5
|
+
import { diag } from './chunk-T7O6K6PX.js';
|
|
5
6
|
import { randomBytes, createHash } from 'crypto';
|
|
6
7
|
import { createServer } from 'http';
|
|
7
8
|
import { createInterface } from 'readline/promises';
|
|
8
9
|
import { existsSync, readFileSync, chmodSync, mkdirSync } from 'fs';
|
|
9
10
|
import { createRequire } from 'module';
|
|
10
11
|
import { homedir } from 'os';
|
|
11
|
-
import {
|
|
12
|
+
import { dirname, join } from 'path';
|
|
12
13
|
|
|
13
14
|
var KEYTAR_SERVICE = "theokit-mcp";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
function storeFilePath() {
|
|
16
|
+
return storeLocation().file;
|
|
17
|
+
}
|
|
18
|
+
function storeLocation() {
|
|
19
|
+
const override = process.env.THEOKIT_HOME?.trim();
|
|
20
|
+
if (override !== void 0 && override.length > 0) {
|
|
21
|
+
return { dir: override, file: join(override, "mcp-tokens.json"), ours: false };
|
|
22
|
+
}
|
|
23
|
+
const fromEnv = process.platform === "win32" ? process.env.USERPROFILE?.trim() : process.env.HOME?.trim();
|
|
24
|
+
const home = fromEnv !== void 0 && fromEnv.length > 0 ? fromEnv : homedir();
|
|
25
|
+
const dir = join(home, ".theokit");
|
|
26
|
+
return { dir, file: join(dir, "mcp-tokens.json"), ours: true };
|
|
27
|
+
}
|
|
28
|
+
function ensurePrivateStoreDir({ dir, ours }) {
|
|
17
29
|
try {
|
|
18
30
|
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
19
|
-
chmodSync(dir, 448);
|
|
31
|
+
if (ours) chmodSync(dir, 448);
|
|
20
32
|
} catch {
|
|
21
33
|
}
|
|
22
34
|
}
|
|
@@ -30,7 +42,8 @@ function tryRequireKeytar() {
|
|
|
30
42
|
} catch {
|
|
31
43
|
if (!keytarWarned) {
|
|
32
44
|
diag(
|
|
33
|
-
|
|
45
|
+
`[theokit-sdk] keytar not installed; MCP OAuth tokens will be stored in ${storeFilePath()} (chmod 600 where POSIX). Install \`keytar\` for OS keychain storage.
|
|
46
|
+
`
|
|
34
47
|
);
|
|
35
48
|
keytarWarned = true;
|
|
36
49
|
}
|
|
@@ -46,19 +59,21 @@ async function setTokens(serverName, tokens) {
|
|
|
46
59
|
await kt.setPassword(KEYTAR_SERVICE, serverName, payload);
|
|
47
60
|
return;
|
|
48
61
|
}
|
|
49
|
-
|
|
62
|
+
const location = storeLocation();
|
|
63
|
+
const filePath = location.file;
|
|
64
|
+
ensurePrivateStoreDir(location);
|
|
50
65
|
let allTokens = {};
|
|
51
|
-
if (existsSync(
|
|
66
|
+
if (existsSync(filePath)) {
|
|
52
67
|
try {
|
|
53
|
-
allTokens = JSON.parse(readFileSync(
|
|
68
|
+
allTokens = JSON.parse(readFileSync(filePath, "utf8"));
|
|
54
69
|
} catch {
|
|
55
70
|
allTokens = {};
|
|
56
71
|
}
|
|
57
72
|
}
|
|
58
73
|
allTokens[serverName] = tokens;
|
|
59
|
-
await atomicWriteJson(
|
|
74
|
+
await atomicWriteJson(filePath, allTokens);
|
|
60
75
|
try {
|
|
61
|
-
chmodSync(
|
|
76
|
+
chmodSync(filePath, 384);
|
|
62
77
|
} catch {
|
|
63
78
|
}
|
|
64
79
|
}
|
|
@@ -73,10 +88,11 @@ async function getTokens(serverName) {
|
|
|
73
88
|
return void 0;
|
|
74
89
|
}
|
|
75
90
|
}
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
const filePath = storeFilePath();
|
|
92
|
+
if (!existsSync(filePath)) return void 0;
|
|
93
|
+
assertSecureModes(dirname(filePath), filePath);
|
|
78
94
|
try {
|
|
79
|
-
const all = JSON.parse(readFileSync(
|
|
95
|
+
const all = JSON.parse(readFileSync(filePath, "utf8"));
|
|
80
96
|
return all[serverName];
|
|
81
97
|
} catch {
|
|
82
98
|
return void 0;
|
package/dist/mcp-auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/mcp/token-storage.ts","../src/internal/mcp/oauth.ts"],"names":[],"mappings":"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","file":"mcp-auth.js","sourcesContent":["import { chmodSync, existsSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { assertSecureModes } from \"../auth/credential-store.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { atomicWriteJson } from \"../persistence/atomic-write.js\";\n\n/**\n * OAuth token bundle persisted per MCP server. See ADR D41.\n *\n * @internal\n */\nexport interface OAuthTokens {\n accessToken: string;\n refreshToken?: string;\n expiresAt: number; // ms epoch\n scope?: string;\n obtainedAt: number; // ms epoch\n}\n\nconst KEYTAR_SERVICE = \"theokit-mcp\";\nconst FILE_PATH = join(homedir(), \".theokit\", \"mcp-tokens.json\");\n\n/**\n * Make the directory private BEFORE anything is written into it.\n *\n * `atomicWriteJson` auto-creates the parent with a bare recursive `mkdir`, so under the common umask\n * 002 `~/.theokit` was born 0775 — and the `chmod 600` applied to the file afterwards protects the\n * wrong thing. Write permission on a DIRECTORY is permission to unlink and recreate its contents, so\n * a 0600 file inside a group-writable directory can be replaced wholesale by another local user. The\n * secret here is a REFRESH TOKEN: replacing it swaps which account the agent authenticates as.\n *\n * The `chmod` is unconditional and not a fallback for the `mkdir` mode: `mkdir`'s mode applies only\n * at CREATION, so every machine that already ran an older build has the loose directory sitting\n * there, and a fix that only covers fresh installs does not reach the population that has the\n * problem.\n */\nfunction ensurePrivateStoreDir(): void {\n const dir = dirname(FILE_PATH);\n try {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n chmodSync(dir, 0o700);\n } catch {\n // Windows: chmod is a no-op and the mode argument is meaningless. Same posture as the file\n // chmod below — documented in ADR D41 / EC-14.\n }\n}\n\ninterface KeytarLike {\n setPassword: (service: string, account: string, password: string) => Promise<void>;\n getPassword: (service: string, account: string) => Promise<string | null>;\n deletePassword: (service: string, account: string) => Promise<boolean>;\n}\n\nlet keytarWarned = false;\nlet cachedKeytar: KeytarLike | undefined | null;\nfunction tryRequireKeytar(): KeytarLike | null {\n if (cachedKeytar !== undefined) return cachedKeytar;\n try {\n const r = createRequire(import.meta.url);\n cachedKeytar = r(\"keytar\") as KeytarLike;\n } catch {\n if (!keytarWarned) {\n diag(\n \"[theokit-sdk] keytar not installed; MCP OAuth tokens will be stored in ~/.theokit/mcp-tokens.json (chmod 600 where POSIX). Install `keytar` for OS keychain storage.\\n\",\n );\n keytarWarned = true;\n }\n cachedKeytar = null;\n }\n return cachedKeytar;\n}\n\n// EC-9 (race): serialize concurrent refreshes per server. Each key maps to\n// the in-flight refresh Promise; subsequent callers await the same promise.\nconst inflightRefresh = new Map<string, Promise<OAuthTokens>>();\n\n/**\n * Persist tokens for `serverName`. Tries keychain first, falls back to file\n * with chmod 600 (POSIX). Idempotent.\n *\n * @internal\n */\nexport async function setTokens(serverName: string, tokens: OAuthTokens): Promise<void> {\n const kt = tryRequireKeytar();\n const payload = JSON.stringify(tokens);\n if (kt !== null && kt !== undefined) {\n await kt.setPassword(KEYTAR_SERVICE, serverName, payload);\n return;\n }\n // File fallback. The directory is locked down first — see `ensurePrivateStoreDir`.\n ensurePrivateStoreDir();\n let allTokens: Record<string, OAuthTokens> = {};\n if (existsSync(FILE_PATH)) {\n try {\n allTokens = JSON.parse(readFileSync(FILE_PATH, \"utf8\")) as Record<string, OAuthTokens>;\n } catch {\n // corrupt file — start fresh\n allTokens = {};\n }\n }\n allTokens[serverName] = tokens;\n await atomicWriteJson(FILE_PATH, allTokens);\n try {\n chmodSync(FILE_PATH, 0o600);\n } catch {\n // Windows: chmod is a no-op. Documented in ADR D41 / EC-14.\n }\n}\n\n/**\n * Retrieve tokens for `serverName`. Returns undefined if absent.\n *\n * @internal\n */\nexport async function getTokens(serverName: string): Promise<OAuthTokens | undefined> {\n const kt = tryRequireKeytar();\n if (kt !== null && kt !== undefined) {\n const value = await kt.getPassword(KEYTAR_SERVICE, serverName);\n if (typeof value !== \"string\") return undefined;\n try {\n return JSON.parse(value) as OAuthTokens;\n } catch {\n return undefined;\n }\n }\n if (!existsSync(FILE_PATH)) return undefined;\n // The same gate the credential file gets, and deliberately the same implementation rather than a\n // second one: a refresh token is a credential, and `assertSecureModes` already carries the attack\n // it defends against in its docstring. It is called OUTSIDE the try/catch on purpose — the catch\n // below exists to treat a corrupt file as absent, and letting it swallow this would turn \"someone\n // else can replace your token\" into a silent `undefined`, which reads as \"not logged in\".\n assertSecureModes(dirname(FILE_PATH), FILE_PATH);\n try {\n const all = JSON.parse(readFileSync(FILE_PATH, \"utf8\")) as Record<string, OAuthTokens>;\n return all[serverName];\n } catch {\n return undefined;\n }\n}\n\n/**\n * Serialize concurrent refresh attempts per server (EC-9). If a refresh is\n * already in flight for the same `serverName`, the second caller awaits\n * the same Promise.\n *\n * @internal\n */\nexport function lockedRefresh(\n serverName: string,\n refreshFn: () => Promise<OAuthTokens>,\n): Promise<OAuthTokens> {\n const existing = inflightRefresh.get(serverName);\n if (existing !== undefined) return existing;\n const promise = (async () => {\n try {\n return await refreshFn();\n } finally {\n inflightRefresh.delete(serverName);\n }\n })();\n inflightRefresh.set(serverName, promise);\n return promise;\n}\n\n/**\n * Reset all cached state. Test-only helper.\n *\n * @internal\n */\nexport function _resetForTests(): void {\n inflightRefresh.clear();\n cachedKeytar = undefined;\n keytarWarned = false;\n}\n","import { createHash, randomBytes } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { createInterface } from \"node:readline/promises\";\n\nimport { ConfigurationError } from \"../../errors.js\";\nimport type { McpOAuthConfig } from \"../../types/mcp.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { type OAuthTokens, setTokens } from \"./token-storage.js\";\n\n/**\n * OAuth 2.1 PKCE flow runner for MCP HTTP servers. See ADR D41.\n *\n * @internal\n */\n\n/**\n * Generate a random base64url-encoded string. Used for both code_verifier\n * (43-128 chars) and state (CSRF protection).\n */\nfunction base64url(n: number): string {\n return randomBytes(n).toString(\"base64url\");\n}\n\n/**\n * Compute PKCE code_challenge = base64url(SHA256(code_verifier)).\n */\nfunction challengeFor(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\n/**\n * Refresh an access token using `refresh_token`. Throws on failure.\n *\n * @internal\n */\nexport async function refreshAccessToken(\n serverName: string,\n clientId: string,\n refreshToken: string,\n oauth: McpOAuthConfig,\n): Promise<OAuthTokens> {\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: clientId,\n });\n const response = await fetch(oauth.tokenEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n if (!response.ok) {\n throw new ConfigurationError(`OAuth refresh failed: HTTP ${response.status}`, {\n code: \"oauth_refresh_failed\",\n });\n }\n const data = (await response.json()) as {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n scope?: string;\n };\n const obtainedAt = Date.now();\n const tokens: OAuthTokens = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token ?? refreshToken,\n // EC-10: default conservative 3600s if expires_in missing.\n expiresAt: obtainedAt + (data.expires_in ?? 3600) * 1000,\n obtainedAt,\n ...(data.scope !== undefined ? { scope: data.scope } : {}),\n };\n await setTokens(serverName, tokens);\n return tokens;\n}\n\n/**\n * Run the full PKCE flow. Generates verifier+challenge+state, opens the\n * authorization URL (browser or manual print), waits for the callback\n * (localhost or stdin), exchanges code for tokens.\n *\n * @internal\n */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: PKCE flow is a linear protocol step (verifier → challenge → state → URL → wait → exchange); refactoring fragments the RFC 7636 narrative.\nexport async function runPkceFlow(\n serverName: string,\n clientId: string,\n scopes: string[] | undefined,\n oauth: McpOAuthConfig,\n): Promise<OAuthTokens> {\n const verifier = base64url(48);\n const challenge = challengeFor(verifier);\n const state = base64url(16);\n const timeoutMs = oauth.timeoutMs ?? 300_000;\n\n let redirectUri: string;\n let codeWaiter: Promise<{ code: string; state: string }>;\n let cleanup: () => void = () => {};\n\n if (oauth.redirectMode === \"localhost\") {\n const result = await openLocalhostCallback(state, timeoutMs);\n redirectUri = result.redirectUri;\n codeWaiter = result.waitFor;\n cleanup = result.close;\n } else {\n redirectUri = \"urn:ietf:wg:oauth:2.0:oob\";\n codeWaiter = readCodeFromStdin(state, timeoutMs);\n }\n\n try {\n const authUrl = new URL(oauth.authorizationEndpoint);\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"client_id\", clientId);\n authUrl.searchParams.set(\"redirect_uri\", redirectUri);\n if (scopes !== undefined && scopes.length > 0) {\n authUrl.searchParams.set(\"scope\", scopes.join(\" \"));\n }\n authUrl.searchParams.set(\"code_challenge\", challenge);\n authUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authUrl.searchParams.set(\"state\", state);\n\n diag(\n `\\n[theokit-sdk] OAuth required for MCP server \"${serverName}\".\\n` +\n `Open this URL to authenticate:\\n ${authUrl.toString()}\\n\\n`,\n );\n\n const { code, state: returnedState } = await codeWaiter;\n // EC-2 MUST FIX: validate state.\n if (returnedState !== state) {\n throw new ConfigurationError(\n \"OAuth state mismatch — possible CSRF attempt; aborting token exchange.\",\n { code: \"oauth_state_mismatch\" },\n );\n }\n\n // Exchange code for tokens.\n const tokenBody = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n client_id: clientId,\n code_verifier: verifier,\n redirect_uri: redirectUri,\n });\n const response = await fetch(oauth.tokenEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: tokenBody.toString(),\n });\n if (!response.ok) {\n const errText = await response.text();\n throw new ConfigurationError(\n `OAuth token exchange failed: HTTP ${response.status}: ${errText.slice(0, 200)}`,\n { code: \"oauth_token_exchange_failed\" },\n );\n }\n const data = (await response.json()) as {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n scope?: string;\n };\n const obtainedAt = Date.now();\n return {\n accessToken: data.access_token,\n ...(data.refresh_token !== undefined ? { refreshToken: data.refresh_token } : {}),\n // EC-10: default 3600s when expires_in absent.\n expiresAt: obtainedAt + (data.expires_in ?? 3600) * 1000,\n obtainedAt,\n ...(data.scope !== undefined ? { scope: data.scope } : {}),\n };\n } finally {\n cleanup();\n }\n}\n\n/**\n * Start a localhost HTTP server on a free port; return the redirect URI,\n * a promise that resolves with the code+state from the first valid request,\n * and a close handle.\n *\n * @internal\n */\nasync function openLocalhostCallback(\n expectedState: string,\n timeoutMs: number,\n): Promise<{\n redirectUri: string;\n waitFor: Promise<{ code: string; state: string }>;\n close: () => void;\n}> {\n let resolveCode: ((value: { code: string; state: string }) => void) | undefined;\n let rejectCode: ((reason: unknown) => void) | undefined;\n const waitFor = new Promise<{ code: string; state: string }>((res, rej) => {\n resolveCode = res;\n rejectCode = rej;\n });\n const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n if (typeof code !== \"string\" || typeof state !== \"string\") {\n res.statusCode = 400;\n res.end(\"Missing code or state\");\n return;\n }\n // EC-2: state must match the one we generated. We DO NOT trust any\n // localhost GET — only the one carrying our exact state.\n if (state !== expectedState) {\n res.statusCode = 400;\n res.end(\"State mismatch — request rejected.\");\n return;\n }\n res.statusCode = 200;\n res.end(\"Authentication successful. You can close this tab and return to the terminal.\");\n resolveCode?.({ code, state });\n });\n server.listen(0, \"127.0.0.1\");\n const timeoutHandle = setTimeout(() => {\n rejectCode?.(new ConfigurationError(\"OAuth flow timed out\", { code: \"oauth_timeout\" }));\n }, timeoutMs);\n // Wait for server.listen to bind so we can read the port.\n await new Promise<void>((r) => {\n if (server.listening) r();\n else server.once(\"listening\", () => r());\n });\n const address = server.address();\n if (typeof address !== \"object\" || address === null) {\n server.close();\n throw new ConfigurationError(\"OAuth localhost callback failed to bind\", {\n code: \"oauth_bind_failed\",\n });\n }\n const port = address.port;\n return {\n redirectUri: `http://127.0.0.1:${port}/callback`,\n waitFor,\n close: () => {\n clearTimeout(timeoutHandle);\n server.close();\n },\n };\n}\n\n/**\n * Read `code` (and `state`) from stdin (manual mode). User pastes the\n * full callback URL or just the code value.\n *\n * @internal\n */\nasync function readCodeFromStdin(\n expectedState: string,\n timeoutMs: number,\n): Promise<{ code: string; state: string }> {\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n const promise = new Promise<{ code: string; state: string }>((resolve, reject) => {\n rl.question(\"Paste the full callback URL (or just the code): \")\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: stdin reader handles 2 input formats (full URL vs raw code) inline; splitting fragments the manual-mode UX.\n .then((answer) => {\n rl.close();\n const trimmed = answer.trim();\n // Try to parse as URL first.\n if (trimmed.includes(\"?\")) {\n try {\n const parsed = new URL(trimmed);\n const code = parsed.searchParams.get(\"code\");\n const state = parsed.searchParams.get(\"state\") ?? \"\";\n if (typeof code === \"string\") {\n resolve({ code, state });\n return;\n }\n } catch {\n // not a URL — fall through\n }\n }\n // Treat the entire input as the code. State validation will fail\n // unless the user also provided state — but in manual mode they\n // typically paste the URL with state baked in.\n resolve({ code: trimmed, state: expectedState });\n })\n .catch(reject);\n setTimeout(() => {\n rl.close();\n reject(new ConfigurationError(\"OAuth manual input timed out\", { code: \"oauth_timeout\" }));\n }, timeoutMs);\n });\n return promise;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/mcp/token-storage.ts","../src/internal/mcp/oauth.ts"],"names":[],"mappings":"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","file":"mcp-auth.js","sourcesContent":["import { chmodSync, existsSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { assertSecureModes } from \"../auth/credential-store.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { atomicWriteJson } from \"../persistence/atomic-write.js\";\n\n/**\n * The OAuth tokens held for one MCP server. See ADR D41.\n *\n * Persisted per server name by `setTokens` and returned unchanged by `getTokens`. Where it lands\n * depends on what is installed: `keytar` puts the serialized bundle in the OS keychain, and\n * without it the bundle is written to a JSON file at mode 0600 inside a 0700 directory — in\n * PLAINTEXT, keyed by server name alongside every other server's tokens. Nothing here encrypts it.\n *\n * `refreshToken` is the field that matters most and the field that is optional. When present it\n * outlives `accessToken` and can mint new ones, so a leaked store is a persistent compromise of\n * the account rather than a temporary one. When absent, an expired access token means re-running\n * the authorization flow.\n *\n * `expiresAt` and `obtainedAt` are both epoch milliseconds and both describe the ACCESS token —\n * when it stops working, and when this bundle was issued. Nothing records when the refresh token\n * expires, so a refresh rejected because the grant itself lapsed is only discovered at the token\n * endpoint.\n *\n * The value is not validated on read: whatever JSON was stored is cast to this shape, so a\n * hand-edited or truncated store yields an object whose fields may be missing rather than an\n * error.\n *\n * `scope` records what the token was granted, as the server returned it. It is stored for\n * inspection; nothing in this module enforces it.\n *\n * @public — re-exported from `@theokit/sdk/mcp-auth`, and therefore under semver.\n */\nexport interface OAuthTokens {\n accessToken: string;\n refreshToken?: string;\n expiresAt: number; // ms epoch\n scope?: string;\n obtainedAt: number; // ms epoch\n}\n\nconst KEYTAR_SERVICE = \"theokit-mcp\";\n/**\n * Resolve the store path on every call instead of binding it once at module load.\n *\n * This used to be `const FILE_PATH = join(homedir(), ...)`. A module-level constant captures\n * ambient global state at IMPORT, so the store kept writing to whichever HOME was set when the\n * module first loaded and never noticed a later change. In production that is invisible, because\n * HOME does not move mid-process — but it made the module's correctness a property of *when* it was\n * imported, which is not a property a credential store should have.\n *\n * The environment variable is read FIRST and `homedir()` is the fallback, and the variable READ IS\n * PER PLATFORM because `os.homedir()` itself is: on POSIX it prefers `$HOME`, on Windows it reads\n * `USERPROFILE` and never consults `HOME`. Mirroring that split is what keeps this a pure\n * binding-time fix instead of a behaviour change.\n *\n * A previous revision read `process.env.HOME` on every platform. Review caught it: under Git Bash,\n * MSYS2 or Cygwin `HOME` IS set, to a POSIX-shaped path, and `path.win32.join(\"/c/Users/N\", ...)`\n * yields `\\c\\Users\\N\\.theokit\\...` where `USERPROFILE` would have given\n * `C:\\Users\\N\\.theokit\\...`. That would have hidden every existing token on those setups and\n * written a new credential file to a drive-relative path. It was published as \"on Windows HOME is\n * typically unset\" — an untested platform claim, and the same defect class it was written to fix.\n *\n * Why read the env at all: inside a worker thread `process.env` is a JS-level copy while\n * `os.homedir()` is a native call reading the real process environment, so code that moves the home\n * inside a worker is invisible to `homedir()`. Reading the env first makes this module independent\n * of the execution model, not just of the import moment.\n *\n * The empty/whitespace guard falls through to `homedir()`, and it buys LESS than two earlier\n * revisions of this comment claimed. Measured on POSIX: `homedir()` with `HOME=\"\"` returns `\"\"` and\n * with `HOME=\" \"` returns `\" \"` untrimmed, so the fallback hands back the same value the guard\n * rejected — close to a no-op. `path.join(\"\", \".theokit\", ...)` yields a CWD-RELATIVE\n * `.theokit/mcp-tokens.json`, never `/.theokit`; an earlier revision named that as the hazard and it\n * does not exist.\n *\n * On Windows it is UNKNOWN rather than load-bearing: the fallback reads the same `USERPROFILE`, so\n * whether the guard changes anything depends on whether an empty variable is reported as absent\n * there, which is untested and not asserted here. The one case where the guard is genuinely\n * load-bearing is a worker thread whose environment copy was blanked.\n *\n * The OS is UNTESTED here: every POSIX-mode test in `mcp-token-store-modes.test.ts` is\n * `it.skipIf(!POSIX)` and CI runs ubuntu only, so nothing exercises real Windows chmod semantics or\n * libuv's `USERPROFILE` lookup. The BRANCH SELECTION is tested — `process.platform` is spy-able, and\n * `test_the_store_reads_USERPROFILE_and_not_HOME_on_win32` pins all three legs.\n *\n * The split is reasoned from `os.homedir()`'s documented per-platform source. A previous revision\n * also cited `internal/runtime/fixtures/fixture-mode.ts:119` as support; that citation was WRONG and\n * is removed rather than quietly dropped. That line reads `process.env.HOME ?? process.env.USERPROFILE`\n * — HOME-first on every platform, which is the exact shape this split exists to avoid. It supports\n * the rejected alternative, not this one. (That the two modules now resolve different homes under\n * Git Bash is real and is filed separately; `fixture-mode` only probes for `~/.aws/credentials`.)\n *\n * Measured cost, not asserted: `homedir()` is 151 ns/op against 13 382 for the read this path\n * performs and 97 079 for the write (89x and 645x). The resolution is free relative to the I/O it\n * precedes.\n *\n * B-089. `packages/sdk/tests/mcp-token-store-modes.test.ts` pins it: import once, move HOME, write,\n * assert the write followed — and it must hold under `--pool=threads`, not only under the repo's\n * configured `forks`.\n *\n * B-090 — `THEOKIT_HOME` now WINS over the home-anchored default, and the reason is not tidiness.\n * `vitest.setup.ts` isolates every test in this package by pointing `THEOKIT_HOME` at a fresh\n * tmpdir; it backs `HOME` up and never sets it. A home-anchored module that ignored the variable\n * therefore resolved to the developer's REAL `~` while the suite believed it was isolated — and it\n * did: a default-config run deposited four refresh-token entries (`test-srv`, `srv-2`, `srv-race`,\n * `srv-roundtrip`) into `~/.theokit/mcp-tokens.json` from `tests/golden/mcp/oauth.golden.test.ts`.\n * A suite that is wrong about its own isolation is a false green about the one property the rest of\n * its greens rest on.\n *\n * **This is the code catching up to a contract the SDK already published**, not a new policy.\n * `src/project-env.ts:47-49` documents `THEOKIT_HOME` as \"Locates the SDK home — sessions, AND THE\n * CREDENTIAL STORE BENEATH IT\", and it is listed there as a sovereign key precisely because it\n * governs where credentials live. The public contract already said the store sits under the\n * variable; this module was the half that disagreed.\n *\n * The resolver adopted is `transcriptRoot()`'s (`internal/persistence/session-transcript.ts`), NOT\n * `paths.ts`'s `getTheokitHome(cwd)`. The transcript is the sibling with the right SHAPE: home-anchored\n * default, `THEOKIT_HOME` override, trimmed, empty-guarded — and its docstring records that before M94\n * it ignored the variable, so \"whoever set it had their state split in two silently\", which is this\n * defect verbatim. M94 ADR-2 already accepted that migration for identically-shaped state.\n * `getTheokitHome(cwd)` falls back to `<cwd>/.theokit`, so adopting IT would move the token file of\n * everyone who does not set the variable — and to a DIFFERENT place per working directory, making\n * whether you are logged in a property of which folder you launched from.\n *\n * **The migration this does carry**, stated rather than buried: a user who already holds\n * `~/.theokit/mcp-tokens.json` AND sets `THEOKIT_HOME` stops seeing those tokens. `getTokens` returns\n * `undefined`, which the caller surfaces as \"not logged in\", and the OAuth flow re-runs. Nothing is\n * deleted and nothing is overwritten — the old file stays where it is and is picked up again the\n * moment the variable is unset. No migration step is performed on the user's behalf, because\n * silently moving a credential file is a worse failure than a re-auth. Users who do NOT set\n * `THEOKIT_HOME` — the default — see no change at all.\n *\n * **Two further consequences for those who DO set it**, both on the directory-mode path rather than\n * on the path resolution, and both spelled out at {@link ensurePrivateStoreDir}: the store no longer\n * re-permissions a `$THEOKIT_HOME` it did not create, and `getTokens` REFUSES — typed, loud — to read\n * out of a group- or world-writable one instead of returning `undefined`.\n */\nfunction storeFilePath(): string {\n return storeLocation().file;\n}\n\n/**\n * Where the store lives, and whether that directory is OURS.\n *\n * `ours` is not bookkeeping — it decides whether this module is entitled to change the directory's\n * permissions. `<home>/.theokit` is a directory the SDK creates and owns; a `THEOKIT_HOME` root is\n * one the operator chose and may share with other state. See {@link ensurePrivateStoreDir}.\n */\ninterface StoreLocation {\n readonly dir: string;\n readonly file: string;\n readonly ours: boolean;\n}\n\n/**\n * The directory the token file lives in: `THEOKIT_HOME` when usable, `<home>/.theokit` otherwise.\n *\n * The empty/whitespace guard on the override is load-bearing in a way the HOME guard below is not:\n * `THEOKIT_HOME=\"\"` with no guard resolves the store to a CWD-RELATIVE `mcp-tokens.json`, and\n * `THEOKIT_HOME=\" \"` to a directory literally named three spaces. Neither falls back to anything;\n * both are new locations invented from an unusable value. `transcriptRoot()` guards it for the same\n * reason.\n */\nfunction storeLocation(): StoreLocation {\n const override = process.env.THEOKIT_HOME?.trim();\n if (override !== undefined && override.length > 0) {\n return { dir: override, file: join(override, \"mcp-tokens.json\"), ours: false };\n }\n // Mirrors `os.homedir()`'s own per-platform source: USERPROFILE on Windows, HOME elsewhere.\n const fromEnv =\n process.platform === \"win32\" ? process.env.USERPROFILE?.trim() : process.env.HOME?.trim();\n const home = fromEnv !== undefined && fromEnv.length > 0 ? fromEnv : homedir();\n const dir = join(home, \".theokit\");\n return { dir, file: join(dir, \"mcp-tokens.json\"), ours: true };\n}\n\n/**\n * Make the directory private BEFORE anything is written into it.\n *\n * `atomicWriteJson` auto-creates the parent with a bare recursive `mkdir`, so under the common umask\n * 002 `~/.theokit` was born 0775 — and the `chmod 600` applied to the file afterwards protects the\n * wrong thing. Write permission on a DIRECTORY is permission to unlink and recreate its contents, so\n * a 0600 file inside a group-writable directory can be replaced wholesale by another local user. The\n * secret here is a REFRESH TOKEN: replacing it swaps which account the agent authenticates as.\n *\n * **The retro-fix `chmod` is scoped to directories we own, and B-090 is why.** It was written\n * unconditional for a specific reason: `mkdir`'s mode applies only at CREATION, so every machine\n * that already ran an older build has a loose `~/.theokit` sitting there, and a fix that only covers\n * fresh installs does not reach the population that has the problem. That reasoning names its own\n * population — directories THIS MODULE created in an older build. Once `THEOKIT_HOME` is honoured,\n * an unconditional `chmod` also reaches a root the operator chose, which we never created and which\n * `paths.ts` documents as a multi-tenant deployment knob. Measured: it silently demoted a 0775\n * `$THEOKIT_HOME` to 0700, taking the sessions, transcripts, personality and credential-pool state\n * that share that root with it. No other consumer of the variable imposes a mode on it.\n *\n * So: always `mkdir` at 0700 (a directory WE create is born private wherever it is), and `chmod` an\n * existing one only when it is `<home>/.theokit`.\n *\n * The `chmod` deliberately does NOT also cover \"we just created it\". A first draft guarded it with\n * `ours || created !== undefined`; mutating that to plain `ours` killed no test, and the reason is\n * that the disjunct cannot make a difference: a umask only CLEARS bits, and 0700 carries none in the\n * group/other range, so `mkdir(0700)` is private for every possible umask. The redundant clause was\n * removed rather than pinned with a test written to justify it.\n *\n * **What that leaves, stated rather than left to be discovered.** A pre-existing group-writable\n * `$THEOKIT_HOME` is no longer repaired, so the next {@link getTokens} throws `CredentialError` from\n * `assertSecureModes` naming the directory and the `chmod 700` that fixes it. That is the intended\n * end state: a refresh token under a directory any local user can replace files in is not safe to\n * return, and the two available alternatives are worse. Silently tightening the operator's root\n * breaks their deployment to protect them from a choice they may have made deliberately; silently\n * returning the token hands the caller a credential that may already have been swapped. A loud,\n * actionable refusal is the only option that neither mutates someone else's directory nor lies about\n * what it read.\n *\n * The asymmetry that remains is real and is NOT fixed here: the write path has no such gate, so\n * `setTokens` will happily write into that directory and the following `getTokens` refuses it.\n * Adding a write-side gate is a separate behaviour change on a path that currently always succeeds.\n */\nfunction ensurePrivateStoreDir({ dir, ours }: StoreLocation): void {\n try {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n if (ours) chmodSync(dir, 0o700);\n } catch {\n // Windows: chmod is a no-op and the mode argument is meaningless. Same posture as the file\n // chmod below — documented in ADR D41 / EC-14.\n }\n}\n\ninterface KeytarLike {\n setPassword: (service: string, account: string, password: string) => Promise<void>;\n getPassword: (service: string, account: string) => Promise<string | null>;\n deletePassword: (service: string, account: string) => Promise<boolean>;\n}\n\nlet keytarWarned = false;\nlet cachedKeytar: KeytarLike | undefined | null;\nfunction tryRequireKeytar(): KeytarLike | null {\n if (cachedKeytar !== undefined) return cachedKeytar;\n try {\n const r = createRequire(import.meta.url);\n cachedKeytar = r(\"keytar\") as KeytarLike;\n } catch {\n if (!keytarWarned) {\n // The path is RESOLVED rather than spelled `~/.theokit/mcp-tokens.json`. That literal was\n // correct until B-090 made `THEOKIT_HOME` win, at which point a message naming a fixed\n // location would send anyone who sets the variable to look at a file the store no longer\n // writes — a diagnostic that lies costs more than one that is absent.\n diag(\n `[theokit-sdk] keytar not installed; MCP OAuth tokens will be stored in ${storeFilePath()} (chmod 600 where POSIX). Install \\`keytar\\` for OS keychain storage.\\n`,\n );\n keytarWarned = true;\n }\n cachedKeytar = null;\n }\n return cachedKeytar;\n}\n\n// EC-9 (race): serialize concurrent refreshes per server. Each key maps to\n// the in-flight refresh Promise; subsequent callers await the same promise.\nconst inflightRefresh = new Map<string, Promise<OAuthTokens>>();\n\n/**\n * Persist tokens for `serverName`. Tries keychain first, falls back to file\n * with chmod 600 (POSIX). Idempotent.\n *\n */\nexport async function setTokens(serverName: string, tokens: OAuthTokens): Promise<void> {\n const kt = tryRequireKeytar();\n const payload = JSON.stringify(tokens);\n if (kt !== null && kt !== undefined) {\n await kt.setPassword(KEYTAR_SERVICE, serverName, payload);\n return;\n }\n // File fallback. The directory is locked down first — see `ensurePrivateStoreDir`.\n // Resolved once for the whole operation and PASSED DOWN. Resolving per use would let a read and\n // the write that follows it disagree if HOME moved in between — and `ensurePrivateStoreDir`\n // resolving its own copy would let the directory be locked down under one home while the token\n // lands under another. Today those two statements are adjacent and synchronous so they cannot\n // diverge, but that is incidental; passing the path makes the invariant structural.\n const location = storeLocation();\n const filePath = location.file;\n ensurePrivateStoreDir(location);\n let allTokens: Record<string, OAuthTokens> = {};\n if (existsSync(filePath)) {\n try {\n allTokens = JSON.parse(readFileSync(filePath, \"utf8\")) as Record<string, OAuthTokens>;\n } catch {\n // corrupt file — start fresh\n allTokens = {};\n }\n }\n allTokens[serverName] = tokens;\n await atomicWriteJson(filePath, allTokens);\n try {\n chmodSync(filePath, 0o600);\n } catch {\n // Windows: chmod is a no-op. Documented in ADR D41 / EC-14.\n }\n}\n\n/**\n * Retrieve tokens for `serverName`. Returns undefined if absent.\n *\n */\nexport async function getTokens(serverName: string): Promise<OAuthTokens | undefined> {\n const kt = tryRequireKeytar();\n if (kt !== null && kt !== undefined) {\n const value = await kt.getPassword(KEYTAR_SERVICE, serverName);\n if (typeof value !== \"string\") return undefined;\n try {\n return JSON.parse(value) as OAuthTokens;\n } catch {\n return undefined;\n }\n }\n const filePath = storeFilePath();\n if (!existsSync(filePath)) return undefined;\n // The same gate the credential file gets, and deliberately the same implementation rather than a\n // second one: a refresh token is a credential, and `assertSecureModes` already carries the attack\n // it defends against in its docstring. It is called OUTSIDE the try/catch on purpose — the catch\n // below exists to treat a corrupt file as absent, and letting it swallow this would turn \"someone\n // else can replace your token\" into a silent `undefined`, which reads as \"not logged in\".\n assertSecureModes(dirname(filePath), filePath);\n try {\n const all = JSON.parse(readFileSync(filePath, \"utf8\")) as Record<string, OAuthTokens>;\n return all[serverName];\n } catch {\n return undefined;\n }\n}\n\n/**\n * Serialize concurrent refresh attempts per server (EC-9). If a refresh is\n * already in flight for the same `serverName`, the second caller awaits\n * the same Promise.\n *\n */\nexport function lockedRefresh(\n serverName: string,\n refreshFn: () => Promise<OAuthTokens>,\n): Promise<OAuthTokens> {\n const existing = inflightRefresh.get(serverName);\n if (existing !== undefined) return existing;\n const promise = (async () => {\n try {\n return await refreshFn();\n } finally {\n inflightRefresh.delete(serverName);\n }\n })();\n inflightRefresh.set(serverName, promise);\n return promise;\n}\n\n/**\n * Reset all cached state. Test-only helper.\n *\n * @internal\n */\nexport function _resetForTests(): void {\n inflightRefresh.clear();\n cachedKeytar = undefined;\n keytarWarned = false;\n}\n","/**\n * OAuth 2.1 PKCE flow runner for MCP HTTP servers. See ADR D41.\n *\n * @internal\n */\n\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { createInterface } from \"node:readline/promises\";\n\nimport { ConfigurationError } from \"../../errors.js\";\nimport type { McpOAuthConfig } from \"../../types/mcp.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { type OAuthTokens, setTokens } from \"./token-storage.js\";\n\n/**\n * Generate a random base64url-encoded string. Used for both code_verifier\n * (43-128 chars) and state (CSRF protection).\n */\nfunction base64url(n: number): string {\n return randomBytes(n).toString(\"base64url\");\n}\n\n/**\n * Compute PKCE code_challenge = base64url(SHA256(code_verifier)).\n */\nfunction challengeFor(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\n/**\n * Refresh an access token using `refresh_token`. Throws on failure.\n *\n */\nexport async function refreshAccessToken(\n serverName: string,\n clientId: string,\n refreshToken: string,\n oauth: McpOAuthConfig,\n): Promise<OAuthTokens> {\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: clientId,\n });\n const response = await fetch(oauth.tokenEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n if (!response.ok) {\n throw new ConfigurationError(`OAuth refresh failed: HTTP ${response.status}`, {\n code: \"oauth_refresh_failed\",\n });\n }\n const data = (await response.json()) as {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n scope?: string;\n };\n const obtainedAt = Date.now();\n const tokens: OAuthTokens = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token ?? refreshToken,\n // EC-10: default conservative 3600s if expires_in missing.\n expiresAt: obtainedAt + (data.expires_in ?? 3600) * 1000,\n obtainedAt,\n ...(data.scope !== undefined ? { scope: data.scope } : {}),\n };\n await setTokens(serverName, tokens);\n return tokens;\n}\n\n/**\n * Run the full PKCE flow. Generates verifier+challenge+state, opens the\n * authorization URL (browser or manual print), waits for the callback\n * (localhost or stdin), exchanges code for tokens.\n *\n */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: PKCE flow is a linear protocol step (verifier → challenge → state → URL → wait → exchange); refactoring fragments the RFC 7636 narrative.\nexport async function runPkceFlow(\n serverName: string,\n clientId: string,\n scopes: string[] | undefined,\n oauth: McpOAuthConfig,\n): Promise<OAuthTokens> {\n const verifier = base64url(48);\n const challenge = challengeFor(verifier);\n const state = base64url(16);\n const timeoutMs = oauth.timeoutMs ?? 300_000;\n\n let redirectUri: string;\n let codeWaiter: Promise<{ code: string; state: string }>;\n let cleanup: () => void = () => {};\n\n if (oauth.redirectMode === \"localhost\") {\n const result = await openLocalhostCallback(state, timeoutMs);\n redirectUri = result.redirectUri;\n codeWaiter = result.waitFor;\n cleanup = result.close;\n } else {\n redirectUri = \"urn:ietf:wg:oauth:2.0:oob\";\n codeWaiter = readCodeFromStdin(state, timeoutMs);\n }\n\n try {\n const authUrl = new URL(oauth.authorizationEndpoint);\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"client_id\", clientId);\n authUrl.searchParams.set(\"redirect_uri\", redirectUri);\n if (scopes !== undefined && scopes.length > 0) {\n authUrl.searchParams.set(\"scope\", scopes.join(\" \"));\n }\n authUrl.searchParams.set(\"code_challenge\", challenge);\n authUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authUrl.searchParams.set(\"state\", state);\n\n diag(\n `\\n[theokit-sdk] OAuth required for MCP server \"${serverName}\".\\n` +\n `Open this URL to authenticate:\\n ${authUrl.toString()}\\n\\n`,\n );\n\n const { code, state: returnedState } = await codeWaiter;\n // EC-2 MUST FIX: validate state.\n if (returnedState !== state) {\n throw new ConfigurationError(\n \"OAuth state mismatch — possible CSRF attempt; aborting token exchange.\",\n { code: \"oauth_state_mismatch\" },\n );\n }\n\n // Exchange code for tokens.\n const tokenBody = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n client_id: clientId,\n code_verifier: verifier,\n redirect_uri: redirectUri,\n });\n const response = await fetch(oauth.tokenEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: tokenBody.toString(),\n });\n if (!response.ok) {\n const errText = await response.text();\n throw new ConfigurationError(\n `OAuth token exchange failed: HTTP ${response.status}: ${errText.slice(0, 200)}`,\n { code: \"oauth_token_exchange_failed\" },\n );\n }\n const data = (await response.json()) as {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n scope?: string;\n };\n const obtainedAt = Date.now();\n return {\n accessToken: data.access_token,\n ...(data.refresh_token !== undefined ? { refreshToken: data.refresh_token } : {}),\n // EC-10: default 3600s when expires_in absent.\n expiresAt: obtainedAt + (data.expires_in ?? 3600) * 1000,\n obtainedAt,\n ...(data.scope !== undefined ? { scope: data.scope } : {}),\n };\n } finally {\n cleanup();\n }\n}\n\n/**\n * Start a localhost HTTP server on a free port; return the redirect URI,\n * a promise that resolves with the code+state from the first valid request,\n * and a close handle.\n *\n * @internal\n */\nasync function openLocalhostCallback(\n expectedState: string,\n timeoutMs: number,\n): Promise<{\n redirectUri: string;\n waitFor: Promise<{ code: string; state: string }>;\n close: () => void;\n}> {\n let resolveCode: ((value: { code: string; state: string }) => void) | undefined;\n let rejectCode: ((reason: unknown) => void) | undefined;\n const waitFor = new Promise<{ code: string; state: string }>((res, rej) => {\n resolveCode = res;\n rejectCode = rej;\n });\n const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n if (typeof code !== \"string\" || typeof state !== \"string\") {\n res.statusCode = 400;\n res.end(\"Missing code or state\");\n return;\n }\n // EC-2: state must match the one we generated. We DO NOT trust any\n // localhost GET — only the one carrying our exact state.\n if (state !== expectedState) {\n res.statusCode = 400;\n res.end(\"State mismatch — request rejected.\");\n return;\n }\n res.statusCode = 200;\n res.end(\"Authentication successful. You can close this tab and return to the terminal.\");\n resolveCode?.({ code, state });\n });\n server.listen(0, \"127.0.0.1\");\n const timeoutHandle = setTimeout(() => {\n rejectCode?.(new ConfigurationError(\"OAuth flow timed out\", { code: \"oauth_timeout\" }));\n }, timeoutMs);\n // Wait for server.listen to bind so we can read the port.\n await new Promise<void>((r) => {\n if (server.listening) r();\n else server.once(\"listening\", () => r());\n });\n const address = server.address();\n if (typeof address !== \"object\" || address === null) {\n server.close();\n throw new ConfigurationError(\"OAuth localhost callback failed to bind\", {\n code: \"oauth_bind_failed\",\n });\n }\n const port = address.port;\n return {\n redirectUri: `http://127.0.0.1:${port}/callback`,\n waitFor,\n close: () => {\n clearTimeout(timeoutHandle);\n server.close();\n },\n };\n}\n\n/**\n * Read `code` (and `state`) from stdin (manual mode). User pastes the\n * full callback URL or just the code value.\n *\n * @internal\n */\nasync function readCodeFromStdin(\n expectedState: string,\n timeoutMs: number,\n): Promise<{ code: string; state: string }> {\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n const promise = new Promise<{ code: string; state: string }>((resolve, reject) => {\n rl.question(\"Paste the full callback URL (or just the code): \")\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: stdin reader handles 2 input formats (full URL vs raw code) inline; splitting fragments the manual-mode UX.\n .then((answer) => {\n rl.close();\n const trimmed = answer.trim();\n // Try to parse as URL first.\n if (trimmed.includes(\"?\")) {\n try {\n const parsed = new URL(trimmed);\n const code = parsed.searchParams.get(\"code\");\n const state = parsed.searchParams.get(\"state\") ?? \"\";\n if (typeof code === \"string\") {\n resolve({ code, state });\n return;\n }\n } catch {\n // not a URL — fall through\n }\n }\n // Treat the entire input as the code. State validation will fail\n // unless the user also provided state — but in manual mode they\n // typically paste the URL with state baked in.\n resolve({ code: trimmed, state: expectedState });\n })\n .catch(reject);\n setTimeout(() => {\n rl.close();\n reject(new ConfigurationError(\"OAuth manual input timed out\", { code: \"oauth_timeout\" }));\n }, timeoutMs);\n });\n return promise;\n}\n"]}
|
package/dist/models.cjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
require('./chunk-
|
|
7
|
-
require('./chunk-
|
|
8
|
-
require('./chunk-
|
|
9
|
-
require('./chunk-
|
|
10
|
-
|
|
3
|
+
var chunkHY57ULY2_cjs = require('./chunk-HY57ULY2.cjs');
|
|
4
|
+
var chunk3EE6LVWT_cjs = require('./chunk-3EE6LVWT.cjs');
|
|
5
|
+
var chunkRM7Y65IG_cjs = require('./chunk-RM7Y65IG.cjs');
|
|
6
|
+
require('./chunk-5USCYPPI.cjs');
|
|
7
|
+
require('./chunk-BVZW2B5V.cjs');
|
|
8
|
+
require('./chunk-52NKC5HT.cjs');
|
|
9
|
+
require('./chunk-K3FW2XZD.cjs');
|
|
10
|
+
require('./chunk-JTB5Q42C.cjs');
|
|
11
|
+
var chunkNUKRL3I6_cjs = require('./chunk-NUKRL3I6.cjs');
|
|
11
12
|
var crypto = require('crypto');
|
|
12
13
|
var fs = require('fs');
|
|
13
14
|
var os = require('os');
|
|
@@ -35,11 +36,11 @@ function capsFromCatalog(m) {
|
|
|
35
36
|
}
|
|
36
37
|
function resolveModelCapabilities(modelId) {
|
|
37
38
|
const bare = stripVariantSuffix(stripRoutingPrefix(modelId));
|
|
38
|
-
const fromIndex =
|
|
39
|
+
const fromIndex = chunkRM7Y65IG_cjs.getCatalogModelInfo(bare);
|
|
39
40
|
if (fromIndex !== void 0) return capsFromCatalog(fromIndex);
|
|
40
41
|
const withVendor = inferVendorPrefix(bare);
|
|
41
42
|
if (withVendor !== bare) {
|
|
42
|
-
const vendored =
|
|
43
|
+
const vendored = chunkRM7Y65IG_cjs.getCatalogModelInfo(withVendor);
|
|
43
44
|
if (vendored !== void 0) return capsFromCatalog(vendored);
|
|
44
45
|
}
|
|
45
46
|
return CONSERVATIVE_DEFAULTS;
|
|
@@ -69,10 +70,10 @@ function prettyToken(token) {
|
|
|
69
70
|
return token.charAt(0).toUpperCase() + token.slice(1);
|
|
70
71
|
}
|
|
71
72
|
function humanizeModelName(modelId) {
|
|
72
|
-
const { name } =
|
|
73
|
+
const { name } = chunk3EE6LVWT_cjs.parseModelId(modelId);
|
|
73
74
|
if (name.length === 0) return "";
|
|
74
75
|
const colon = name.indexOf(":");
|
|
75
|
-
const base = (colon >= 0 ? name.slice(0, colon) : name)
|
|
76
|
+
const base = trimTrailingSlashes(colon >= 0 ? name.slice(0, colon) : name);
|
|
76
77
|
const variant = colon >= 0 ? name.slice(colon + 1) : "";
|
|
77
78
|
const lastSlash = base.lastIndexOf("/");
|
|
78
79
|
const core = lastSlash >= 0 ? base.slice(lastSlash + 1) : base;
|
|
@@ -84,10 +85,17 @@ function toModelOption(modelId) {
|
|
|
84
85
|
return {
|
|
85
86
|
value: modelId,
|
|
86
87
|
label: humanizeModelName(modelId),
|
|
87
|
-
provider:
|
|
88
|
+
provider: chunk3EE6LVWT_cjs.parseModelId(modelId).provider
|
|
88
89
|
};
|
|
89
90
|
}
|
|
91
|
+
var SLASH_CODE = 47;
|
|
92
|
+
function trimTrailingSlashes(value) {
|
|
93
|
+
let end = value.length;
|
|
94
|
+
while (end > 0 && value.charCodeAt(end - 1) === SLASH_CODE) end--;
|
|
95
|
+
return end === value.length ? value : value.slice(0, end);
|
|
96
|
+
}
|
|
90
97
|
var DEFAULT_URL = "https://models.dev/api.json";
|
|
98
|
+
var MAX_CATALOG_BYTES = 32 * 1024 * 1024;
|
|
91
99
|
var TTL_MS = 60 * 60 * 1e3;
|
|
92
100
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
93
101
|
function cachePathFor(url) {
|
|
@@ -124,7 +132,7 @@ function catalogTargets() {
|
|
|
124
132
|
if (_catalogTargets !== void 0) return _catalogTargets;
|
|
125
133
|
_catalogTargets = /* @__PURE__ */ new Map();
|
|
126
134
|
try {
|
|
127
|
-
for (const entry of Object.values(
|
|
135
|
+
for (const entry of Object.values(chunkRM7Y65IG_cjs.loadProviderCatalog())) {
|
|
128
136
|
const keys = [entry.id, ...entry.aliases ?? []];
|
|
129
137
|
for (const k of keys) {
|
|
130
138
|
if (!_catalogTargets.has(k)) _catalogTargets.set(k, { keys });
|
|
@@ -138,7 +146,7 @@ function resolvePatchKeys(externalId) {
|
|
|
138
146
|
const mapped = MODELS_DEV_ID_MAP[externalId] ?? externalId;
|
|
139
147
|
const fromCatalog = catalogTargets().get(mapped);
|
|
140
148
|
if (fromCatalog !== void 0) return fromCatalog.keys;
|
|
141
|
-
const profile =
|
|
149
|
+
const profile = chunkRM7Y65IG_cjs.getProviderProfile(mapped);
|
|
142
150
|
if (profile !== void 0) return [profile.name, ...profile.aliases ?? []];
|
|
143
151
|
return void 0;
|
|
144
152
|
}
|
|
@@ -155,14 +163,14 @@ function patchIndexFromApiJson(raw) {
|
|
|
155
163
|
continue;
|
|
156
164
|
}
|
|
157
165
|
for (const [modelId, rawModel] of Object.entries(models)) {
|
|
158
|
-
const parsed =
|
|
166
|
+
const parsed = chunkRM7Y65IG_cjs.catalogModelSchema.safeParse(rawModel);
|
|
159
167
|
if (!parsed.success) continue;
|
|
160
|
-
for (const key of keys)
|
|
168
|
+
for (const key of keys) chunkRM7Y65IG_cjs.patchModelInfo(`${key}/${modelId}`, parsed.data);
|
|
161
169
|
patched++;
|
|
162
170
|
}
|
|
163
171
|
}
|
|
164
172
|
if (skipped.length > 0) {
|
|
165
|
-
|
|
173
|
+
chunkNUKRL3I6_cjs.diag(
|
|
166
174
|
`[theokit-sdk] WARN: models-dev refresh skipped ${skipped.length} unknown provider(s) (e.g. ${skipped.slice(0, 3).join(", ")})
|
|
167
175
|
`
|
|
168
176
|
);
|
|
@@ -185,20 +193,20 @@ function loadCacheIntoIndex(url = DEFAULT_URL) {
|
|
|
185
193
|
fs.unlinkSync(path);
|
|
186
194
|
} catch {
|
|
187
195
|
}
|
|
188
|
-
|
|
196
|
+
chunkNUKRL3I6_cjs.diag(`[theokit-sdk] WARN: corrupt models-dev cache deleted (${path})
|
|
189
197
|
`);
|
|
190
198
|
return 0;
|
|
191
199
|
}
|
|
192
200
|
try {
|
|
193
201
|
return patchIndexFromApiJson(parsed);
|
|
194
202
|
} catch (err) {
|
|
195
|
-
|
|
203
|
+
chunkNUKRL3I6_cjs.diag(`[theokit-sdk] WARN: models-dev cache patch failed (${err.message})
|
|
196
204
|
`);
|
|
197
205
|
return 0;
|
|
198
206
|
}
|
|
199
207
|
}
|
|
200
208
|
async function refreshModelCatalog(opts = {}) {
|
|
201
|
-
|
|
209
|
+
chunkRM7Y65IG_cjs.registerBuiltins();
|
|
202
210
|
const kill = process.env.THEOKIT_DISABLE_MODELS_FETCH;
|
|
203
211
|
if (kill !== void 0 && kill !== "" && kill !== "0" && kill.toLowerCase() !== "false") {
|
|
204
212
|
return { source: "skipped", models: 0 };
|
|
@@ -218,20 +226,27 @@ async function refreshModelCatalog(opts = {}) {
|
|
|
218
226
|
const fetchImpl = opts.deps?.fetch ?? fetch;
|
|
219
227
|
let body;
|
|
220
228
|
try {
|
|
221
|
-
const res = await
|
|
229
|
+
const res = await chunkHY57ULY2_cjs.Retry.create(
|
|
222
230
|
async () => {
|
|
223
231
|
const r = await fetchImpl(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
|
|
224
232
|
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
225
233
|
return r;
|
|
226
234
|
},
|
|
227
|
-
// 2 transient retries with backoff
|
|
235
|
+
// 2 transient retries with backoff; every error here is worth one more try —
|
|
228
236
|
// the whole call is already fail-closed at the caller.
|
|
229
237
|
{ retries: 2, isRetryable: () => true, initialDelayMs: 200 }
|
|
230
238
|
);
|
|
239
|
+
const declaredLength = Number(res.headers.get("content-length") ?? Number.NaN);
|
|
240
|
+
if (Number.isFinite(declaredLength) && declaredLength > MAX_CATALOG_BYTES) {
|
|
241
|
+
throw new Error(`catalog too large: ${declaredLength} bytes declared`);
|
|
242
|
+
}
|
|
231
243
|
body = await res.text();
|
|
244
|
+
if (body.length > MAX_CATALOG_BYTES) {
|
|
245
|
+
throw new Error(`catalog too large: ${body.length} bytes received`);
|
|
246
|
+
}
|
|
232
247
|
JSON.parse(body);
|
|
233
248
|
} catch (err) {
|
|
234
|
-
|
|
249
|
+
chunkNUKRL3I6_cjs.diag(
|
|
235
250
|
`[theokit-sdk] WARN: models-dev refresh failed (${err.message}) \u2014 serving existing data
|
|
236
251
|
`
|
|
237
252
|
);
|
|
@@ -240,13 +255,13 @@ async function refreshModelCatalog(opts = {}) {
|
|
|
240
255
|
try {
|
|
241
256
|
writeCacheAtomic(path, body);
|
|
242
257
|
} catch (err) {
|
|
243
|
-
|
|
258
|
+
chunkNUKRL3I6_cjs.diag(`[theokit-sdk] WARN: models-dev cache write failed (${err.message})
|
|
244
259
|
`);
|
|
245
260
|
}
|
|
246
261
|
try {
|
|
247
262
|
return { source: "network", models: patchIndexFromApiJson(JSON.parse(body)) };
|
|
248
263
|
} catch (err) {
|
|
249
|
-
|
|
264
|
+
chunkNUKRL3I6_cjs.diag(
|
|
250
265
|
`[theokit-sdk] WARN: models-dev patch failed (${err.message}) \u2014 serving existing data
|
|
251
266
|
`
|
|
252
267
|
);
|
|
@@ -254,12 +269,12 @@ async function refreshModelCatalog(opts = {}) {
|
|
|
254
269
|
}
|
|
255
270
|
}
|
|
256
271
|
function getModelInfo(modelId) {
|
|
257
|
-
return
|
|
272
|
+
return chunkRM7Y65IG_cjs.getCatalogModelInfo(modelId);
|
|
258
273
|
}
|
|
259
274
|
|
|
260
275
|
Object.defineProperty(exports, "parseModelId", {
|
|
261
276
|
enumerable: true,
|
|
262
|
-
get: function () { return
|
|
277
|
+
get: function () { return chunk3EE6LVWT_cjs.parseModelId; }
|
|
263
278
|
});
|
|
264
279
|
exports.getModelInfo = getModelInfo;
|
|
265
280
|
exports.humanizeModelName = humanizeModelName;
|
package/dist/models.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/llm/model-capabilities.ts","../src/internal/llm/model-option.ts","../src/internal/providers/catalog-source-models-dev.ts"],"names":["getCatalogModelInfo","parseModelId","join","homedir","createHash","path","mkdirSync","dirname","randomBytes","writeFileSync","renameSync","unlinkSync","loadProviderCatalog","getProviderProfile","catalogModelSchema","patchModelInfo","diag","readFileSync","registerBuiltins","statSync","Retry"],"mappings":"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","file":"models.cjs","sourcesContent":["/**\n * T3.10c — Model capability registry (DR3 #17).\n *\n * Typed per-model flags that let the SDK gate features at the boundary\n * (before hitting the provider) instead of letting opaque 400s surface.\n *\n * Resolution algorithm:\n * 1. Strip routing prefixes (openrouter/, vertex/, bedrock/) AND the\n * OpenRouter `:variant` suffix (:free/:nitro/…) to find the bare vendor id.\n * 2. Exact match in the `EXACT` catalog → return entry.\n * 3. Vendor inference (e.g., `claude-*` → `anthropic/claude-*`) → return entry.\n * 4. No match → conservative defaults (all false, minimum tokens).\n *\n * Module is internal, but `ModelCapabilities` + `resolveModelCapabilities` are\n * re-exported publicly via the `@theokit/sdk/models` subpath (see their @public tags).\n */\n\n/**\n * Per-model capability shape. Consumers use this to gate features at\n * the SDK boundary (before request construction, not after 400).\n *\n * @public\n */\nexport interface ModelCapabilities {\n supportsVision: boolean;\n supportsStructuredOutput: boolean;\n supportsToolUse: boolean;\n supportsCacheControl: boolean;\n maxContextTokens: number;\n maxOutputTokens: number;\n}\n\nconst CONSERVATIVE_DEFAULTS: ModelCapabilities = {\n supportsVision: false,\n supportsStructuredOutput: false,\n supportsToolUse: false,\n supportsCacheControl: false,\n maxContextTokens: 4096,\n maxOutputTokens: 4096,\n};\n\n/** Routing prefixes to strip to find the underlying vendor model. */\nconst ROUTING_PREFIXES = [\"openrouter/\", \"vertex/\", \"bedrock/\"] as const;\n\nimport { getCatalogModelInfo } from \"../providers/catalog-loader.js\";\nimport type { CatalogModel } from \"../providers/catalog-schema.js\";\n\n/** Map a catalog model block (models.dev shape) to the SDK's ModelCapabilities (M44 — catalog-backed). */\nfunction capsFromCatalog(m: CatalogModel): ModelCapabilities {\n return {\n supportsVision: m.modalities?.input?.includes(\"image\") ?? m.attachment ?? false,\n supportsStructuredOutput: m.structured_output ?? false,\n supportsToolUse: m.tool_call ?? false,\n supportsCacheControl: (m as { cache_control?: boolean }).cache_control ?? false,\n maxContextTokens: m.limit?.context ?? CONSERVATIVE_DEFAULTS.maxContextTokens,\n maxOutputTokens: m.limit?.output ?? CONSERVATIVE_DEFAULTS.maxOutputTokens,\n };\n}\n\n/**\n * Resolve per-model capability flags (vision/structured-output/tool-use/cache +\n * `maxContextTokens`/`maxOutputTokens`) for a model id. Pure, sync, offline (a\n * static catalog — no network). Strips routing prefixes (`openrouter/`/`vertex/`/\n * `bedrock/`) and OpenRouter `:variant` suffixes before lookup; unknown models get\n * conservative defaults. Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function resolveModelCapabilities(modelId: string): ModelCapabilities {\n const bare = stripVariantSuffix(stripRoutingPrefix(modelId));\n // M44 — the catalog model-info index replaced the hand-curated EXACT map (single source of truth; the\n // vendored provider-catalog.json carries the migrated data — parity-tested against the old map snapshot).\n const fromIndex = getCatalogModelInfo(bare);\n if (fromIndex !== undefined) return capsFromCatalog(fromIndex);\n // Routing-prefixed models (vertex/claude-3-5-sonnet) strip to bare\n // model name without vendor. Try inferring the vendor from the name.\n const withVendor = inferVendorPrefix(bare);\n if (withVendor !== bare) {\n const vendored = getCatalogModelInfo(withVendor);\n if (vendored !== undefined) return capsFromCatalog(vendored);\n }\n return CONSERVATIVE_DEFAULTS;\n}\n\nfunction stripRoutingPrefix(modelId: string): string {\n for (const prefix of ROUTING_PREFIXES) {\n if (modelId.startsWith(prefix)) return modelId.slice(prefix.length);\n }\n return modelId;\n}\n\n/**\n * Strip an OpenRouter variant suffix (`:free`/`:nitro`/`:floor`/`:beta`/…) so the\n * catalog lookup hits the underlying model. Model slugs contain no `:` except the\n * variant separator, so cutting at the first `:` is safe.\n */\nfunction stripVariantSuffix(modelId: string): string {\n const i = modelId.indexOf(\":\");\n return i >= 0 ? modelId.slice(0, i) : modelId;\n}\n\n/** Infer vendor prefix from bare model name for routing-prefixed lookups. */\nfunction inferVendorPrefix(bare: string): string {\n if (bare.startsWith(\"claude\")) return `anthropic/${bare}`;\n if (bare.startsWith(\"gpt-\") || bare.startsWith(\"o1\") || bare.startsWith(\"o3\"))\n return `openai/${bare}`;\n if (bare.startsWith(\"gemini\")) return `google/${bare}`;\n return bare;\n}\n","import { parseModelId } from \"./model-identifier.js\";\n\n/**\n * A UI-friendly model option — the shape a `<select>`/dropdown consumes.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport interface ModelOption {\n /** The original model id (what you pass back to the SDK). */\n value: string;\n /** Best-effort human label (see {@link humanizeModelName}). */\n label: string;\n /** Provider from the slug prefix, or `undefined` when none. */\n provider: string | undefined;\n}\n\n/** Tokens rendered upper-case rather than title-case. */\nconst ACRONYMS = new Set([\"gpt\", \"ai\", \"hd\", \"ui\", \"api\", \"sdk\", \"llm\", \"xl\"]);\n\nfunction prettyToken(token: string): string {\n if (ACRONYMS.has(token.toLowerCase())) return token.toUpperCase();\n return token.charAt(0).toUpperCase() + token.slice(1);\n}\n\n/**\n * Turn a model id into a best-effort human label: strip the routing/vendor\n * prefix to the core model segment, split on `-`/`_`/`.`/whitespace, title-case\n * each token (known acronyms upper-cased), and append an OpenRouter `:variant`\n * in parentheses. Deterministic, pure, dependency-free.\n *\n * Best-effort, NOT vendor-canonical: `\"anthropic/claude-3-5-sonnet\"` →\n * `\"Claude 3 5 Sonnet\"`. A UI wanting exact marketing names overrides per id.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function humanizeModelName(modelId: string): string {\n const { name } = parseModelId(modelId);\n if (name.length === 0) return \"\";\n const colon = name.indexOf(\":\");\n // Strip a trailing slash so a typo'd `gpt-4o/` keeps its name (not lost to an\n // empty last segment).\n const base = (colon >= 0 ? name.slice(0, colon) : name).replace(/\\/+$/, \"\");\n const variant = colon >= 0 ? name.slice(colon + 1) : \"\";\n const lastSlash = base.lastIndexOf(\"/\");\n const core = lastSlash >= 0 ? base.slice(lastSlash + 1) : base;\n const label = core\n .split(/[-_.\\s]+/)\n .filter((t) => t.length > 0)\n .map(prettyToken)\n .join(\" \");\n if (label.length === 0) return variant; // no base label (e.g. \":free\") → bare variant\n return variant.length > 0 ? `${label} (${variant})` : label;\n}\n\n/**\n * Build a {@link ModelOption} (`{ value, label, provider }`) for a model id —\n * a dropdown-ready entry composing {@link humanizeModelName} + `parseModelId`.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function toModelOption(modelId: string): ModelOption {\n return {\n value: modelId,\n label: humanizeModelName(modelId),\n provider: parseModelId(modelId).provider,\n };\n}\n","import { createHash, randomBytes } from \"node:crypto\";\nimport { mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { Retry } from \"../../retry.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { registerBuiltins } from \"./builtin/index.js\";\nimport { getCatalogModelInfo, loadProviderCatalog, patchModelInfo } from \"./catalog-loader.js\";\nimport { catalogModelSchema } from \"./catalog-schema.js\";\nimport { getProviderProfile } from \"./registry.js\";\n\n/**\n * M44 — the OPTIONAL models.dev catalog source. Explicit opt-in ONLY (`refreshModelCatalog()`): the SDK\n * NEVER fetches at startup or per-request — the vendored catalog + any existing disk cache are the offline\n * base, and every failure mode fails CLOSED back to them (ROADMAP constraint: no runtime hard network dep).\n *\n * Mechanism adapted from OpenCode's models.dev consumption (MIT © 2025 opencode — `core/src/models-dev.ts`):\n * disk cache with mtime TTL, atomic tempfile+rename write, corrupt-cache delete-and-fall-through, kill-switch\n * env. Library adaptations: NO background refresh loop (a consumer composes refresh with the SDK's cron);\n * TTL 1h (not 5min — no background refresher to keep it warm); no cross-process flock v1 (atomic rename +\n * idempotent upstream content — at most one wasted fetch).\n *\n * @internal (the public surface is `refreshModelCatalog` re-exported via `@theokit/sdk/models`)\n */\n\nconst DEFAULT_URL = \"https://models.dev/api.json\";\nconst TTL_MS = 60 * 60 * 1000; // 1 hour\nconst FETCH_TIMEOUT_MS = 10_000;\n\nexport interface RefreshModelCatalogOptions {\n /** Override the source URL (`THEOKIT_MODELS_URL` env also honored). */\n url?: string;\n /** Bypass the TTL freshness gate. */\n force?: boolean;\n /** Injected for tests. */\n deps?: { fetch?: typeof fetch; now?: () => number };\n}\n\nexport interface RefreshModelCatalogResult {\n /** Where the data came from: a fresh network fetch, the still-fresh disk cache, or skipped entirely. */\n source: \"network\" | \"cache\" | \"skipped\";\n /** How many models were patched into the index. */\n models: number;\n}\n\n/** The cache file for a source URL (custom URLs get a hash-suffixed name, mirroring OpenCode). */\nexport function cachePathFor(url: string): string {\n // M44 L8 fix — honor the SDK home override so tests and multi-home setups never touch the real ~/.theokit.\n const base = process.env.THEOKIT_HOME?.trim() || join(homedir(), \".theokit\");\n const dir = join(base, \"cache\", \"models-dev\");\n if (url === DEFAULT_URL) return join(dir, \"api.json\");\n const hash = createHash(\"sha256\").update(url).digest(\"hex\").slice(0, 12);\n return join(dir, `api-${hash}.json`);\n}\n\n/** Atomic write: temp file + rename (crash mid-write never leaves a partial cache). */\nfunction writeCacheAtomic(path: string, body: string): void {\n mkdirSync(dirname(path), { recursive: true });\n const tmp = `${path}.tmp-${randomBytes(6).toString(\"hex\")}`;\n try {\n writeFileSync(tmp, body);\n renameSync(tmp, path);\n } catch (err) {\n try {\n unlinkSync(tmp);\n } catch {\n // best effort\n }\n throw err;\n }\n}\n\n/**\n * M44 H3 fix — models.dev provider ids ≠ theokit ids (google↔google-gemini, zai↔zhipu, togetherai↔together,\n * fireworks-ai↔fireworks, amazon-bedrock↔bedrock, google-vertex↔vertex). The RUNTIME mapping mirrors the\n * maintenance script's table; targets resolve against the CATALOG entries (id + aliases — the same namespace\n * the vendored index uses) first, then the registry.\n */\nconst MODELS_DEV_ID_MAP: Record<string, string> = {\n google: \"google-gemini\",\n zai: \"zhipu\",\n togetherai: \"together\",\n \"fireworks-ai\": \"fireworks\",\n \"amazon-bedrock\": \"bedrock\",\n \"google-vertex\": \"vertex\",\n};\n\nlet _catalogTargets: Map<string, { keys: string[] }> | undefined;\n/** external-id → the index keys (entry id + aliases) its models patch under. Lazy; catalog-first. */\nfunction catalogTargets(): Map<string, { keys: string[] }> {\n if (_catalogTargets !== undefined) return _catalogTargets;\n _catalogTargets = new Map();\n try {\n for (const entry of Object.values(loadProviderCatalog())) {\n const keys = [entry.id, ...(entry.aliases ?? [])];\n for (const k of keys) {\n if (!_catalogTargets.has(k)) _catalogTargets.set(k, { keys });\n }\n }\n } catch {\n // catalog unavailable — registry fallback below still works\n }\n return _catalogTargets;\n}\n\nfunction resolvePatchKeys(externalId: string): string[] | undefined {\n const mapped = MODELS_DEV_ID_MAP[externalId] ?? externalId;\n const fromCatalog = catalogTargets().get(mapped);\n if (fromCatalog !== undefined) return fromCatalog.keys;\n const profile = getProviderProfile(mapped);\n if (profile !== undefined) return [profile.name, ...(profile.aliases ?? [])];\n return undefined;\n}\n\n/** Parse + patch the index from an api.json payload. Unknown providers are skipped with WARN (once each). */\n// PRE-EXISTING debt, exposed when M75 fixed the Biome config that used to abort before\n// sweeping these files (a nested root under refactor/). It is not new code and was not touched\n// by M75; refactoring SDK internals without review would trade a visible problem for a diff\n// risky. Tracked in usetheodev/theokit-sdk#151.\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: see the reason just above\nfunction patchIndexFromApiJson(raw: unknown): number {\n if (typeof raw !== \"object\" || raw === null) return 0;\n let patched = 0;\n const skipped: string[] = [];\n for (const [providerId, provider] of Object.entries(raw as Record<string, unknown>)) {\n const models = (provider as { models?: Record<string, unknown> })?.models;\n if (models === undefined || typeof models !== \"object\") continue;\n // Enrich ONLY providers the SDK knows — models.dev's npm/api fields cannot be mapped to a theokit\n // apiMode/authType safely, so unknown providers are data we cannot route.\n const keys = resolvePatchKeys(providerId);\n if (keys === undefined) {\n skipped.push(providerId);\n continue;\n }\n for (const [modelId, rawModel] of Object.entries(models)) {\n const parsed = catalogModelSchema.safeParse(rawModel);\n if (!parsed.success) continue; // malformed model — drop silently (live data, additive drift expected)\n for (const key of keys) patchModelInfo(`${key}/${modelId}`, parsed.data);\n patched++;\n }\n }\n if (skipped.length > 0) {\n diag(\n `[theokit-sdk] WARN: models-dev refresh skipped ${skipped.length} unknown provider(s) (e.g. ${skipped.slice(0, 3).join(\", \")})\\n`,\n );\n }\n return patched;\n}\n\n/**\n * Load an existing disk cache into the index (called by refresh when fresh, or opportunistically by a\n * consumer at startup — NEVER fetches). Corrupt cache → delete + fall through to vendored data.\n */\nexport function loadCacheIntoIndex(url: string = DEFAULT_URL): number {\n const path = cachePathFor(url);\n let body: string;\n try {\n body = readFileSync(path, \"utf-8\");\n } catch {\n return 0; // no cache — vendored data only\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n // corrupt cache: delete and fall through to the vendored catalog (OpenCode's delete-and-fall-through).\n // M44 L9 fix — only a PARSE failure is cache corruption; a patch error must never delete a valid cache.\n try {\n unlinkSync(path);\n } catch {\n // best effort\n }\n diag(`[theokit-sdk] WARN: corrupt models-dev cache deleted (${path})\\n`);\n return 0;\n }\n try {\n return patchIndexFromApiJson(parsed);\n } catch (err) {\n diag(`[theokit-sdk] WARN: models-dev cache patch failed (${(err as Error).message})\\n`);\n return 0;\n }\n}\n\n/**\n * Explicitly refresh the model catalog from models.dev (the ONLY network trigger in the subsystem).\n * Fail-closed: any failure keeps serving the current index (cache or vendored). Kill-switch:\n * `THEOKIT_DISABLE_MODELS_FETCH`.\n */\n// PRE-EXISTING debt, exposed when M75 fixed the Biome config that used to abort before\n// sweeping these files (a nested root under refactor/). It is not new code and was not touched\n// by M75; refactoring SDK internals without review would trade a visible problem for a diff\n// risky. Tracked in usetheodev/theokit-sdk#151.\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: see the reason just above\nexport async function refreshModelCatalog(\n opts: RefreshModelCatalogOptions = {},\n): Promise<RefreshModelCatalogResult> {\n // M44 M4 fix — self-initialize provider registration so the `@theokit/sdk/models` subpath works standalone\n // (without the consumer having built an Agent first).\n registerBuiltins();\n // M44 L11 fix — presence-based would treat \"0\"/\"false\"/\"\" as disabled; only truthy values disable.\n const kill = process.env.THEOKIT_DISABLE_MODELS_FETCH;\n if (kill !== undefined && kill !== \"\" && kill !== \"0\" && kill.toLowerCase() !== \"false\") {\n return { source: \"skipped\", models: 0 };\n }\n const url = opts.url ?? process.env.THEOKIT_MODELS_URL ?? DEFAULT_URL;\n const path = cachePathFor(url);\n const now = opts.deps?.now ?? (() => Date.now());\n\n // TTL gate: a fresh cache serves without network (mtime freshness, OpenCode's gate).\n if (opts.force !== true) {\n try {\n const age = now() - statSync(path).mtimeMs;\n if (age < TTL_MS) {\n return { source: \"cache\", models: loadCacheIntoIndex(url) };\n }\n } catch {\n // no cache — proceed to fetch\n }\n }\n\n const fetchImpl = opts.deps?.fetch ?? fetch;\n let body: string;\n try {\n const res = await Retry.create(\n async () => {\n const r = await fetchImpl(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r;\n },\n // 2 transient retries with backoff (OpenCode does the same); every error here is worth one more try —\n // the whole call is already fail-closed at the caller.\n { retries: 2, isRetryable: () => true, initialDelayMs: 200 },\n );\n body = await res.text();\n JSON.parse(body); // validate before persisting — never cache garbage\n } catch (err) {\n diag(\n `[theokit-sdk] WARN: models-dev refresh failed (${(err as Error).message}) — serving existing data\\n`,\n );\n // fail-closed: serve whatever we already have (stale cache if present, else vendored)\n return { source: \"cache\", models: loadCacheIntoIndex(url) };\n }\n\n try {\n writeCacheAtomic(path, body);\n } catch (err) {\n diag(`[theokit-sdk] WARN: models-dev cache write failed (${(err as Error).message})\\n`);\n }\n try {\n return { source: \"network\", models: patchIndexFromApiJson(JSON.parse(body)) };\n } catch (err) {\n diag(\n `[theokit-sdk] WARN: models-dev patch failed (${(err as Error).message}) — serving existing data\\n`,\n );\n return { source: \"cache\", models: 0 };\n }\n}\n\n/** The enriched per-model view (public via `@theokit/sdk/models`): index lookup by (possibly prefixed) id. */\nexport function getModelInfo(modelId: string): ReturnType<typeof getCatalogModelInfo> {\n return getCatalogModelInfo(modelId);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/llm/model-capabilities.ts","../src/internal/llm/model-option.ts","../src/internal/providers/catalog-source-models-dev.ts"],"names":["getCatalogModelInfo","parseModelId","join","homedir","createHash","path","mkdirSync","dirname","randomBytes","writeFileSync","renameSync","unlinkSync","loadProviderCatalog","getProviderProfile","catalogModelSchema","patchModelInfo","diag","readFileSync","registerBuiltins","statSync","Retry"],"mappings":"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","file":"models.cjs","sourcesContent":["/**\n * T3.10c — Model capability registry (DR3 #17).\n *\n * Typed per-model flags that let the SDK gate features at the boundary\n * (before hitting the provider) instead of letting opaque 400s surface.\n *\n * Resolution algorithm:\n * 1. Strip routing prefixes (openrouter/, vertex/, bedrock/) AND the\n * OpenRouter `:variant` suffix (:free/:nitro/…) to find the bare vendor id.\n * 2. Exact match in the `EXACT` catalog → return entry.\n * 3. Vendor inference (e.g., `claude-*` → `anthropic/claude-*`) → return entry.\n * 4. No match → conservative defaults (all false, minimum tokens).\n *\n * Module is internal, but `ModelCapabilities` + `resolveModelCapabilities` are\n * re-exported publicly via the `@theokit/sdk/models` subpath (see their @public tags).\n */\n\n/**\n * Per-model capability shape. Consumers use this to gate features at\n * the SDK boundary (before request construction, not after 400).\n *\n * @public\n */\nexport interface ModelCapabilities {\n supportsVision: boolean;\n supportsStructuredOutput: boolean;\n supportsToolUse: boolean;\n supportsCacheControl: boolean;\n maxContextTokens: number;\n maxOutputTokens: number;\n}\n\nconst CONSERVATIVE_DEFAULTS: ModelCapabilities = {\n supportsVision: false,\n supportsStructuredOutput: false,\n supportsToolUse: false,\n supportsCacheControl: false,\n maxContextTokens: 4096,\n maxOutputTokens: 4096,\n};\n\n/** Routing prefixes to strip to find the underlying vendor model. */\nconst ROUTING_PREFIXES = [\"openrouter/\", \"vertex/\", \"bedrock/\"] as const;\n\nimport { getCatalogModelInfo } from \"../providers/catalog-loader.js\";\nimport type { CatalogModel } from \"../providers/catalog-schema.js\";\n\n/** Map a catalog model block (models.dev shape) to the SDK's ModelCapabilities (M44 — catalog-backed). */\nfunction capsFromCatalog(m: CatalogModel): ModelCapabilities {\n return {\n supportsVision: m.modalities?.input?.includes(\"image\") ?? m.attachment ?? false,\n supportsStructuredOutput: m.structured_output ?? false,\n supportsToolUse: m.tool_call ?? false,\n supportsCacheControl: (m as { cache_control?: boolean }).cache_control ?? false,\n maxContextTokens: m.limit?.context ?? CONSERVATIVE_DEFAULTS.maxContextTokens,\n maxOutputTokens: m.limit?.output ?? CONSERVATIVE_DEFAULTS.maxOutputTokens,\n };\n}\n\n/**\n * Resolve per-model capability flags (vision/structured-output/tool-use/cache +\n * `maxContextTokens`/`maxOutputTokens`) for a model id. Pure, sync, offline (a\n * static catalog — no network). Strips routing prefixes (`openrouter/`/`vertex/`/\n * `bedrock/`) and OpenRouter `:variant` suffixes before lookup; unknown models get\n * conservative defaults. Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function resolveModelCapabilities(modelId: string): ModelCapabilities {\n const bare = stripVariantSuffix(stripRoutingPrefix(modelId));\n // M44 — the catalog model-info index replaced the hand-curated EXACT map (single source of truth; the\n // vendored provider-catalog.json carries the migrated data — parity-tested against the old map snapshot).\n const fromIndex = getCatalogModelInfo(bare);\n if (fromIndex !== undefined) return capsFromCatalog(fromIndex);\n // Routing-prefixed models (vertex/claude-3-5-sonnet) strip to bare\n // model name without vendor. Try inferring the vendor from the name.\n const withVendor = inferVendorPrefix(bare);\n if (withVendor !== bare) {\n const vendored = getCatalogModelInfo(withVendor);\n if (vendored !== undefined) return capsFromCatalog(vendored);\n }\n return CONSERVATIVE_DEFAULTS;\n}\n\nfunction stripRoutingPrefix(modelId: string): string {\n for (const prefix of ROUTING_PREFIXES) {\n if (modelId.startsWith(prefix)) return modelId.slice(prefix.length);\n }\n return modelId;\n}\n\n/**\n * Strip an OpenRouter variant suffix (`:free`/`:nitro`/`:floor`/`:beta`/…) so the\n * catalog lookup hits the underlying model. Model slugs contain no `:` except the\n * variant separator, so cutting at the first `:` is safe.\n */\nfunction stripVariantSuffix(modelId: string): string {\n const i = modelId.indexOf(\":\");\n return i >= 0 ? modelId.slice(0, i) : modelId;\n}\n\n/** Infer vendor prefix from bare model name for routing-prefixed lookups. */\nfunction inferVendorPrefix(bare: string): string {\n if (bare.startsWith(\"claude\")) return `anthropic/${bare}`;\n if (bare.startsWith(\"gpt-\") || bare.startsWith(\"o1\") || bare.startsWith(\"o3\"))\n return `openai/${bare}`;\n if (bare.startsWith(\"gemini\")) return `google/${bare}`;\n return bare;\n}\n","import { parseModelId } from \"./model-identifier.js\";\n\n/**\n * A UI-friendly model option — the shape a `<select>`/dropdown consumes.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport interface ModelOption {\n /** The original model id (what you pass back to the SDK). */\n value: string;\n /** Best-effort human label (see {@link humanizeModelName}). */\n label: string;\n /** Provider from the slug prefix, or `undefined` when none. */\n provider: string | undefined;\n}\n\n/** Tokens rendered upper-case rather than title-case. */\nconst ACRONYMS = new Set([\"gpt\", \"ai\", \"hd\", \"ui\", \"api\", \"sdk\", \"llm\", \"xl\"]);\n\nfunction prettyToken(token: string): string {\n if (ACRONYMS.has(token.toLowerCase())) return token.toUpperCase();\n return token.charAt(0).toUpperCase() + token.slice(1);\n}\n\n/**\n * Turn a model id into a best-effort human label: strip the routing/vendor\n * prefix to the core model segment, split on `-`/`_`/`.`/whitespace, title-case\n * each token (known acronyms upper-cased), and append an OpenRouter `:variant`\n * in parentheses. Deterministic, pure, dependency-free.\n *\n * Best-effort, NOT vendor-canonical: `\"anthropic/claude-3-5-sonnet\"` →\n * `\"Claude 3 5 Sonnet\"`. A UI wanting exact marketing names overrides per id.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function humanizeModelName(modelId: string): string {\n const { name } = parseModelId(modelId);\n if (name.length === 0) return \"\";\n const colon = name.indexOf(\":\");\n // Strip a trailing slash so a typo'd `gpt-4o/` keeps its name (not lost to an\n // empty last segment).\n //\n // Done by index rather than with `/\\/+$/`, and the difference is not stylistic: that pattern\n // consumes slashes to the end of the string at every start position and then backtracks\n // looking for an end-anchor that is not there (CodeQL js/polynomial-redos #6). This function\n // is `@public` and takes a caller-supplied model id. Measured on a run of slashes followed by\n // one other character: 25_000 took 496 ms, 100_000 took 31_305 ms — half a minute of pinned\n // CPU to render a label. Walking back from the end is linear and cannot backtrack.\n const base = trimTrailingSlashes(colon >= 0 ? name.slice(0, colon) : name);\n const variant = colon >= 0 ? name.slice(colon + 1) : \"\";\n const lastSlash = base.lastIndexOf(\"/\");\n const core = lastSlash >= 0 ? base.slice(lastSlash + 1) : base;\n const label = core\n .split(/[-_.\\s]+/)\n .filter((t) => t.length > 0)\n .map(prettyToken)\n .join(\" \");\n if (label.length === 0) return variant; // no base label (e.g. \":free\") → bare variant\n return variant.length > 0 ? `${label} (${variant})` : label;\n}\n\n/**\n * Build a {@link ModelOption} (`{ value, label, provider }`) for a model id —\n * a dropdown-ready entry composing {@link humanizeModelName} + `parseModelId`.\n *\n * Public via `@theokit/sdk/models`.\n *\n * @public\n */\nexport function toModelOption(modelId: string): ModelOption {\n return {\n value: modelId,\n label: humanizeModelName(modelId),\n provider: parseModelId(modelId).provider,\n };\n}\n\nconst SLASH_CODE = 47; // \"/\"\n\n/** Removes trailing `/` characters in one linear pass. See the call site for why not a regex. */\nfunction trimTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === SLASH_CODE) end--;\n return end === value.length ? value : value.slice(0, end);\n}\n","import { createHash, randomBytes } from \"node:crypto\";\nimport { mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { Retry } from \"../../retry.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { registerBuiltins } from \"./builtin/index.js\";\nimport { getCatalogModelInfo, loadProviderCatalog, patchModelInfo } from \"./catalog-loader.js\";\nimport { catalogModelSchema } from \"./catalog-schema.js\";\nimport { getProviderProfile } from \"./registry.js\";\n\n/**\n * M44 — the OPTIONAL models.dev catalog source. Explicit opt-in ONLY (`refreshModelCatalog()`): the SDK\n * NEVER fetches at startup or per-request — the vendored catalog + any existing disk cache are the offline\n * base, and every failure mode fails CLOSED back to them (ROADMAP constraint: no runtime hard network dep).\n *\n * The models.dev consumption mechanism:\n * disk cache with mtime TTL, atomic tempfile+rename write, corrupt-cache delete-and-fall-through, kill-switch\n * env. Library adaptations: NO background refresh loop (a consumer composes refresh with the SDK's cron);\n * TTL 1h (not 5min — no background refresher to keep it warm); no cross-process flock v1 (atomic rename +\n * idempotent upstream content — at most one wasted fetch).\n *\n * @internal (the public surface is `refreshModelCatalog` re-exported via `@theokit/sdk/models`)\n */\n\nconst DEFAULT_URL = \"https://models.dev/api.json\";\n\n/**\n * Ceiling on a fetched catalog, before it is parsed or written to the cache.\n *\n * The response body was read with `res.text()` and persisted with no bound, so a host serving a\n * multi-gigabyte document would have been materialised in memory and then written to disk. The\n * default URL is trusted, but `THEOKIT_MODELS_URL` lets an operator point this anywhere, and a\n * limit is the difference between \"we only fetch from a host we trust\" and \"we cannot be hurt by\n * one we do not\".\n *\n * 32 MiB is roughly 40x the real catalog (~800 KiB in 2026-08), so it bounds the failure without\n * being a number anyone has to tune when models.dev grows.\n */\nconst MAX_CATALOG_BYTES = 32 * 1024 * 1024;\nconst TTL_MS = 60 * 60 * 1000; // 1 hour\nconst FETCH_TIMEOUT_MS = 10_000;\n\n/**\n * Arguments to `refreshModelCatalog`, the SDK's only network trigger for model metadata.\n *\n * `url` wins over the `THEOKIT_MODELS_URL` environment variable, which in turn wins over\n * `https://models.dev/api.json`. A non-default URL gets its own cache file, named by a hash of\n * the URL, so switching sources never reads another source's cache.\n *\n * `force` skips only the freshness check — it does not skip the kill switch. When\n * `THEOKIT_DISABLE_MODELS_FETCH` is set to anything other than an empty string, `\"0\"` or\n * `\"false\"`, the call returns `source: \"skipped\"` with no fetch and no cache read, whatever\n * `force` says.\n *\n * Without `force`, a cache file whose mtime is under an hour old is served directly and no\n * request is made.\n *\n * `deps` exists so tests can drive the fetch and the clock; production leaves it unset.\n */\nexport interface RefreshModelCatalogOptions {\n /** Override the source URL (`THEOKIT_MODELS_URL` env also honored). */\n url?: string;\n /** Bypass the TTL freshness gate. */\n force?: boolean;\n /** Injected for tests. */\n deps?: { fetch?: typeof fetch; now?: () => number };\n}\n\n/**\n * What `refreshModelCatalog` did. It never throws on a failed refresh, so this is the only place\n * the outcome is reported.\n *\n * `source` is `\"network\"` only when a request succeeded, its body parsed as JSON, and the models\n * were patched in. Every failure path — kill switch aside — returns `\"cache\"`: an HTTP error\n * after retries, a timeout, an unparseable body, or a patch that threw. `\"cache\"` therefore means\n * \"serving what was already there\", which may be a fresh cache, a stale one, or nothing but the\n * vendored catalog. Read `models` to tell those apart. `\"skipped\"` means the kill switch was set.\n *\n * `models` counts the models patched into the index during this call, not the catalog's size. It\n * counts each model once even when the provider has aliases and the model is written under several\n * index keys, and it excludes models whose payload failed schema validation and models under\n * providers the SDK does not know. It is 0 whenever there was no cache to fall back on, and 0 for\n * `\"skipped\"`.\n *\n * A cache write that fails is logged and otherwise ignored: the result can still say `\"network\"`\n * with the data live in memory and nothing on disk.\n */\nexport interface RefreshModelCatalogResult {\n /** Where the data came from: a fresh network fetch, the still-fresh disk cache, or skipped entirely. */\n source: \"network\" | \"cache\" | \"skipped\";\n /** How many models were patched into the index. */\n models: number;\n}\n\n/** The cache file for a source URL (custom URLs get a hash-suffixed name). */\nexport function cachePathFor(url: string): string {\n // M44 L8 fix — honor the SDK home override so tests and multi-home setups never touch the real ~/.theokit.\n const base = process.env.THEOKIT_HOME?.trim() || join(homedir(), \".theokit\");\n const dir = join(base, \"cache\", \"models-dev\");\n if (url === DEFAULT_URL) return join(dir, \"api.json\");\n const hash = createHash(\"sha256\").update(url).digest(\"hex\").slice(0, 12);\n return join(dir, `api-${hash}.json`);\n}\n\n/** Atomic write: temp file + rename (crash mid-write never leaves a partial cache). */\nfunction writeCacheAtomic(path: string, body: string): void {\n mkdirSync(dirname(path), { recursive: true });\n const tmp = `${path}.tmp-${randomBytes(6).toString(\"hex\")}`;\n try {\n writeFileSync(tmp, body);\n renameSync(tmp, path);\n } catch (err) {\n try {\n unlinkSync(tmp);\n } catch {\n // best effort\n }\n throw err;\n }\n}\n\n/**\n * M44 H3 fix — models.dev provider ids ≠ theokit ids (google↔google-gemini, zai↔zhipu, togetherai↔together,\n * fireworks-ai↔fireworks, amazon-bedrock↔bedrock, google-vertex↔vertex). The RUNTIME mapping mirrors the\n * maintenance script's table; targets resolve against the CATALOG entries (id + aliases — the same namespace\n * the vendored index uses) first, then the registry.\n */\nconst MODELS_DEV_ID_MAP: Record<string, string> = {\n google: \"google-gemini\",\n zai: \"zhipu\",\n togetherai: \"together\",\n \"fireworks-ai\": \"fireworks\",\n \"amazon-bedrock\": \"bedrock\",\n \"google-vertex\": \"vertex\",\n};\n\nlet _catalogTargets: Map<string, { keys: string[] }> | undefined;\n/** external-id → the index keys (entry id + aliases) its models patch under. Lazy; catalog-first. */\nfunction catalogTargets(): Map<string, { keys: string[] }> {\n if (_catalogTargets !== undefined) return _catalogTargets;\n _catalogTargets = new Map();\n try {\n for (const entry of Object.values(loadProviderCatalog())) {\n const keys = [entry.id, ...(entry.aliases ?? [])];\n for (const k of keys) {\n if (!_catalogTargets.has(k)) _catalogTargets.set(k, { keys });\n }\n }\n } catch {\n // catalog unavailable — registry fallback below still works\n }\n return _catalogTargets;\n}\n\nfunction resolvePatchKeys(externalId: string): string[] | undefined {\n const mapped = MODELS_DEV_ID_MAP[externalId] ?? externalId;\n const fromCatalog = catalogTargets().get(mapped);\n if (fromCatalog !== undefined) return fromCatalog.keys;\n const profile = getProviderProfile(mapped);\n if (profile !== undefined) return [profile.name, ...(profile.aliases ?? [])];\n return undefined;\n}\n\n/** Parse + patch the index from an api.json payload. Unknown providers are skipped with WARN (once each). */\n// PRE-EXISTING debt, exposed when M75 fixed the Biome config that used to abort before\n// sweeping these files (a nested root under refactor/). It is not new code and was not touched\n// by M75; refactoring SDK internals without review would trade a visible problem for a diff\n// risky. Tracked in usetheodev/theokit-sdk#151.\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: see the reason just above\nfunction patchIndexFromApiJson(raw: unknown): number {\n if (typeof raw !== \"object\" || raw === null) return 0;\n let patched = 0;\n const skipped: string[] = [];\n for (const [providerId, provider] of Object.entries(raw as Record<string, unknown>)) {\n const models = (provider as { models?: Record<string, unknown> })?.models;\n if (models === undefined || typeof models !== \"object\") continue;\n // Enrich ONLY providers the SDK knows — models.dev's npm/api fields cannot be mapped to a theokit\n // apiMode/authType safely, so unknown providers are data we cannot route.\n const keys = resolvePatchKeys(providerId);\n if (keys === undefined) {\n skipped.push(providerId);\n continue;\n }\n for (const [modelId, rawModel] of Object.entries(models)) {\n const parsed = catalogModelSchema.safeParse(rawModel);\n if (!parsed.success) continue; // malformed model — drop silently (live data, additive drift expected)\n for (const key of keys) patchModelInfo(`${key}/${modelId}`, parsed.data);\n patched++;\n }\n }\n if (skipped.length > 0) {\n diag(\n `[theokit-sdk] WARN: models-dev refresh skipped ${skipped.length} unknown provider(s) (e.g. ${skipped.slice(0, 3).join(\", \")})\\n`,\n );\n }\n return patched;\n}\n\n/**\n * Load an existing disk cache into the index (called by refresh when fresh, or opportunistically by a\n * consumer at startup — NEVER fetches). Corrupt cache → delete + fall through to vendored data.\n */\nexport function loadCacheIntoIndex(url: string = DEFAULT_URL): number {\n const path = cachePathFor(url);\n let body: string;\n try {\n body = readFileSync(path, \"utf-8\");\n } catch {\n return 0; // no cache — vendored data only\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n // corrupt cache: delete and fall through to the vendored catalog.\n // M44 L9 fix — only a PARSE failure is cache corruption; a patch error must never delete a valid cache.\n try {\n unlinkSync(path);\n } catch {\n // best effort\n }\n diag(`[theokit-sdk] WARN: corrupt models-dev cache deleted (${path})\\n`);\n return 0;\n }\n try {\n return patchIndexFromApiJson(parsed);\n } catch (err) {\n diag(`[theokit-sdk] WARN: models-dev cache patch failed (${(err as Error).message})\\n`);\n return 0;\n }\n}\n\n/**\n * Explicitly refresh the model catalog from models.dev (the ONLY network trigger in the subsystem).\n * Fail-closed: any failure keeps serving the current index (cache or vendored). Kill-switch:\n * `THEOKIT_DISABLE_MODELS_FETCH`.\n */\n// PRE-EXISTING debt, exposed when M75 fixed the Biome config that used to abort before\n// sweeping these files (a nested root under refactor/). It is not new code and was not touched\n// by M75; refactoring SDK internals without review would trade a visible problem for a diff\n// risky. Tracked in usetheodev/theokit-sdk#151.\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: see the reason just above\nexport async function refreshModelCatalog(\n opts: RefreshModelCatalogOptions = {},\n): Promise<RefreshModelCatalogResult> {\n // M44 M4 fix — self-initialize provider registration so the `@theokit/sdk/models` subpath works standalone\n // (without the consumer having built an Agent first).\n registerBuiltins();\n // M44 L11 fix — presence-based would treat \"0\"/\"false\"/\"\" as disabled; only truthy values disable.\n const kill = process.env.THEOKIT_DISABLE_MODELS_FETCH;\n if (kill !== undefined && kill !== \"\" && kill !== \"0\" && kill.toLowerCase() !== \"false\") {\n return { source: \"skipped\", models: 0 };\n }\n const url = opts.url ?? process.env.THEOKIT_MODELS_URL ?? DEFAULT_URL;\n const path = cachePathFor(url);\n const now = opts.deps?.now ?? (() => Date.now());\n\n // TTL gate: a fresh cache serves without network (mtime freshness).\n if (opts.force !== true) {\n try {\n const age = now() - statSync(path).mtimeMs;\n if (age < TTL_MS) {\n return { source: \"cache\", models: loadCacheIntoIndex(url) };\n }\n } catch {\n // no cache — proceed to fetch\n }\n }\n\n const fetchImpl = opts.deps?.fetch ?? fetch;\n let body: string;\n try {\n const res = await Retry.create(\n async () => {\n const r = await fetchImpl(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r;\n },\n // 2 transient retries with backoff; every error here is worth one more try —\n // the whole call is already fail-closed at the caller.\n { retries: 2, isRetryable: () => true, initialDelayMs: 200 },\n );\n const declaredLength = Number(res.headers.get(\"content-length\") ?? Number.NaN);\n if (Number.isFinite(declaredLength) && declaredLength > MAX_CATALOG_BYTES) {\n throw new Error(`catalog too large: ${declaredLength} bytes declared`);\n }\n body = await res.text();\n // Checked again after reading: `content-length` is the server's claim, and a server that\n // omits it or lies about it is exactly the one worth bounding. Both checks are cheap and\n // neither alone is sufficient.\n if (body.length > MAX_CATALOG_BYTES) {\n throw new Error(`catalog too large: ${body.length} bytes received`);\n }\n JSON.parse(body); // validate before persisting — never cache garbage\n } catch (err) {\n diag(\n `[theokit-sdk] WARN: models-dev refresh failed (${(err as Error).message}) — serving existing data\\n`,\n );\n // fail-closed: serve whatever we already have (stale cache if present, else vendored)\n return { source: \"cache\", models: loadCacheIntoIndex(url) };\n }\n\n try {\n writeCacheAtomic(path, body);\n } catch (err) {\n diag(`[theokit-sdk] WARN: models-dev cache write failed (${(err as Error).message})\\n`);\n }\n try {\n return { source: \"network\", models: patchIndexFromApiJson(JSON.parse(body)) };\n } catch (err) {\n diag(\n `[theokit-sdk] WARN: models-dev patch failed (${(err as Error).message}) — serving existing data\\n`,\n );\n return { source: \"cache\", models: 0 };\n }\n}\n\n/** The enriched per-model view (public via `@theokit/sdk/models`): index lookup by (possibly prefixed) id. */\nexport function getModelInfo(modelId: string): ReturnType<typeof getCatalogModelInfo> {\n return getCatalogModelInfo(modelId);\n}\n"]}
|