@theokit/sdk 4.36.0 → 4.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/dist/agent-4MHQUGO5.cjs +51 -0
- package/dist/{agent-P77NPBF4.cjs.map → agent-4MHQUGO5.cjs.map} +1 -1
- package/dist/agent-GV36S2CF.js +42 -0
- package/dist/{agent-H6HL5ITH.js.map → agent-GV36S2CF.js.map} +1 -1
- package/dist/agent.d.ts +2 -1
- package/dist/auth/index.cjs +15 -15
- package/dist/auth/index.js +4 -4
- package/dist/{batch-2FSD2UNL.cjs → batch-3SEPDXCU.cjs} +23 -23
- package/dist/{batch-2FSD2UNL.cjs.map → batch-3SEPDXCU.cjs.map} +1 -1
- package/dist/{batch-MR2HKYMS.js → batch-SY5GZLFD.js} +9 -9
- package/dist/{batch-MR2HKYMS.js.map → batch-SY5GZLFD.js.map} +1 -1
- package/dist/{chunk-JLMXKTBX.cjs → chunk-2423XDPT.cjs} +26 -26
- package/dist/{chunk-JLMXKTBX.cjs.map → chunk-2423XDPT.cjs.map} +1 -1
- package/dist/{chunk-5IB2UKSN.js → chunk-2WFB5ZOX.js} +5 -5
- package/dist/{chunk-5IB2UKSN.js.map → chunk-2WFB5ZOX.js.map} +1 -1
- package/dist/{chunk-EPYZOCOL.cjs → chunk-3ILFUXNE.cjs} +5 -5
- package/dist/{chunk-EPYZOCOL.cjs.map → chunk-3ILFUXNE.cjs.map} +1 -1
- package/dist/{chunk-KSKU6JY6.cjs → chunk-3O2ELBST.cjs} +5 -5
- package/dist/{chunk-KSKU6JY6.cjs.map → chunk-3O2ELBST.cjs.map} +1 -1
- package/dist/{chunk-M2PU44HP.cjs → chunk-4YB7B3RP.cjs} +8 -8
- package/dist/{chunk-M2PU44HP.cjs.map → chunk-4YB7B3RP.cjs.map} +1 -1
- package/dist/{chunk-S2BBRVQX.js → chunk-56OXYUZE.js} +8 -7
- package/dist/chunk-56OXYUZE.js.map +1 -0
- package/dist/{chunk-D42XHI4O.cjs → chunk-56ZM6P7Z.cjs} +13 -14
- package/dist/chunk-56ZM6P7Z.cjs.map +1 -0
- package/dist/{chunk-7BTE3RXJ.js → chunk-5SB4V74H.js} +7 -8
- package/dist/chunk-5SB4V74H.js.map +1 -0
- package/dist/{chunk-MZ5ZRORA.cjs → chunk-6EDQBX7U.cjs} +17 -16
- package/dist/chunk-6EDQBX7U.cjs.map +1 -0
- package/dist/{chunk-RKG6QFCJ.js → chunk-6VP3XGEK.js} +4 -4
- package/dist/{chunk-RKG6QFCJ.js.map → chunk-6VP3XGEK.js.map} +1 -1
- package/dist/{chunk-KAP4GJHO.js → chunk-77WHPVXE.js} +10 -11
- package/dist/chunk-77WHPVXE.js.map +1 -0
- package/dist/{chunk-LALRCFSN.cjs → chunk-7DXLNNKH.cjs} +4 -4
- package/dist/{chunk-LALRCFSN.cjs.map → chunk-7DXLNNKH.cjs.map} +1 -1
- package/dist/{chunk-WEHUJ7ZS.cjs → chunk-ALU3KC4G.cjs} +267 -120
- package/dist/chunk-ALU3KC4G.cjs.map +1 -0
- package/dist/{chunk-Z2OC3UIW.cjs → chunk-BJMKQOY2.cjs} +11 -11
- package/dist/{chunk-Z2OC3UIW.cjs.map → chunk-BJMKQOY2.cjs.map} +1 -1
- package/dist/{chunk-WLKFWQSJ.js → chunk-CD73YHEH.js} +3 -3
- package/dist/{chunk-WLKFWQSJ.js.map → chunk-CD73YHEH.js.map} +1 -1
- package/dist/{chunk-BXV2QUIC.js → chunk-CSZRJ4RE.js} +6 -5
- package/dist/chunk-CSZRJ4RE.js.map +1 -0
- package/dist/{chunk-6M6A6WWW.cjs → chunk-D4ZUJTFB.cjs} +9 -10
- package/dist/chunk-D4ZUJTFB.cjs.map +1 -0
- package/dist/{chunk-XAUBQMQU.js → chunk-DCJ5MCJ3.js} +7 -7
- package/dist/{chunk-XAUBQMQU.js.map → chunk-DCJ5MCJ3.js.map} +1 -1
- package/dist/{chunk-6CLRANZA.js → chunk-EXQV452X.js} +3 -3
- package/dist/{chunk-6CLRANZA.js.map → chunk-EXQV452X.js.map} +1 -1
- package/dist/{chunk-XIG2IE3L.js → chunk-F6Y4IEQM.js} +5 -4
- package/dist/chunk-F6Y4IEQM.js.map +1 -0
- package/dist/{chunk-N24XBYNX.cjs → chunk-FAY3QDGC.cjs} +11 -10
- package/dist/chunk-FAY3QDGC.cjs.map +1 -0
- package/dist/{chunk-JD74LN7R.cjs → chunk-FK4EJD2I.cjs} +7 -6
- package/dist/chunk-FK4EJD2I.cjs.map +1 -0
- package/dist/{chunk-IX2LKBCD.js → chunk-GL7CFBVC.js} +176 -35
- package/dist/chunk-GL7CFBVC.js.map +1 -0
- package/dist/{chunk-77FOZCOT.js → chunk-GLUWH6JO.js} +6 -5
- package/dist/chunk-GLUWH6JO.js.map +1 -0
- package/dist/{chunk-RZQ6E5YZ.cjs → chunk-GM7QDQ24.cjs} +11 -11
- package/dist/{chunk-RZQ6E5YZ.cjs.map → chunk-GM7QDQ24.cjs.map} +1 -1
- package/dist/{chunk-G4WI3VW2.cjs → chunk-H5YVJB4K.cjs} +9 -10
- package/dist/chunk-H5YVJB4K.cjs.map +1 -0
- package/dist/{chunk-HRA3CPGG.js → chunk-HEN5WXXI.js} +9 -8
- package/dist/chunk-HEN5WXXI.js.map +1 -0
- package/dist/{chunk-LU7VALW5.js → chunk-I35DI7ES.js} +3 -3
- package/dist/{chunk-LU7VALW5.js.map → chunk-I35DI7ES.js.map} +1 -1
- package/dist/{chunk-TIZ4TS5V.cjs → chunk-ICYBIC6N.cjs} +8 -7
- package/dist/chunk-ICYBIC6N.cjs.map +1 -0
- package/dist/{chunk-2DYI7MIF.cjs → chunk-IEUDKUPM.cjs} +8 -8
- package/dist/{chunk-2DYI7MIF.cjs.map → chunk-IEUDKUPM.cjs.map} +1 -1
- package/dist/{chunk-AIDNODHJ.cjs → chunk-ITLS5LRF.cjs} +11 -11
- package/dist/{chunk-AIDNODHJ.cjs.map → chunk-ITLS5LRF.cjs.map} +1 -1
- package/dist/{chunk-M72RJVPC.js → chunk-JNIWFCKI.js} +3 -3
- package/dist/{chunk-M72RJVPC.js.map → chunk-JNIWFCKI.js.map} +1 -1
- package/dist/{chunk-Y66627E4.cjs → chunk-KDDL5HKQ.cjs} +24 -24
- package/dist/{chunk-Y66627E4.cjs.map → chunk-KDDL5HKQ.cjs.map} +1 -1
- package/dist/{chunk-BEURCLDV.cjs → chunk-LTCOPATU.cjs} +9 -3
- package/dist/chunk-LTCOPATU.cjs.map +1 -0
- package/dist/{chunk-TQKCU7CL.js → chunk-M5ZQBOIZ.js} +3 -3
- package/dist/{chunk-TQKCU7CL.js.map → chunk-M5ZQBOIZ.js.map} +1 -1
- package/dist/{chunk-A44COQJJ.cjs → chunk-MHCKWQR3.cjs} +8 -8
- package/dist/{chunk-A44COQJJ.cjs.map → chunk-MHCKWQR3.cjs.map} +1 -1
- package/dist/{chunk-7S7KKUO6.cjs → chunk-MRODLUGY.cjs} +4 -4
- package/dist/{chunk-7S7KKUO6.cjs.map → chunk-MRODLUGY.cjs.map} +1 -1
- package/dist/{chunk-BOTK6ZUP.js → chunk-MXSMAGDU.js} +3 -3
- package/dist/{chunk-BOTK6ZUP.js.map → chunk-MXSMAGDU.js.map} +1 -1
- package/dist/{chunk-5PZMMF4H.js → chunk-NFCKEBHI.js} +3 -3
- package/dist/{chunk-5PZMMF4H.js.map → chunk-NFCKEBHI.js.map} +1 -1
- package/dist/{chunk-6M4ODB2V.cjs → chunk-NNSKJCBM.cjs} +10 -10
- package/dist/{chunk-6M4ODB2V.cjs.map → chunk-NNSKJCBM.cjs.map} +1 -1
- package/dist/{chunk-4WL52CXU.cjs → chunk-NQ4AC2U4.cjs} +9 -9
- package/dist/{chunk-4WL52CXU.cjs.map → chunk-NQ4AC2U4.cjs.map} +1 -1
- package/dist/{chunk-YRXTIESB.cjs → chunk-P34DHHYQ.cjs} +4 -4
- package/dist/{chunk-YRXTIESB.cjs.map → chunk-P34DHHYQ.cjs.map} +1 -1
- package/dist/{chunk-HFPGOTVF.cjs → chunk-PAEJPLVN.cjs} +4 -4
- package/dist/{chunk-HFPGOTVF.cjs.map → chunk-PAEJPLVN.cjs.map} +1 -1
- package/dist/{chunk-S5RCBTSF.js → chunk-QFMXXUUT.js} +3 -3
- package/dist/{chunk-S5RCBTSF.js.map → chunk-QFMXXUUT.js.map} +1 -1
- package/dist/{chunk-V4XRLPEF.js → chunk-QGDKZDPN.js} +3 -3
- package/dist/{chunk-V4XRLPEF.js.map → chunk-QGDKZDPN.js.map} +1 -1
- package/dist/{chunk-DHLZIMP6.cjs → chunk-QUFSDDNU.cjs} +15 -15
- package/dist/{chunk-DHLZIMP6.cjs.map → chunk-QUFSDDNU.cjs.map} +1 -1
- package/dist/{chunk-3XJ7CS2C.cjs → chunk-S3WZ7NHF.cjs} +597 -671
- package/dist/chunk-S3WZ7NHF.cjs.map +1 -0
- package/dist/{chunk-BFWPZMG7.js → chunk-SDIBMLL5.js} +8 -8
- package/dist/{chunk-BFWPZMG7.js.map → chunk-SDIBMLL5.js.map} +1 -1
- package/dist/{chunk-LEJXBUBD.js → chunk-SSH2ZAZF.js} +5 -5
- package/dist/{chunk-LEJXBUBD.js.map → chunk-SSH2ZAZF.js.map} +1 -1
- package/dist/{chunk-GIW4L6HY.cjs → chunk-SWIBQFPH.cjs} +4 -4
- package/dist/{chunk-GIW4L6HY.cjs.map → chunk-SWIBQFPH.cjs.map} +1 -1
- package/dist/{chunk-JTFYYKDT.js → chunk-TAPQWDW2.js} +9 -4
- package/dist/chunk-TAPQWDW2.js.map +1 -0
- package/dist/{chunk-4GTXATWK.cjs → chunk-THEYGCYS.cjs} +4 -4
- package/dist/{chunk-4GTXATWK.cjs.map → chunk-THEYGCYS.cjs.map} +1 -1
- package/dist/{chunk-CJVMDRQB.cjs → chunk-TQI3KRXZ.cjs} +5 -4
- package/dist/chunk-TQI3KRXZ.cjs.map +1 -0
- package/dist/{chunk-LUSXDZPV.cjs → chunk-U2WLFOA3.cjs} +4 -4
- package/dist/{chunk-LUSXDZPV.cjs.map → chunk-U2WLFOA3.cjs.map} +1 -1
- package/dist/{chunk-FKCC2MED.js → chunk-UQPDFW4E.js} +3 -3
- package/dist/{chunk-FKCC2MED.js.map → chunk-UQPDFW4E.js.map} +1 -1
- package/dist/{chunk-CR3DGWUQ.js → chunk-VNNK6AKU.js} +3 -3
- package/dist/{chunk-CR3DGWUQ.js.map → chunk-VNNK6AKU.js.map} +1 -1
- package/dist/{chunk-ANIZEWTU.cjs → chunk-W4QN5CMG.cjs} +9 -8
- package/dist/chunk-W4QN5CMG.cjs.map +1 -0
- package/dist/{chunk-POQT2OIF.js → chunk-WDGCZDRG.js} +3 -3
- package/dist/{chunk-POQT2OIF.js.map → chunk-WDGCZDRG.js.map} +1 -1
- package/dist/{chunk-Q56IYTBZ.js → chunk-XAEAMI5H.js} +4 -4
- package/dist/{chunk-Q56IYTBZ.js.map → chunk-XAEAMI5H.js.map} +1 -1
- package/dist/{chunk-BWT67BI4.cjs → chunk-XAYVHS2B.cjs} +4 -4
- package/dist/{chunk-BWT67BI4.cjs.map → chunk-XAYVHS2B.cjs.map} +1 -1
- package/dist/{chunk-EKFA76N4.js → chunk-XJLGRJ7K.js} +387 -458
- package/dist/chunk-XJLGRJ7K.js.map +1 -0
- package/dist/{chunk-KIO7QFIV.cjs → chunk-YBFDBOUN.cjs} +8 -8
- package/dist/{chunk-KIO7QFIV.cjs.map → chunk-YBFDBOUN.cjs.map} +1 -1
- package/dist/{chunk-BNIFFFH3.js → chunk-YCXMSDSP.js} +4 -4
- package/dist/{chunk-BNIFFFH3.js.map → chunk-YCXMSDSP.js.map} +1 -1
- package/dist/{chunk-UVNG67DG.js → chunk-YDLNI7J6.js} +3 -3
- package/dist/{chunk-UVNG67DG.js.map → chunk-YDLNI7J6.js.map} +1 -1
- package/dist/{chunk-UAYYNWYJ.js → chunk-YHZXBDAW.js} +5 -4
- package/dist/chunk-YHZXBDAW.js.map +1 -0
- package/dist/{chunk-OKXUMCGM.js → chunk-YVTNFKZO.js} +5 -5
- package/dist/{chunk-OKXUMCGM.js.map → chunk-YVTNFKZO.js.map} +1 -1
- package/dist/{chunk-GJAGKFTR.js → chunk-ZJN6NTHE.js} +3 -3
- package/dist/{chunk-GJAGKFTR.js.map → chunk-ZJN6NTHE.js.map} +1 -1
- package/dist/{chunk-XV2RBL6D.js → chunk-ZW345YOI.js} +8 -9
- package/dist/chunk-ZW345YOI.js.map +1 -0
- package/dist/compact-session-H5TKLD55.cjs +54 -0
- package/dist/{compact-session-BEA3IOON.cjs.map → compact-session-H5TKLD55.cjs.map} +1 -1
- package/dist/compact-session-WNKKIIDW.js +17 -0
- package/dist/{compact-session-5BDD4HIB.js.map → compact-session-WNKKIIDW.js.map} +1 -1
- package/dist/compaction.cjs +16 -16
- package/dist/compaction.js +3 -3
- package/dist/concurrency.cjs +6 -6
- package/dist/concurrency.js +4 -4
- package/dist/context-VAYLPT4O.js +5 -0
- package/dist/{context-GWANQLX4.js.map → context-VAYLPT4O.js.map} +1 -1
- package/dist/context-ZV33V4DC.cjs +22 -0
- package/dist/{context-KNWVTZSY.cjs.map → context-ZV33V4DC.cjs.map} +1 -1
- package/dist/cron.cjs +28 -28
- package/dist/cron.js +27 -27
- package/dist/errors.cjs +21 -21
- package/dist/errors.js +2 -2
- package/dist/eval.cjs +31 -31
- package/dist/eval.js +27 -27
- package/dist/{executor-Y4MKPIUD.cjs → executor-OZSYXDKF.cjs} +23 -23
- package/dist/{executor-Y4MKPIUD.cjs.map → executor-OZSYXDKF.cjs.map} +1 -1
- package/dist/{executor-ORJS5GV2.js → executor-PAH72CB5.js} +7 -7
- package/dist/{executor-ORJS5GV2.js.map → executor-PAH72CB5.js.map} +1 -1
- package/dist/filesystem/index.cjs +7 -7
- package/dist/filesystem/index.js +3 -3
- package/dist/fs-session-store-6MY7PNI2.js +10 -0
- package/dist/{fs-session-store-4ALCDU3K.js.map → fs-session-store-6MY7PNI2.js.map} +1 -1
- package/dist/fs-session-store-7E7UPLF2.cjs +19 -0
- package/dist/{fs-session-store-IQYE35HX.cjs.map → fs-session-store-7E7UPLF2.cjs.map} +1 -1
- package/dist/generate-object-5SCEH2EE.cjs +20 -0
- package/dist/{generate-object-H3RNAM6S.cjs.map → generate-object-5SCEH2EE.cjs.map} +1 -1
- package/dist/generate-object-I7UD4NWN.js +7 -0
- package/dist/{generate-object-YJPDV5BS.js.map → generate-object-I7UD4NWN.js.map} +1 -1
- package/dist/index-manager-KKAK7NT3.js +10 -0
- package/dist/{index-manager-P7ZUX2RG.js.map → index-manager-KKAK7NT3.js.map} +1 -1
- package/dist/index-manager-R6ZJFEZF.cjs +19 -0
- package/dist/{index-manager-H7HUMW52.cjs.map → index-manager-R6ZJFEZF.cjs.map} +1 -1
- package/dist/index.cjs +124 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +45 -50
- package/dist/index.js.map +1 -1
- package/dist/{inject-session-SMH56NXP.cjs → inject-session-DM4SKTZO.cjs} +8 -8
- package/dist/{inject-session-SMH56NXP.cjs.map → inject-session-DM4SKTZO.cjs.map} +1 -1
- package/dist/{inject-session-V5FTK72N.js → inject-session-UXNJQTZ6.js} +6 -6
- package/dist/{inject-session-V5FTK72N.js.map → inject-session-UXNJQTZ6.js.map} +1 -1
- package/dist/internal/diagnostics.d.ts +54 -0
- package/dist/internal/local-agent/local-agent-invalidate.d.ts +0 -7
- package/dist/internal/local-agent/local-agent-lifecycle.d.ts +13 -0
- package/dist/internal/local-agent/local-agent.d.ts +1 -93
- package/dist/internal/persistence/index.cjs +25 -25
- package/dist/internal/persistence/index.js +6 -6
- package/dist/internal/persistence/sqlite-wal.d.cts +0 -9
- package/dist/internal/persistence/sqlite-wal.d.ts +0 -9
- package/dist/internal/persistence/transcript-ops.d.cts +14 -0
- package/dist/internal/persistence/transcript-ops.d.ts +14 -0
- package/dist/internal/plugins/lifecycle.d.cts +1 -0
- package/dist/internal/plugins/lifecycle.d.ts +1 -0
- package/dist/internal/runtime/fixtures/fixture-run-base.d.ts +19 -0
- package/dist/internal/runtime/registry/agent-registry.d.ts +0 -1
- package/dist/internal/security/index.cjs +13 -13
- package/dist/internal/security/index.js +3 -3
- package/dist/internal/security/redact.d.cts +0 -18
- package/dist/internal/security/redact.d.ts +0 -18
- package/dist/judge-call-SP3G3X2Y.cjs +22 -0
- package/dist/{judge-call-2FULQ6KL.cjs.map → judge-call-SP3G3X2Y.cjs.map} +1 -1
- package/dist/judge-call-TAEIXMYG.js +5 -0
- package/dist/{judge-call-D7R3ZTZS.js.map → judge-call-TAEIXMYG.js.map} +1 -1
- package/dist/models.cjs +22 -26
- package/dist/models.cjs.map +1 -1
- package/dist/models.js +13 -17
- package/dist/models.js.map +1 -1
- package/dist/path-safety.cjs +10 -10
- package/dist/path-safety.js +3 -3
- package/dist/persistence.cjs +27 -27
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.js +8 -8
- package/dist/persistence.js.map +1 -1
- package/dist/project.cjs +5 -5
- package/dist/project.js +3 -3
- package/dist/registry-N3GTKYCI.cjs +46 -0
- package/dist/{registry-APYDISL6.cjs.map → registry-N3GTKYCI.cjs.map} +1 -1
- package/dist/registry-SOXE4RY6.js +9 -0
- package/dist/{registry-34IWWDQQ.js.map → registry-SOXE4RY6.js.map} +1 -1
- package/dist/retry.cjs +4 -4
- package/dist/retry.js +3 -3
- package/dist/sandbox/index.cjs +6 -6
- package/dist/sandbox/index.js +2 -2
- package/dist/server/errors-envelope.cjs +14 -14
- package/dist/server/errors-envelope.js +3 -3
- package/dist/session-transcript-6WKLYIN4.js +5 -0
- package/dist/{session-transcript-F2ANTA2M.js.map → session-transcript-6WKLYIN4.js.map} +1 -1
- package/dist/session-transcript-EAKR4D2W.cjs +50 -0
- package/dist/{session-transcript-JXFMPLOT.cjs.map → session-transcript-EAKR4D2W.cjs.map} +1 -1
- package/dist/skills.cjs +7 -7
- package/dist/skills.js +5 -5
- package/dist/stream-object-OFM66VUT.js +7 -0
- package/dist/{stream-object-WUQSSRY2.js.map → stream-object-OFM66VUT.js.map} +1 -1
- package/dist/stream-object-Y7YCX3BI.cjs +20 -0
- package/dist/{stream-object-QEQJJDTI.cjs.map → stream-object-Y7YCX3BI.cjs.map} +1 -1
- package/dist/subagents-loader.cjs +6 -6
- package/dist/subagents-loader.js +4 -4
- package/dist/subscription/index.cjs +3 -3
- package/dist/subscription/index.js +2 -2
- package/dist/task-store.cjs +7 -7
- package/dist/task-store.js +4 -4
- package/dist/workflow.cjs +27 -27
- package/dist/workflow.js +6 -6
- package/package.json +13 -12
- package/dist/agent-H6HL5ITH.js +0 -42
- package/dist/agent-P77NPBF4.cjs +0 -51
- package/dist/chunk-3XJ7CS2C.cjs.map +0 -1
- package/dist/chunk-6M6A6WWW.cjs.map +0 -1
- package/dist/chunk-77FOZCOT.js.map +0 -1
- package/dist/chunk-7BTE3RXJ.js.map +0 -1
- package/dist/chunk-ANIZEWTU.cjs.map +0 -1
- package/dist/chunk-BEURCLDV.cjs.map +0 -1
- package/dist/chunk-BXV2QUIC.js.map +0 -1
- package/dist/chunk-CJVMDRQB.cjs.map +0 -1
- package/dist/chunk-D42XHI4O.cjs.map +0 -1
- package/dist/chunk-EKFA76N4.js.map +0 -1
- package/dist/chunk-G4WI3VW2.cjs.map +0 -1
- package/dist/chunk-HRA3CPGG.js.map +0 -1
- package/dist/chunk-IX2LKBCD.js.map +0 -1
- package/dist/chunk-JD74LN7R.cjs.map +0 -1
- package/dist/chunk-JTFYYKDT.js.map +0 -1
- package/dist/chunk-KAP4GJHO.js.map +0 -1
- package/dist/chunk-MZ5ZRORA.cjs.map +0 -1
- package/dist/chunk-N24XBYNX.cjs.map +0 -1
- package/dist/chunk-S2BBRVQX.js.map +0 -1
- package/dist/chunk-TIZ4TS5V.cjs.map +0 -1
- package/dist/chunk-UAYYNWYJ.js.map +0 -1
- package/dist/chunk-WEHUJ7ZS.cjs.map +0 -1
- package/dist/chunk-XIG2IE3L.js.map +0 -1
- package/dist/chunk-XV2RBL6D.js.map +0 -1
- package/dist/compact-session-5BDD4HIB.js +0 -17
- package/dist/compact-session-BEA3IOON.cjs +0 -54
- package/dist/context-GWANQLX4.js +0 -5
- package/dist/context-KNWVTZSY.cjs +0 -22
- package/dist/fs-session-store-4ALCDU3K.js +0 -10
- package/dist/fs-session-store-IQYE35HX.cjs +0 -19
- package/dist/generate-object-H3RNAM6S.cjs +0 -20
- package/dist/generate-object-YJPDV5BS.js +0 -7
- package/dist/index-manager-H7HUMW52.cjs +0 -19
- package/dist/index-manager-P7ZUX2RG.js +0 -10
- package/dist/judge-call-2FULQ6KL.cjs +0 -22
- package/dist/judge-call-D7R3ZTZS.js +0 -5
- package/dist/registry-34IWWDQQ.js +0 -9
- package/dist/registry-APYDISL6.cjs +0 -46
- package/dist/session-transcript-F2ANTA2M.js +0 -5
- package/dist/session-transcript-JXFMPLOT.cjs +0 -50
- package/dist/stream-object-QEQJJDTI.cjs +0 -20
- package/dist/stream-object-WUQSSRY2.js +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/runtime/skills/skill-frontmatter.ts","../src/internal/runtime/skills/discover-skills.ts","../src/internal/runtime/system-prompt/escape.ts","../src/internal/runtime/skills/skills-block.ts"],"names":[],"mappings":"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","file":"chunk-5IB2UKSN.js","sourcesContent":["import { ConfigurationError } from \"../../../errors.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\n\ntype StringFields = Record<string, string | undefined>;\n\n/** Narrow a FrontmatterValue to string; non-strings + undefined → undefined. */\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n return typeof v === \"string\" ? v : undefined;\n}\n\n/** Coerce parser output to legacy string-only shape (skill schema is all-string). */\nfunction toStringFields(raw: Record<string, FrontmatterValue | undefined>): StringFields {\n const out: StringFields = {};\n for (const [k, v] of Object.entries(raw)) out[k] = asString(v);\n return out;\n}\n\n/**\n * Strict skill frontmatter schema (ADR D10).\n *\n * Required: `name`, `description`.\n * Optional: `category`, `dependencies` (comma-separated string in the\n * simple-YAML dialect — parsed to `string[]`).\n *\n * Unknown fields are ignored (forward-compat). Malformed YAML or missing\n * required fields surface as `ConfigurationError` with one of the typed\n * codes below.\n *\n * @internal\n */\nexport interface SkillFrontmatter {\n name: string;\n description: string;\n category?: string;\n dependencies?: string[];\n}\n\n/**\n * Parse a SKILL.md file body into validated frontmatter.\n *\n * @throws ConfigurationError(code: \"missing_frontmatter\") — no `---` block at file head.\n * @throws ConfigurationError(code: \"schema_invalid\") — YAML malformed OR required field missing.\n *\n * @internal\n */\nexport function parseSkillFrontmatter(raw: string, fallbackName: string): SkillFrontmatter {\n const fields = extractAndParseFrontmatter(raw, fallbackName);\n const name = resolveName(fields, fallbackName);\n ensureRequiredFields(fields, name);\n return buildFrontmatter(fields, name);\n}\n\n/**\n * SE20 — return a SKILL.md's BODY (everything after the frontmatter block), trimmed.\n * When there is no frontmatter block, the whole file is the body. Reuses the same\n * frontmatter regex as {@link parseSkillFrontmatter} (DRY).\n */\nexport function stripSkillFrontmatter(raw: string): string {\n const match = /^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n/.exec(raw);\n return (match === null ? raw : raw.slice(match[0].length)).trim();\n}\n\nfunction extractAndParseFrontmatter(raw: string, fallbackName: string): StringFields {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Skill ${fallbackName} is missing frontmatter`, {\n code: \"missing_frontmatter\",\n });\n }\n const frontmatter = match[1] ?? \"\";\n // EC-5: guard against syntactically invalid frontmatter so the loader\n // surfaces schema_invalid rather than crashing.\n try {\n return toStringFields(parseSimpleYaml(frontmatter));\n } catch (cause) {\n const detail = cause instanceof Error ? cause.message : String(cause);\n throw new ConfigurationError(\n `Skill ${fallbackName} has malformed YAML frontmatter: ${detail}`,\n { code: \"schema_invalid\", cause },\n );\n }\n}\n\nfunction resolveName(fields: StringFields, fallbackName: string): string {\n if (hasContent(fields.name)) return fields.name;\n if (hasContent(fallbackName)) return fallbackName;\n throw new ConfigurationError(\"Skill at unknown path is missing required field: name\", {\n code: \"schema_invalid\",\n });\n}\n\nfunction ensureRequiredFields(fields: StringFields, name: string): void {\n if (!hasContent(fields.description)) {\n throw new ConfigurationError(`Skill ${name} is missing required field: description`, {\n code: \"schema_invalid\",\n });\n }\n}\n\nfunction buildFrontmatter(fields: StringFields, name: string): SkillFrontmatter {\n const description = fields.description;\n if (description === undefined) {\n // ensureRequiredFields already threw; this is unreachable but satisfies TS\n throw new ConfigurationError(`Skill ${name} missing description`, { code: \"schema_invalid\" });\n }\n const result: SkillFrontmatter = { name, description };\n if (hasContent(fields.category)) result.category = fields.category;\n const deps = parseDependencies(fields.dependencies);\n if (deps !== undefined) result.dependencies = deps;\n return result;\n}\n\nfunction parseDependencies(raw: string | undefined): string[] | undefined {\n if (!hasContent(raw)) return undefined;\n const deps = (raw as string)\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n return deps.length > 0 ? deps : undefined;\n}\n\nfunction hasContent(value: string | undefined): value is string {\n return value !== undefined && value.trim().length > 0;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport { assertNoSymlinkEscape, safePathJoin } from \"../../security/path-guard.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { parseSkillFrontmatter } from \"./skill-frontmatter.js\";\n\n/**\n * A discovered skill's metadata. The skill BODY is never included — only the\n * strict frontmatter fields plus the resolved `source` path.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport interface Skill {\n name: string;\n description: string;\n /** Absolute path to the discovered `SKILL.md`. */\n source: string;\n category?: string;\n dependencies?: string[];\n}\n\n/**\n * Information passed to `onInvalidSkill` when a `SKILL.md` is present but its\n * frontmatter is malformed (missing required field or invalid YAML).\n *\n * @public\n */\nexport interface InvalidSkillInfo {\n /** The skill directory name (used as the fallback skill name). */\n name: string;\n /** Absolute path to the offending `SKILL.md`. */\n source: string;\n /** Typed reason: `missing_frontmatter` or `schema_invalid`. */\n code: string;\n message: string;\n}\n\n/**\n * Options for {@link discoverSkills}.\n *\n * @public\n */\nexport interface DiscoverSkillsOptions {\n /**\n * Called once per directory that contains a `SKILL.md` with malformed\n * frontmatter. The skill is excluded from the result; discovery continues\n * (strict-frontmatter ADR / EC-5). A directory WITHOUT a `SKILL.md` is NOT a\n * malformed skill and does not trigger this callback.\n *\n * Default: no-op (a library primitive must not write to the consumer's\n * stderr by default).\n */\n onInvalidSkill?: (info: InvalidSkillInfo) => void;\n}\n\n/**\n * Discover `SKILL.md` skills under an arbitrary directory.\n *\n * For each immediate subdirectory `<dir>/<name>/` containing a `SKILL.md`, the\n * file's strict YAML frontmatter is parsed (`name`/`description` required;\n * `category`/`dependencies` optional). Malformed skills are skipped (optionally\n * reported via {@link DiscoverSkillsOptions.onInvalidSkill}); a subdirectory\n * whose realpath escapes `dir` (via symlink) is skipped (symlink-escape guard,\n * reusing `@theokit/sdk/path-safety`).\n *\n * NEVER throws: a missing, unreadable, or non-directory `dir` yields `[]`.\n *\n * Discovery order follows the filesystem `readdir` order (OS-dependent). Sort\n * the result before {@link buildSkillsBlock} if a stable block order matters.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport async function discoverSkills(\n dir: string,\n options?: DiscoverSkillsOptions,\n): Promise<Skill[]> {\n let entries: Awaited<ReturnType<typeof readWorkspaceDir>>;\n try {\n entries = await readWorkspaceDir(dir, \"skills_read_error\", \"skills directory\");\n } catch {\n // never-throw contract: unreadable / not-a-directory → no skills (EC-1)\n return [];\n }\n\n const skills: Skill[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n let skillDir: string;\n try {\n skillDir = safePathJoin(dir, entry.name);\n assertNoSymlinkEscape(skillDir, dir);\n } catch {\n continue;\n }\n const skillPath = join(skillDir, \"SKILL.md\");\n let raw: string;\n try {\n raw = await readFile(skillPath, \"utf8\");\n } catch {\n // no SKILL.md in this subdir → not a skill, not an error (EC-2)\n continue;\n }\n const skill = tryParseSkill(raw, entry.name, skillPath, options);\n if (skill !== undefined) skills.push(skill);\n }\n return skills;\n}\n\nfunction tryParseSkill(\n raw: string,\n fallbackName: string,\n source: string,\n options: DiscoverSkillsOptions | undefined,\n): Skill | undefined {\n try {\n const frontmatter = parseSkillFrontmatter(raw, fallbackName);\n const skill: Skill = {\n name: frontmatter.name,\n description: frontmatter.description,\n source,\n };\n if (frontmatter.category !== undefined) skill.category = frontmatter.category;\n if (frontmatter.dependencies !== undefined) skill.dependencies = frontmatter.dependencies;\n return skill;\n } catch (cause) {\n if (cause instanceof ConfigurationError) {\n options?.onInvalidSkill?.({\n name: fallbackName,\n source,\n code: cause.code ?? \"unknown\",\n message: cause.message,\n });\n return undefined;\n }\n throw cause;\n }\n}\n","/**\n * Block-body XML escape (ADR D9 — prompt-injection defence).\n *\n * Order matters: `&` MUST be escaped first so subsequent `<`/`>` replacements\n * do not double-encode the `&` characters they introduce.\n *\n * @internal\n */\nexport const escapeBlockBody = (s: string): string =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n","import { escapeBlockBody } from \"../system-prompt/escape.js\";\n\n/**\n * Render the `<skills>` system-prompt block from a skill list.\n *\n * Input is the structural subset `{ name, description }` — the skill BODY is\n * NOT in the type, so it cannot leak into the prompt. Both fields are passed\n * through `escapeBlockBody` to neutralise prompt-injection vectors hidden in\n * user-controlled SKILL.md frontmatter (injection-escape ADR).\n *\n * Returns `undefined` for an empty list so the caller can omit the block.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport function buildSkillsBlock(\n skills: ReadonlyArray<{ name: string; description: string }>,\n): string | undefined {\n if (skills.length === 0) return undefined;\n const lines = skills.map(\n (skill) => ` - ${escapeBlockBody(skill.name)}: ${escapeBlockBody(skill.description)}`,\n );\n return `<skills>\\n${lines.join(\"\\n\")}\\n</skills>`;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/runtime/skills/skill-frontmatter.ts","../src/internal/runtime/skills/discover-skills.ts","../src/internal/runtime/system-prompt/escape.ts","../src/internal/runtime/skills/skills-block.ts"],"names":[],"mappings":";;;;;;;AAMA,SAAS,SAAS,CAAA,EAAqD;AACrE,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,GAAI,MAAA;AACrC;AAGA,SAAS,eAAe,GAAA,EAAiE;AACvF,EAAA,MAAM,MAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG,GAAA,CAAI,CAAC,CAAA,GAAI,QAAA,CAAS,CAAC,CAAA;AAC7D,EAAA,OAAO,GAAA;AACT;AA8BO,SAAS,qBAAA,CAAsB,KAAa,YAAA,EAAwC;AACzF,EAAA,MAAM,MAAA,GAAS,0BAAA,CAA2B,GAAA,EAAK,YAAY,CAAA;AAC3D,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,MAAA,EAAQ,YAAY,CAAA;AAC7C,EAAA,oBAAA,CAAqB,QAAQ,IAAI,CAAA;AACjC,EAAA,OAAO,gBAAA,CAAiB,QAAQ,IAAI,CAAA;AACtC;AAOO,SAAS,sBAAsB,GAAA,EAAqB;AACzD,EAAA,MAAM,KAAA,GAAQ,6BAAA,CAA8B,IAAA,CAAK,GAAG,CAAA;AACpD,EAAA,OAAA,CAAQ,KAAA,KAAU,IAAA,GAAO,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,MAAM,CAAC,CAAA,CAAE,MAAM,CAAA,EAAG,IAAA,EAAK;AAClE;AAEA,SAAS,0BAAA,CAA2B,KAAa,YAAA,EAAoC;AACnF,EAAA,MAAM,KAAA,GAAQ,+BAAA,CAAgC,IAAA,CAAK,GAAG,CAAA;AACtD,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,MAAA,EAAS,YAAY,CAAA,uBAAA,CAAA,EAA2B;AAAA,MAC3E,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACA,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,CAAC,CAAA,IAAK,EAAA;AAGhC,EAAA,IAAI;AACF,IAAA,OAAO,cAAA,CAAe,eAAA,CAAgB,WAAW,CAAC,CAAA;AAAA,EACpD,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,SAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACpE,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,CAAA,MAAA,EAAS,YAAY,CAAA,iCAAA,EAAoC,MAAM,CAAA,CAAA;AAAA,MAC/D,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA;AAAM,KAClC;AAAA,EACF;AACF;AAEA,SAAS,WAAA,CAAY,QAAsB,YAAA,EAA8B;AACvE,EAAA,IAAI,UAAA,CAAW,MAAA,CAAO,IAAI,CAAA,SAAU,MAAA,CAAO,IAAA;AAC3C,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG,OAAO,YAAA;AACrC,EAAA,MAAM,IAAI,mBAAmB,uDAAA,EAAyD;AAAA,IACpF,IAAA,EAAM;AAAA,GACP,CAAA;AACH;AAEA,SAAS,oBAAA,CAAqB,QAAsB,IAAA,EAAoB;AACtE,EAAA,IAAI,CAAC,UAAA,CAAW,MAAA,CAAO,WAAW,CAAA,EAAG;AACnC,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,MAAA,EAAS,IAAI,CAAA,uCAAA,CAAA,EAA2C;AAAA,MACnF,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF;AAEA,SAAS,gBAAA,CAAiB,QAAsB,IAAA,EAAgC;AAC9E,EAAA,MAAM,cAAc,MAAA,CAAO,WAAA;AAC3B,EAAA,IAAI,gBAAgB,MAAA,EAAW;AAE7B,IAAA,MAAM,IAAI,mBAAmB,CAAA,MAAA,EAAS,IAAI,wBAAwB,EAAE,IAAA,EAAM,kBAAkB,CAAA;AAAA,EAC9F;AACA,EAAA,MAAM,MAAA,GAA2B,EAAE,IAAA,EAAM,WAAA,EAAY;AACrD,EAAA,IAAI,WAAW,MAAA,CAAO,QAAQ,CAAA,EAAG,MAAA,CAAO,WAAW,MAAA,CAAO,QAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,iBAAA,CAAkB,MAAA,CAAO,YAAY,CAAA;AAClD,EAAA,IAAI,IAAA,KAAS,MAAA,EAAW,MAAA,CAAO,YAAA,GAAe,IAAA;AAC9C,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,kBAAkB,GAAA,EAA+C;AACxE,EAAA,IAAI,CAAC,UAAA,CAAW,GAAG,CAAA,EAAG,OAAO,MAAA;AAC7B,EAAA,MAAM,OAAQ,GAAA,CACX,KAAA,CAAM,GAAG,CAAA,CACT,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CACnB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA;AAC7B,EAAA,OAAO,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,IAAA,GAAO,MAAA;AAClC;AAEA,SAAS,WAAW,KAAA,EAA4C;AAC9D,EAAA,OAAO,KAAA,KAAU,MAAA,IAAa,KAAA,CAAM,IAAA,GAAO,MAAA,GAAS,CAAA;AACtD;;;AC7CA,eAAsB,cAAA,CACpB,KACA,OAAA,EACkB;AAClB,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,MAAM,gBAAA,CAAiB,GAAA,EAAK,mBAAA,EAAqB,kBAAkB,CAAA;AAAA,EAC/E,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,SAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,IAAI,CAAC,KAAA,CAAM,WAAA,EAAY,EAAG;AAC1B,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,YAAA,CAAa,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA;AACvC,MAAA,qBAAA,CAAsB,UAAU,GAAG,CAAA;AAAA,IACrC,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,EAAU,UAAU,CAAA;AAC3C,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,MAAM,QAAA,CAAS,SAAA,EAAW,MAAM,CAAA;AAAA,IACxC,CAAA,CAAA,MAAQ;AAEN,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAQ,aAAA,CAAc,GAAA,EAAK,KAAA,CAAM,IAAA,EAAM,WAAW,OAAO,CAAA;AAC/D,IAAA,IAAI,KAAA,KAAU,MAAA,EAAW,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA;AAAA,EAC5C;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,aAAA,CACP,GAAA,EACA,YAAA,EACA,MAAA,EACA,OAAA,EACmB;AACnB,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,qBAAA,CAAsB,GAAA,EAAK,YAAY,CAAA;AAC3D,IAAA,MAAM,KAAA,GAAe;AAAA,MACnB,MAAM,WAAA,CAAY,IAAA;AAAA,MAClB,aAAa,WAAA,CAAY,WAAA;AAAA,MACzB;AAAA,KACF;AACA,IAAA,IAAI,WAAA,CAAY,QAAA,KAAa,KAAA,CAAA,EAAW,KAAA,CAAM,WAAW,WAAA,CAAY,QAAA;AACrE,IAAA,IAAI,WAAA,CAAY,YAAA,KAAiB,KAAA,CAAA,EAAW,KAAA,CAAM,eAAe,WAAA,CAAY,YAAA;AAC7E,IAAA,OAAO,KAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,IAAI,iBAAiB,kBAAA,EAAoB;AACvC,MAAA,OAAA,EAAS,cAAA,GAAiB;AAAA,QACxB,IAAA,EAAM,YAAA;AAAA,QACN,MAAA;AAAA,QACA,IAAA,EAAM,MAAM,IAAA,IAAQ,SAAA;AAAA,QACpB,SAAS,KAAA,CAAM;AAAA,OAChB,CAAA;AACD,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAM,KAAA;AAAA,EACR;AACF;;;ACtIO,IAAM,eAAA,GAAkB,CAAC,CAAA,KAC9B,CAAA,CAAE,QAAQ,IAAA,EAAM,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,MAAM;;;ACO9D,SAAS,iBACd,MAAA,EACoB;AACpB,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAChC,EAAA,MAAM,QAAQ,MAAA,CAAO,GAAA;AAAA,IACnB,CAAC,KAAA,KAAU,CAAA,IAAA,EAAO,eAAA,CAAgB,KAAA,CAAM,IAAI,CAAC,CAAA,EAAA,EAAK,eAAA,CAAgB,KAAA,CAAM,WAAW,CAAC,CAAA;AAAA,GACtF;AACA,EAAA,OAAO,CAAA;AAAA,EAAa,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC;AAAA,SAAA,CAAA;AACtC","file":"chunk-2WFB5ZOX.js","sourcesContent":["import { ConfigurationError } from \"../../../errors.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\n\ntype StringFields = Record<string, string | undefined>;\n\n/** Narrow a FrontmatterValue to string; non-strings + undefined → undefined. */\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n return typeof v === \"string\" ? v : undefined;\n}\n\n/** Coerce parser output to legacy string-only shape (skill schema is all-string). */\nfunction toStringFields(raw: Record<string, FrontmatterValue | undefined>): StringFields {\n const out: StringFields = {};\n for (const [k, v] of Object.entries(raw)) out[k] = asString(v);\n return out;\n}\n\n/**\n * Strict skill frontmatter schema (ADR D10).\n *\n * Required: `name`, `description`.\n * Optional: `category`, `dependencies` (comma-separated string in the\n * simple-YAML dialect — parsed to `string[]`).\n *\n * Unknown fields are ignored (forward-compat). Malformed YAML or missing\n * required fields surface as `ConfigurationError` with one of the typed\n * codes below.\n *\n * @internal\n */\nexport interface SkillFrontmatter {\n name: string;\n description: string;\n category?: string;\n dependencies?: string[];\n}\n\n/**\n * Parse a SKILL.md file body into validated frontmatter.\n *\n * @throws ConfigurationError(code: \"missing_frontmatter\") — no `---` block at file head.\n * @throws ConfigurationError(code: \"schema_invalid\") — YAML malformed OR required field missing.\n *\n * @internal\n */\nexport function parseSkillFrontmatter(raw: string, fallbackName: string): SkillFrontmatter {\n const fields = extractAndParseFrontmatter(raw, fallbackName);\n const name = resolveName(fields, fallbackName);\n ensureRequiredFields(fields, name);\n return buildFrontmatter(fields, name);\n}\n\n/**\n * SE20 — return a SKILL.md's BODY (everything after the frontmatter block), trimmed.\n * When there is no frontmatter block, the whole file is the body. Reuses the same\n * frontmatter regex as {@link parseSkillFrontmatter} (DRY).\n */\nexport function stripSkillFrontmatter(raw: string): string {\n const match = /^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n/.exec(raw);\n return (match === null ? raw : raw.slice(match[0].length)).trim();\n}\n\nfunction extractAndParseFrontmatter(raw: string, fallbackName: string): StringFields {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Skill ${fallbackName} is missing frontmatter`, {\n code: \"missing_frontmatter\",\n });\n }\n const frontmatter = match[1] ?? \"\";\n // EC-5: guard against syntactically invalid frontmatter so the loader\n // surfaces schema_invalid rather than crashing.\n try {\n return toStringFields(parseSimpleYaml(frontmatter));\n } catch (cause) {\n const detail = cause instanceof Error ? cause.message : String(cause);\n throw new ConfigurationError(\n `Skill ${fallbackName} has malformed YAML frontmatter: ${detail}`,\n { code: \"schema_invalid\", cause },\n );\n }\n}\n\nfunction resolveName(fields: StringFields, fallbackName: string): string {\n if (hasContent(fields.name)) return fields.name;\n if (hasContent(fallbackName)) return fallbackName;\n throw new ConfigurationError(\"Skill at unknown path is missing required field: name\", {\n code: \"schema_invalid\",\n });\n}\n\nfunction ensureRequiredFields(fields: StringFields, name: string): void {\n if (!hasContent(fields.description)) {\n throw new ConfigurationError(`Skill ${name} is missing required field: description`, {\n code: \"schema_invalid\",\n });\n }\n}\n\nfunction buildFrontmatter(fields: StringFields, name: string): SkillFrontmatter {\n const description = fields.description;\n if (description === undefined) {\n // ensureRequiredFields already threw; this is unreachable but satisfies TS\n throw new ConfigurationError(`Skill ${name} missing description`, { code: \"schema_invalid\" });\n }\n const result: SkillFrontmatter = { name, description };\n if (hasContent(fields.category)) result.category = fields.category;\n const deps = parseDependencies(fields.dependencies);\n if (deps !== undefined) result.dependencies = deps;\n return result;\n}\n\nfunction parseDependencies(raw: string | undefined): string[] | undefined {\n if (!hasContent(raw)) return undefined;\n const deps = (raw as string)\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n return deps.length > 0 ? deps : undefined;\n}\n\nfunction hasContent(value: string | undefined): value is string {\n return value !== undefined && value.trim().length > 0;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport { assertNoSymlinkEscape, safePathJoin } from \"../../security/path-guard.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { parseSkillFrontmatter } from \"./skill-frontmatter.js\";\n\n/**\n * A discovered skill's metadata. The skill BODY is never included — only the\n * strict frontmatter fields plus the resolved `source` path.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport interface Skill {\n name: string;\n description: string;\n /** Absolute path to the discovered `SKILL.md`. */\n source: string;\n category?: string;\n dependencies?: string[];\n}\n\n/**\n * Information passed to `onInvalidSkill` when a `SKILL.md` is present but its\n * frontmatter is malformed (missing required field or invalid YAML).\n *\n * @public\n */\nexport interface InvalidSkillInfo {\n /** The skill directory name (used as the fallback skill name). */\n name: string;\n /** Absolute path to the offending `SKILL.md`. */\n source: string;\n /** Typed reason: `missing_frontmatter` or `schema_invalid`. */\n code: string;\n message: string;\n}\n\n/**\n * Options for {@link discoverSkills}.\n *\n * @public\n */\nexport interface DiscoverSkillsOptions {\n /**\n * Called once per directory that contains a `SKILL.md` with malformed\n * frontmatter. The skill is excluded from the result; discovery continues\n * (strict-frontmatter ADR / EC-5). A directory WITHOUT a `SKILL.md` is NOT a\n * malformed skill and does not trigger this callback.\n *\n * Default: no-op (a library primitive must not write to the consumer's\n * stderr by default).\n */\n onInvalidSkill?: (info: InvalidSkillInfo) => void;\n}\n\n/**\n * Discover `SKILL.md` skills under an arbitrary directory.\n *\n * For each immediate subdirectory `<dir>/<name>/` containing a `SKILL.md`, the\n * file's strict YAML frontmatter is parsed (`name`/`description` required;\n * `category`/`dependencies` optional). Malformed skills are skipped (optionally\n * reported via {@link DiscoverSkillsOptions.onInvalidSkill}); a subdirectory\n * whose realpath escapes `dir` (via symlink) is skipped (symlink-escape guard,\n * reusing `@theokit/sdk/path-safety`).\n *\n * NEVER throws: a missing, unreadable, or non-directory `dir` yields `[]`.\n *\n * Discovery order follows the filesystem `readdir` order (OS-dependent). Sort\n * the result before {@link buildSkillsBlock} if a stable block order matters.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport async function discoverSkills(\n dir: string,\n options?: DiscoverSkillsOptions,\n): Promise<Skill[]> {\n let entries: Awaited<ReturnType<typeof readWorkspaceDir>>;\n try {\n entries = await readWorkspaceDir(dir, \"skills_read_error\", \"skills directory\");\n } catch {\n // never-throw contract: unreadable / not-a-directory → no skills (EC-1)\n return [];\n }\n\n const skills: Skill[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n let skillDir: string;\n try {\n skillDir = safePathJoin(dir, entry.name);\n assertNoSymlinkEscape(skillDir, dir);\n } catch {\n continue;\n }\n const skillPath = join(skillDir, \"SKILL.md\");\n let raw: string;\n try {\n raw = await readFile(skillPath, \"utf8\");\n } catch {\n // no SKILL.md in this subdir → not a skill, not an error (EC-2)\n continue;\n }\n const skill = tryParseSkill(raw, entry.name, skillPath, options);\n if (skill !== undefined) skills.push(skill);\n }\n return skills;\n}\n\nfunction tryParseSkill(\n raw: string,\n fallbackName: string,\n source: string,\n options: DiscoverSkillsOptions | undefined,\n): Skill | undefined {\n try {\n const frontmatter = parseSkillFrontmatter(raw, fallbackName);\n const skill: Skill = {\n name: frontmatter.name,\n description: frontmatter.description,\n source,\n };\n if (frontmatter.category !== undefined) skill.category = frontmatter.category;\n if (frontmatter.dependencies !== undefined) skill.dependencies = frontmatter.dependencies;\n return skill;\n } catch (cause) {\n if (cause instanceof ConfigurationError) {\n options?.onInvalidSkill?.({\n name: fallbackName,\n source,\n code: cause.code ?? \"unknown\",\n message: cause.message,\n });\n return undefined;\n }\n throw cause;\n }\n}\n","/**\n * Block-body XML escape (ADR D9 — prompt-injection defence).\n *\n * Order matters: `&` MUST be escaped first so subsequent `<`/`>` replacements\n * do not double-encode the `&` characters they introduce.\n *\n * @internal\n */\nexport const escapeBlockBody = (s: string): string =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n","import { escapeBlockBody } from \"../system-prompt/escape.js\";\n\n/**\n * Render the `<skills>` system-prompt block from a skill list.\n *\n * Input is the structural subset `{ name, description }` — the skill BODY is\n * NOT in the type, so it cannot leak into the prompt. Both fields are passed\n * through `escapeBlockBody` to neutralise prompt-injection vectors hidden in\n * user-controlled SKILL.md frontmatter (injection-escape ADR).\n *\n * Returns `undefined` for an empty list so the caller can omit the block.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport function buildSkillsBlock(\n skills: ReadonlyArray<{ name: string; description: string }>,\n): string | undefined {\n if (skills.length === 0) return undefined;\n const lines = skills.map(\n (skill) => ` - ${escapeBlockBody(skill.name)}: ${escapeBlockBody(skill.description)}`,\n );\n return `<skills>\\n${lines.join(\"\\n\")}\\n</skills>`;\n}\n"]}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkWJVHMTKB_cjs = require('./chunk-WJVHMTKB.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkMHCKWQR3_cjs = require('./chunk-MHCKWQR3.cjs');
|
|
5
5
|
var module$1 = require('module');
|
|
6
6
|
|
|
7
7
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
8
8
|
var cachedZ;
|
|
9
9
|
function requireZod() {
|
|
10
10
|
if (cachedZ !== void 0) return cachedZ;
|
|
11
|
-
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
11
|
+
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-3ILFUXNE.cjs', document.baseURI).href)));
|
|
12
12
|
let mod;
|
|
13
13
|
try {
|
|
14
14
|
mod = r("zod");
|
|
15
15
|
} catch (cause) {
|
|
16
|
-
throw new
|
|
16
|
+
throw new chunkMHCKWQR3_cjs.ConfigurationError(
|
|
17
17
|
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
18
18
|
{ code: "zod_not_installed", cause }
|
|
19
19
|
);
|
|
@@ -78,5 +78,5 @@ exports.disposeAndDeleteTransient = disposeAndDeleteTransient;
|
|
|
78
78
|
exports.extractUsage = extractUsage;
|
|
79
79
|
exports.makeOutputTool = makeOutputTool;
|
|
80
80
|
exports.setupStructuredOutput = setupStructuredOutput;
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
82
|
-
//# sourceMappingURL=chunk-
|
|
81
|
+
//# sourceMappingURL=chunk-3ILFUXNE.cjs.map
|
|
82
|
+
//# sourceMappingURL=chunk-3ILFUXNE.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/structured-output-helpers.ts"],"names":["createRequire","ConfigurationError","toJsonSchema"],"mappings":";;;;;;;AAoBA,IAAI,OAAA;AAMG,SAAS,UAAA,GAAkC;AAChD,EAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAClC,EAAA,MAAM,CAAA,GAAIA,sBAAA,CAAc,oQAAe,CAAA;AACvC,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,EAAE,KAAK,CAAA;AAAA,EACf,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAIC,oCAAA;AAAA,MACR,qIAAA;AAAA,MAEA,EAAE,IAAA,EAAM,mBAAA,EAAqB,KAAA;AAAM,KACrC;AAAA,EACF;AACA,EAAA,OAAA,GAAW,IAAI,CAAA,IAAK,GAAA;AACpB,EAAA,OAAO,OAAA;AACT;AAQO,SAAS,cAAA,CACd,YACA,SAAA,EACY;AACZ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,kFAAA;AAAA,IACb,WAAA,EAAa,UAAA;AAAA,IACb,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,MAAA,MAAM,GAAA,GAAM,UAAU,KAAK,CAAA;AAG3B,MAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,GAAA;AACpC,MAAA,IAAI,GAAA,YAAe,SAAS,OAAO,GAAA;AACnC,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,GACF;AACF;AAMO,SAAS,2BAA2B,MAAA,EAS1B;AACf,EAAA,OAAO;AAAA,IACL,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,KAAA,EAAO,CAAC,MAAA,CAAO,UAAU,CAAA;AAAA,IACzB,YAAA,EACE,OAAO,YAAA,IACP,iGAAA;AAAA,IACF,GAAI,OAAO,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAO,GAAI,EAAC;AAAA,IAC/D,GAAI,OAAO,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,MAAA,CAAO,SAAA,EAAU,GAAI;AAAC,GAC1E;AACF;AAMO,SAAS,aAAa,MAAA,EAAgE;AAC3F,EAAA,MAAM,IAAK,MAAA,CAAuE,KAAA;AAClF,EAAA,IAAI,MAAM,MAAA,EAAW,OAAO,EAAE,WAAA,EAAa,CAAA,EAAG,cAAc,CAAA,EAAE;AAC9D,EAAA,OAAO,EAAE,aAAa,CAAA,CAAE,WAAA,IAAe,GAAG,YAAA,EAAc,CAAA,CAAE,gBAAgB,CAAA,EAAE;AAC9E;AAMO,SAAS,gBAAgB,MAAA,EAAwB;AACtD,EAAA,OAAO,GAAG,MAAM;;AAAA,0FAAA,CAAA;AAClB;AAOO,SAAS,qBAAA,CACd,QACA,UAAA,EACA;AACA,EAAA,MAAM,IAAI,UAAA,EAAW;AAErB,EAAA,MAAM,aAAaC,8BAAA,CAAa,MAAA,EAAQ,EAAE,eAAA,EAAiB,OAAO,CAAA;AAClE,EAAA,OAAO;AAAA,IACL,CAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAY,UAAA,IAAc,CAAA;AAAA,IAC1B,YAAA,EAAc,EAAE,WAAA,EAAa,CAAA,EAAG,cAAc,CAAA;AAAE,GAClD;AACF;AAQA,eAAsB,yBAAA,CACpB,OACA,OAAA,EACe;AACf,EAAA,MAAM,MAAM,OAAA,EAAQ;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,CAAQ,MAAM,OAAO,CAAA;AAAA,EAC7B,CAAA,CAAA,MAAQ;AAAA,EAER;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/internal/structured-output-helpers.ts"],"names":["createRequire","ConfigurationError","toJsonSchema"],"mappings":";;;;;;;AAoBA,IAAI,OAAA;AAMG,SAAS,UAAA,GAAkC;AAChD,EAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAClC,EAAA,MAAM,CAAA,GAAIA,sBAAA,CAAc,oQAAe,CAAA;AACvC,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,EAAE,KAAK,CAAA;AAAA,EACf,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAIC,oCAAA;AAAA,MACR,qIAAA;AAAA,MAEA,EAAE,IAAA,EAAM,mBAAA,EAAqB,KAAA;AAAM,KACrC;AAAA,EACF;AACA,EAAA,OAAA,GAAW,IAAI,CAAA,IAAK,GAAA;AACpB,EAAA,OAAO,OAAA;AACT;AAQO,SAAS,cAAA,CACd,YACA,SAAA,EACY;AACZ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,kFAAA;AAAA,IACb,WAAA,EAAa,UAAA;AAAA,IACb,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,MAAA,MAAM,GAAA,GAAM,UAAU,KAAK,CAAA;AAG3B,MAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,GAAA;AACpC,MAAA,IAAI,GAAA,YAAe,SAAS,OAAO,GAAA;AACnC,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,GACF;AACF;AAMO,SAAS,2BAA2B,MAAA,EAS1B;AACf,EAAA,OAAO;AAAA,IACL,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,KAAA,EAAO,CAAC,MAAA,CAAO,UAAU,CAAA;AAAA,IACzB,YAAA,EACE,OAAO,YAAA,IACP,iGAAA;AAAA,IACF,GAAI,OAAO,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAO,GAAI,EAAC;AAAA,IAC/D,GAAI,OAAO,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,MAAA,CAAO,SAAA,EAAU,GAAI;AAAC,GAC1E;AACF;AAMO,SAAS,aAAa,MAAA,EAAgE;AAC3F,EAAA,MAAM,IAAK,MAAA,CAAuE,KAAA;AAClF,EAAA,IAAI,MAAM,MAAA,EAAW,OAAO,EAAE,WAAA,EAAa,CAAA,EAAG,cAAc,CAAA,EAAE;AAC9D,EAAA,OAAO,EAAE,aAAa,CAAA,CAAE,WAAA,IAAe,GAAG,YAAA,EAAc,CAAA,CAAE,gBAAgB,CAAA,EAAE;AAC9E;AAMO,SAAS,gBAAgB,MAAA,EAAwB;AACtD,EAAA,OAAO,GAAG,MAAM;;AAAA,0FAAA,CAAA;AAClB;AAOO,SAAS,qBAAA,CACd,QACA,UAAA,EACA;AACA,EAAA,MAAM,IAAI,UAAA,EAAW;AAErB,EAAA,MAAM,aAAaC,8BAAA,CAAa,MAAA,EAAQ,EAAE,eAAA,EAAiB,OAAO,CAAA;AAClE,EAAA,OAAO;AAAA,IACL,CAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAY,UAAA,IAAc,CAAA;AAAA,IAC1B,YAAA,EAAc,EAAE,WAAA,EAAa,CAAA,EAAG,cAAc,CAAA;AAAE,GAClD;AACF;AAQA,eAAsB,yBAAA,CACpB,OACA,OAAA,EACe;AACf,EAAA,MAAM,MAAM,OAAA,EAAQ;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,CAAQ,MAAM,OAAO,CAAA;AAAA,EAC7B,CAAA,CAAA,MAAQ;AAAA,EAER;AACF","file":"chunk-3ILFUXNE.cjs","sourcesContent":["import { createRequire } from \"node:module\";\nimport type { z as ZodNamespace, ZodType } from \"zod\";\nimport { ConfigurationError } from \"../errors.js\";\n\nimport type { AgentOptions, CustomTool, LocalOptions, ModelSelection } from \"../types/agent.js\";\nimport type { ProviderRoutingSettings } from \"../types/providers.js\";\nimport { toJsonSchema } from \"./zod/to-json-schema.js\";\n\n/**\n * Shared helpers for `Agent.generateObject` (ADR D33) and\n * `Agent.streamObject` (ADR D39). Both build a transient agent with a\n * single synthetic `output` tool whose handler captures the model's\n * structured response.\n *\n * Extracted from inline duplicates to keep jscpd quiet AND to keep the\n * two public APIs in lockstep.\n *\n * @internal\n */\n\nlet cachedZ: typeof ZodNamespace | undefined;\n\n/**\n * Load Zod via createRequire (it's an optional peer dep). Throws a typed\n * ConfigurationError if Zod isn't installed.\n */\nexport function requireZod(): typeof ZodNamespace {\n if (cachedZ !== undefined) return cachedZ;\n const r = createRequire(import.meta.url);\n let mod: { z?: typeof ZodNamespace } & typeof ZodNamespace;\n try {\n mod = r(\"zod\") as typeof mod;\n } catch (cause) {\n throw new ConfigurationError(\n \"Structured output requires the optional peer dependency `zod`. \" +\n 'Add `\"zod\": \"^3.25.0 || ^4.0.0\"` to your package.json and reinstall.',\n { code: \"zod_not_installed\", cause },\n );\n }\n cachedZ = (mod.z ?? mod) as typeof ZodNamespace;\n return cachedZ;\n}\n\n/**\n * Build the synthetic `output` tool used by both `generateObject` and\n * `streamObject`. The handler captures the raw input on first call only\n * (EC-D10 / EC-6: parallel tool use in Claude 3.5+ may invoke `output`\n * twice; later calls are ignored).\n */\nexport function makeOutputTool(\n jsonSchema: Record<string, unknown>,\n onCapture: (input: unknown) => string | Promise<string> | undefined,\n): CustomTool {\n return {\n name: \"output\",\n description: \"Call this tool with your final structured answer. Match the JSON schema exactly.\",\n inputSchema: jsonSchema,\n handler: (input) => {\n const out = onCapture(input);\n // Some callers throw a sentinel (generate-object) and never return.\n // Others return a string (stream-object). Anything else → empty string.\n if (typeof out === \"string\") return out;\n if (out instanceof Promise) return out;\n return \"\";\n },\n };\n}\n\n/**\n * Assemble the AgentOptions for the transient agent. Shared shape:\n * model + local + tools[output] + systemPrompt + apiKey.\n */\nexport function buildTransientAgentOptions(params: {\n // SE8 — accepts the bare-string shorthand; forwarded to AgentOptions.model\n // (normalized at Agent.create).\n model: string | ModelSelection;\n local: LocalOptions;\n outputTool: CustomTool;\n systemPrompt?: string;\n apiKey?: string;\n providers?: ProviderRoutingSettings;\n}): AgentOptions {\n return {\n model: params.model,\n local: params.local,\n tools: [params.outputTool],\n systemPrompt:\n params.systemPrompt ??\n \"You produce structured output by calling the `output` tool exactly once. Match the JSON schema.\",\n ...(params.apiKey !== undefined ? { apiKey: params.apiKey } : {}),\n ...(params.providers !== undefined ? { providers: params.providers } : {}),\n };\n}\n\n/**\n * Best-effort extraction of token usage from a run result. Local runtimes\n * may not expose it; default to zeros.\n */\nexport function extractUsage(result: unknown): { inputTokens: number; outputTokens: number } {\n const u = (result as { usage?: { inputTokens?: number; outputTokens?: number } }).usage;\n if (u === undefined) return { inputTokens: 0, outputTokens: 0 };\n return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };\n}\n\n/**\n * Build the user-message prompt that instructs the model to call the\n * `output` tool with a schema-matched structured answer.\n */\nexport function buildToolPrompt(prompt: string): string {\n return `${prompt}\\n\\nRespond by calling the \\`output\\` tool with the structured answer that matches the schema.`;\n}\n\n/**\n * One-shot setup shared by both `generateObject` and `streamObject`. Loads\n * Zod, computes the JSON schema, primes the captured-raw / usage / retry\n * state. Returns the values needed by the caller's loop.\n */\nexport function setupStructuredOutput<T extends ZodType>(\n schema: T,\n maxRetries: number | undefined,\n) {\n const z = requireZod();\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const jsonSchema = toJsonSchema(schema, { unrepresentable: \"any\" });\n return {\n z,\n jsonSchema,\n maxRetries: maxRetries ?? 1,\n initialUsage: { inputTokens: 0, outputTokens: 0 },\n };\n}\n\n/**\n * Cleanup the transient agent after generateObject/streamObject finish.\n * Disposes AND hard-deletes from the registry so the count stays stable.\n *\n * @internal\n */\nexport async function disposeAndDeleteTransient(\n agent: { dispose: () => Promise<void>; agentId: string },\n deletor: (agentId: string) => Promise<void>,\n): Promise<void> {\n await agent.dispose();\n try {\n await deletor(agent.agentId);\n } catch {\n // Best-effort cleanup.\n }\n}\n\nvoid (null as unknown as ZodType); // satisfies unused-import check\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkMHCKWQR3_cjs = require('./chunk-MHCKWQR3.cjs');
|
|
4
4
|
|
|
5
5
|
// src/internal/runtime/retry/with-retry.ts
|
|
6
6
|
function defaultSleep(ms, signal) {
|
|
@@ -23,14 +23,14 @@ function defaultSleep(ms, signal) {
|
|
|
23
23
|
function resolveRetryOptions(options) {
|
|
24
24
|
const retries = options?.retries ?? 3;
|
|
25
25
|
if (!Number.isInteger(retries) || retries < 0) {
|
|
26
|
-
throw new
|
|
26
|
+
throw new chunkMHCKWQR3_cjs.ConfigurationError(
|
|
27
27
|
`withRetry: retries must be a non-negative integer, got ${retries}`,
|
|
28
28
|
{ code: "invalid_retry_config" }
|
|
29
29
|
);
|
|
30
30
|
}
|
|
31
31
|
return {
|
|
32
32
|
retries,
|
|
33
|
-
isRetryable: options?.isRetryable ??
|
|
33
|
+
isRetryable: options?.isRetryable ?? chunkMHCKWQR3_cjs.isTransientError,
|
|
34
34
|
initialDelayMs: options?.initialDelayMs ?? 100,
|
|
35
35
|
maxDelayMs: options?.maxDelayMs ?? 3e4,
|
|
36
36
|
backoffMultiplier: options?.backoffMultiplier ?? 2,
|
|
@@ -67,5 +67,5 @@ var Retry = class {
|
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
exports.Retry = Retry;
|
|
70
|
-
//# sourceMappingURL=chunk-
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
70
|
+
//# sourceMappingURL=chunk-3O2ELBST.cjs.map
|
|
71
|
+
//# sourceMappingURL=chunk-3O2ELBST.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/runtime/retry/with-retry.ts","../src/retry.ts"],"names":["ConfigurationError","isTransientError"],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/internal/runtime/retry/with-retry.ts","../src/retry.ts"],"names":["ConfigurationError","isTransientError"],"mappings":"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","file":"chunk-3O2ELBST.cjs","sourcesContent":["/**\n * Generic retry wrapper (plan m0-foundation-expose-primitives, M0-3).\n *\n * Exponential backoff with full jitter, deterministically testable via an\n * injectable `sleep` and `rng` (no real timers in unit tests, per the repo\n * testing rule). The default `isRetryable` predicate is {@link isTransientError}\n * so SDK errors retry exactly as the SDK classifies them. The workflow-internal\n * `withRetry` (RetryPolicy-coupled) is intentionally separate (ADR-M0-3).\n *\n * @internal — public via `@theokit/sdk/retry`\n */\n\nimport { ConfigurationError, isTransientError } from \"../../../errors.js\";\n\n/** Options for {@link withRetry}. All fields optional; sensible defaults applied. */\nexport interface RetryOptions {\n /** Number of retries after the first attempt (total attempts = retries + 1). Default 3. */\n retries?: number;\n /** Predicate deciding whether a thrown error is worth retrying. Default {@link isTransientError}. */\n isRetryable?: (err: unknown) => boolean;\n /** Base backoff in ms for the first retry. Default 100. */\n initialDelayMs?: number;\n /** Upper bound for a single backoff sleep. Default 30_000. */\n maxDelayMs?: number;\n /** Exponential multiplier applied per retry. Default 2. */\n backoffMultiplier?: number;\n /** [0, 1) source for full-jitter. Default `Math.random`. Inject for deterministic tests. */\n rng?: () => number;\n /** Sleep function. Default a `setTimeout`-based abortable sleep. Inject for deterministic tests. */\n sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n /** Abort signal; once aborted, the abortable default sleep rejects and the loop stops. */\n signal?: AbortSignal;\n}\n\nfunction defaultSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason instanceof Error ? signal.reason : new Error(\"withRetry: aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n function onAbort(): void {\n clearTimeout(timer);\n reject(signal?.reason instanceof Error ? signal.reason : new Error(\"withRetry: aborted\"));\n }\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\ninterface ResolvedRetry {\n retries: number;\n isRetryable: (err: unknown) => boolean;\n initialDelayMs: number;\n maxDelayMs: number;\n backoffMultiplier: number;\n rng: () => number;\n sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n signal?: AbortSignal;\n}\n\nfunction resolveRetryOptions(options?: RetryOptions): ResolvedRetry {\n const retries = options?.retries ?? 3;\n if (!Number.isInteger(retries) || retries < 0) {\n throw new ConfigurationError(\n `withRetry: retries must be a non-negative integer, got ${retries}`,\n { code: \"invalid_retry_config\" },\n );\n }\n return {\n retries,\n isRetryable: options?.isRetryable ?? isTransientError,\n initialDelayMs: options?.initialDelayMs ?? 100,\n maxDelayMs: options?.maxDelayMs ?? 30_000,\n backoffMultiplier: options?.backoffMultiplier ?? 2,\n rng: options?.rng ?? Math.random,\n sleep: options?.sleep ?? defaultSleep,\n signal: options?.signal,\n };\n}\n\n/** Full-jitter backoff for the given (0-indexed) retry attempt. */\nfunction backoffMs(cfg: ResolvedRetry, attempt: number): number {\n const ceiling = Math.min(cfg.maxDelayMs, cfg.initialDelayMs * cfg.backoffMultiplier ** attempt);\n return Math.floor(cfg.rng() * ceiling);\n}\n\n/**\n * Run `fn`, retrying transient failures with exponential backoff + full jitter.\n *\n * @returns the resolved value of the first successful `fn()` call\n * @throws the last error when retries are exhausted or the error is not retryable\n *\n * @example\n * const data = await withRetry(() => fetchJson(url)); // retries rate-limit/network\n */\nexport async function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T> {\n const cfg = resolveRetryOptions(options);\n let attempt = 0;\n for (;;) {\n try {\n return await fn();\n } catch (err) {\n if (attempt >= cfg.retries || !cfg.isRetryable(err)) throw err;\n await cfg.sleep(backoffMs(cfg, attempt), cfg.signal);\n attempt += 1;\n }\n }\n}\n","/**\n * Public generic retry primitive (plan m0-foundation-expose-primitives, M0-3).\n *\n * Split into its own top-level module so `tsup` builds a dedicated\n * `@theokit/sdk/retry` sub-path entry, mirroring the `path-safety` pattern.\n * The default retry predicate is `isTransientError`, so retries follow the\n * SDK's own error classification.\n */\n\nimport { type RetryOptions, withRetry } from \"./internal/runtime/retry/with-retry.js\";\n\nexport type { RetryOptions };\n\n/**\n * SE36 — `Retry.create` replaces `withRetry` (ADR 0015 / ADR-P2). NOTE: `withRetry` is an\n * EXECUTOR, not a constructor — `Retry.create(fn, opts)` RUNS `fn` with retry and resolves to\n * its result (`Promise<T>`), not a `Retry` instance. The `.create` name is the uniformity\n * mandate; the executor semantics are the documented, accepted awkwardness. @public\n */\nexport class Retry {\n private constructor() {}\n static create<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T> {\n return withRetry(fn, options);\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkMHCKWQR3_cjs = require('./chunk-MHCKWQR3.cjs');
|
|
4
|
+
var chunkLTCOPATU_cjs = require('./chunk-LTCOPATU.cjs');
|
|
5
5
|
|
|
6
6
|
// src/internal/runtime/compression/compression-helpers.ts
|
|
7
7
|
function selectCompressionWindow(messages, preserveLast = 6) {
|
|
@@ -40,7 +40,7 @@ Anything that MUST NOT be forgotten (preserve verbatim: error messages, exact va
|
|
|
40
40
|
File paths touched or referenced (verbatim).`;
|
|
41
41
|
function assertMarker(marker) {
|
|
42
42
|
if (marker === "") {
|
|
43
|
-
throw new
|
|
43
|
+
throw new chunkMHCKWQR3_cjs.TheokitAgentError("compaction marker must be non-empty", {
|
|
44
44
|
code: "invalid_argument"
|
|
45
45
|
});
|
|
46
46
|
}
|
|
@@ -74,7 +74,7 @@ async function runSummarize(summarize, head, template, failSafe) {
|
|
|
74
74
|
} catch (err) {
|
|
75
75
|
if (!failSafe) throw err;
|
|
76
76
|
console.warn(
|
|
77
|
-
`[compaction] summarizer failed \u2014 proceeding uncompacted: ${
|
|
77
|
+
`[compaction] summarizer failed \u2014 proceeding uncompacted: ${chunkLTCOPATU_cjs.redactSecrets(err instanceof Error ? err.message : String(err))}`
|
|
78
78
|
);
|
|
79
79
|
return FAILSAFE_ABORT;
|
|
80
80
|
}
|
|
@@ -116,9 +116,9 @@ function filterFromLatestCheckpoint(messages, options = {}) {
|
|
|
116
116
|
return [...messages];
|
|
117
117
|
}
|
|
118
118
|
function isContextOverflowError(err) {
|
|
119
|
-
return err instanceof
|
|
119
|
+
return err instanceof chunkMHCKWQR3_cjs.TheokitAgentError && (err.code === "context_too_long" || err.metadata?.code === "context_too_long");
|
|
120
120
|
}
|
|
121
|
-
var ContextWindowMarginError = class extends
|
|
121
|
+
var ContextWindowMarginError = class extends chunkMHCKWQR3_cjs.TheokitAgentError {
|
|
122
122
|
constructor(margin) {
|
|
123
123
|
super(
|
|
124
124
|
`context-window margin must be in (0, 1], got ${String(margin)}. A margin above 1 grows the assumed window and delays compaction past the real limit.`,
|
|
@@ -166,5 +166,5 @@ exports.filterFromLatestCheckpoint = filterFromLatestCheckpoint;
|
|
|
166
166
|
exports.isContextOverflowError = isContextOverflowError;
|
|
167
167
|
exports.resolveEffectiveContextWindow = resolveEffectiveContextWindow;
|
|
168
168
|
exports.shouldCompact = shouldCompact;
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
170
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-4YB7B3RP.cjs.map
|
|
170
|
+
//# sourceMappingURL=chunk-4YB7B3RP.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/runtime/compression/compression-helpers.ts","../src/compaction.ts"],"names":["TheokitAgentError","redactSecrets"],"mappings":"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","file":"chunk-M2PU44HP.cjs","sourcesContent":["/**\n * Compression helpers (T2.3, ADR D92).\n *\n * Scaffold for future compression LLM integration:\n * - `selectCompressionWindow` — splits messages into compress/preserve halves\n * - `assertCompressionReduced` — 10% reduction floor to detect \"compression placebo\"\n *\n * The compression LLM call itself is out of scope for this plan (requires\n * an auxiliary-model ADR). These helpers are used by `Agent.send` when a\n * future iteration adds compression.\n *\n * @internal\n */\n\nexport interface CompressionWindow<M> {\n toCompress: M[];\n toPreserve: M[];\n}\n\n/**\n * Split `messages` into the half to compress (older) and the half to\n * preserve verbatim (recent). When `messages.length <= preserveLast`,\n * everything is preserved.\n *\n * @internal\n */\nexport function selectCompressionWindow<M>(\n messages: readonly M[],\n preserveLast = 6,\n): CompressionWindow<M> {\n if (messages.length <= preserveLast) {\n return { toCompress: [], toPreserve: [...messages] };\n }\n return {\n toCompress: messages.slice(0, -preserveLast),\n toPreserve: messages.slice(-preserveLast),\n };\n}\n\nexport interface CompressionCheck {\n reduced: boolean;\n reductionPct: number;\n reason?: string;\n}\n\n/**\n * Check that compression actually reduced token count by at least `minPct`\n * (default 10%). Returns `{ reduced: false }` for spirals-in-formation\n * (compression LLM outputs that grow or barely shrink).\n *\n * @internal\n */\nexport function assertCompressionReduced(\n before: number,\n after: number,\n minPct = 10,\n): CompressionCheck {\n if (before <= 0) {\n return { reduced: false, reductionPct: 0, reason: \"before count was zero\" };\n }\n const reductionPct = ((before - after) / before) * 100;\n if (reductionPct >= minPct) {\n return { reduced: true, reductionPct };\n }\n return {\n reduced: false,\n reductionPct,\n reason: `compression reduced ${reductionPct.toFixed(1)}% (< ${minPct}% min). Spiral likely.`,\n };\n}\n","/**\n * Public compaction / context-management helpers (M2-1, extended V3-3).\n *\n * Promotes the SDK's compaction capability to a public surface so consumers can\n * compact a transcript, mark/filter conversation checkpoints, and detect\n * context-overflow — without reaching into `internal/`.\n *\n * Two recent-window modes (V3-3):\n * - `keepRecent` (turn-count, default) — keeps the last N turns verbatim and\n * always preserves leading system PROMPTS; reuses the internal\n * `selectCompressionWindow` (no second algorithm).\n * - `keepTokens` (token-budget) — keeps the trailing turns whose accumulated\n * `estimateTokens` fits the budget (theocode `splitTranscript` semantics). In\n * this mode leading system prompts are NOT special-cased (D6).\n *\n * Summarization is delegated to a caller-supplied callback (which receives the\n * older window + the summary template). With `failSafe`, a thrown summarizer\n * returns the ORIGINAL transcript + a structured warn (compaction is an\n * optimization, never a cause of data loss); without it, the error propagates.\n *\n * Public from the `@theokit/sdk/compaction` sub-path.\n */\n\nimport { TheokitAgentError } from \"./errors.js\";\nimport { selectCompressionWindow } from \"./internal/runtime/compression/compression-helpers.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\n\n/**\n * Minimal message shape for compaction/compression input. THE canonical public origin (leaf type —\n * rollup-plugin-dts cannot re-export types from internal modules into entry bundles; M42 lesson).\n *\n * @public\n */\nexport interface CompressibleMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n}\n\n/**\n * Sentinel prefix marking a conversation checkpoint turn. A visible, structured,\n * prose-unlikely token (no invisible/control bytes — safe to persist and to read\n * in source). Only {@link buildCheckpoint} should produce content beginning with it.\n */\nexport const CHECKPOINT_MARKER = \"[[theokit:checkpoint]] \";\n\n/**\n * The 7-section summary template handed to the `summarize` callback (theocode\n * parity shape). Every header is always present so the summarizer cannot silently\n * drop a category; the model is told to preserve file paths, commands, and error\n * text verbatim. Override per-call via {@link CompactTranscriptOptions.summaryTemplate}.\n */\nexport const SUMMARY_TEMPLATE = `Summarize the conversation so far into these sections (keep every header even if empty):\n\n## Goal\nWhat the user is ultimately trying to achieve.\n\n## Constraints\nHard requirements, conventions, and rules stated.\n\n## Progress\nWhat has been done so far.\n\n## Decisions\nChoices made and their rationale.\n\n## Next\nThe immediate next steps.\n\n## Critical\nAnything that MUST NOT be forgotten (preserve verbatim: error messages, exact values).\n\n## Files\nFile paths touched or referenced (verbatim).`;\n\n/** Reject an empty marker — it would match every turn via `startsWith(\"\")` (EC-3). */\nfunction assertMarker(marker: string): void {\n if (marker === \"\") {\n throw new TheokitAgentError(\"compaction marker must be non-empty\", {\n code: \"invalid_argument\",\n });\n }\n}\n\n/** True for a real system prompt — a `system` turn that is NOT a checkpoint marker. */\nfunction isSystemPrompt(message: CompressibleMessage, marker: string): boolean {\n return message.role === \"system\" && !message.content.startsWith(marker);\n}\n\n/** Carried split: leading system prompts (preserved), the older window, the verbatim tail. */\ninterface TranscriptSplit {\n systemPrompts: CompressibleMessage[];\n head: CompressibleMessage[];\n recent: CompressibleMessage[];\n}\n\n/**\n * Token-budget split (theocode `splitTranscript`): walk from the END accumulating\n * `estimateTokens` until `keepTokens` is exceeded; everything older is the head.\n * Always keeps ≥ 1 recent turn. No system-prompt special-casing (D6).\n */\nfunction selectByTokenBudget(\n messages: CompressibleMessage[],\n keepTokens: number,\n): { head: CompressibleMessage[]; recent: CompressibleMessage[] } {\n let acc = 0;\n let splitIndex = messages.length;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n acc += estimateTokens(messages[i]?.content ?? \"\");\n if (acc > keepTokens && i < messages.length - 1) {\n splitIndex = i + 1;\n break;\n }\n splitIndex = i;\n }\n return { head: messages.slice(0, splitIndex), recent: messages.slice(splitIndex) };\n}\n\n/** Turn-count split (M2): preserve leading system prompts; window the rest by `keepRecent`. */\nfunction splitByRecent(\n messages: CompressibleMessage[],\n keepRecent: number,\n marker: string,\n): TranscriptSplit {\n const systemPrompts = messages.filter((m) => isSystemPrompt(m, marker));\n const rest = messages.filter((m) => !isSystemPrompt(m, marker));\n const { toCompress, toPreserve } = selectCompressionWindow(rest, keepRecent);\n return { systemPrompts, head: toCompress, recent: toPreserve };\n}\n\n/** Options for {@link compactTranscript}. */\nexport interface CompactTranscriptOptions {\n /** Trailing turns preserved verbatim by COUNT (default 6). Ignored when `keepTokens` is set. */\n keepRecent?: number;\n /**\n * Trailing turns preserved verbatim by TOKEN BUDGET (theocode mode). When set,\n * takes precedence over `keepRecent` and disables system-prompt preservation (D6).\n */\n keepTokens?: number;\n /** Checkpoint marker (default {@link CHECKPOINT_MARKER}). Must be non-empty. */\n marker?: string;\n /** Summary template passed to `summarize` (default {@link SUMMARY_TEMPLATE}). */\n summaryTemplate?: string;\n /** Summarize the older window into one turn; if omitted, the older window is dropped. */\n summarize?: (older: CompressibleMessage[], template: string) => Promise<CompressibleMessage>;\n /**\n * When true, a thrown `summarize` returns the ORIGINAL transcript + a structured\n * warn (compaction never loses data). Default false: the error propagates.\n */\n failSafe?: boolean;\n}\n\n/** Sentinel returned by {@link runSummarize} when fail-safe swallowed a throw. */\nconst FAILSAFE_ABORT = Symbol(\"failsafe-abort\");\n\n/** Run the summarizer; on throw, either propagate or (fail-safe) warn + signal abort. */\nasync function runSummarize(\n summarize: NonNullable<CompactTranscriptOptions[\"summarize\"]>,\n head: CompressibleMessage[],\n template: string,\n failSafe: boolean,\n): Promise<CompressibleMessage | typeof FAILSAFE_ABORT> {\n try {\n return await summarize(head, template);\n } catch (err) {\n if (!failSafe) throw err;\n // Unbreakable Rule 8 — never fail silently. The breadcrumb points at the root\n // cause when a summarizer fails every turn and context grows unchecked. The\n // summarizer is caller-supplied, so its error text is routed through\n // `redactSecrets` (ADR D68 — no unredacted output sink in src/).\n console.warn(\n `[compaction] summarizer failed — proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}`,\n );\n return FAILSAFE_ABORT;\n }\n}\n\n/**\n * Compact a transcript. In `keepRecent` mode (default) the last `keepRecent` turns\n * are kept verbatim and leading system PROMPTS preserved; in `keepTokens` mode the\n * trailing turns within the token budget are kept (no system special-casing, D6).\n * The older window is summarized (via `summarize`, receiving the template) or\n * dropped. Never mutates the input.\n */\nexport async function compactTranscript(\n messages: CompressibleMessage[],\n options: CompactTranscriptOptions = {},\n): Promise<CompressibleMessage[]> {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n assertMarker(marker);\n const split =\n options.keepTokens != null\n ? { systemPrompts: [], ...selectByTokenBudget(messages, options.keepTokens) }\n : splitByRecent(messages, options.keepRecent ?? 6, marker);\n if (split.head.length === 0) {\n return [...messages];\n }\n if (!options.summarize) {\n return [...split.systemPrompts, ...split.recent];\n }\n const template = options.summaryTemplate ?? SUMMARY_TEMPLATE;\n const summary = await runSummarize(\n options.summarize,\n split.head,\n template,\n options.failSafe ?? false,\n );\n if (summary === FAILSAFE_ABORT) {\n return [...messages];\n }\n return [...split.systemPrompts, summary, ...split.recent];\n}\n\n/**\n * Build a checkpoint marker turn (a `system` turn whose content starts with\n * `marker`, default {@link CHECKPOINT_MARKER}). `marker` must be non-empty.\n */\nexport function buildCheckpoint(\n label?: string,\n marker: string = CHECKPOINT_MARKER,\n): CompressibleMessage {\n assertMarker(marker);\n return { role: \"system\", content: marker + (label ?? \"\") };\n}\n\n/** Options for {@link filterFromLatestCheckpoint}. */\nexport interface FilterCheckpointOptions {\n /** Marker to scan for (default {@link CHECKPOINT_MARKER}). */\n marker?: string;\n /**\n * `'after'` (default, M2) returns turns AFTER the latest marker (exclusive);\n * `'from'` (theocode) returns turns FROM the latest marker (inclusive).\n */\n include?: \"after\" | \"from\";\n}\n\n/**\n * Return the turns relative to the most recent checkpoint marker (all turns if\n * none). `include: 'after'` (default) excludes the checkpoint; `'from'` includes\n * it (the summary stands in for the pruned head). Never mutates the input.\n */\nexport function filterFromLatestCheckpoint(\n messages: CompressibleMessage[],\n options: FilterCheckpointOptions = {},\n): CompressibleMessage[] {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n const offset = options.include === \"from\" ? 0 : 1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.content.startsWith(marker)) {\n return messages.slice(i + offset);\n }\n }\n return [...messages];\n}\n\n/**\n * True iff `err` is a {@link TheokitAgentError} (or subclass) reporting a\n * context-window-exceeded condition (the typed `context_too_long` code). Reads\n * both `code` (set by provider mappers) and `metadata.code` (the preferred field)\n * — never a brittle message regex.\n */\nexport function isContextOverflowError(err: unknown): boolean {\n return (\n err instanceof TheokitAgentError &&\n (err.code === \"context_too_long\" || err.metadata?.code === \"context_too_long\")\n );\n}\n\n/**\n * M77 — the margin is outside `(0, 1]`. Typed, because a margin > 1 would GROW the assumed window,\n * which is the unsafe direction: `shouldCompact` is monotonically decreasing in `contextWindow`, so\n * overestimating it makes the trigger fire too late and the context overflow.\n */\nexport class ContextWindowMarginError extends TheokitAgentError {\n constructor(readonly margin: number) {\n super(\n `context-window margin must be in (0, 1], got ${String(margin)}. ` +\n `A margin above 1 grows the assumed window and delays compaction past the real limit.`,\n { code: \"invalid_context_window_margin\" },\n );\n }\n}\n\n/**\n * M77 — default safety margin on the context window.\n *\n * `0.95` is not a guess: it is the single reference's value. Codex ships\n * `effective_context_window_percent: 95` (`models-manager/src/model_info.rs:158`) and never budgets\n * against 100% of a window. Being MULTIPLICATIVE, it stays conservative at any window size, which a\n * fixed subtraction would not.\n */\nexport const CONTEXT_WINDOW_MARGIN = 0.95;\n\n/**\n * M77 — the floor used ONLY when neither the catalog nor the caller knows the window.\n *\n * Honest about its own weakness. This number has **one** source (the M77 milestone text); the search\n * for a second one failed, because the reference has no fallback at all — Codex returns `Option` and\n * its callers early-return (`core/src/session/turn_context.rs:213`, `core/src/compact_remote.rs:374`).\n *\n * It is conservative only UPWARD. For a model whose real window is larger, budgeting against 128k\n * compacts early — wasteful but safe. For a model whose real window is SMALLER (an 8k or 32k model\n * absent from the catalog), it compacts too late and the context still overflows. That residual risk\n * is real and is why {@link resolveEffectiveContextWindow} never lets this floor compete with a known\n * catalog value, and why the `compaction_fallback` event exists: a surface can show that the budget is\n * a guess instead of the user finding out when the provider rejects the request.\n */\nexport const CONTEXT_WINDOW_FLOOR = 128_000;\n\n/** Where the effective window came from — carried into the M77 structured event. */\nexport type ContextWindowSource = \"override\" | \"catalog\" | \"fallback\";\n\n/** Input to {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindowInput {\n /** Caller-supplied window, in tokens. Clamped by `catalog` when both are present. */\n readonly override?: number | undefined;\n /** The model's window from the catalog, in tokens. Absent when the model is unknown. */\n readonly catalog?: number | undefined;\n /** Safety margin in `(0, 1]`. Codex uses 0.95 (`model_info.rs:158`). */\n readonly margin: number;\n /** Conservative floor used ONLY when neither `override` nor `catalog` is available. */\n readonly floor?: number | undefined;\n}\n\n/** Result of {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindow {\n /** The window to budget against, after clamp and margin. */\n readonly window: number;\n /** Which input won — `\"fallback\"` means neither override nor catalog was available. */\n readonly source: ContextWindowSource;\n /** `true` when an `override` above the catalog window was clamped down to it. */\n readonly clamped: boolean;\n}\n\n/**\n * Resolve the window to budget against — the fail-SAFE replacement for reading the catalog directly.\n *\n * Today `post-run-lifecycle.ts` reads `getCatalogModelInfo(model)?.limit?.context` and, when that is\n * `undefined`, auto-compaction simply never fires. That is fail-OPEN: the context grows until the\n * provider rejects the request. (The comment there calls it \"fail-safe\" — M77 corrects it.)\n *\n * Three techniques, two of them borrowed from the single reference:\n *\n * 1. **Override, CLAMPED by the catalog** — Codex `models-manager/src/model_info.rs:26-31` lets\n * config override the window but limits it with `context_window.min(max_context_window)`.\n * Without the clamp, declaring 999k on a 200k model reopens the overflow through another door.\n * 2. **Multiplicative margin** — Codex `model_info.rs:158` (`effective_context_window_percent: 95`)\n * never budgets against 100% of the window. Being multiplicative, it is conservative for ANY\n * window size.\n * 3. **Floor, only when nothing is known** — deliberately NOT a blanket default. A fixed floor is\n * conservative only upward: applied to a small model it would inflate the assumed window and\n * reproduce the very fail-open this function exists to close. Hence the floor never competes\n * with a known catalog value.\n *\n * Pure — no catalog lookup, no I/O. The caller supplies the numbers, mirroring `shouldCompact`.\n */\n/**\n * Teto absoluto de janela declarada, usado quando não há entrada de catálogo para comparar.\n *\n * **10M**, não 2M. A primeira versão usou 2M com a justificativa de estar \"acima da maior janela\n * publicada com folga larga\" — e a revisão adversarial mediu o contrário: o Llama 4 Scout publica\n * **10M**, e chega justamente por OpenRouter, que é o provider **sem** catálogo, isto é, o caso que\n * este teto existe para cobrir. O usuário perderia 80% da janela declarada, em silêncio.\n *\n * O teto continua servindo ao que motiva sua existência — um zero a mais em 400k dá 4M, que passa;\n * dois zeros dão 40M, que não. Um limite que recusa configuração legítima é pior que limite nenhum,\n * porque o fail-OPEN é visível quando acontece e a perda silenciosa de 80% não é.\n */\nexport const TETO_ABSOLUTO_DE_JANELA = 10_000_000;\n\nexport function resolveEffectiveContextWindow(\n input: EffectiveContextWindowInput,\n): EffectiveContextWindow {\n if (!(input.margin > 0) || input.margin > 1) {\n throw new ContextWindowMarginError(input.margin);\n }\n\n const withMargin = (raw: number): number => Math.floor(raw * input.margin);\n\n if (input.override !== undefined) {\n // O catálogo é o teto preferido; sem ele vale o TETO ABSOLUTO.\n //\n // M95 (revisão adversarial do M94) — a versão anterior clampeava **apenas** quando havia\n // entrada de catálogo, e a razão de ser da chave `contextWindow` é justamente o modelo que\n // NÃO tem entrada (OpenRouter tem zero). Ou seja: o clamp faltava exatamente no caso que\n // justifica a feature, enquanto a documentação — inclusive um CHANGELOG já publicado —\n // afirmava sem condicional que \"declarar 10M não estoura o provider\".\n //\n // O cenário concreto é um zero a mais: `context_window = 4000000`. O único guarda era um\n // `.positive().int()`, que não limita para cima. O agente nunca compactaria até o provider\n // recusar o turno — o fail-OPEN silencioso que o M77 existe para impedir.\n const teto = input.catalog ?? TETO_ABSOLUTO_DE_JANELA;\n const clamped = input.override > teto;\n return { window: withMargin(clamped ? teto : input.override), source: \"override\", clamped };\n }\n\n if (input.catalog !== undefined) {\n return { window: withMargin(input.catalog), source: \"catalog\", clamped: false };\n }\n\n return { window: withMargin(input.floor ?? 0), source: \"fallback\", clamped: false };\n}\n\n/** Input to {@link shouldCompact}: an estimate, the model's window, and reserved headroom. */\nexport interface ShouldCompactInput {\n /** Estimated token count of the next request (e.g. from {@link estimateTokens}). */\n readonly estimated: number;\n /** The model's total context window, in tokens. */\n readonly contextWindow: number;\n /** Tokens to reserve as headroom (output + safety margin). */\n readonly buffer: number;\n /**\n * Tokens reserved for the model's response generation, SEPARATE from `buffer`.\n * Default 0 — omitting it preserves the legacy\n * `estimated >= contextWindow - buffer` result.\n */\n readonly maxOutput?: number;\n}\n\n/**\n * Tokenizer-free token estimate via the conventional ~4-chars-per-token\n * heuristic: `ceil(text.length / 4)`. `\"\"` → 0; any non-empty text → ≥ 1.\n * A cheap PRE-CALL gate for {@link shouldCompact} — NOT exact tokenization\n * (a consumer needing exactness supplies their own tokenizer). Uses UTF-16\n * `.length` (code units), so multibyte text is approximate.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Decide BEFORE sending whether to compact: `true` when the `estimated` token\n * count leaves less than `buffer` headroom in the `contextWindow`\n * (`estimated >= contextWindow - buffer`). A `buffer >= contextWindow`\n * (non-positive threshold) always returns `true`. Pure — the caller supplies\n * the window (e.g. from `resolveModelCapabilities`), keeping this decoupled\n * from the per-model catalog.\n */\nexport function shouldCompact(input: ShouldCompactInput): boolean {\n return input.estimated >= input.contextWindow - input.buffer - (input.maxOutput ?? 0);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/runtime/compression/compression-helpers.ts","../src/compaction.ts"],"names":["TheokitAgentError","redactSecrets"],"mappings":"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","file":"chunk-4YB7B3RP.cjs","sourcesContent":["/**\n * Compression helpers (T2.3, ADR D92).\n *\n * Scaffold for future compression LLM integration:\n * - `selectCompressionWindow` — splits messages into compress/preserve halves\n * - `assertCompressionReduced` — 10% reduction floor to detect \"compression placebo\"\n *\n * The compression LLM call itself is out of scope for this plan (requires\n * an auxiliary-model ADR). These helpers are used by `Agent.send` when a\n * future iteration adds compression.\n *\n * @internal\n */\n\nexport interface CompressionWindow<M> {\n toCompress: M[];\n toPreserve: M[];\n}\n\n/**\n * Split `messages` into the half to compress (older) and the half to\n * preserve verbatim (recent). When `messages.length <= preserveLast`,\n * everything is preserved.\n *\n * @internal\n */\nexport function selectCompressionWindow<M>(\n messages: readonly M[],\n preserveLast = 6,\n): CompressionWindow<M> {\n if (messages.length <= preserveLast) {\n return { toCompress: [], toPreserve: [...messages] };\n }\n return {\n toCompress: messages.slice(0, -preserveLast),\n toPreserve: messages.slice(-preserveLast),\n };\n}\n\nexport interface CompressionCheck {\n reduced: boolean;\n reductionPct: number;\n reason?: string;\n}\n\n/**\n * Check that compression actually reduced token count by at least `minPct`\n * (default 10%). Returns `{ reduced: false }` for spirals-in-formation\n * (compression LLM outputs that grow or barely shrink).\n *\n * @internal\n */\nexport function assertCompressionReduced(\n before: number,\n after: number,\n minPct = 10,\n): CompressionCheck {\n if (before <= 0) {\n return { reduced: false, reductionPct: 0, reason: \"before count was zero\" };\n }\n const reductionPct = ((before - after) / before) * 100;\n if (reductionPct >= minPct) {\n return { reduced: true, reductionPct };\n }\n return {\n reduced: false,\n reductionPct,\n reason: `compression reduced ${reductionPct.toFixed(1)}% (< ${minPct}% min). Spiral likely.`,\n };\n}\n","/**\n * Public compaction / context-management helpers (M2-1, extended V3-3).\n *\n * Promotes the SDK's compaction capability to a public surface so consumers can\n * compact a transcript, mark/filter conversation checkpoints, and detect\n * context-overflow — without reaching into `internal/`.\n *\n * Two recent-window modes (V3-3):\n * - `keepRecent` (turn-count, default) — keeps the last N turns verbatim and\n * always preserves leading system PROMPTS; reuses the internal\n * `selectCompressionWindow` (no second algorithm).\n * - `keepTokens` (token-budget) — keeps the trailing turns whose accumulated\n * `estimateTokens` fits the budget (theocode `splitTranscript` semantics). In\n * this mode leading system prompts are NOT special-cased (D6).\n *\n * Summarization is delegated to a caller-supplied callback (which receives the\n * older window + the summary template). With `failSafe`, a thrown summarizer\n * returns the ORIGINAL transcript + a structured warn (compaction is an\n * optimization, never a cause of data loss); without it, the error propagates.\n *\n * Public from the `@theokit/sdk/compaction` sub-path.\n */\n\nimport { TheokitAgentError } from \"./errors.js\";\nimport { selectCompressionWindow } from \"./internal/runtime/compression/compression-helpers.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\n\n/**\n * Minimal message shape for compaction/compression input. THE canonical public origin (leaf type —\n * rollup-plugin-dts cannot re-export types from internal modules into entry bundles; M42 lesson).\n *\n * @public\n */\nexport interface CompressibleMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n}\n\n/**\n * Sentinel prefix marking a conversation checkpoint turn. A visible, structured,\n * prose-unlikely token (no invisible/control bytes — safe to persist and to read\n * in source). Only {@link buildCheckpoint} should produce content beginning with it.\n */\nexport const CHECKPOINT_MARKER = \"[[theokit:checkpoint]] \";\n\n/**\n * The 7-section summary template handed to the `summarize` callback (theocode\n * parity shape). Every header is always present so the summarizer cannot silently\n * drop a category; the model is told to preserve file paths, commands, and error\n * text verbatim. Override per-call via {@link CompactTranscriptOptions.summaryTemplate}.\n */\nexport const SUMMARY_TEMPLATE = `Summarize the conversation so far into these sections (keep every header even if empty):\n\n## Goal\nWhat the user is ultimately trying to achieve.\n\n## Constraints\nHard requirements, conventions, and rules stated.\n\n## Progress\nWhat has been done so far.\n\n## Decisions\nChoices made and their rationale.\n\n## Next\nThe immediate next steps.\n\n## Critical\nAnything that MUST NOT be forgotten (preserve verbatim: error messages, exact values).\n\n## Files\nFile paths touched or referenced (verbatim).`;\n\n/** Reject an empty marker — it would match every turn via `startsWith(\"\")` (EC-3). */\nfunction assertMarker(marker: string): void {\n if (marker === \"\") {\n throw new TheokitAgentError(\"compaction marker must be non-empty\", {\n code: \"invalid_argument\",\n });\n }\n}\n\n/** True for a real system prompt — a `system` turn that is NOT a checkpoint marker. */\nfunction isSystemPrompt(message: CompressibleMessage, marker: string): boolean {\n return message.role === \"system\" && !message.content.startsWith(marker);\n}\n\n/** Carried split: leading system prompts (preserved), the older window, the verbatim tail. */\ninterface TranscriptSplit {\n systemPrompts: CompressibleMessage[];\n head: CompressibleMessage[];\n recent: CompressibleMessage[];\n}\n\n/**\n * Token-budget split (theocode `splitTranscript`): walk from the END accumulating\n * `estimateTokens` until `keepTokens` is exceeded; everything older is the head.\n * Always keeps ≥ 1 recent turn. No system-prompt special-casing (D6).\n */\nfunction selectByTokenBudget(\n messages: CompressibleMessage[],\n keepTokens: number,\n): { head: CompressibleMessage[]; recent: CompressibleMessage[] } {\n let acc = 0;\n let splitIndex = messages.length;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n acc += estimateTokens(messages[i]?.content ?? \"\");\n if (acc > keepTokens && i < messages.length - 1) {\n splitIndex = i + 1;\n break;\n }\n splitIndex = i;\n }\n return { head: messages.slice(0, splitIndex), recent: messages.slice(splitIndex) };\n}\n\n/** Turn-count split (M2): preserve leading system prompts; window the rest by `keepRecent`. */\nfunction splitByRecent(\n messages: CompressibleMessage[],\n keepRecent: number,\n marker: string,\n): TranscriptSplit {\n const systemPrompts = messages.filter((m) => isSystemPrompt(m, marker));\n const rest = messages.filter((m) => !isSystemPrompt(m, marker));\n const { toCompress, toPreserve } = selectCompressionWindow(rest, keepRecent);\n return { systemPrompts, head: toCompress, recent: toPreserve };\n}\n\n/** Options for {@link compactTranscript}. */\nexport interface CompactTranscriptOptions {\n /** Trailing turns preserved verbatim by COUNT (default 6). Ignored when `keepTokens` is set. */\n keepRecent?: number;\n /**\n * Trailing turns preserved verbatim by TOKEN BUDGET (theocode mode). When set,\n * takes precedence over `keepRecent` and disables system-prompt preservation (D6).\n */\n keepTokens?: number;\n /** Checkpoint marker (default {@link CHECKPOINT_MARKER}). Must be non-empty. */\n marker?: string;\n /** Summary template passed to `summarize` (default {@link SUMMARY_TEMPLATE}). */\n summaryTemplate?: string;\n /** Summarize the older window into one turn; if omitted, the older window is dropped. */\n summarize?: (older: CompressibleMessage[], template: string) => Promise<CompressibleMessage>;\n /**\n * When true, a thrown `summarize` returns the ORIGINAL transcript + a structured\n * warn (compaction never loses data). Default false: the error propagates.\n */\n failSafe?: boolean;\n}\n\n/** Sentinel returned by {@link runSummarize} when fail-safe swallowed a throw. */\nconst FAILSAFE_ABORT = Symbol(\"failsafe-abort\");\n\n/** Run the summarizer; on throw, either propagate or (fail-safe) warn + signal abort. */\nasync function runSummarize(\n summarize: NonNullable<CompactTranscriptOptions[\"summarize\"]>,\n head: CompressibleMessage[],\n template: string,\n failSafe: boolean,\n): Promise<CompressibleMessage | typeof FAILSAFE_ABORT> {\n try {\n return await summarize(head, template);\n } catch (err) {\n if (!failSafe) throw err;\n // Unbreakable Rule 8 — never fail silently. The breadcrumb points at the root\n // cause when a summarizer fails every turn and context grows unchecked. The\n // summarizer is caller-supplied, so its error text is routed through\n // `redactSecrets` (ADR D68 — no unredacted output sink in src/).\n console.warn(\n `[compaction] summarizer failed — proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}`,\n );\n return FAILSAFE_ABORT;\n }\n}\n\n/**\n * Compact a transcript. In `keepRecent` mode (default) the last `keepRecent` turns\n * are kept verbatim and leading system PROMPTS preserved; in `keepTokens` mode the\n * trailing turns within the token budget are kept (no system special-casing, D6).\n * The older window is summarized (via `summarize`, receiving the template) or\n * dropped. Never mutates the input.\n */\nexport async function compactTranscript(\n messages: CompressibleMessage[],\n options: CompactTranscriptOptions = {},\n): Promise<CompressibleMessage[]> {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n assertMarker(marker);\n const split =\n options.keepTokens != null\n ? { systemPrompts: [], ...selectByTokenBudget(messages, options.keepTokens) }\n : splitByRecent(messages, options.keepRecent ?? 6, marker);\n if (split.head.length === 0) {\n return [...messages];\n }\n if (!options.summarize) {\n return [...split.systemPrompts, ...split.recent];\n }\n const template = options.summaryTemplate ?? SUMMARY_TEMPLATE;\n const summary = await runSummarize(\n options.summarize,\n split.head,\n template,\n options.failSafe ?? false,\n );\n if (summary === FAILSAFE_ABORT) {\n return [...messages];\n }\n return [...split.systemPrompts, summary, ...split.recent];\n}\n\n/**\n * Build a checkpoint marker turn (a `system` turn whose content starts with\n * `marker`, default {@link CHECKPOINT_MARKER}). `marker` must be non-empty.\n */\nexport function buildCheckpoint(\n label?: string,\n marker: string = CHECKPOINT_MARKER,\n): CompressibleMessage {\n assertMarker(marker);\n return { role: \"system\", content: marker + (label ?? \"\") };\n}\n\n/** Options for {@link filterFromLatestCheckpoint}. */\nexport interface FilterCheckpointOptions {\n /** Marker to scan for (default {@link CHECKPOINT_MARKER}). */\n marker?: string;\n /**\n * `'after'` (default, M2) returns turns AFTER the latest marker (exclusive);\n * `'from'` (theocode) returns turns FROM the latest marker (inclusive).\n */\n include?: \"after\" | \"from\";\n}\n\n/**\n * Return the turns relative to the most recent checkpoint marker (all turns if\n * none). `include: 'after'` (default) excludes the checkpoint; `'from'` includes\n * it (the summary stands in for the pruned head). Never mutates the input.\n */\nexport function filterFromLatestCheckpoint(\n messages: CompressibleMessage[],\n options: FilterCheckpointOptions = {},\n): CompressibleMessage[] {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n const offset = options.include === \"from\" ? 0 : 1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.content.startsWith(marker)) {\n return messages.slice(i + offset);\n }\n }\n return [...messages];\n}\n\n/**\n * True iff `err` is a {@link TheokitAgentError} (or subclass) reporting a\n * context-window-exceeded condition (the typed `context_too_long` code). Reads\n * both `code` (set by provider mappers) and `metadata.code` (the preferred field)\n * — never a brittle message regex.\n */\nexport function isContextOverflowError(err: unknown): boolean {\n return (\n err instanceof TheokitAgentError &&\n (err.code === \"context_too_long\" || err.metadata?.code === \"context_too_long\")\n );\n}\n\n/**\n * M77 — the margin is outside `(0, 1]`. Typed, because a margin > 1 would GROW the assumed window,\n * which is the unsafe direction: `shouldCompact` is monotonically decreasing in `contextWindow`, so\n * overestimating it makes the trigger fire too late and the context overflow.\n */\nexport class ContextWindowMarginError extends TheokitAgentError {\n constructor(readonly margin: number) {\n super(\n `context-window margin must be in (0, 1], got ${String(margin)}. ` +\n `A margin above 1 grows the assumed window and delays compaction past the real limit.`,\n { code: \"invalid_context_window_margin\" },\n );\n }\n}\n\n/**\n * M77 — default safety margin on the context window.\n *\n * `0.95` is not a guess: it is the single reference's value. Codex ships\n * `effective_context_window_percent: 95` (`models-manager/src/model_info.rs:158`) and never budgets\n * against 100% of a window. Being MULTIPLICATIVE, it stays conservative at any window size, which a\n * fixed subtraction would not.\n */\nexport const CONTEXT_WINDOW_MARGIN = 0.95;\n\n/**\n * M77 — the floor used ONLY when neither the catalog nor the caller knows the window.\n *\n * Honest about its own weakness. This number has **one** source (the M77 milestone text); the search\n * for a second one failed, because the reference has no fallback at all — Codex returns `Option` and\n * its callers early-return (`core/src/session/turn_context.rs:213`, `core/src/compact_remote.rs:374`).\n *\n * It is conservative only UPWARD. For a model whose real window is larger, budgeting against 128k\n * compacts early — wasteful but safe. For a model whose real window is SMALLER (an 8k or 32k model\n * absent from the catalog), it compacts too late and the context still overflows. That residual risk\n * is real and is why {@link resolveEffectiveContextWindow} never lets this floor compete with a known\n * catalog value, and why the `compaction_fallback` event exists: a surface can show that the budget is\n * a guess instead of the user finding out when the provider rejects the request.\n */\nexport const CONTEXT_WINDOW_FLOOR = 128_000;\n\n/** Where the effective window came from — carried into the M77 structured event. */\nexport type ContextWindowSource = \"override\" | \"catalog\" | \"fallback\";\n\n/** Input to {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindowInput {\n /** Caller-supplied window, in tokens. Clamped by `catalog` when both are present. */\n readonly override?: number | undefined;\n /** The model's window from the catalog, in tokens. Absent when the model is unknown. */\n readonly catalog?: number | undefined;\n /** Safety margin in `(0, 1]`. Codex uses 0.95 (`model_info.rs:158`). */\n readonly margin: number;\n /** Conservative floor used ONLY when neither `override` nor `catalog` is available. */\n readonly floor?: number | undefined;\n}\n\n/** Result of {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindow {\n /** The window to budget against, after clamp and margin. */\n readonly window: number;\n /** Which input won — `\"fallback\"` means neither override nor catalog was available. */\n readonly source: ContextWindowSource;\n /** `true` when an `override` above the catalog window was clamped down to it. */\n readonly clamped: boolean;\n}\n\n/**\n * Resolve the window to budget against — the fail-SAFE replacement for reading the catalog directly.\n *\n * Today `post-run-lifecycle.ts` reads `getCatalogModelInfo(model)?.limit?.context` and, when that is\n * `undefined`, auto-compaction simply never fires. That is fail-OPEN: the context grows until the\n * provider rejects the request. (The comment there calls it \"fail-safe\" — M77 corrects it.)\n *\n * Three techniques, two of them borrowed from the single reference:\n *\n * 1. **Override, CLAMPED by the catalog** — Codex `models-manager/src/model_info.rs:26-31` lets\n * config override the window but limits it with `context_window.min(max_context_window)`.\n * Without the clamp, declaring 999k on a 200k model reopens the overflow through another door.\n * 2. **Multiplicative margin** — Codex `model_info.rs:158` (`effective_context_window_percent: 95`)\n * never budgets against 100% of the window. Being multiplicative, it is conservative for ANY\n * window size.\n * 3. **Floor, only when nothing is known** — deliberately NOT a blanket default. A fixed floor is\n * conservative only upward: applied to a small model it would inflate the assumed window and\n * reproduce the very fail-open this function exists to close. Hence the floor never competes\n * with a known catalog value.\n *\n * Pure — no catalog lookup, no I/O. The caller supplies the numbers, mirroring `shouldCompact`.\n */\n/**\n * Teto absoluto de janela declarada, usado quando não há entrada de catálogo para comparar.\n *\n * **10M**, não 2M. A primeira versão usou 2M com a justificativa de estar \"acima da maior janela\n * publicada com folga larga\" — e a revisão adversarial mediu o contrário: o Llama 4 Scout publica\n * **10M**, e chega justamente por OpenRouter, que é o provider **sem** catálogo, isto é, o caso que\n * este teto existe para cobrir. O usuário perderia 80% da janela declarada, em silêncio.\n *\n * O teto continua servindo ao que motiva sua existência — um zero a mais em 400k dá 4M, que passa;\n * dois zeros dão 40M, que não. Um limite que recusa configuração legítima é pior que limite nenhum,\n * porque o fail-OPEN é visível quando acontece e a perda silenciosa de 80% não é.\n */\nexport const TETO_ABSOLUTO_DE_JANELA = 10_000_000;\n\nexport function resolveEffectiveContextWindow(\n input: EffectiveContextWindowInput,\n): EffectiveContextWindow {\n if (!(input.margin > 0) || input.margin > 1) {\n throw new ContextWindowMarginError(input.margin);\n }\n\n const withMargin = (raw: number): number => Math.floor(raw * input.margin);\n\n if (input.override !== undefined) {\n // O catálogo é o teto preferido; sem ele vale o TETO ABSOLUTO.\n //\n // M95 (revisão adversarial do M94) — a versão anterior clampeava **apenas** quando havia\n // entrada de catálogo, e a razão de ser da chave `contextWindow` é justamente o modelo que\n // NÃO tem entrada (OpenRouter tem zero). Ou seja: o clamp faltava exatamente no caso que\n // justifica a feature, enquanto a documentação — inclusive um CHANGELOG já publicado —\n // afirmava sem condicional que \"declarar 10M não estoura o provider\".\n //\n // O cenário concreto é um zero a mais: `context_window = 4000000`. O único guarda era um\n // `.positive().int()`, que não limita para cima. O agente nunca compactaria até o provider\n // recusar o turno — o fail-OPEN silencioso que o M77 existe para impedir.\n const teto = input.catalog ?? TETO_ABSOLUTO_DE_JANELA;\n const clamped = input.override > teto;\n return { window: withMargin(clamped ? teto : input.override), source: \"override\", clamped };\n }\n\n if (input.catalog !== undefined) {\n return { window: withMargin(input.catalog), source: \"catalog\", clamped: false };\n }\n\n return { window: withMargin(input.floor ?? 0), source: \"fallback\", clamped: false };\n}\n\n/** Input to {@link shouldCompact}: an estimate, the model's window, and reserved headroom. */\nexport interface ShouldCompactInput {\n /** Estimated token count of the next request (e.g. from {@link estimateTokens}). */\n readonly estimated: number;\n /** The model's total context window, in tokens. */\n readonly contextWindow: number;\n /** Tokens to reserve as headroom (output + safety margin). */\n readonly buffer: number;\n /**\n * Tokens reserved for the model's response generation, SEPARATE from `buffer`.\n * Default 0 — omitting it preserves the legacy\n * `estimated >= contextWindow - buffer` result.\n */\n readonly maxOutput?: number;\n}\n\n/**\n * Tokenizer-free token estimate via the conventional ~4-chars-per-token\n * heuristic: `ceil(text.length / 4)`. `\"\"` → 0; any non-empty text → ≥ 1.\n * A cheap PRE-CALL gate for {@link shouldCompact} — NOT exact tokenization\n * (a consumer needing exactness supplies their own tokenizer). Uses UTF-16\n * `.length` (code units), so multibyte text is approximate.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Decide BEFORE sending whether to compact: `true` when the `estimated` token\n * count leaves less than `buffer` headroom in the `contextWindow`\n * (`estimated >= contextWindow - buffer`). A `buffer >= contextWindow`\n * (non-positive threshold) always returns `true`. Pure — the caller supplies\n * the window (e.g. from `resolveModelCapabilities`), keeping this decoupled\n * from the per-model catalog.\n */\nexport function shouldCompact(input: ShouldCompactInput): boolean {\n return input.estimated >= input.contextWindow - input.buffer - (input.maxOutput ?? 0);\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { diag } from './chunk-TAPQWDW2.js';
|
|
1
2
|
import { randomBytes } from 'crypto';
|
|
2
3
|
import { open, rename, unlink, mkdir, statfs } from 'fs/promises';
|
|
3
4
|
import { dirname } from 'path';
|
|
4
5
|
|
|
5
|
-
// src/internal/persistence/atomic-write.ts
|
|
6
6
|
var NETWORK_FS_MAGIC = /* @__PURE__ */ new Map([
|
|
7
7
|
[26985, "nfs"],
|
|
8
8
|
[20859, "smb"],
|
|
@@ -21,21 +21,22 @@ async function warnOnNetworkFsOnce(dirPath, label) {
|
|
|
21
21
|
const info = await statfs(dirPath);
|
|
22
22
|
const fsName = detectNetworkFsName(info.type);
|
|
23
23
|
if (fsName === null) return;
|
|
24
|
-
|
|
24
|
+
diag(
|
|
25
25
|
`[theokit-sdk] ${label}: detected network fs (${fsName}) at ${dirPath} \u2014 rename() atomicity guarantees may be weaker than expected.
|
|
26
26
|
`
|
|
27
27
|
);
|
|
28
28
|
} catch {
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
async function replaceFileAtomic(filePath, content) {
|
|
31
|
+
async function replaceFileAtomic(filePath, content, options) {
|
|
32
32
|
await warnOnNetworkFsOnce(dirname(filePath), "atomic-write");
|
|
33
33
|
const suffix = randomBytes(8).toString("hex");
|
|
34
34
|
const tmp = `${filePath}.${process.pid}.${suffix}.tmp`;
|
|
35
|
-
const handle = await open(tmp, "w", 384);
|
|
35
|
+
const handle = await open(tmp, options?.exclusive === true ? "wx" : "w", options?.mode ?? 384);
|
|
36
36
|
try {
|
|
37
37
|
await handle.writeFile(content, "utf8");
|
|
38
38
|
await handle.sync();
|
|
39
|
+
if (options?.mode !== void 0) await handle.chmod(options.mode);
|
|
39
40
|
} finally {
|
|
40
41
|
await handle.close();
|
|
41
42
|
}
|
|
@@ -56,7 +57,7 @@ async function atomicWriteJson(filePath, data, options) {
|
|
|
56
57
|
const content = trailingNewline ? `${json}
|
|
57
58
|
` : json;
|
|
58
59
|
await mkdir(dirname(filePath), { recursive: true });
|
|
59
|
-
await replaceFileAtomic(filePath, content);
|
|
60
|
+
await replaceFileAtomic(filePath, content, options);
|
|
60
61
|
}
|
|
61
62
|
async function atomicWriteText(filePath, content) {
|
|
62
63
|
await mkdir(dirname(filePath), { recursive: true });
|
|
@@ -64,5 +65,5 @@ async function atomicWriteText(filePath, content) {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
export { atomicWriteJson, atomicWriteText, replaceFileAtomic };
|
|
67
|
-
//# sourceMappingURL=chunk-
|
|
68
|
-
//# sourceMappingURL=chunk-
|
|
68
|
+
//# sourceMappingURL=chunk-56OXYUZE.js.map
|
|
69
|
+
//# sourceMappingURL=chunk-56OXYUZE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/persistence/atomic-write.ts"],"names":[],"mappings":"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","file":"chunk-56OXYUZE.js","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { mkdir, open, rename, statfs, unlink } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { diag } from \"../diagnostics.js\";\n\n// T5.8 — Linux filesystem magic numbers (from `<linux/magic.h>`).\n// Used by `detectNetworkFsName` to identify the parent directory's\n// filesystem type from a `statfs()` return value. The four entries\n// below cover the network/FUSE cases where `rename()` is best-effort\n// rather than strictly atomic; everything else is treated as local.\nconst NETWORK_FS_MAGIC: ReadonlyMap<number, string> = new Map([\n [0x6969, \"nfs\"],\n [0x517b, \"smb\"],\n [0xff534d42, \"cifs\"],\n [0x65735546, \"fuse\"],\n]);\n\n/**\n * T5.8 — Map a `statfs().type` magic number to a network-FS label, or\n * `null` for local filesystems. Pure function — exported via the\n * `__TESTING__` seam so unit tests can drive the parse logic without\n * needing a network mount.\n *\n * @internal\n */\nfunction detectNetworkFsName(typeMagic: number): string | null {\n return NETWORK_FS_MAGIC.get(typeMagic) ?? null;\n}\n\nconst warnedNfsDirs = new Set<string>();\n\n/**\n * T5.8 — Best-effort one-shot stderr warning when `dirPath` lives on a\n * network/FUSE filesystem. Silent no-op on local filesystems, on\n * statfs failure (Windows / Node < 18.15 / EACCES), or after the\n * first warning per (dir + label) pair. Mirrors the `sqlite-wal.ts`\n * warn-once-per-label pattern (D63).\n *\n * @internal\n */\nasync function warnOnNetworkFsOnce(dirPath: string, label: string): Promise<void> {\n const key = `${dirPath}\\0${label}`;\n if (warnedNfsDirs.has(key)) return;\n warnedNfsDirs.add(key);\n try {\n const info = await statfs(dirPath);\n const fsName = detectNetworkFsName(info.type);\n if (fsName === null) return;\n diag(\n `[theokit-sdk] ${label}: detected network fs (${fsName}) at ${dirPath} — ` +\n \"rename() atomicity guarantees may be weaker than expected.\\n\",\n );\n } catch {\n // statfs unavailable (Windows / Node < 18.15) or unreadable —\n // silent fallback. The warning is purely informational.\n }\n}\n\n/**\n * T5.8 — Test seam exposing the pure detection function so unit tests\n * can assert magic-number coverage without spinning up a network FS.\n * NOT included in the public barrel.\n *\n * @internal\n */\nexport function __TESTING__detectNetworkFsName(typeMagic: number): string | null {\n return detectNetworkFsName(typeMagic);\n}\n\n/**\n * T5.8 — Test seam: clear the per-directory warn-once registry between\n * tests so warning-emission tests stay deterministic.\n *\n * @internal\n */\nexport function __TESTING__resetNfsWarnings(): void {\n warnedNfsDirs.clear();\n}\n\n/**\n * M107 — controle de criação do temporário, comum a `replaceFileAtomic`,\n * `atomicWriteJson` e `atomicWriteText`.\n *\n * Ambos os campos são OPCIONAIS e o default é byte-idêntico ao comportamento\n * anterior a M107. Ver `replaceFileAtomic` para por que a reafirmação de modo\n * é condicional.\n *\n * @internal\n */\nexport interface AtomicWriteFileOptions {\n /**\n * Bits de permissão do arquivo criado. Default: `0o600`, o literal fixo de\n * antes — filtrado pelo `umask`, como sempre foi. Quando informado, o modo é\n * reafirmado no descritor, de modo que o `umask` não pode silenciosamente\n * limpar bits que o chamador pediu.\n */\n mode?: number;\n /**\n * Criar o temporário com `wx` (criação exclusiva) em vez de `w`. Default:\n * `false` — a flag de antes. Com `true`, um temporário pré-existente vira\n * `EEXIST` em vez de ser truncado.\n */\n exclusive?: boolean;\n}\n\n/**\n * Atomic file replacement: write content to a per-call unique tmp path,\n * fsync, then rename over the target. Crash mid-write leaves either the old\n * file intact or the new file complete — never a half-written file.\n *\n * The tmp suffix is `<pid>.<rand>.tmp` so parallel processes (and concurrent\n * burst writes within one process) never collide on the same tmp path — a\n * race that would manifest as `ENOENT` on `rename` after the rival process\n * already moved its tmp into place.\n *\n * Mirrors peer-project's `replaceFileAtomic` from\n * `referencia/peer-project/packages/memory-host-sdk/src/host/fs-utils.ts` with\n * the multi-writer robustness fix.\n *\n * ## M107 — `options` é opcional, e o default é byte-idêntico\n *\n * O terceiro parâmetro é aditivo: todo chamador anterior continua compilando e\n * escrevendo exatamente o mesmo byte, com o mesmo modo, no mesmo caminho.\n *\n * A reafirmação de modo (`handle.chmod`) é **condicional a `mode !== undefined`**,\n * e isso não é cosmético. O argumento de modo do `open` é filtrado pelo `umask`,\n * que só LIMPA bits — medido nesta base de código antes da mudança:\n *\n * ```\n * umask 0o002 -> 0o600 umask 0o022 -> 0o600 umask 0o200 -> 0o400\n * ```\n *\n * Um `chmod` incondicional levaria o terceiro caso de `0o400` para `0o600` — uma\n * mudança de disco para todo chamador que não pediu nada, incluindo consumidores\n * externos. Quando o chamador PEDE um modo, porém, deixar o `umask` decidir em\n * silêncio é o defeito que este parâmetro existe para fechar; daí a reafirmação.\n *\n * Ela vai no DESCRITOR, antes do `rename`, nunca depois: dar `chmod` no arquivo\n * final deixaria uma janela em que ele está com o modo do `umask` — o anti-padrão\n * de `opencode/packages/core/src/fs-util.ts:110-114`. A forma escolhida (modo como\n * argumento do `open`) é a de `codex-rs/network-proxy/src/certs.rs:687,783-791`.\n *\n * @internal\n */\nexport async function replaceFileAtomic(\n filePath: string,\n content: string,\n options?: AtomicWriteFileOptions,\n): Promise<void> {\n // T5.8 — warn once per parent directory if it lives on a network /\n // FUSE filesystem where `rename()` atomicity is best-effort. The\n // write proceeds unchanged; the warning is purely informational so\n // operators can spot the case in stderr / log aggregators.\n await warnOnNetworkFsOnce(dirname(filePath), \"atomic-write\");\n // T5.7 — crypto-random tmp suffix (CSPRNG, 64 bits of entropy)\n // replaces the predictable `Math.random().toString(36)` source. An\n // attacker observing the process can no longer predict the next\n // tmp path and pre-stage a hostile file to be renamed into place.\n const suffix = randomBytes(8).toString(\"hex\");\n const tmp = `${filePath}.${process.pid}.${suffix}.tmp`;\n // T5.7 — mode 0o600 on the tmp file (owner read+write only). The\n // tmp file holds the FULL in-flight content (credential snapshots,\n // OAuth tokens) before the rename. World-readable default would\n // expose secrets during the ms-window between open and rename\n // (TOCTOU). On modern Linux the post-rename target inherits the\n // tmp's permission bits, so the final file is also 0o600.\n const handle = await open(tmp, options?.exclusive === true ? \"wx\" : \"w\", options?.mode ?? 0o600);\n try {\n await handle.writeFile(content, \"utf8\");\n await handle.sync();\n // Condicional por medição, não por gosto — ver o docblock desta função.\n if (options?.mode !== undefined) await handle.chmod(options.mode);\n } finally {\n await handle.close();\n }\n try {\n await rename(tmp, filePath);\n } catch (cause) {\n // Cleanup tmp on rename failure so we don't leak stale .tmp files.\n await unlink(tmp).catch(() => undefined);\n throw cause;\n }\n}\n\n/**\n * Options for `atomicWriteJson`.\n *\n * @internal\n */\nexport interface AtomicWriteJsonOptions extends AtomicWriteFileOptions {\n /** Indent passed to `JSON.stringify`. Default: 2. */\n indent?: number;\n /** Whether to append a trailing newline (POSIX convention). Default: true. */\n trailingNewline?: boolean;\n}\n\n/**\n * Typed JSON atomic write helper.\n *\n * Serializes `data` to JSON, then delegates to `replaceFileAtomic`. The\n * parent directory is auto-created (recursive `mkdir`) to make this helper\n * safe for callers who haven't ensured the directory exists (EC-4 in the\n * persistence-state-hardening plan).\n *\n * Throws `TypeError` on circular refs or `undefined` data (propagates from\n * `JSON.stringify`).\n *\n * @internal\n */\nexport async function atomicWriteJson<T>(\n filePath: string,\n data: T,\n options?: AtomicWriteJsonOptions,\n): Promise<void> {\n const indent = options?.indent ?? 2;\n const trailingNewline = options?.trailingNewline ?? true;\n const json = JSON.stringify(data, null, indent);\n if (json === undefined) {\n throw new TypeError(\"atomicWriteJson: cannot serialize undefined\");\n }\n const content = trailingNewline ? `${json}\\n` : json;\n await mkdir(dirname(filePath), { recursive: true });\n await replaceFileAtomic(filePath, content, options);\n}\n\n/**\n * Atomic text write. Same crash-safety guarantees as `replaceFileAtomic` +\n * auto-mkdir of the parent directory. Used by `theokit-migrate-config`\n * (T4.1, EC-2 MUST FIX) so a crash mid-migration leaves previous MD files\n * intact rather than corrupting them.\n *\n * @internal\n */\nexport async function atomicWriteText(filePath: string, content: string): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n await replaceFileAtomic(filePath, content);\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkPAEJPLVN_cjs = require('./chunk-PAEJPLVN.cjs');
|
|
4
|
+
var chunkLTCOPATU_cjs = require('./chunk-LTCOPATU.cjs');
|
|
4
5
|
var fs = require('fs');
|
|
5
6
|
var path = require('path');
|
|
6
7
|
var url = require('url');
|
|
@@ -24,17 +25,15 @@ var REGISTRY = globalSingleton(
|
|
|
24
25
|
var ALIASES = globalSingleton("theokit-sdk.providers.aliases", () => /* @__PURE__ */ new Map());
|
|
25
26
|
function registerProvider(profile) {
|
|
26
27
|
if (REGISTRY.has(profile.name)) {
|
|
27
|
-
|
|
28
|
+
chunkLTCOPATU_cjs.diag(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
|
|
28
29
|
`);
|
|
29
30
|
}
|
|
30
31
|
REGISTRY.set(profile.name, profile);
|
|
31
32
|
for (const alias of profile.aliases ?? []) {
|
|
32
33
|
const previous = ALIASES.get(alias);
|
|
33
34
|
if (previous !== void 0 && previous !== profile.name) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
`
|
|
37
|
-
);
|
|
35
|
+
chunkLTCOPATU_cjs.diag(`[theokit-sdk] Alias "${alias}" collision: was "${previous}", now "${profile.name}".
|
|
36
|
+
`);
|
|
38
37
|
}
|
|
39
38
|
ALIASES.set(alias, profile.name);
|
|
40
39
|
}
|
|
@@ -81,7 +80,7 @@ var catalogModelSchema = zod.z.object({
|
|
|
81
80
|
}).loose();
|
|
82
81
|
|
|
83
82
|
// src/internal/providers/catalog-loader.ts
|
|
84
|
-
var __dirname_resolved = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
83
|
+
var __dirname_resolved = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-56ZM6P7Z.cjs', document.baseURI).href))));
|
|
85
84
|
var modelInfoIndex = globalSingleton(
|
|
86
85
|
"theokit-sdk.providers.model-info-index",
|
|
87
86
|
() => /* @__PURE__ */ new Map()
|
|
@@ -115,7 +114,7 @@ function ensureModelIndexLoaded() {
|
|
|
115
114
|
indexEntryModels(entry);
|
|
116
115
|
}
|
|
117
116
|
} catch (err) {
|
|
118
|
-
|
|
117
|
+
chunkLTCOPATU_cjs.diag(
|
|
119
118
|
`[theokit-sdk] WARN: provider catalog unavailable (${err.message}) \u2014 per-model data disabled
|
|
120
119
|
`
|
|
121
120
|
);
|
|
@@ -126,7 +125,7 @@ function indexEntryModels(entry) {
|
|
|
126
125
|
for (const [modelId, raw] of Object.entries(entry.models)) {
|
|
127
126
|
const parsed = catalogModelSchema.safeParse(raw);
|
|
128
127
|
if (!parsed.success) {
|
|
129
|
-
|
|
128
|
+
chunkLTCOPATU_cjs.diag(
|
|
130
129
|
`[theokit-sdk] WARN: Skipping malformed catalog model "${entry.id}/${modelId}": ${parsed.error.issues[0]?.message ?? "invalid"}
|
|
131
130
|
`
|
|
132
131
|
);
|
|
@@ -159,7 +158,7 @@ function loadProviderCatalog(opts) {
|
|
|
159
158
|
for (const raw of entries) {
|
|
160
159
|
const validated = validateEntry(raw);
|
|
161
160
|
if (validated === null) {
|
|
162
|
-
|
|
161
|
+
chunkLTCOPATU_cjs.diag(
|
|
163
162
|
`[theokit-sdk] WARN: Skipping malformed catalog entry: ${JSON.stringify(raw).slice(0, 100)}
|
|
164
163
|
`
|
|
165
164
|
);
|
|
@@ -397,7 +396,7 @@ var OPENAI_OAUTH_CONFIG = {
|
|
|
397
396
|
function codexFetch() {
|
|
398
397
|
return (async (input, init) => {
|
|
399
398
|
const env = process.env;
|
|
400
|
-
const resolved = await
|
|
399
|
+
const resolved = await chunkPAEJPLVN_cjs.resolveCredential({
|
|
401
400
|
provider: "openai",
|
|
402
401
|
store: DEFAULT_STORE,
|
|
403
402
|
oauth: OPENAI_OAUTH_CONFIG,
|
|
@@ -408,7 +407,7 @@ function codexFetch() {
|
|
|
408
407
|
'openai-chatgpt: no ChatGPT credential found \u2014 run the OpenAI device login (e.g. "/login openai") first.'
|
|
409
408
|
);
|
|
410
409
|
}
|
|
411
|
-
const accountId =
|
|
410
|
+
const accountId = chunkPAEJPLVN_cjs.readStoredOAuth(DEFAULT_STORE, env)?.account_id;
|
|
412
411
|
const headers = new Headers(init?.headers);
|
|
413
412
|
headers.set("authorization", `Bearer ${resolved.apiKey}`);
|
|
414
413
|
if (accountId !== void 0) headers.set("ChatGPT-Account-Id", accountId);
|
|
@@ -561,5 +560,5 @@ exports.resolveBedrockBaseUrl = resolveBedrockBaseUrl;
|
|
|
561
560
|
exports.resolveVertexBaseUrl = resolveVertexBaseUrl;
|
|
562
561
|
exports.stripBedrockPrefix = stripBedrockPrefix;
|
|
563
562
|
exports.stripVertexPrefix = stripVertexPrefix;
|
|
564
|
-
//# sourceMappingURL=chunk-
|
|
565
|
-
//# sourceMappingURL=chunk-
|
|
563
|
+
//# sourceMappingURL=chunk-56ZM6P7Z.cjs.map
|
|
564
|
+
//# sourceMappingURL=chunk-56ZM6P7Z.cjs.map
|