@poetic-ai/poetic 1.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/SECURITY.md +47 -0
- package/.nvmrc +1 -0
- package/.poetic/README.md +37 -0
- package/.poetic/providers/catalog.json +12051 -0
- package/.poetic/providers/pricing.json +1272 -0
- package/.poetic/providers/registry.json +3369 -0
- package/CHANGELOG.md +552 -0
- package/CODE_OF_CONDUCT.md +40 -0
- package/CONTRIBUTING.md +23 -0
- package/INSTALL.md +454 -0
- package/LICENSE +21 -0
- package/README.md +474 -0
- package/dist/BasicOptimizationCompetitionRunner-5H5TBYO4.js +153 -0
- package/dist/ExecutionTracker-UVONC4C6.js +16 -0
- package/dist/OptimizationConfig-7DFY2TST.js +17 -0
- package/dist/OptimizationEngine-JIMGP3LY.js +1597 -0
- package/dist/PromptStore-U6ZD3ZMQ.js +18 -0
- package/dist/actions-LUJPINLJ.js +322 -0
- package/dist/agent-ingest-3DJUJ7FU.js +53 -0
- package/dist/aggregator-DNCBINFO.js +12 -0
- package/dist/ai-judge-5QT5QJVU.js +156 -0
- package/dist/allowlist-grounding-RO6HKUFI.js +16 -0
- package/dist/allowlist-utils-23V7TJ3G.js +28 -0
- package/dist/anchored-turn-service-JULUCUIK.js +489 -0
- package/dist/api-transport-4TYTNLTJ.js +1087 -0
- package/dist/apply-completion-mode-AW2MOS3R.js +89 -0
- package/dist/artifact-migrator-23L45ISD.js +267 -0
- package/dist/ask-HWVV6QFR.js +135 -0
- package/dist/auth-5KEDKAPP.js +67 -0
- package/dist/auth-7TT3JINV.js +78 -0
- package/dist/auth-E6XUNZ5M.js +68 -0
- package/dist/auth-H3XDZE22.js +134 -0
- package/dist/auth-OC4E6633.js +71 -0
- package/dist/auth-S4CTX4GQ.js +44 -0
- package/dist/auth-YLH3S7EY.js +69 -0
- package/dist/auth-liveness-TDDEZY3T.js +46 -0
- package/dist/auto-optimizer-VPRWOWGU.js +80 -0
- package/dist/autoloop-cleanup-JOGKTLWA.js +109 -0
- package/dist/autoloop-evidence-gates-PCDALGVJ.js +38 -0
- package/dist/autoloop-gate-policy-Z7FVJVXV.js +175 -0
- package/dist/autoloop-helpers-2KTK43GL.js +22 -0
- package/dist/autoloop-ledger-W7QO62PX.js +96 -0
- package/dist/autoloop-ledger-subscriber-Z5RW5EIE.js +162 -0
- package/dist/autoloop-run-defaults-FERGRZGP.js +19 -0
- package/dist/autoloop-run-lock-CT2NWSV3.js +197 -0
- package/dist/autoloop-success-J2VKKBXQ.js +85 -0
- package/dist/autoloop-termination-summary-RN75F422.js +58 -0
- package/dist/autoloop-trajectory-XFIEXP5Z.js +282 -0
- package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
- package/dist/autonomous-loop-controller-PW4XVFGQ.js +4120 -0
- package/dist/backend-P3DAYRP7.js +29 -0
- package/dist/background-executor-CBN552V4.js +257 -0
- package/dist/backlog-execution-intent-U4XYPTV6.js +15 -0
- package/dist/backup-active-store-5WXG6SXT.js +17 -0
- package/dist/backup-telemetry-db-XGLXAA3N.js +254 -0
- package/dist/basic-competition-master-VCSBJVRN.js +344 -0
- package/dist/branch-archive-manager-RP6FP3ZC.js +254 -0
- package/dist/branch-cleanup-manager-RSHAI7YR.js +20 -0
- package/dist/build-gate-YHGRB4QB.js +71 -0
- package/dist/change-summary-WY7J5TOX.js +33 -0
- package/dist/chunk-23A26CSN.js +123 -0
- package/dist/chunk-27UTJD3M.js +265 -0
- package/dist/chunk-2A5CILN3.js +310 -0
- package/dist/chunk-2AQUWJPW.js +225 -0
- package/dist/chunk-2BZ53J6J.js +2344 -0
- package/dist/chunk-2DY5KNVM.js +276 -0
- package/dist/chunk-2EIA4RBE.js +659 -0
- package/dist/chunk-2IUXIGQD.js +1064 -0
- package/dist/chunk-2N42MS2Z.js +2193 -0
- package/dist/chunk-2QJ3H3L7.js +42 -0
- package/dist/chunk-2QLYTVYX.js +791 -0
- package/dist/chunk-2VSQMRCB.js +18 -0
- package/dist/chunk-2XQXYBM2.js +130 -0
- package/dist/chunk-2YFUIER7.js +426 -0
- package/dist/chunk-34CNP2HB.js +148 -0
- package/dist/chunk-35P3W3JX.js +456 -0
- package/dist/chunk-36PEBZAF.js +18 -0
- package/dist/chunk-3AOKYKA7.js +22 -0
- package/dist/chunk-3BCUNHKF.js +475 -0
- package/dist/chunk-3FLXLLB7.js +26 -0
- package/dist/chunk-3FOZ2VHV.js +100 -0
- package/dist/chunk-3G6FZCRF.js +106 -0
- package/dist/chunk-3M57DADF.js +44 -0
- package/dist/chunk-3S62LLWJ.js +543 -0
- package/dist/chunk-3ZPQLGV7.js +2904 -0
- package/dist/chunk-44N5WZZH.js +45 -0
- package/dist/chunk-45FPSA3B.js +125 -0
- package/dist/chunk-4BJ3O4RQ.js +929 -0
- package/dist/chunk-4BOP7T6L.js +2321 -0
- package/dist/chunk-4BTDUT2S.js +42 -0
- package/dist/chunk-4CSS7WVI.js +143 -0
- package/dist/chunk-4CUY7AFY.js +247 -0
- package/dist/chunk-4GSN5O5J.js +62 -0
- package/dist/chunk-4HN6DF7V.js +1027 -0
- package/dist/chunk-4IAPOG5V.js +415 -0
- package/dist/chunk-4IYIZQWV.js +48 -0
- package/dist/chunk-4NXPXE62.js +84 -0
- package/dist/chunk-4RCCF5BR.js +712 -0
- package/dist/chunk-4V7NAQ4R.js +19527 -0
- package/dist/chunk-4VJITV4P.js +445 -0
- package/dist/chunk-4YX7J6QL.js +1859 -0
- package/dist/chunk-527OBWQB.js +338 -0
- package/dist/chunk-5D4A7E3D.js +448 -0
- package/dist/chunk-5DLKYTQX.js +4003 -0
- package/dist/chunk-5EERLVZB.js +139 -0
- package/dist/chunk-5H72XE4H.js +256 -0
- package/dist/chunk-5HDP7XZG.js +91 -0
- package/dist/chunk-5LAMRH4X.js +969 -0
- package/dist/chunk-5LTN43AS.js +1972 -0
- package/dist/chunk-5RBHQYDB.js +2206 -0
- package/dist/chunk-5WCQRDRB.js +588 -0
- package/dist/chunk-5WRLK5KW.js +700 -0
- package/dist/chunk-5ZCXC23G.js +595 -0
- package/dist/chunk-6BM72ZMG.js +31 -0
- package/dist/chunk-6EDAJH2I.js +68 -0
- package/dist/chunk-6EQKFDBH.js +457 -0
- package/dist/chunk-6MFRHTRI.js +115 -0
- package/dist/chunk-6TZJRKNW.js +321 -0
- package/dist/chunk-6V7HGQFZ.js +20 -0
- package/dist/chunk-6VWVO2TU.js +3746 -0
- package/dist/chunk-6Y5TWI7H.js +146 -0
- package/dist/chunk-6Y5U7UFY.js +91 -0
- package/dist/chunk-6ZLAK3XG.js +14 -0
- package/dist/chunk-72XCRQED.js +34 -0
- package/dist/chunk-72YTZMAM.js +589 -0
- package/dist/chunk-73BBJOKA.js +263 -0
- package/dist/chunk-73NCTWKL.js +188 -0
- package/dist/chunk-77I6G4CO.js +1 -0
- package/dist/chunk-7DHRDWFS.js +3104 -0
- package/dist/chunk-7DNSNKJV.js +78 -0
- package/dist/chunk-7FMJVYBS.js +307 -0
- package/dist/chunk-7GDRQBQC.js +419 -0
- package/dist/chunk-7GPCEFUV.js +270 -0
- package/dist/chunk-7IL4A2PP.js +948 -0
- package/dist/chunk-7MMLMXO6.js +3679 -0
- package/dist/chunk-7QCZSLBH.js +1 -0
- package/dist/chunk-7R2WLDOS.js +62 -0
- package/dist/chunk-7T7RUJI7.js +949 -0
- package/dist/chunk-A2WKSVX7.js +43 -0
- package/dist/chunk-A3YGID55.js +133 -0
- package/dist/chunk-A722DEVA.js +14 -0
- package/dist/chunk-ACDIT7OP.js +1376 -0
- package/dist/chunk-ACKIPAOJ.js +302 -0
- package/dist/chunk-APPNGGN7.js +365 -0
- package/dist/chunk-APV6MK5E.js +137 -0
- package/dist/chunk-ASEP3M2W.js +968 -0
- package/dist/chunk-AT4TNPWW.js +2931 -0
- package/dist/chunk-ATVKCSGT.js +250 -0
- package/dist/chunk-AURFMVCD.js +899 -0
- package/dist/chunk-AX6GWE7V.js +47 -0
- package/dist/chunk-AY5EWJPF.js +385 -0
- package/dist/chunk-BAV2HJXS.js +194 -0
- package/dist/chunk-BBHRN366.js +89 -0
- package/dist/chunk-BBPSTTPA.js +1004 -0
- package/dist/chunk-BDATUDDJ.js +992 -0
- package/dist/chunk-BKE5PG5L.js +20414 -0
- package/dist/chunk-BLPHWMDK.js +797 -0
- package/dist/chunk-BSE4R6XD.js +322 -0
- package/dist/chunk-BXGMAU4A.js +396 -0
- package/dist/chunk-BXI4NXL3.js +507 -0
- package/dist/chunk-BZU2O43F.js +1125 -0
- package/dist/chunk-C3L6YQ7P.js +147 -0
- package/dist/chunk-C57KJOUQ.js +121 -0
- package/dist/chunk-CCV7BPSY.js +118 -0
- package/dist/chunk-CD7ISXA4.js +826 -0
- package/dist/chunk-CE5OZBYY.js +21 -0
- package/dist/chunk-CFBIG37O.js +154 -0
- package/dist/chunk-CJC6GZ46.js +457 -0
- package/dist/chunk-CKCDGXIV.js +408 -0
- package/dist/chunk-CKNX3TTP.js +10338 -0
- package/dist/chunk-CLKSETWE.js +10 -0
- package/dist/chunk-CP7H3HSP.js +1552 -0
- package/dist/chunk-CPLEWXNZ.js +66 -0
- package/dist/chunk-CQM3A35X.js +844 -0
- package/dist/chunk-CS6P76D3.js +103 -0
- package/dist/chunk-CTLUBNCW.js +622 -0
- package/dist/chunk-CUSRN6RJ.js +632 -0
- package/dist/chunk-D5EP5D2W.js +26 -0
- package/dist/chunk-D5RYINO7.js +412 -0
- package/dist/chunk-DBFS4HMH.js +751 -0
- package/dist/chunk-DC4ZYMXJ.js +115 -0
- package/dist/chunk-DCBZP442.js +9243 -0
- package/dist/chunk-DCYF7EKG.js +26 -0
- package/dist/chunk-DDMAFNUK.js +5351 -0
- package/dist/chunk-DF5SLDE4.js +966 -0
- package/dist/chunk-DJFW7SMX.js +348 -0
- package/dist/chunk-DQFLLBJW.js +121 -0
- package/dist/chunk-DSFM56OA.js +1203 -0
- package/dist/chunk-DTY4APYV.js +218 -0
- package/dist/chunk-DXH5JBRS.js +437 -0
- package/dist/chunk-E3NTPHEO.js +194 -0
- package/dist/chunk-E74LUIID.js +302 -0
- package/dist/chunk-EI57M5BI.js +194 -0
- package/dist/chunk-EJ4ZAWLV.js +305 -0
- package/dist/chunk-EJGCZGUF.js +1483 -0
- package/dist/chunk-EK2U3YEG.js +486 -0
- package/dist/chunk-ELMFYNV7.js +109 -0
- package/dist/chunk-ENRGKNR5.js +25 -0
- package/dist/chunk-ETYDXCK7.js +679 -0
- package/dist/chunk-EYRH3W74.js +239 -0
- package/dist/chunk-F23DIWNN.js +1024 -0
- package/dist/chunk-F5JO7HAS.js +94 -0
- package/dist/chunk-F7ER6ANO.js +174 -0
- package/dist/chunk-FATUVIIN.js +374 -0
- package/dist/chunk-FC23CTXV.js +322 -0
- package/dist/chunk-FD4ERYEG.js +22 -0
- package/dist/chunk-FH7WOJAE.js +79 -0
- package/dist/chunk-FHOWVDF5.js +1342 -0
- package/dist/chunk-FKAUPHMR.js +96 -0
- package/dist/chunk-FONNFJXA.js +137 -0
- package/dist/chunk-FQ7FSZRW.js +75 -0
- package/dist/chunk-FRG57FPM.js +240 -0
- package/dist/chunk-FUVP64ER.js +31 -0
- package/dist/chunk-FYOILAN5.js +6818 -0
- package/dist/chunk-G35UYQ6Z.js +69 -0
- package/dist/chunk-G36W2T2S.js +1143 -0
- package/dist/chunk-G3L2L5XZ.js +49 -0
- package/dist/chunk-G4THLFV3.js +148 -0
- package/dist/chunk-GAFJEYLK.js +29 -0
- package/dist/chunk-GFGYB2ZU.js +1689 -0
- package/dist/chunk-GG6KJYW6.js +85 -0
- package/dist/chunk-GHHFDU2U.js +55 -0
- package/dist/chunk-GHTZSQB7.js +57 -0
- package/dist/chunk-GK37ILCX.js +1231 -0
- package/dist/chunk-GKN3HMN4.js +2809 -0
- package/dist/chunk-GNVDBVJP.js +156 -0
- package/dist/chunk-GPEL3FBM.js +924 -0
- package/dist/chunk-GPSNGPZS.js +1604 -0
- package/dist/chunk-GSGD5E4C.js +30 -0
- package/dist/chunk-GSUQJJXQ.js +331 -0
- package/dist/chunk-GSV226X6.js +110 -0
- package/dist/chunk-H2AYQIHW.js +224 -0
- package/dist/chunk-H66DXFS5.js +1374 -0
- package/dist/chunk-H6G7QRMQ.js +35 -0
- package/dist/chunk-H7JAGHZT.js +59 -0
- package/dist/chunk-H7ZEFECA.js +316 -0
- package/dist/chunk-HAC6EHZZ.js +79 -0
- package/dist/chunk-HIO33P3G.js +19 -0
- package/dist/chunk-HMVQIPH3.js +547 -0
- package/dist/chunk-HOYBYAOA.js +257 -0
- package/dist/chunk-HX5P3CSP.js +1784 -0
- package/dist/chunk-I46EG2XQ.js +65 -0
- package/dist/chunk-I4NPDSCB.js +279 -0
- package/dist/chunk-I5WRT7ZR.js +514 -0
- package/dist/chunk-IC7I6YIJ.js +301 -0
- package/dist/chunk-IDCSOZVN.js +78 -0
- package/dist/chunk-IFCBYECK.js +112 -0
- package/dist/chunk-IFZCPEY2.js +66 -0
- package/dist/chunk-IKFP2KUR.js +48 -0
- package/dist/chunk-IRFBN336.js +878 -0
- package/dist/chunk-IUXNGKA6.js +152 -0
- package/dist/chunk-IV2RVAN7.js +1356 -0
- package/dist/chunk-IZYIQQ7X.js +53 -0
- package/dist/chunk-J3UUR7DE.js +210 -0
- package/dist/chunk-J54VUAY2.js +566 -0
- package/dist/chunk-J62KPGII.js +464 -0
- package/dist/chunk-J6P3FWWW.js +130 -0
- package/dist/chunk-JKBHJQMT.js +434 -0
- package/dist/chunk-JLS65NUQ.js +14 -0
- package/dist/chunk-JOSYEJKY.js +141 -0
- package/dist/chunk-JPKSXKNB.js +94 -0
- package/dist/chunk-JQNJB2BB.js +2440 -0
- package/dist/chunk-JRVNSWSQ.js +2626 -0
- package/dist/chunk-JSWMRQYG.js +28 -0
- package/dist/chunk-JZKNBBIB.js +152 -0
- package/dist/chunk-K54Y7MLK.js +160 -0
- package/dist/chunk-K65546RE.js +183 -0
- package/dist/chunk-KM3F7SYE.js +702 -0
- package/dist/chunk-KNDYMVWN.js +102 -0
- package/dist/chunk-KNT72VR6.js +132 -0
- package/dist/chunk-KP6YILMU.js +482 -0
- package/dist/chunk-KQEBSK3T.js +274 -0
- package/dist/chunk-KT6VHSPF.js +84 -0
- package/dist/chunk-KTMW65UX.js +14 -0
- package/dist/chunk-KZ5CJVBP.js +1813 -0
- package/dist/chunk-L4427KOE.js +26 -0
- package/dist/chunk-L6OM4A22.js +189 -0
- package/dist/chunk-L7E6XCRA.js +1042 -0
- package/dist/chunk-L7JZLXQL.js +173 -0
- package/dist/chunk-LAMKBTXX.js +40 -0
- package/dist/chunk-LDCF2MKN.js +132 -0
- package/dist/chunk-LEIIWPWQ.js +78 -0
- package/dist/chunk-LFTQVYBB.js +31 -0
- package/dist/chunk-LG3PDRTR.js +2872 -0
- package/dist/chunk-LGHII5ET.js +23 -0
- package/dist/chunk-LH5QY22X.js +1205 -0
- package/dist/chunk-LIVJ6266.js +438 -0
- package/dist/chunk-LKRAR3IH.js +276 -0
- package/dist/chunk-LO23NABI.js +3063 -0
- package/dist/chunk-LO3X5NLS.js +326 -0
- package/dist/chunk-LPITVM7M.js +339 -0
- package/dist/chunk-LR5IJIGV.js +810 -0
- package/dist/chunk-LRGMHROI.js +79 -0
- package/dist/chunk-LUVKFFWR.js +315 -0
- package/dist/chunk-LWCBNGH6.js +35 -0
- package/dist/chunk-LWTN3WRV.js +260 -0
- package/dist/chunk-M3HQYKQX.js +308 -0
- package/dist/chunk-M6GVSPEH.js +1016 -0
- package/dist/chunk-MF5HP6XV.js +221 -0
- package/dist/chunk-MHLCBZJB.js +328 -0
- package/dist/chunk-MN6PL4AN.js +120 -0
- package/dist/chunk-MOEY65Z6.js +5678 -0
- package/dist/chunk-MQ4WA34C.js +206 -0
- package/dist/chunk-MWHF5V7U.js +223 -0
- package/dist/chunk-MWHLBPNU.js +211 -0
- package/dist/chunk-MWK5UZQ3.js +1068 -0
- package/dist/chunk-MYLH2S4G.js +64 -0
- package/dist/chunk-MZ5WYKNA.js +28 -0
- package/dist/chunk-N4VTRA7K.js +131 -0
- package/dist/chunk-N5DX4JAK.js +12 -0
- package/dist/chunk-N65O4XTH.js +5011 -0
- package/dist/chunk-NEQUQHOX.js +223 -0
- package/dist/chunk-NGK6PEOG.js +25 -0
- package/dist/chunk-NJVD4PWE.js +1033 -0
- package/dist/chunk-NM6PMYY4.js +768 -0
- package/dist/chunk-NN4PJDHP.js +708 -0
- package/dist/chunk-NP2V3L7K.js +226 -0
- package/dist/chunk-NRLY536M.js +260 -0
- package/dist/chunk-NRNE225N.js +1270 -0
- package/dist/chunk-NS2K2GTP.js +605 -0
- package/dist/chunk-NS33V3IM.js +51 -0
- package/dist/chunk-NSHASMZZ.js +71 -0
- package/dist/chunk-NWOYOA6H.js +378 -0
- package/dist/chunk-NWRUSEXG.js +322 -0
- package/dist/chunk-NZGDAWIP.js +1905 -0
- package/dist/chunk-O47UOKU3.js +395 -0
- package/dist/chunk-O4G2W3ST.js +9831 -0
- package/dist/chunk-O6V4PNLO.js +63 -0
- package/dist/chunk-OA4GPILI.js +624 -0
- package/dist/chunk-OGMSYL6J.js +227 -0
- package/dist/chunk-OIS7J26S.js +319 -0
- package/dist/chunk-OMX5VL43.js +79 -0
- package/dist/chunk-ON3G73BU.js +264 -0
- package/dist/chunk-OPYFYTWQ.js +220 -0
- package/dist/chunk-OQ6K46CK.js +1734 -0
- package/dist/chunk-OYZYO7TV.js +47 -0
- package/dist/chunk-OZ4REHIN.js +4386 -0
- package/dist/chunk-P47VN5F4.js +282 -0
- package/dist/chunk-P5I4X7A7.js +353 -0
- package/dist/chunk-P6VQROCO.js +594 -0
- package/dist/chunk-P7CQGPLS.js +30 -0
- package/dist/chunk-PCAGC5MR.js +1763 -0
- package/dist/chunk-PFTQBXS6.js +5181 -0
- package/dist/chunk-PGSPX4SU.js +15 -0
- package/dist/chunk-PIKLF7BM.js +432 -0
- package/dist/chunk-PJWJ3SAV.js +22 -0
- package/dist/chunk-PKIFMV72.js +100 -0
- package/dist/chunk-PL37JDNA.js +189 -0
- package/dist/chunk-PTH5E5XO.js +195 -0
- package/dist/chunk-PW6AXLQC.js +4128 -0
- package/dist/chunk-PYITM4N2.js +79 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-Q3RO7N35.js +45 -0
- package/dist/chunk-Q3WIC6GQ.js +2670 -0
- package/dist/chunk-Q5XIXSHX.js +271 -0
- package/dist/chunk-QGJDMEOV.js +34 -0
- package/dist/chunk-QNOB37UH.js +58 -0
- package/dist/chunk-QOCOVLUH.js +462 -0
- package/dist/chunk-QTCJ5CC5.js +172 -0
- package/dist/chunk-QVFV5IP2.js +232 -0
- package/dist/chunk-QVZMFDYG.js +29 -0
- package/dist/chunk-R35PEUKH.js +511 -0
- package/dist/chunk-R4UWBC35.js +200 -0
- package/dist/chunk-R6MLCREW.js +44 -0
- package/dist/chunk-R6W23LKN.js +254 -0
- package/dist/chunk-R7XDDX2A.js +4007 -0
- package/dist/chunk-RDFRCT64.js +168 -0
- package/dist/chunk-RE5VZDFQ.js +58 -0
- package/dist/chunk-RGROYC2G.js +638 -0
- package/dist/chunk-RGWHUI5E.js +68 -0
- package/dist/chunk-RHVG6UNL.js +205 -0
- package/dist/chunk-RI4EX2QE.js +18 -0
- package/dist/chunk-RJAAKDRX.js +17 -0
- package/dist/chunk-ROMHOSMQ.js +185 -0
- package/dist/chunk-RWREC3KJ.js +517 -0
- package/dist/chunk-RYNETRDJ.js +118 -0
- package/dist/chunk-RZY7RKM5.js +500 -0
- package/dist/chunk-S2MNWFAG.js +52 -0
- package/dist/chunk-S2VQCZO4.js +22 -0
- package/dist/chunk-S54MKU6V.js +117 -0
- package/dist/chunk-S5OIDFRM.js +302 -0
- package/dist/chunk-SCW4ZF6R.js +150 -0
- package/dist/chunk-SLS2N4PH.js +2213 -0
- package/dist/chunk-SNLBO4BF.js +247 -0
- package/dist/chunk-SP3LFU6B.js +60 -0
- package/dist/chunk-SQQTDDQA.js +537 -0
- package/dist/chunk-STV6LYYE.js +45 -0
- package/dist/chunk-SURZ2WFE.js +326 -0
- package/dist/chunk-SZ7DL357.js +1047 -0
- package/dist/chunk-T5E4NQCM.js +5742 -0
- package/dist/chunk-TAJPCXSB.js +13 -0
- package/dist/chunk-TAOOYK3P.js +358 -0
- package/dist/chunk-TDSEX5CF.js +24 -0
- package/dist/chunk-TFTGP7Z7.js +174 -0
- package/dist/chunk-TGON4N4O.js +197 -0
- package/dist/chunk-TGQZHDY2.js +2373 -0
- package/dist/chunk-TJJZ2OKV.js +6783 -0
- package/dist/chunk-TRSVUPCX.js +25 -0
- package/dist/chunk-TSXGRLPR.js +107 -0
- package/dist/chunk-U2S3YEX3.js +224 -0
- package/dist/chunk-U45RTRGY.js +818 -0
- package/dist/chunk-U6C3VVWS.js +13 -0
- package/dist/chunk-UDMS5AD3.js +307 -0
- package/dist/chunk-UGX7GI37.js +94 -0
- package/dist/chunk-UH3JJSHK.js +1 -0
- package/dist/chunk-UHRBTZYY.js +208 -0
- package/dist/chunk-UHT2KRG5.js +193 -0
- package/dist/chunk-UI2F6DJ5.js +118 -0
- package/dist/chunk-UMAKSB4Z.js +284 -0
- package/dist/chunk-UR2IBGIM.js +521 -0
- package/dist/chunk-UUH2RVKS.js +585 -0
- package/dist/chunk-UVJ4PJDK.js +4533 -0
- package/dist/chunk-V53UG2OT.js +9924 -0
- package/dist/chunk-V72RMBM4.js +48 -0
- package/dist/chunk-VBNCKCCI.js +16 -0
- package/dist/chunk-VNSYKC25.js +24 -0
- package/dist/chunk-VPHVFK4A.js +1984 -0
- package/dist/chunk-VTLNJQ44.js +133 -0
- package/dist/chunk-VTW7HP3R.js +100 -0
- package/dist/chunk-VVGEPBPS.js +218 -0
- package/dist/chunk-VVLLL7I4.js +166 -0
- package/dist/chunk-VX3UMWB7.js +483 -0
- package/dist/chunk-VXF4Q3FW.js +20 -0
- package/dist/chunk-W3JMT2YY.js +712 -0
- package/dist/chunk-WDUORIHF.js +877 -0
- package/dist/chunk-WDVTY4U6.js +148 -0
- package/dist/chunk-WIFZCHEG.js +12566 -0
- package/dist/chunk-WIRN3F75.js +736 -0
- package/dist/chunk-WMPU2UOV.js +82 -0
- package/dist/chunk-WTOKKE2V.js +784 -0
- package/dist/chunk-WX5IRLF6.js +740 -0
- package/dist/chunk-WZ6U3O7I.js +1581 -0
- package/dist/chunk-XAONGNST.js +57 -0
- package/dist/chunk-XB5YLCLB.js +13 -0
- package/dist/chunk-XEP5NQ5Y.js +688 -0
- package/dist/chunk-XGYF2QMZ.js +351 -0
- package/dist/chunk-XHEKQENB.js +255 -0
- package/dist/chunk-XNO4FM6X.js +1124 -0
- package/dist/chunk-XPHKYHO4.js +878 -0
- package/dist/chunk-XPK2I4NC.js +405 -0
- package/dist/chunk-XPU2XADL.js +2175 -0
- package/dist/chunk-XQD2B6BB.js +507 -0
- package/dist/chunk-XT2ZQVTC.js +558 -0
- package/dist/chunk-XTXJGGUV.js +351 -0
- package/dist/chunk-XUXVDPSZ.js +50 -0
- package/dist/chunk-XV7NZL4B.js +57 -0
- package/dist/chunk-XZE4XARH.js +563 -0
- package/dist/chunk-XZYR5EDO.js +152 -0
- package/dist/chunk-Y3J4JMTU.js +61 -0
- package/dist/chunk-Y55LZN5U.js +52 -0
- package/dist/chunk-Y5VN7DMP.js +112 -0
- package/dist/chunk-Y67VAHN4.js +459 -0
- package/dist/chunk-YAXSKEUH.js +3544 -0
- package/dist/chunk-YB3JD4E6.js +975 -0
- package/dist/chunk-YESZJFK6.js +220 -0
- package/dist/chunk-YGXKOBQQ.js +292 -0
- package/dist/chunk-YMX76IOS.js +31 -0
- package/dist/chunk-YOTXESEH.js +257 -0
- package/dist/chunk-YTYIEZQY.js +119 -0
- package/dist/chunk-YVORHQ2S.js +579 -0
- package/dist/chunk-Z2CUQDAR.js +3429 -0
- package/dist/chunk-Z2KYOFHS.js +7000 -0
- package/dist/chunk-Z6PC7QX6.js +161 -0
- package/dist/chunk-ZDTGECTN.js +235 -0
- package/dist/chunk-ZIPWI2LY.js +151 -0
- package/dist/chunk-ZSKKMTQJ.js +554 -0
- package/dist/chunk-ZTT5IVPY.js +1160 -0
- package/dist/chunk-ZX65UI5W.js +78 -0
- package/dist/chunk-ZYG7GGKO.js +218 -0
- package/dist/chunk-ZZZUL4OF.js +38 -0
- package/dist/cli-utils-IXL26KJT.js +40 -0
- package/dist/cli-validation-WLXWLUJL.js +111 -0
- package/dist/commit-utils-P7CRJF5N.js +202 -0
- package/dist/compete-config-resolver-R5ULXMYH.js +76 -0
- package/dist/compete-request-62JESVET.js +364 -0
- package/dist/compete-results-QEPG6FZX.js +208 -0
- package/dist/competition-outcome-tracker-R32OOZ43.js +38 -0
- package/dist/config-JCOKXOQT.js +166 -0
- package/dist/config-audit-EL3GHXS7.js +360 -0
- package/dist/config-explain-TNILDEVJ.js +12 -0
- package/dist/config-loader-VPFPFO4B.js +38 -0
- package/dist/config-manager-7T4E2BQO.js +67 -0
- package/dist/config-validator-KKOHOW7O.js +72 -0
- package/dist/cost-YC42XUF3.js +53 -0
- package/dist/coverage-orchestrator-CISNKJC2.js +772 -0
- package/dist/coverage-scanner-YVD62MLH.js +12 -0
- package/dist/createCompetitionRunner-LJG6ZQSO.js +46 -0
- package/dist/data-migration-state-VJK64DLT.js +31 -0
- package/dist/db-migrator-XSEIOGWY.js +34 -0
- package/dist/discovery-JGYGDD25.js +25 -0
- package/dist/doctor-GJOYE7AE.js +186 -0
- package/dist/domain-analyzer-AWF3RP6E.js +29 -0
- package/dist/ensure-initialized-744DIZEZ.js +52 -0
- package/dist/entry.js +940 -0
- package/dist/environment-YS45U5ZI.js +81 -0
- package/dist/error-parser-core-PPZ36A4S.js +50 -0
- package/dist/escalation-ladder-MKTCEGSA.js +130 -0
- package/dist/evaluation-context-KV4GZNN7.js +35 -0
- package/dist/evidence-plan-resolver-GBSYSAPX.js +85 -0
- package/dist/execution-data-writer-3ODTBDLH.js +53 -0
- package/dist/execution-policy-applier-ZHD3DCF3.js +31 -0
- package/dist/execution-preflight-Z4Y64V3I.js +209 -0
- package/dist/execution-roles-R3DPPMD3.js +66 -0
- package/dist/exit-code-error-Z4SW2DVK.js +14 -0
- package/dist/external-temp-cleanup-N2RZH4QP.js +311 -0
- package/dist/factory-XBN7DFIM.js +149 -0
- package/dist/file-utils-XIVR2ZMA.js +47 -0
- package/dist/flywheel-autoloop-executor-UILGOFFK.js +249 -0
- package/dist/flywheel-competition-executor-JOBEXTRB.js +259 -0
- package/dist/flywheel-executor-6JFLA6J5.js +369 -0
- package/dist/flywheel-git-isolation-UC5NIEVU.js +48 -0
- package/dist/flywheel-manifest-5UC4VBMA.js +108 -0
- package/dist/flywheel-model-defaults-7CVKP53V.js +27 -0
- package/dist/flywheel-preflight-XEY5SHM6.js +104 -0
- package/dist/flywheel-resume-7HELH7QS.js +23 -0
- package/dist/flywheel-safety-7U7DPOAP.js +28 -0
- package/dist/flywheel-scope-decision-ZHKF6ZIN.js +11 -0
- package/dist/get-telemetry-logger-DPVWWIYY.js +73 -0
- package/dist/git-worktree-IY6V6DUO.js +18 -0
- package/dist/github-pr-manager-4LXEKJTA.js +211 -0
- package/dist/guidance-profile-config-E7XJL2VP.js +117 -0
- package/dist/guidance-profile-renderer-QK2YMAAP.js +21 -0
- package/dist/index-query-4JEUKA44.js +31 -0
- package/dist/index.js +108661 -0
- package/dist/instructions-6BURLQJC.js +64 -0
- package/dist/invoke-provider-auth-GRUYP44M.js +223 -0
- package/dist/judge-scoring.json +80 -0
- package/dist/judge-test.js +555 -0
- package/dist/lab-mode-OTWVHN63.js +39 -0
- package/dist/lab-utils-BJRFLGK4.js +23 -0
- package/dist/linux-host-class-UY4KVLFD.js +29 -0
- package/dist/llm-judge-executor-F7Z3HO77.js +133 -0
- package/dist/local-executor-CEHWE2PL.js +223 -0
- package/dist/logger-33TR6EE5.js +72 -0
- package/dist/loop-spec-XTLQAVZ7.js +191 -0
- package/dist/manager-2HJG5CLT.js +25 -0
- package/dist/matrix-prompt-builder-6UDN5X3F.js +497 -0
- package/dist/matrix-result-parser-7W35EUOV.js +15 -0
- package/dist/metadata-HQ43NDEK.js +22 -0
- package/dist/model-invocations-db-QBO4Y7WZ.js +38 -0
- package/dist/monitor-XGYBG2DW.js +72 -0
- package/dist/next-PB5ZXZKB.js +90 -0
- package/dist/next-ZBDK725T.js +69 -0
- package/dist/optimization-config-resolver-O6WKR47U.js +75 -0
- package/dist/package-3YCWIQQ5.js +10 -0
- package/dist/parallel-orchestrator-NL7YJJU2.js +297 -0
- package/dist/parallel-worker.js +279 -0
- package/dist/parse-git-status-PIAF3OTP.js +10 -0
- package/dist/path-security-ETTH6TZL.js +39 -0
- package/dist/pattern-bank-UNJR5ADV.js +15 -0
- package/dist/plan-backlog-list-fast-VAGYBV3J.js +270 -0
- package/dist/plan-backlog-show-fast-SG2CZPW3.js +406 -0
- package/dist/plan-sprint-list-fast-LURAX47V.js +162 -0
- package/dist/plan-sprint-status-fast-FJAODCHD.js +208 -0
- package/dist/plan-task-status-fast-HNYBMQI4.js +349 -0
- package/dist/plan-to-flywheel-Z4U3GWPN.js +456 -0
- package/dist/planning-backlog-3CQ5QQBQ.js +319 -0
- package/dist/poetic-root-V5DNXEAE.js +17 -0
- package/dist/preflight-OPANWMME.js +12 -0
- package/dist/process-registry-PDZJPTAS.js +27 -0
- package/dist/process-scanner-C22SYXYD.js +22 -0
- package/dist/processes-KMQUD7HY.js +29 -0
- package/dist/processes-json-fast-IBDXZ6WW.js +135 -0
- package/dist/profile-SE5EVXAP.js +149 -0
- package/dist/prompts-WZZPGWBX.js +168 -0
- package/dist/protected-branches-RNTEX7ET.js +57 -0
- package/dist/provider-aware-resource-manager-QBTZJMNP.js +18 -0
- package/dist/provider-matrix-N5X57V3Y.js +154 -0
- package/dist/provider-matrix-renderer-MZDWKKID.js +139 -0
- package/dist/provider-output-forwarding-DERID3TP.js +30 -0
- package/dist/provider-registry-J5NRBJKI.js +128 -0
- package/dist/provider-temp-cleanup-KYGLF6YU.js +14 -0
- package/dist/prune-engine-Q6E2DXBN.js +451 -0
- package/dist/quality-gate-YRHMQAEI.js +70 -0
- package/dist/quickstart-FIRLKGJI.js +62 -0
- package/dist/readiness-VZTMSG6J.js +96 -0
- package/dist/registry-YODFY77A.js +153 -0
- package/dist/repair-helpers-TTV5FEF4.js +117 -0
- package/dist/repo-root-2IGD4H7X.js +22 -0
- package/dist/resolution-engine-D6TX6FRG.js +127 -0
- package/dist/resolve-provider-cli-O2P6XZBZ.js +35 -0
- package/dist/restore-telemetry-db-BQL6DTQF.js +360 -0
- package/dist/result-streamer-WEHW476R.js +19 -0
- package/dist/routing-events-DHPUZDDF.js +27 -0
- package/dist/routing-history-store-UWCEXAP3.js +46 -0
- package/dist/routing-planner-F5WQEUOM.js +160 -0
- package/dist/run-poetic-tui-J6LWRJUP.js +13517 -0
- package/dist/run-simulation.js +376 -0
- package/dist/runner-CS2TNGHA.js +1092 -0
- package/dist/runner-HHH7ZN2Z.js +1571 -0
- package/dist/safety-OCC4KJJR.js +64 -0
- package/dist/safety-stanza-7SV3HGG3.js +60 -0
- package/dist/sandbox-32QXJEMV.js +81 -0
- package/dist/sandbox-RSO7VP6V.js +94 -0
- package/dist/schema-extensions.sql +234 -0
- package/dist/security-2KI5XNDG.js +17 -0
- package/dist/setup-bb-plugin-QAQWZCV5.js +738 -0
- package/dist/setup-claude-code-P7BTTSPO.js +317 -0
- package/dist/setup-temp-cleanup-GASCWZ2I.js +20 -0
- package/dist/shared-utils-D6U6UREP.js +37 -0
- package/dist/simple-artifact-goal-OTXNGZY6.js +25 -0
- package/dist/sprint-UIXPYOXQ.js +338 -0
- package/dist/sprint-bridge-4BHMSC3M.js +68 -0
- package/dist/sprint-execution-service-2B7WHL5L.js +311 -0
- package/dist/sprint-manager-IDQUDNQI.js +91 -0
- package/dist/sqlite-wrapper-UDWCTNLJ.js +17 -0
- package/dist/stale-cleanup-orchestrator-XWXV7KCZ.js +62 -0
- package/dist/storage-access-F6ALDN4S.js +22 -0
- package/dist/synthesis-XD6EDVHF.js +185 -0
- package/dist/task-classifier-LNLXSHOM.js +494 -0
- package/dist/task-list-fast-PTMA4LUC.js +147 -0
- package/dist/task-manager-XAT7GOWB.js +93 -0
- package/dist/task-splitter-U7DJ7W6A.js +79 -0
- package/dist/task-type-detector-OLVOMXZO.js +21 -0
- package/dist/task-type-resolver-KKNQYSB4.js +42 -0
- package/dist/telemetry-5HWBBXLX.js +131 -0
- package/dist/telemetry-health-tracker-DMSSGBZ2.js +11 -0
- package/dist/telemetry-path-resolver-7ICSG276.js +28 -0
- package/dist/telemetry-reliability-XUOZNZZ6.js +125 -0
- package/dist/token-estimator-MEQUL3EJ.js +37 -0
- package/dist/transports-KNSSV2V4.js +255 -0
- package/dist/unified-cost-tracker-4TFRBVPR.js +35 -0
- package/dist/unified-state-cleanup-LJPF2BOW.js +276 -0
- package/dist/universal-cost-calculator-BAJV35GA.js +42 -0
- package/dist/user-agents-GHUGCSKN.js +22 -0
- package/dist/variant-delivery-state-KLRNG6XA.js +33 -0
- package/dist/variant-state-cleanup-MZGGLQAJ.js +280 -0
- package/dist/variant-success-PJXWE3ZV.js +12 -0
- package/dist/variant-worker-KUWKBLAH.js +4196 -0
- package/dist/variant-worker.js +24 -0
- package/dist/variants-JE2FSAQS.js +233 -0
- package/dist/verification-toolchains-V24UHW6Q.js +28 -0
- package/dist/verify-commands-H3DTCSGI.js +37 -0
- package/dist/warning-EGQGUUIO.js +12 -0
- package/dist/work-edge-RWEDWJZF.js +49 -0
- package/dist/work-item-writer-WHAVZXAY.js +19 -0
- package/dist/worker-7SA2VS2Y.js +1435 -0
- package/dist/worker.js +19 -0
- package/dist/worktree-metrics-3DFUYVYE.js +26 -0
- package/dist/writeback-VZKHYHSN.js +44 -0
- package/docs/CLI_REFERENCE.md +7042 -0
- package/docs/PROVIDER_SETUP.md +1570 -0
- package/docs/README.md +96 -0
- package/docs/TROUBLESHOOTING.md +2232 -0
- package/docs/getting-started/QUICK_START.md +294 -0
- package/docs/getting-started/README.md +188 -0
- package/docs/getting-started/SETUP.md +52 -0
- package/docs/reference/AGENT_CONTEXT.md +38 -0
- package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
- package/docs/reference/README.md +381 -0
- package/docs/reference/SECURITY.md +262 -0
- package/integrations/bb-plugin-poetic/README.md +362 -0
- package/integrations/bb-plugin-poetic/app.css +341 -0
- package/integrations/bb-plugin-poetic/app.tsx +5059 -0
- package/integrations/bb-plugin-poetic/package.json +45 -0
- package/integrations/bb-plugin-poetic/server.ts +444 -0
- package/integrations/bb-plugin-poetic/src/adapter.ts +3312 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-model.ts +150 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-schema.ts +355 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-service.ts +419 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-view.ts +1026 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-schema.ts +122 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-service.ts +105 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-view.ts +138 -0
- package/integrations/bb-plugin-poetic/src/contract.ts +615 -0
- package/integrations/bb-plugin-poetic/src/finalize-model.ts +205 -0
- package/integrations/bb-plugin-poetic/src/finalize-schema.ts +158 -0
- package/integrations/bb-plugin-poetic/src/finalize-service.ts +382 -0
- package/integrations/bb-plugin-poetic/src/finalize-view.ts +159 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-readback.ts +303 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-schema.ts +33 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-view.ts +459 -0
- package/integrations/bb-plugin-poetic/src/model.ts +1302 -0
- package/integrations/bb-plugin-poetic/src/monitor-service.ts +233 -0
- package/integrations/bb-plugin-poetic/src/panel-read-ux.ts +97 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-schema.ts +166 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-service.ts +480 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-view.ts +109 -0
- package/integrations/bb-plugin-poetic/src/planning-readback.ts +204 -0
- package/integrations/bb-plugin-poetic/src/planning-service.ts +594 -0
- package/integrations/bb-plugin-poetic/src/planning-workspace-schema.ts +95 -0
- package/integrations/bb-plugin-poetic/src/planning-workspace.ts +323 -0
- package/integrations/bb-plugin-poetic/src/poll-handoff.ts +136 -0
- package/integrations/bb-plugin-poetic/src/project-target-server.ts +21 -0
- package/integrations/bb-plugin-poetic/src/project-target.ts +45 -0
- package/integrations/bb-plugin-poetic/src/reference-index.ts +192 -0
- package/integrations/bb-plugin-poetic/src/repository-schema.ts +30 -0
- package/integrations/bb-plugin-poetic/src/result-explorer-view.ts +597 -0
- package/integrations/bb-plugin-poetic/src/result-readback-model.ts +163 -0
- package/integrations/bb-plugin-poetic/src/result-readback-schema.ts +319 -0
- package/integrations/bb-plugin-poetic/src/result-readback-service.ts +333 -0
- package/integrations/bb-plugin-poetic/src/run-page-view.ts +177 -0
- package/integrations/bb-plugin-poetic/src/setup-config-schema.ts +291 -0
- package/integrations/bb-plugin-poetic/src/setup-config-service.ts +590 -0
- package/integrations/bb-plugin-poetic/src/setup-config-view.ts +413 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-model.ts +150 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-schema.ts +136 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-service.ts +341 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-view.ts +116 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-model.ts +714 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-readback.ts +231 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-schema.ts +601 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-service.ts +775 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-view.ts +1221 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-model.ts +567 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-schema.ts +635 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-service.ts +842 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-view.ts +1227 -0
- package/integrations/bb-plugin-poetic/src/task-detail-readback.ts +56 -0
- package/integrations/bb-plugin-poetic/src/task-detail-schema.ts +144 -0
- package/integrations/bb-plugin-poetic/src/task-navigation.ts +446 -0
- package/integrations/bb-plugin-poetic/src/workbench-route.ts +74 -0
- package/integrations/bb-plugin-poetic/tests/host-contract.test.ts +773 -0
- package/integrations/bb-plugin-poetic/tsconfig.json +18 -0
- package/integrations/bb-plugin-poetic/types/PROVENANCE.json +52 -0
- package/integrations/bb-plugin-poetic/types/bb-plugin-sdk-app.d.ts +1444 -0
- package/integrations/bb-plugin-poetic/types/bb-plugin-sdk.d.ts +13030 -0
- package/integrations/bb-plugin-poetic/vitest.host.config.ts +71 -0
- package/npm-shrinkwrap.json +4950 -0
- package/package.json +331 -0
- package/schemas/README.md +80 -0
- package/schemas/config-v1.schema.json +136 -0
- package/schemas/execution-config.schema.json +47 -0
- package/schemas/judge-scoring.schema.json +370 -0
- package/schemas/poetic.config.schema.json +2214 -0
- package/schemas/provider-config.schema.json +203 -0
- package/schemas/telemetry-config.schema.json +79 -0
- package/schemas/user-preferences.schema.json +141 -0
- package/scripts/assert-node-runtime.mjs +140 -0
- package/scripts/preflight-native.mjs +49 -0
- package/scripts/preinstall-node-check.mjs +78 -0
- package/scripts/setup-git-hooks.mjs +24 -0
- package/scripts/sync.sh +2722 -0
- package/scripts/write-node-launcher.sh +108 -0
- package/src/resources/gemini/slash-packs/default/plan.toml +15 -0
- package/src/resources/gemini/slash-packs/default/summary.toml +16 -0
- package/src/resources/gemini/slash-packs/default/tests.toml +16 -0
- package/templates/.poetic/README.md +37 -0
- package/templates/.poetic/agents/README.md +296 -0
- package/templates/.poetic/agents/api-documenter.md +147 -0
- package/templates/.poetic/agents/backend-architect.md +31 -0
- package/templates/.poetic/agents/code-reviewer.md +157 -0
- package/templates/.poetic/agents/data-scientist.md +179 -0
- package/templates/.poetic/agents/database-optimizer.md +145 -0
- package/templates/.poetic/agents/debugger.md +31 -0
- package/templates/.poetic/agents/deployment-engineer.md +164 -0
- package/templates/.poetic/agents/devops-troubleshooter.md +139 -0
- package/templates/.poetic/agents/frontend-developer.md +150 -0
- package/templates/.poetic/agents/javascript-pro.md +36 -0
- package/templates/.poetic/agents/performance-engineer.md +151 -0
- package/templates/.poetic/agents/python-pro.md +137 -0
- package/templates/.poetic/agents/test-automator.md +147 -0
- package/templates/.poetic/agents/typescript-pro.md +34 -0
- package/templates/.poetic/config/poetic.config.jsonc +69 -0
- package/templates/.poetic/config/project-context.template.json +6 -0
- package/templates/.poetic/config/task-type-aliases.presets/kanban.yaml +14 -0
- package/templates/.poetic/config/task-type-aliases.presets/scrum.yaml +17 -0
- package/templates/.poetic/config/task-type-aliases.presets/xp.yaml +12 -0
- package/templates/.poetic/config/task-type-aliases.yaml +28 -0
- package/templates/.poetic/gitignore.template +55 -0
- package/templates/.poetic/task-types/analysis.yaml +40 -0
- package/templates/.poetic/task-types/architecture.yaml +38 -0
- package/templates/.poetic/task-types/doc.yaml +35 -0
- package/templates/.poetic/task-types/feature.yaml +23 -0
- package/templates/.poetic/task-types/general.yaml +6 -0
- package/templates/.poetic/task-types/security.yaml +39 -0
- package/templates/AGENTS.template.md +99 -0
- package/templates/CLAUDE.template.md +1 -0
- package/templates/GEMINI.template.md +1 -0
- package/templates/builtin-workflows/code-review.yaml +73 -0
- package/templates/builtin-workflows/compete-streak.yaml +78 -0
- package/templates/builtin-workflows/hello-verify.yaml +10 -0
- package/templates/builtin-workflows/judge-regression.yaml +114 -0
- package/templates/builtin-workflows/skills/code-review/SKILL.md +60 -0
- package/templates/builtin-workflows/skills/hello-verify/SKILL.md +6 -0
- package/templates/guard-kit/GUARD_SETUP.md.template +255 -0
- package/templates/guard-kit/check.mjs.template +777 -0
- package/templates/guard-kit/config.json.template +6 -0
- package/templates/guard-kit/poetic-guard.yml.template +189 -0
- package/templates/profiles/README.md +56 -0
- package/templates/profiles/frontier-claude.json +27 -0
- package/templates/profiles/frontier-codex.json +26 -0
|
@@ -0,0 +1,1068 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logDebug
|
|
3
|
+
} from "./chunk-V72RMBM4.js";
|
|
4
|
+
import {
|
|
5
|
+
ProviderRegistry,
|
|
6
|
+
registerProviderRegistryReloadInvalidator
|
|
7
|
+
} from "./chunk-AT4TNPWW.js";
|
|
8
|
+
import {
|
|
9
|
+
getPoeticProjectRoot
|
|
10
|
+
} from "./chunk-LEIIWPWQ.js";
|
|
11
|
+
|
|
12
|
+
// src/core/safety/circuit-breaker.ts
|
|
13
|
+
var CircuitState = /* @__PURE__ */ ((CircuitState2) => {
|
|
14
|
+
CircuitState2["CLOSED"] = "closed";
|
|
15
|
+
CircuitState2["OPEN"] = "open";
|
|
16
|
+
CircuitState2["HALF_OPEN"] = "half_open";
|
|
17
|
+
return CircuitState2;
|
|
18
|
+
})(CircuitState || {});
|
|
19
|
+
var CircuitBreaker = class {
|
|
20
|
+
options;
|
|
21
|
+
state = "closed" /* CLOSED */;
|
|
22
|
+
failures = [];
|
|
23
|
+
// Timestamp array
|
|
24
|
+
successes = [];
|
|
25
|
+
// Timestamp array
|
|
26
|
+
halfOpenCallsMade = 0;
|
|
27
|
+
rejectedCalls = 0;
|
|
28
|
+
totalResponseTime = 0;
|
|
29
|
+
totalSuccessfulCalls = 0;
|
|
30
|
+
recoveryInFlight = null;
|
|
31
|
+
constructor(options = {}) {
|
|
32
|
+
const recoveryTimeout = options.timeout ?? options.recoveryTimeout ?? 3e4;
|
|
33
|
+
const failureWindow = options.windowMs ?? options.failureWindow ?? 6e4;
|
|
34
|
+
if (options.halfOpenMaxCalls !== void 0 && options.halfOpenMaxCalls < 1) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`halfOpenMaxCalls must be >= 1 (got ${options.halfOpenMaxCalls}); a value of 0 makes HALF_OPEN state non-functional`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
this.options = {
|
|
40
|
+
failureThreshold: options.failureThreshold ?? 5,
|
|
41
|
+
errorThreshold: options.errorThreshold,
|
|
42
|
+
minRequests: options.minRequests ?? 5,
|
|
43
|
+
failureWindow,
|
|
44
|
+
windowMs: failureWindow,
|
|
45
|
+
recoveryTimeout,
|
|
46
|
+
timeout: recoveryTimeout,
|
|
47
|
+
halfOpenMaxCalls: options.halfOpenMaxCalls ?? 1,
|
|
48
|
+
baseDelay: options.baseDelay ?? 1e3,
|
|
49
|
+
maxDelay: options.maxDelay ?? 3e4,
|
|
50
|
+
// 30 seconds
|
|
51
|
+
healthCheck: options.healthCheck,
|
|
52
|
+
healthCheckTimeoutMs: options.healthCheckTimeoutMs ?? 5e3
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Execute a function through the circuit breaker
|
|
57
|
+
* @returns Promise that resolves with the function result or rejects with CircuitBreakerError
|
|
58
|
+
*/
|
|
59
|
+
async execute(fn) {
|
|
60
|
+
const now = Date.now();
|
|
61
|
+
this.cleanupOldData(now);
|
|
62
|
+
if (this.state === "open" /* OPEN */) {
|
|
63
|
+
if (this.canAttemptRecovery(now)) {
|
|
64
|
+
if (this.recoveryInFlight) {
|
|
65
|
+
await this.recoveryInFlight;
|
|
66
|
+
} else {
|
|
67
|
+
this.recoveryInFlight = (async () => {
|
|
68
|
+
const healthOk = await this.runHealthCheck();
|
|
69
|
+
if (!healthOk) {
|
|
70
|
+
this.failures.push(Date.now());
|
|
71
|
+
throw new CircuitBreakerError("Health check failed. Circuit remains OPEN.", {
|
|
72
|
+
state: this.state,
|
|
73
|
+
waitTime: this.options.recoveryTimeout,
|
|
74
|
+
metrics: this.getMetrics()
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
this.state = "half_open" /* HALF_OPEN */;
|
|
78
|
+
this.halfOpenCallsMade = 0;
|
|
79
|
+
})().finally(() => {
|
|
80
|
+
this.recoveryInFlight = null;
|
|
81
|
+
});
|
|
82
|
+
await this.recoveryInFlight;
|
|
83
|
+
}
|
|
84
|
+
if (this.state !== "half_open" /* HALF_OPEN */) {
|
|
85
|
+
this.rejectedCalls++;
|
|
86
|
+
const waitTime = this.options.recoveryTimeout;
|
|
87
|
+
throw new CircuitBreakerError("Health check failed. Circuit remains OPEN.", {
|
|
88
|
+
state: this.state,
|
|
89
|
+
waitTime,
|
|
90
|
+
metrics: this.getMetrics()
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
this.rejectedCalls++;
|
|
95
|
+
const waitTime = Math.max(
|
|
96
|
+
0,
|
|
97
|
+
this.options.recoveryTimeout - (now - (this.failures.at(-1) || now))
|
|
98
|
+
);
|
|
99
|
+
throw new CircuitBreakerError("Circuit breaker is OPEN. Rejected call.", {
|
|
100
|
+
state: this.state,
|
|
101
|
+
waitTime,
|
|
102
|
+
metrics: this.getMetrics()
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (this.state === "half_open" /* HALF_OPEN */) {
|
|
107
|
+
if (this.halfOpenCallsMade >= this.options.halfOpenMaxCalls) {
|
|
108
|
+
this.rejectedCalls++;
|
|
109
|
+
throw new CircuitBreakerError("Circuit breaker is HALF_OPEN and test limit reached.", {
|
|
110
|
+
state: this.state,
|
|
111
|
+
waitTime: this.options.recoveryTimeout,
|
|
112
|
+
metrics: this.getMetrics()
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
this.halfOpenCallsMade++;
|
|
116
|
+
}
|
|
117
|
+
const startTime = Date.now();
|
|
118
|
+
try {
|
|
119
|
+
const result = await fn();
|
|
120
|
+
const responseTime = Date.now() - startTime;
|
|
121
|
+
this.recordSuccessInternal(responseTime);
|
|
122
|
+
if (this.state === "half_open" /* HALF_OPEN */) {
|
|
123
|
+
this.state = "closed" /* CLOSED */;
|
|
124
|
+
this.halfOpenCallsMade = 0;
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
const responseTime = Date.now() - startTime;
|
|
129
|
+
this.recordFailureInternal(responseTime);
|
|
130
|
+
if (this.state === "half_open" /* HALF_OPEN */) {
|
|
131
|
+
this.state = "open" /* OPEN */;
|
|
132
|
+
} else if (this.shouldOpenCircuit()) {
|
|
133
|
+
this.state = "open" /* OPEN */;
|
|
134
|
+
}
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get current circuit breaker metrics
|
|
140
|
+
*/
|
|
141
|
+
getMetrics() {
|
|
142
|
+
const latestFailure = this.failures.at(-1);
|
|
143
|
+
return {
|
|
144
|
+
state: this.state,
|
|
145
|
+
failureCount: this.failures.length,
|
|
146
|
+
successCount: this.successes.length,
|
|
147
|
+
lastFailureTime: latestFailure,
|
|
148
|
+
rejectedCalls: this.rejectedCalls,
|
|
149
|
+
averageResponseTime: this.totalSuccessfulCalls > 0 ? Math.round(this.totalResponseTime / this.totalSuccessfulCalls) : 0,
|
|
150
|
+
nextRecoveryAttempt: latestFailure ? latestFailure + this.options.recoveryTimeout : void 0
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Force the circuit breaker to OPEN state (for testing)
|
|
155
|
+
*/
|
|
156
|
+
forceOpen() {
|
|
157
|
+
this.state = "open" /* OPEN */;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Reset the circuit breaker to CLOSED state (for testing)
|
|
161
|
+
*/
|
|
162
|
+
reset() {
|
|
163
|
+
this.state = "closed" /* CLOSED */;
|
|
164
|
+
this.failures = [];
|
|
165
|
+
this.successes = [];
|
|
166
|
+
this.halfOpenCallsMade = 0;
|
|
167
|
+
this.rejectedCalls = 0;
|
|
168
|
+
this.totalResponseTime = 0;
|
|
169
|
+
this.totalSuccessfulCalls = 0;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Calculate exponential backoff delay
|
|
173
|
+
*/
|
|
174
|
+
getBackoffDelay() {
|
|
175
|
+
const failureCount = Math.min(this.failures.length, 10);
|
|
176
|
+
const delay = this.options.baseDelay * 2 ** Math.max(0, failureCount - 1);
|
|
177
|
+
return Math.min(delay, this.options.maxDelay);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if a request can be made (for manual usage pattern)
|
|
181
|
+
* @returns true if circuit allows request, false if circuit is OPEN
|
|
182
|
+
*/
|
|
183
|
+
canMakeRequest() {
|
|
184
|
+
const now = Date.now();
|
|
185
|
+
this.cleanupOldData(now);
|
|
186
|
+
if (this.state === "closed" /* CLOSED */) {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
if (this.state === "open" /* OPEN */) {
|
|
190
|
+
if (this.canAttemptRecovery(now)) {
|
|
191
|
+
if (this.options.healthCheck) return false;
|
|
192
|
+
this.state = "half_open" /* HALF_OPEN */;
|
|
193
|
+
this.halfOpenCallsMade = 0;
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
if (this.halfOpenCallsMade >= this.options.halfOpenMaxCalls) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Record a successful request (for manual usage pattern)
|
|
205
|
+
*/
|
|
206
|
+
recordSuccess() {
|
|
207
|
+
const now = Date.now();
|
|
208
|
+
this.cleanupOldData(now);
|
|
209
|
+
this.successes.push(now);
|
|
210
|
+
this.totalSuccessfulCalls++;
|
|
211
|
+
this.halfOpenCallsMade++;
|
|
212
|
+
if (this.state === "half_open" /* HALF_OPEN */) {
|
|
213
|
+
this.failures = [];
|
|
214
|
+
this.state = "closed" /* CLOSED */;
|
|
215
|
+
this.halfOpenCallsMade = 0;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Record a failed request (for manual usage pattern)
|
|
220
|
+
*/
|
|
221
|
+
recordFailure() {
|
|
222
|
+
const now = Date.now();
|
|
223
|
+
this.cleanupOldData(now);
|
|
224
|
+
this.failures.push(now);
|
|
225
|
+
this.halfOpenCallsMade++;
|
|
226
|
+
if (this.state === "closed" /* CLOSED */ && this.shouldOpenCircuit()) {
|
|
227
|
+
this.state = "open" /* OPEN */;
|
|
228
|
+
} else if (this.state === "half_open" /* HALF_OPEN */) {
|
|
229
|
+
this.state = "open" /* OPEN */;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
canAttemptRecovery(now) {
|
|
233
|
+
const lastFailure = this.failures.at(-1);
|
|
234
|
+
if (!lastFailure) return true;
|
|
235
|
+
return now - lastFailure >= this.options.recoveryTimeout;
|
|
236
|
+
}
|
|
237
|
+
/** Run optional health check with timeout; returns true if no check or check passed. */
|
|
238
|
+
async runHealthCheck() {
|
|
239
|
+
if (!this.options.healthCheck) return true;
|
|
240
|
+
const timeoutMs = this.options.healthCheckTimeoutMs;
|
|
241
|
+
let timeoutHandle;
|
|
242
|
+
try {
|
|
243
|
+
const result = await Promise.race([
|
|
244
|
+
this.options.healthCheck?.(),
|
|
245
|
+
new Promise((_, reject) => {
|
|
246
|
+
timeoutHandle = setTimeout(() => reject(new Error("Health check timeout")), timeoutMs);
|
|
247
|
+
})
|
|
248
|
+
]);
|
|
249
|
+
return result === true;
|
|
250
|
+
} catch {
|
|
251
|
+
return false;
|
|
252
|
+
} finally {
|
|
253
|
+
if (timeoutHandle !== void 0) {
|
|
254
|
+
clearTimeout(timeoutHandle);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
shouldOpenCircuit() {
|
|
259
|
+
if (this.options.errorThreshold !== void 0) {
|
|
260
|
+
const total = this.failures.length + this.successes.length;
|
|
261
|
+
if (total < this.options.minRequests) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
const errorRate = this.failures.length / total;
|
|
265
|
+
return errorRate > this.options.errorThreshold;
|
|
266
|
+
}
|
|
267
|
+
return this.failures.length >= this.options.failureThreshold;
|
|
268
|
+
}
|
|
269
|
+
recordFailureInternal(_responseTime) {
|
|
270
|
+
const now = Date.now();
|
|
271
|
+
this.failures.push(now);
|
|
272
|
+
}
|
|
273
|
+
recordSuccessInternal(responseTime) {
|
|
274
|
+
const now = Date.now();
|
|
275
|
+
this.successes.push(now);
|
|
276
|
+
this.totalSuccessfulCalls++;
|
|
277
|
+
this.totalResponseTime += responseTime;
|
|
278
|
+
if (this.state === "half_open" /* HALF_OPEN */) {
|
|
279
|
+
this.failures = [];
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
cleanupOldData(now) {
|
|
283
|
+
const cutoff = now - this.options.failureWindow;
|
|
284
|
+
this.failures = this.failures.filter((timestamp) => timestamp > cutoff);
|
|
285
|
+
this.successes = this.successes.filter((timestamp) => timestamp > cutoff);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
var CircuitBreakerError = class extends Error {
|
|
289
|
+
state;
|
|
290
|
+
waitTime;
|
|
291
|
+
metrics;
|
|
292
|
+
constructor(message, options) {
|
|
293
|
+
super(message);
|
|
294
|
+
this.name = "CircuitBreakerError";
|
|
295
|
+
this.state = options.state;
|
|
296
|
+
this.waitTime = options.waitTime;
|
|
297
|
+
this.metrics = options.metrics;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
function createCircuitBreakerOptions(options) {
|
|
301
|
+
return {
|
|
302
|
+
failureThreshold: options.failureThreshold ?? 5,
|
|
303
|
+
errorThreshold: options.errorThreshold,
|
|
304
|
+
minRequests: options.minRequests ?? 5,
|
|
305
|
+
failureWindow: options.failureWindow ?? options.windowMs ?? 6e4,
|
|
306
|
+
windowMs: options.windowMs ?? options.failureWindow ?? 6e4,
|
|
307
|
+
recoveryTimeout: options.recoveryTimeout ?? options.timeout ?? 3e4,
|
|
308
|
+
timeout: options.timeout ?? options.recoveryTimeout ?? 3e4,
|
|
309
|
+
halfOpenMaxCalls: options.halfOpenMaxCalls ?? 1,
|
|
310
|
+
baseDelay: options.baseDelay ?? 1e3,
|
|
311
|
+
maxDelay: options.maxDelay ?? 3e4,
|
|
312
|
+
healthCheck: options.healthCheck,
|
|
313
|
+
healthCheckTimeoutMs: options.healthCheckTimeoutMs ?? 5e3
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/core/safety/circuit-breaker-registry.ts
|
|
318
|
+
var CircuitBreakerRegistry = class {
|
|
319
|
+
breakers = /* @__PURE__ */ new Map();
|
|
320
|
+
defaultOptions;
|
|
321
|
+
/**
|
|
322
|
+
* Creates a new circuit breaker registry
|
|
323
|
+
* @param defaultOptions - Default options to apply to all circuit breakers
|
|
324
|
+
*/
|
|
325
|
+
constructor(defaultOptions = {}) {
|
|
326
|
+
this.defaultOptions = defaultOptions;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Gets or creates a circuit breaker for the specified provider.
|
|
330
|
+
* @param provider - The provider name (e.g., 'gemini', 'claude')
|
|
331
|
+
* @param options - Optional circuit breaker configuration (merged with defaults)
|
|
332
|
+
* @returns The circuit breaker instance for this provider
|
|
333
|
+
*/
|
|
334
|
+
getBreaker(provider, options = {}) {
|
|
335
|
+
let breaker = this.breakers.get(provider);
|
|
336
|
+
if (!breaker) {
|
|
337
|
+
const mergedOptions = {
|
|
338
|
+
failureThreshold: 5,
|
|
339
|
+
recoveryTimeout: 3e4,
|
|
340
|
+
...this.defaultOptions,
|
|
341
|
+
...options
|
|
342
|
+
};
|
|
343
|
+
breaker = new CircuitBreaker(mergedOptions);
|
|
344
|
+
this.breakers.set(provider, breaker);
|
|
345
|
+
}
|
|
346
|
+
return breaker;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Resets the circuit breaker for a specific provider.
|
|
350
|
+
* @param provider - The provider name
|
|
351
|
+
*/
|
|
352
|
+
resetBreaker(provider) {
|
|
353
|
+
const breaker = this.breakers.get(provider);
|
|
354
|
+
if (breaker) {
|
|
355
|
+
breaker.reset();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Removes the circuit breaker for a specific provider.
|
|
360
|
+
* This completely removes the breaker from the registry.
|
|
361
|
+
* @param provider - The provider name
|
|
362
|
+
*/
|
|
363
|
+
removeBreaker(provider) {
|
|
364
|
+
this.breakers.delete(provider);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Resets all circuit breakers in the registry.
|
|
368
|
+
*/
|
|
369
|
+
resetAllBreakers() {
|
|
370
|
+
for (const breaker of this.breakers.values()) {
|
|
371
|
+
breaker.reset();
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Removes all circuit breakers from the registry.
|
|
376
|
+
*/
|
|
377
|
+
clear() {
|
|
378
|
+
this.breakers.clear();
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Gets all circuit breakers in the registry.
|
|
382
|
+
* @returns Map of provider names to circuit breakers
|
|
383
|
+
*/
|
|
384
|
+
getAllBreakers() {
|
|
385
|
+
return this.breakers;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Checks if a circuit breaker exists for the specified provider.
|
|
389
|
+
* @param provider - The provider name
|
|
390
|
+
* @returns true if a breaker exists, false otherwise
|
|
391
|
+
*/
|
|
392
|
+
hasBreaker(provider) {
|
|
393
|
+
return this.breakers.has(provider);
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Gets the number of registered circuit breakers.
|
|
397
|
+
* @returns The count of circuit breakers
|
|
398
|
+
*/
|
|
399
|
+
get size() {
|
|
400
|
+
return this.breakers.size;
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
// src/core/safety/file-token-bucket.ts
|
|
405
|
+
import { promises as fs } from "fs";
|
|
406
|
+
import path from "path";
|
|
407
|
+
import { setTimeout as timersSetTimeout } from "timers/promises";
|
|
408
|
+
var DEFAULT_STATE_DIR = path.join(process.cwd(), ".poetic", "rate-limits");
|
|
409
|
+
var DEFAULT_STALE_LOCK_THRESHOLD_MS = 6e4;
|
|
410
|
+
var DEFAULT_MAX_WAIT_MS = 3e4;
|
|
411
|
+
var LOCK_RETRY_INTERVAL_MS = 50;
|
|
412
|
+
var FileTokenBucket = class {
|
|
413
|
+
key;
|
|
414
|
+
bucketSize;
|
|
415
|
+
refillRate;
|
|
416
|
+
initialTokens;
|
|
417
|
+
stateDir;
|
|
418
|
+
staleLockThresholdMs;
|
|
419
|
+
maxWaitMs;
|
|
420
|
+
// In-memory fallback for sync operations (tryAcquire)
|
|
421
|
+
inMemoryTokens;
|
|
422
|
+
inMemoryLastRefill;
|
|
423
|
+
inMemoryTotalWaitMs = 0;
|
|
424
|
+
inMemoryTotalRequests = 0;
|
|
425
|
+
constructor(key, options) {
|
|
426
|
+
this.key = key.replace(/[^a-zA-Z0-9_.-]/g, "_").replace(/\.{2,}/g, "_");
|
|
427
|
+
this.bucketSize = options.bucketSize;
|
|
428
|
+
this.refillRate = options.refillRate;
|
|
429
|
+
this.initialTokens = options.initialTokens ?? options.bucketSize;
|
|
430
|
+
this.stateDir = options.stateDir ?? DEFAULT_STATE_DIR;
|
|
431
|
+
this.staleLockThresholdMs = options.staleLockThresholdMs ?? DEFAULT_STALE_LOCK_THRESHOLD_MS;
|
|
432
|
+
this.maxWaitMs = options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
|
|
433
|
+
this.inMemoryTokens = this.initialTokens;
|
|
434
|
+
this.inMemoryLastRefill = Date.now();
|
|
435
|
+
}
|
|
436
|
+
get statePath() {
|
|
437
|
+
return path.join(this.stateDir, `${this.key}.json`);
|
|
438
|
+
}
|
|
439
|
+
get lockPath() {
|
|
440
|
+
return path.join(this.stateDir, `${this.key}.lock`);
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Acquire tokens from the cross-process bucket (async - waits if insufficient).
|
|
444
|
+
*/
|
|
445
|
+
async acquire(tokens = 1) {
|
|
446
|
+
await this.ensureStateDir();
|
|
447
|
+
const deadline = Date.now() + this.maxWaitMs;
|
|
448
|
+
while (Date.now() < deadline) {
|
|
449
|
+
const acquired = await this.tryAcquireFromFile(tokens);
|
|
450
|
+
if (acquired.success) {
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
const waitMs = Math.min(acquired.waitMs ?? 500, deadline - Date.now());
|
|
454
|
+
if (waitMs <= 0) break;
|
|
455
|
+
await timersSetTimeout(waitMs);
|
|
456
|
+
}
|
|
457
|
+
throw new Error(
|
|
458
|
+
`FileTokenBucket(${this.key}): timed out waiting for ${tokens} token(s) after ${this.maxWaitMs}ms`
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Try to acquire tokens without waiting (non-blocking).
|
|
463
|
+
* Falls back to in-memory bucket for synchronous operation.
|
|
464
|
+
*/
|
|
465
|
+
tryAcquire(tokens = 1) {
|
|
466
|
+
this.inMemoryTotalRequests += 1;
|
|
467
|
+
this.refillInMemory();
|
|
468
|
+
if (this.inMemoryTokens >= tokens) {
|
|
469
|
+
this.inMemoryTokens -= tokens;
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Get current metrics (in-memory snapshot).
|
|
476
|
+
*/
|
|
477
|
+
getMetrics() {
|
|
478
|
+
this.refillInMemory();
|
|
479
|
+
return {
|
|
480
|
+
availableTokens: this.inMemoryTokens,
|
|
481
|
+
bucketSize: this.bucketSize,
|
|
482
|
+
refillRate: this.refillRate,
|
|
483
|
+
lastRefillTime: this.inMemoryLastRefill,
|
|
484
|
+
totalWaitTimeMs: this.inMemoryTotalWaitMs,
|
|
485
|
+
totalRequests: this.inMemoryTotalRequests
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Reset both in-memory and file-based state.
|
|
490
|
+
* WARNING: Not safe to call during concurrent acquire/release operations.
|
|
491
|
+
* Only use when no other callers are active (e.g., between test runs).
|
|
492
|
+
*/
|
|
493
|
+
reset() {
|
|
494
|
+
this.inMemoryTokens = this.initialTokens;
|
|
495
|
+
this.inMemoryLastRefill = Date.now();
|
|
496
|
+
this.inMemoryTotalWaitMs = 0;
|
|
497
|
+
this.inMemoryTotalRequests = 0;
|
|
498
|
+
fs.unlink(this.statePath).catch(() => {
|
|
499
|
+
});
|
|
500
|
+
fs.unlink(this.lockPath).catch(() => {
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
// --- Internal file-based operations ---
|
|
504
|
+
async ensureStateDir() {
|
|
505
|
+
await fs.mkdir(this.stateDir, { recursive: true });
|
|
506
|
+
}
|
|
507
|
+
async tryAcquireFromFile(tokens) {
|
|
508
|
+
let lockHandle;
|
|
509
|
+
try {
|
|
510
|
+
lockHandle = await this.acquireLock();
|
|
511
|
+
if (!lockHandle) {
|
|
512
|
+
return { success: false, waitMs: LOCK_RETRY_INTERVAL_MS };
|
|
513
|
+
}
|
|
514
|
+
const state = await this.readState();
|
|
515
|
+
this.refillState(state);
|
|
516
|
+
state.totalRequests += 1;
|
|
517
|
+
if (state.availableTokens >= tokens) {
|
|
518
|
+
state.availableTokens -= tokens;
|
|
519
|
+
await this.writeState(state);
|
|
520
|
+
this.inMemoryTokens = state.availableTokens;
|
|
521
|
+
this.inMemoryLastRefill = state.lastRefillTime;
|
|
522
|
+
this.inMemoryTotalRequests = state.totalRequests;
|
|
523
|
+
this.inMemoryTotalWaitMs = state.totalWaitTimeMs;
|
|
524
|
+
return { success: true };
|
|
525
|
+
}
|
|
526
|
+
const tokensNeeded = tokens - state.availableTokens;
|
|
527
|
+
const waitMs = Math.ceil(tokensNeeded / this.refillRate * 1e3);
|
|
528
|
+
state.totalWaitTimeMs += waitMs;
|
|
529
|
+
await this.writeState(state);
|
|
530
|
+
return { success: false, waitMs };
|
|
531
|
+
} finally {
|
|
532
|
+
await this.releaseLock(lockHandle);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async acquireLock() {
|
|
536
|
+
try {
|
|
537
|
+
const lockStat = await fs.stat(this.lockPath);
|
|
538
|
+
if (Date.now() - lockStat.mtimeMs > this.staleLockThresholdMs) {
|
|
539
|
+
await fs.unlink(this.lockPath).catch(() => {
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
} catch {
|
|
543
|
+
}
|
|
544
|
+
try {
|
|
545
|
+
const handle = await fs.open(this.lockPath, "wx");
|
|
546
|
+
await handle.write(`${process.pid}
|
|
547
|
+
`);
|
|
548
|
+
return handle;
|
|
549
|
+
} catch {
|
|
550
|
+
return void 0;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async releaseLock(handle) {
|
|
554
|
+
if (handle) {
|
|
555
|
+
await handle.close().catch(() => {
|
|
556
|
+
});
|
|
557
|
+
await fs.unlink(this.lockPath).catch(() => {
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
async readState() {
|
|
562
|
+
try {
|
|
563
|
+
const content = await fs.readFile(this.statePath, "utf-8");
|
|
564
|
+
const parsed = JSON.parse(content);
|
|
565
|
+
if (typeof parsed.availableTokens === "number" && typeof parsed.lastRefillTime === "number") {
|
|
566
|
+
return parsed;
|
|
567
|
+
}
|
|
568
|
+
} catch {
|
|
569
|
+
}
|
|
570
|
+
return {
|
|
571
|
+
availableTokens: this.initialTokens,
|
|
572
|
+
lastRefillTime: Date.now(),
|
|
573
|
+
totalWaitTimeMs: 0,
|
|
574
|
+
totalRequests: 0
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
async writeState(state) {
|
|
578
|
+
const content = JSON.stringify(state);
|
|
579
|
+
const fd = await fs.open(this.statePath, "w");
|
|
580
|
+
try {
|
|
581
|
+
await fd.write(content);
|
|
582
|
+
await fd.datasync();
|
|
583
|
+
} finally {
|
|
584
|
+
await fd.close();
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
refillState(state) {
|
|
588
|
+
const now = Date.now();
|
|
589
|
+
const elapsedMs = now - state.lastRefillTime;
|
|
590
|
+
const elapsedSeconds = elapsedMs / 1e3;
|
|
591
|
+
const tokensToAdd = elapsedSeconds * this.refillRate;
|
|
592
|
+
if (tokensToAdd > 0) {
|
|
593
|
+
state.availableTokens = Math.min(this.bucketSize, state.availableTokens + tokensToAdd);
|
|
594
|
+
state.lastRefillTime = now;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
refillInMemory() {
|
|
598
|
+
const now = Date.now();
|
|
599
|
+
const elapsedMs = now - this.inMemoryLastRefill;
|
|
600
|
+
const elapsedSeconds = elapsedMs / 1e3;
|
|
601
|
+
const tokensToAdd = elapsedSeconds * this.refillRate;
|
|
602
|
+
if (tokensToAdd > 0) {
|
|
603
|
+
this.inMemoryTokens = Math.min(this.bucketSize, this.inMemoryTokens + tokensToAdd);
|
|
604
|
+
this.inMemoryLastRefill = now;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
// src/core/safety/rate-limiter-factory.ts
|
|
610
|
+
import * as fsSync from "fs";
|
|
611
|
+
import path2 from "path";
|
|
612
|
+
|
|
613
|
+
// src/core/safety/token-bucket.ts
|
|
614
|
+
var TokenBucket = class {
|
|
615
|
+
options;
|
|
616
|
+
availableTokens;
|
|
617
|
+
lastRefillTime;
|
|
618
|
+
totalWaitTimeMs = 0;
|
|
619
|
+
totalRequests = 0;
|
|
620
|
+
_queue = Promise.resolve();
|
|
621
|
+
queuedAcquires = 0;
|
|
622
|
+
generation = 0;
|
|
623
|
+
constructor(options) {
|
|
624
|
+
this.options = {
|
|
625
|
+
bucketSize: options.bucketSize,
|
|
626
|
+
refillRate: options.refillRate,
|
|
627
|
+
initialTokens: options.initialTokens ?? options.bucketSize
|
|
628
|
+
};
|
|
629
|
+
this.availableTokens = this.options.initialTokens;
|
|
630
|
+
this.lastRefillTime = Date.now();
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Acquire tokens from the bucket (async - waits if insufficient tokens)
|
|
634
|
+
* @param tokens - Number of tokens to acquire (default: 1)
|
|
635
|
+
* @returns Promise that resolves when tokens are acquired
|
|
636
|
+
*/
|
|
637
|
+
async acquire(tokens = 1) {
|
|
638
|
+
if (tokens > this.options.bucketSize) {
|
|
639
|
+
throw new Error(
|
|
640
|
+
`TokenBucket cannot acquire ${tokens} token(s); bucket size is ${this.options.bucketSize}`
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
const generationAtEnqueue = this.generation;
|
|
644
|
+
const execute = async () => {
|
|
645
|
+
if (generationAtEnqueue !== this.generation) {
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
this.prepareAcquire();
|
|
649
|
+
if (this.availableTokens >= tokens) {
|
|
650
|
+
this.availableTokens -= tokens;
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
const tokensNeeded = tokens - this.availableTokens;
|
|
654
|
+
if (this.options.refillRate <= 0) {
|
|
655
|
+
throw new Error(
|
|
656
|
+
`TokenBucket cannot acquire ${tokens} token(s); refill rate is zero or negative`
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
const waitTimeMs = tokensNeeded / this.options.refillRate * 1e3;
|
|
660
|
+
this.totalWaitTimeMs += waitTimeMs;
|
|
661
|
+
await this.sleep(waitTimeMs);
|
|
662
|
+
if (generationAtEnqueue !== this.generation) {
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
this.refreshState();
|
|
666
|
+
this.availableTokens = Math.max(0, this.availableTokens - tokens);
|
|
667
|
+
};
|
|
668
|
+
this.queuedAcquires++;
|
|
669
|
+
const next = this.queuedAcquires === 1 ? execute() : this._queue.then(execute, execute);
|
|
670
|
+
this._queue = next.finally(() => {
|
|
671
|
+
if (this.queuedAcquires > 0) {
|
|
672
|
+
this.queuedAcquires--;
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
return this._queue;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Try to acquire tokens without waiting (non-blocking)
|
|
679
|
+
* @param tokens - Number of tokens to acquire (default: 1)
|
|
680
|
+
* @returns true if tokens were acquired, false if insufficient tokens
|
|
681
|
+
*/
|
|
682
|
+
tryAcquire(tokens = 1) {
|
|
683
|
+
if (tokens > this.options.bucketSize) {
|
|
684
|
+
return false;
|
|
685
|
+
}
|
|
686
|
+
if (this.queuedAcquires > 0) {
|
|
687
|
+
return false;
|
|
688
|
+
}
|
|
689
|
+
this.prepareAcquire();
|
|
690
|
+
if (this.availableTokens >= tokens) {
|
|
691
|
+
this.availableTokens -= tokens;
|
|
692
|
+
return true;
|
|
693
|
+
}
|
|
694
|
+
return false;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Get current token bucket metrics
|
|
698
|
+
*/
|
|
699
|
+
getMetrics() {
|
|
700
|
+
this.refreshState();
|
|
701
|
+
return {
|
|
702
|
+
availableTokens: this.availableTokens,
|
|
703
|
+
bucketSize: this.options.bucketSize,
|
|
704
|
+
refillRate: this.options.refillRate,
|
|
705
|
+
lastRefillTime: this.lastRefillTime,
|
|
706
|
+
totalWaitTimeMs: this.totalWaitTimeMs,
|
|
707
|
+
totalRequests: this.totalRequests
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Reset the token bucket to initial state (for testing)
|
|
712
|
+
*/
|
|
713
|
+
reset() {
|
|
714
|
+
this.generation++;
|
|
715
|
+
this._queue = Promise.resolve();
|
|
716
|
+
this.queuedAcquires = 0;
|
|
717
|
+
this.availableTokens = this.options.initialTokens;
|
|
718
|
+
this.lastRefillTime = Date.now();
|
|
719
|
+
this.totalWaitTimeMs = 0;
|
|
720
|
+
this.totalRequests = 0;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Get current number of available tokens
|
|
724
|
+
*/
|
|
725
|
+
getAvailableTokens() {
|
|
726
|
+
this.refreshState();
|
|
727
|
+
return this.availableTokens;
|
|
728
|
+
}
|
|
729
|
+
refreshState() {
|
|
730
|
+
const now = Date.now();
|
|
731
|
+
this.refillTokens(now);
|
|
732
|
+
}
|
|
733
|
+
prepareAcquire() {
|
|
734
|
+
this.totalRequests++;
|
|
735
|
+
this.refreshState();
|
|
736
|
+
}
|
|
737
|
+
refillTokens(now) {
|
|
738
|
+
const elapsedMs = now - this.lastRefillTime;
|
|
739
|
+
const elapsedSeconds = elapsedMs / 1e3;
|
|
740
|
+
const tokensToAdd = elapsedSeconds * this.options.refillRate;
|
|
741
|
+
if (tokensToAdd > 0) {
|
|
742
|
+
this.availableTokens = Math.min(this.options.bucketSize, this.availableTokens + tokensToAdd);
|
|
743
|
+
this.lastRefillTime = now;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
sleep(ms) {
|
|
747
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
var TokenBucketError = class extends Error {
|
|
751
|
+
availableTokens;
|
|
752
|
+
requiredTokens;
|
|
753
|
+
metrics;
|
|
754
|
+
constructor(message, options) {
|
|
755
|
+
super(message);
|
|
756
|
+
this.name = "TokenBucketError";
|
|
757
|
+
this.availableTokens = options.availableTokens;
|
|
758
|
+
this.requiredTokens = options.requiredTokens;
|
|
759
|
+
this.metrics = options.metrics;
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
// src/core/safety/rate-limiter-registry.ts
|
|
764
|
+
var RateLimiterRegistry = class {
|
|
765
|
+
buckets = /* @__PURE__ */ new Map();
|
|
766
|
+
defaultOptions;
|
|
767
|
+
bucketFactory;
|
|
768
|
+
/**
|
|
769
|
+
* Creates a new rate limiter registry
|
|
770
|
+
* @param defaultOptions - Default options to apply to all token buckets
|
|
771
|
+
* @param bucketFactory - Optional factory for creating buckets (defaults to in-memory TokenBucket)
|
|
772
|
+
*/
|
|
773
|
+
constructor(defaultOptions = {}, bucketFactory) {
|
|
774
|
+
this.defaultOptions = defaultOptions;
|
|
775
|
+
this.bucketFactory = bucketFactory ?? ((_key, opts) => new TokenBucket(opts));
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Gets or creates a token bucket for the specified provider and optional model.
|
|
779
|
+
* @param provider - The provider name (e.g., 'gemini', 'claude')
|
|
780
|
+
* @param model - Optional model name (e.g., 'gpt-4', 'claude-3-opus')
|
|
781
|
+
* @param options - Optional token bucket configuration (merged with defaults)
|
|
782
|
+
* @returns The token bucket instance for this provider/model combination
|
|
783
|
+
*/
|
|
784
|
+
getBucket(provider, model, options = {}) {
|
|
785
|
+
const key = model ? `${provider}:${model}` : provider;
|
|
786
|
+
let bucket = this.buckets.get(key);
|
|
787
|
+
if (!bucket) {
|
|
788
|
+
const mergedOptions = {
|
|
789
|
+
bucketSize: 60,
|
|
790
|
+
refillRate: 1,
|
|
791
|
+
...this.defaultOptions,
|
|
792
|
+
...options
|
|
793
|
+
};
|
|
794
|
+
bucket = this.bucketFactory(key, mergedOptions);
|
|
795
|
+
this.buckets.set(key, bucket);
|
|
796
|
+
}
|
|
797
|
+
return bucket;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Resets the token bucket for a specific provider/model combination.
|
|
801
|
+
* @param provider - The provider name
|
|
802
|
+
* @param model - Optional model name
|
|
803
|
+
*/
|
|
804
|
+
resetBucket(provider, model) {
|
|
805
|
+
const key = model ? `${provider}:${model}` : provider;
|
|
806
|
+
const bucket = this.buckets.get(key);
|
|
807
|
+
if (bucket) {
|
|
808
|
+
bucket.reset();
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Removes the token bucket for a specific provider/model combination.
|
|
813
|
+
* This completely removes the bucket from the registry.
|
|
814
|
+
* @param provider - The provider name
|
|
815
|
+
* @param model - Optional model name
|
|
816
|
+
*/
|
|
817
|
+
removeBucket(provider, model) {
|
|
818
|
+
const key = model ? `${provider}:${model}` : provider;
|
|
819
|
+
this.buckets.delete(key);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Resets all token buckets in the registry.
|
|
823
|
+
*/
|
|
824
|
+
resetAllBuckets() {
|
|
825
|
+
for (const bucket of this.buckets.values()) {
|
|
826
|
+
bucket.reset();
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Removes all token buckets from the registry.
|
|
831
|
+
*/
|
|
832
|
+
clear() {
|
|
833
|
+
this.buckets.clear();
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Gets all token buckets in the registry.
|
|
837
|
+
* @returns Map of provider:model keys to token buckets
|
|
838
|
+
*/
|
|
839
|
+
getAllBuckets() {
|
|
840
|
+
return this.buckets;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Checks if a token bucket exists for the specified provider/model combination.
|
|
844
|
+
* @param provider - The provider name
|
|
845
|
+
* @param model - Optional model name
|
|
846
|
+
* @returns true if a bucket exists, false otherwise
|
|
847
|
+
*/
|
|
848
|
+
hasBucket(provider, model) {
|
|
849
|
+
const key = model ? `${provider}:${model}` : provider;
|
|
850
|
+
return this.buckets.has(key);
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Gets the number of registered token buckets.
|
|
854
|
+
* @returns The count of token buckets
|
|
855
|
+
*/
|
|
856
|
+
get size() {
|
|
857
|
+
return this.buckets.size;
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
|
|
861
|
+
// src/core/safety/rate-limiter-factory.ts
|
|
862
|
+
var DEFAULT_RATE_LIMITS = {
|
|
863
|
+
bucketSize: 10,
|
|
864
|
+
// 10 request burst
|
|
865
|
+
refillRate: 0.83
|
|
866
|
+
// ~50 RPM
|
|
867
|
+
};
|
|
868
|
+
function resolveRefillRate(entry) {
|
|
869
|
+
if (typeof entry?.refill_rate === "number" && Number.isFinite(entry.refill_rate)) {
|
|
870
|
+
return entry.refill_rate;
|
|
871
|
+
}
|
|
872
|
+
if (typeof entry?.rpm === "number" && Number.isFinite(entry.rpm)) {
|
|
873
|
+
return entry.rpm / 60;
|
|
874
|
+
}
|
|
875
|
+
return DEFAULT_RATE_LIMITS.refillRate;
|
|
876
|
+
}
|
|
877
|
+
function configToOptions(config) {
|
|
878
|
+
if (!config) {
|
|
879
|
+
return DEFAULT_RATE_LIMITS;
|
|
880
|
+
}
|
|
881
|
+
const entry = config.default || {
|
|
882
|
+
rpm: config.rpm,
|
|
883
|
+
bucket_size: config.bucket_size,
|
|
884
|
+
refill_rate: config.refill_rate
|
|
885
|
+
};
|
|
886
|
+
return {
|
|
887
|
+
bucketSize: entry.bucket_size ?? DEFAULT_RATE_LIMITS.bucketSize,
|
|
888
|
+
refillRate: resolveRefillRate(entry)
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
function shouldUseDistributedRateLimiting() {
|
|
892
|
+
if (process.env.POETIC_DISTRIBUTED_RATE_LIMIT === "1") {
|
|
893
|
+
return true;
|
|
894
|
+
}
|
|
895
|
+
const agents = Number.parseInt(process.env.POETIC_AGENTS ?? "1", 10);
|
|
896
|
+
return !Number.isNaN(agents) && agents > 1;
|
|
897
|
+
}
|
|
898
|
+
function createFileBucketFactory() {
|
|
899
|
+
const stateDir = path2.join(getPoeticProjectRoot(), ".poetic", "rate-limits");
|
|
900
|
+
return (key, options) => new FileTokenBucket(key, { ...options, stateDir });
|
|
901
|
+
}
|
|
902
|
+
function createRateLimiterFromConfig(providerId) {
|
|
903
|
+
let config = null;
|
|
904
|
+
let defaultOptions = DEFAULT_RATE_LIMITS;
|
|
905
|
+
try {
|
|
906
|
+
const registryConfig = ProviderRegistry.load();
|
|
907
|
+
if (registryConfig.defaults?.rate_limits) {
|
|
908
|
+
defaultOptions = configToOptions(registryConfig.defaults.rate_limits);
|
|
909
|
+
}
|
|
910
|
+
const providerConfig = providerId ? registryConfig.providers[providerId] : void 0;
|
|
911
|
+
if (providerConfig?.rate_limits) {
|
|
912
|
+
defaultOptions = configToOptions(providerConfig.rate_limits);
|
|
913
|
+
}
|
|
914
|
+
config = registryConfig;
|
|
915
|
+
} catch {
|
|
916
|
+
}
|
|
917
|
+
const bucketFactory = shouldUseDistributedRateLimiting() ? createFileBucketFactory() : void 0;
|
|
918
|
+
const registry = new RateLimiterRegistry(defaultOptions, bucketFactory);
|
|
919
|
+
if (config) {
|
|
920
|
+
const registryConfig = config;
|
|
921
|
+
for (const [provider, providerConfig] of Object.entries(registryConfig.providers)) {
|
|
922
|
+
if (providerConfig.rate_limits?.models) {
|
|
923
|
+
for (const [model, modelConfig] of Object.entries(providerConfig.rate_limits.models)) {
|
|
924
|
+
registry.getBucket(provider, model, {
|
|
925
|
+
bucketSize: modelConfig.bucket_size,
|
|
926
|
+
refillRate: resolveRefillRate(modelConfig)
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
return registry;
|
|
933
|
+
}
|
|
934
|
+
function getRateLimitOptions(providerId, modelId) {
|
|
935
|
+
try {
|
|
936
|
+
const config = ProviderRegistry.load();
|
|
937
|
+
const providerConfig = config.providers[providerId];
|
|
938
|
+
const rateLimits = providerConfig?.rate_limits;
|
|
939
|
+
const modelConfig = modelId ? rateLimits?.models?.[modelId] : void 0;
|
|
940
|
+
if (modelConfig) {
|
|
941
|
+
return {
|
|
942
|
+
bucketSize: modelConfig.bucket_size,
|
|
943
|
+
refillRate: resolveRefillRate(modelConfig)
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
if (rateLimits) {
|
|
947
|
+
return configToOptions(rateLimits);
|
|
948
|
+
}
|
|
949
|
+
if (config.defaults?.rate_limits) {
|
|
950
|
+
return configToOptions(config.defaults.rate_limits);
|
|
951
|
+
}
|
|
952
|
+
} catch {
|
|
953
|
+
}
|
|
954
|
+
return DEFAULT_RATE_LIMITS;
|
|
955
|
+
}
|
|
956
|
+
var globalRegistry = null;
|
|
957
|
+
function getGlobalRateLimiterRegistry() {
|
|
958
|
+
if (!globalRegistry) {
|
|
959
|
+
globalRegistry = createRateLimiterFromConfig();
|
|
960
|
+
}
|
|
961
|
+
return globalRegistry;
|
|
962
|
+
}
|
|
963
|
+
function clearGlobalRateLimiterRegistryCache() {
|
|
964
|
+
globalRegistry = null;
|
|
965
|
+
}
|
|
966
|
+
registerProviderRegistryReloadInvalidator(clearGlobalRateLimiterRegistryCache);
|
|
967
|
+
function resetGlobalRateLimiterRegistry() {
|
|
968
|
+
if (globalRegistry) {
|
|
969
|
+
globalRegistry.clear();
|
|
970
|
+
globalRegistry = null;
|
|
971
|
+
}
|
|
972
|
+
if (shouldUseDistributedRateLimiting()) {
|
|
973
|
+
const stateDir = path2.join(getPoeticProjectRoot(), ".poetic", "rate-limits");
|
|
974
|
+
try {
|
|
975
|
+
if (fsSync.existsSync(stateDir)) {
|
|
976
|
+
for (const entry of fsSync.readdirSync(stateDir)) {
|
|
977
|
+
if (entry.endsWith(".json")) {
|
|
978
|
+
fsSync.rmSync(path2.join(stateDir, entry), { force: true });
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
} catch {
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// src/core/safety/index.ts
|
|
988
|
+
async function acquireRateLimitToken(provider, model, options) {
|
|
989
|
+
const registry = getGlobalRateLimiterRegistry();
|
|
990
|
+
const isNewBucket = !registry.hasBucket(provider, model);
|
|
991
|
+
const bucket = registry.getBucket(provider, model, options ?? {});
|
|
992
|
+
if (isNewBucket && options != null && (typeof options.bucketSize === "number" || typeof options.refillRate === "number")) {
|
|
993
|
+
logDebug(
|
|
994
|
+
"rate-limiter",
|
|
995
|
+
`Created rate limit bucket provider=${provider} model=${model ?? "(default)"} bucketSize=${String(options.bucketSize)} refillRate=${String(options.refillRate)}`
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
await bucket.acquire();
|
|
999
|
+
}
|
|
1000
|
+
var globalRegistry2;
|
|
1001
|
+
var scopedRegistries = /* @__PURE__ */ new Map();
|
|
1002
|
+
function getOrCreateGlobalRegistry() {
|
|
1003
|
+
if (!globalRegistry2) {
|
|
1004
|
+
globalRegistry2 = new CircuitBreakerRegistry();
|
|
1005
|
+
}
|
|
1006
|
+
return globalRegistry2;
|
|
1007
|
+
}
|
|
1008
|
+
function getScopedRegistry(scope) {
|
|
1009
|
+
let registry = scopedRegistries.get(scope);
|
|
1010
|
+
if (!registry) {
|
|
1011
|
+
registry = new CircuitBreakerRegistry();
|
|
1012
|
+
scopedRegistries.set(scope, registry);
|
|
1013
|
+
}
|
|
1014
|
+
return registry;
|
|
1015
|
+
}
|
|
1016
|
+
function clearScopedRegistry(scope) {
|
|
1017
|
+
scopedRegistries.delete(scope);
|
|
1018
|
+
}
|
|
1019
|
+
async function executeWithCircuitBreaker(providerName, fn, options = {}, scope) {
|
|
1020
|
+
const registry = scope ? getScopedRegistry(scope) : getOrCreateGlobalRegistry();
|
|
1021
|
+
const breaker = registry.getBreaker(providerName, options);
|
|
1022
|
+
return await breaker.execute(fn);
|
|
1023
|
+
}
|
|
1024
|
+
function getCircuitBreakerStats(providerName) {
|
|
1025
|
+
const registry = getOrCreateGlobalRegistry();
|
|
1026
|
+
if (!registry.hasBreaker(providerName)) {
|
|
1027
|
+
return null;
|
|
1028
|
+
}
|
|
1029
|
+
return registry.getBreaker(providerName).getMetrics();
|
|
1030
|
+
}
|
|
1031
|
+
function resetCircuitBreaker(providerName) {
|
|
1032
|
+
getOrCreateGlobalRegistry().removeBreaker(providerName);
|
|
1033
|
+
}
|
|
1034
|
+
function resetAllCircuitBreakers() {
|
|
1035
|
+
getOrCreateGlobalRegistry().clear();
|
|
1036
|
+
}
|
|
1037
|
+
function _getGlobalRegistry() {
|
|
1038
|
+
return getOrCreateGlobalRegistry();
|
|
1039
|
+
}
|
|
1040
|
+
function _clearGlobalRegistry() {
|
|
1041
|
+
getOrCreateGlobalRegistry().clear();
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
export {
|
|
1045
|
+
CircuitState,
|
|
1046
|
+
CircuitBreaker,
|
|
1047
|
+
CircuitBreakerError,
|
|
1048
|
+
createCircuitBreakerOptions,
|
|
1049
|
+
CircuitBreakerRegistry,
|
|
1050
|
+
FileTokenBucket,
|
|
1051
|
+
TokenBucket,
|
|
1052
|
+
TokenBucketError,
|
|
1053
|
+
RateLimiterRegistry,
|
|
1054
|
+
createRateLimiterFromConfig,
|
|
1055
|
+
getRateLimitOptions,
|
|
1056
|
+
getGlobalRateLimiterRegistry,
|
|
1057
|
+
resetGlobalRateLimiterRegistry,
|
|
1058
|
+
acquireRateLimitToken,
|
|
1059
|
+
getScopedRegistry,
|
|
1060
|
+
clearScopedRegistry,
|
|
1061
|
+
executeWithCircuitBreaker,
|
|
1062
|
+
getCircuitBreakerStats,
|
|
1063
|
+
resetCircuitBreaker,
|
|
1064
|
+
resetAllCircuitBreakers,
|
|
1065
|
+
_getGlobalRegistry,
|
|
1066
|
+
_clearGlobalRegistry
|
|
1067
|
+
};
|
|
1068
|
+
//# sourceMappingURL=chunk-MWK5UZQ3.js.map
|