@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,2206 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getTelemetryLogger
|
|
3
|
+
} from "./chunk-U6C3VVWS.js";
|
|
4
|
+
import {
|
|
5
|
+
SCHEMA_INVARIANTS,
|
|
6
|
+
VARIANT_EXECUTION_COLUMNS
|
|
7
|
+
} from "./chunk-FYOILAN5.js";
|
|
8
|
+
import {
|
|
9
|
+
projectScope
|
|
10
|
+
} from "./chunk-GAFJEYLK.js";
|
|
11
|
+
import {
|
|
12
|
+
TelemetryPathResolver
|
|
13
|
+
} from "./chunk-ZDTGECTN.js";
|
|
14
|
+
import {
|
|
15
|
+
emitTelemetryFallbackWarning
|
|
16
|
+
} from "./chunk-YMX76IOS.js";
|
|
17
|
+
import {
|
|
18
|
+
getSqliteBusyTimeoutMs
|
|
19
|
+
} from "./chunk-QGJDMEOV.js";
|
|
20
|
+
import {
|
|
21
|
+
LabPathResolver
|
|
22
|
+
} from "./chunk-7GDRQBQC.js";
|
|
23
|
+
import {
|
|
24
|
+
getGlobalTelemetryDir
|
|
25
|
+
} from "./chunk-UUH2RVKS.js";
|
|
26
|
+
import {
|
|
27
|
+
emitWarning
|
|
28
|
+
} from "./chunk-EJGCZGUF.js";
|
|
29
|
+
|
|
30
|
+
// src/telemetry/dashboard.ts
|
|
31
|
+
import fs from "fs";
|
|
32
|
+
import path from "path";
|
|
33
|
+
import Database from "better-sqlite3";
|
|
34
|
+
var TelemetryDashboard = class _TelemetryDashboard {
|
|
35
|
+
/**
|
|
36
|
+
* Exclude synthetic test rows from dashboard queries.
|
|
37
|
+
* Tests that leak into the real DB typically have NULL verdict and/or task IDs
|
|
38
|
+
* prefixed with common test IDs (test-* and task-*).
|
|
39
|
+
* Without this filter, synthetic rows appear as failures and distort success-rate metrics.
|
|
40
|
+
*/
|
|
41
|
+
static REAL_DATA_FILTER = "verdict IS NOT NULL AND verdict != '' AND task_id NOT LIKE 'test-%' AND task_id NOT LIKE 'task-%'";
|
|
42
|
+
/** SQLite database connection for variant execution telemetry */
|
|
43
|
+
variantsDb;
|
|
44
|
+
/** SQLite database connection for validation telemetry */
|
|
45
|
+
validationsDb;
|
|
46
|
+
enabled = true;
|
|
47
|
+
projectScopeWhere;
|
|
48
|
+
projectScopeParams;
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new TelemetryDashboard instance
|
|
51
|
+
*
|
|
52
|
+
* Establishes connections to SQLite telemetry databases in .poetic/telemetry/db/
|
|
53
|
+
*
|
|
54
|
+
* @param options - Configuration options
|
|
55
|
+
* @throws {Error} If database files cannot be accessed
|
|
56
|
+
*/
|
|
57
|
+
constructor(options = {}) {
|
|
58
|
+
const poeticDir = options.poeticDir || path.join(process.cwd(), ".poetic");
|
|
59
|
+
const resolver = TelemetryPathResolver.getInstance();
|
|
60
|
+
const dbDir = resolver.resolveDbDir(poeticDir);
|
|
61
|
+
const projectId = options.projectId?.trim() || resolver.getProjectId(poeticDir, { register: false });
|
|
62
|
+
const isGlobalDb = path.resolve(dbDir) === path.resolve(path.join(getGlobalTelemetryDir(), "db"));
|
|
63
|
+
const tenancyScope = projectScope(projectId, {
|
|
64
|
+
includeLabs: true,
|
|
65
|
+
includeLegacyProjectRows: !isGlobalDb,
|
|
66
|
+
legacyProjectIds: [""]
|
|
67
|
+
});
|
|
68
|
+
this.projectScopeWhere = tenancyScope.where;
|
|
69
|
+
this.projectScopeParams = tenancyScope.params;
|
|
70
|
+
try {
|
|
71
|
+
if (!fs.existsSync(dbDir)) {
|
|
72
|
+
fs.mkdirSync(dbDir, { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
this.variantsDb = new Database(path.join(dbDir, "variants.db"));
|
|
75
|
+
this.validationsDb = new Database(path.join(dbDir, "validations.db"));
|
|
76
|
+
try {
|
|
77
|
+
this.variantsDb.pragma("journal_mode = WAL");
|
|
78
|
+
} catch {
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
this.variantsDb.pragma(`busy_timeout = ${getSqliteBusyTimeoutMs()}`);
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
this.validationsDb.pragma("journal_mode = WAL");
|
|
86
|
+
} catch {
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
this.validationsDb.pragma(`busy_timeout = ${getSqliteBusyTimeoutMs()}`);
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
this.enabled = true;
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.warn(
|
|
95
|
+
"Telemetry dashboard: directory creation failed, attempting to open DB files directly",
|
|
96
|
+
err
|
|
97
|
+
);
|
|
98
|
+
try {
|
|
99
|
+
this.variantsDb = new Database(path.join(dbDir, "variants.db"));
|
|
100
|
+
this.validationsDb = new Database(path.join(dbDir, "validations.db"));
|
|
101
|
+
try {
|
|
102
|
+
this.variantsDb.pragma("journal_mode = WAL");
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
this.variantsDb.pragma(`busy_timeout = ${getSqliteBusyTimeoutMs()}`);
|
|
107
|
+
} catch {
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
this.validationsDb.pragma("journal_mode = WAL");
|
|
111
|
+
} catch {
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
this.validationsDb.pragma(`busy_timeout = ${getSqliteBusyTimeoutMs()}`);
|
|
115
|
+
} catch {
|
|
116
|
+
}
|
|
117
|
+
this.enabled = true;
|
|
118
|
+
} catch (err2) {
|
|
119
|
+
emitWarning(
|
|
120
|
+
"CFG-002",
|
|
121
|
+
{
|
|
122
|
+
taskId: "system",
|
|
123
|
+
subsystem: "telemetry",
|
|
124
|
+
executionPhase: "setup"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
severity: "ERROR" /* ERROR */,
|
|
128
|
+
metadata: {
|
|
129
|
+
operation: "dashboard_initialization",
|
|
130
|
+
error: err2 instanceof Error ? err2.message : String(err2),
|
|
131
|
+
dbDir
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
this.variantsDb = new Database(":memory:");
|
|
136
|
+
this.validationsDb = new Database(":memory:");
|
|
137
|
+
this.enabled = false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Returns true if the dashboard has persistent DB backing (not in-memory fallback) */
|
|
142
|
+
isEnabled() {
|
|
143
|
+
return this.enabled;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Retrieve leaderboard data with optional advanced metrics and CI bounds.
|
|
147
|
+
* Returns structured rows for programmatic consumption (CLI export, UI).
|
|
148
|
+
*/
|
|
149
|
+
getLeaderboardData(options = {}) {
|
|
150
|
+
const filters = [
|
|
151
|
+
this.projectScopeWhere,
|
|
152
|
+
"completed_at IS NOT NULL",
|
|
153
|
+
_TelemetryDashboard.REAL_DATA_FILTER
|
|
154
|
+
];
|
|
155
|
+
const params = [...this.projectScopeParams];
|
|
156
|
+
if (options.taskId && options.taskId.trim() !== "") {
|
|
157
|
+
filters.push("task_id = ?");
|
|
158
|
+
params.push(options.taskId.trim());
|
|
159
|
+
}
|
|
160
|
+
let baseQuery = `
|
|
161
|
+
SELECT
|
|
162
|
+
variant,
|
|
163
|
+
COUNT(*) as total_tasks,
|
|
164
|
+
SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) as successes,
|
|
165
|
+
CAST(SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) as success_rate,
|
|
166
|
+
AVG(completeness) as avg_completeness,
|
|
167
|
+
AVG(total_duration_sec) as avg_duration_sec,
|
|
168
|
+
MIN(started_at) as first_execution,
|
|
169
|
+
MAX(started_at) as last_execution
|
|
170
|
+
FROM variant_executions
|
|
171
|
+
WHERE ${filters.join(" AND ")}
|
|
172
|
+
GROUP BY variant
|
|
173
|
+
`;
|
|
174
|
+
const limit = typeof options.limit === "number" && Number.isFinite(options.limit) && options.limit > 0 ? Math.floor(options.limit) : void 0;
|
|
175
|
+
if (limit !== void 0) {
|
|
176
|
+
baseQuery += " ORDER BY total_tasks DESC LIMIT ?";
|
|
177
|
+
params.push(limit);
|
|
178
|
+
}
|
|
179
|
+
const stmt = this.variantsDb.prepare(baseQuery);
|
|
180
|
+
const rows = params.length ? stmt.all(...params) : stmt.all();
|
|
181
|
+
if (!rows) {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
const result = rows.map((row) => {
|
|
185
|
+
const enriched = { ...row };
|
|
186
|
+
if (options.includeCI) {
|
|
187
|
+
const { lower, upper, width } = this.wilsonCI(row.success_rate, row.total_tasks);
|
|
188
|
+
enriched.ci_lower = lower;
|
|
189
|
+
enriched.ci_upper = upper;
|
|
190
|
+
enriched.ci_width = width;
|
|
191
|
+
}
|
|
192
|
+
return enriched;
|
|
193
|
+
});
|
|
194
|
+
if (options.includeFScore) {
|
|
195
|
+
const perVariantConf = this.computeConfusionByVariant();
|
|
196
|
+
result.forEach((row) => {
|
|
197
|
+
const conf = perVariantConf.get(row.variant);
|
|
198
|
+
if (!conf) {
|
|
199
|
+
Object.assign(row, {
|
|
200
|
+
precision: null,
|
|
201
|
+
recall: null,
|
|
202
|
+
f1: null,
|
|
203
|
+
f05: null,
|
|
204
|
+
f2: null,
|
|
205
|
+
mcc: null,
|
|
206
|
+
balanced_accuracy: null
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const { tp, fp, tn, fn } = conf;
|
|
211
|
+
const precision = tp + fp > 0 ? tp / (tp + fp) : null;
|
|
212
|
+
const recall = tp + fn > 0 ? tp / (tp + fn) : null;
|
|
213
|
+
const f1 = precision && recall && precision + recall > 0 ? 2 * precision * recall / (precision + recall) : null;
|
|
214
|
+
const beta05 = 0.5;
|
|
215
|
+
const f05 = precision && recall && beta05 * beta05 * precision + recall > 0 ? (1 + beta05 * beta05) * precision * recall / (beta05 * beta05 * precision + recall) : null;
|
|
216
|
+
const beta2 = 2;
|
|
217
|
+
const f2 = precision && recall && beta2 * beta2 * precision + recall > 0 ? (1 + beta2 * beta2) * precision * recall / (beta2 * beta2 * precision + recall) : null;
|
|
218
|
+
const tpr = tp + fn > 0 ? tp / (tp + fn) : null;
|
|
219
|
+
const tnr = tn + fp > 0 ? tn / (tn + fp) : null;
|
|
220
|
+
const balancedAccuracy = tpr !== null && tnr !== null ? (tpr + tnr) / 2 : null;
|
|
221
|
+
const mccDen = Math.sqrt((tp + fp) * (tp + fn) * (tn + fp) * (tn + fn));
|
|
222
|
+
const mcc = mccDen > 0 ? (tp * tn - fp * fn) / mccDen : null;
|
|
223
|
+
Object.assign(row, {
|
|
224
|
+
precision,
|
|
225
|
+
recall,
|
|
226
|
+
f1,
|
|
227
|
+
f05,
|
|
228
|
+
f2,
|
|
229
|
+
mcc,
|
|
230
|
+
balanced_accuracy: balancedAccuracy
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Retrieve prompt performance data with optional CI and F-scores.
|
|
238
|
+
* Grouped by prompt_version with per-variant breakdowns.
|
|
239
|
+
*/
|
|
240
|
+
getPromptPerformanceData(options = {}) {
|
|
241
|
+
const query = `
|
|
242
|
+
SELECT
|
|
243
|
+
variant,
|
|
244
|
+
prompt_version,
|
|
245
|
+
COUNT(*) as sample_size,
|
|
246
|
+
CAST(SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) as success_rate
|
|
247
|
+
FROM variant_executions
|
|
248
|
+
WHERE ${this.projectScopeWhere}
|
|
249
|
+
AND completed_at IS NOT NULL AND prompt_version IS NOT NULL
|
|
250
|
+
AND ${_TelemetryDashboard.REAL_DATA_FILTER}
|
|
251
|
+
GROUP BY variant, prompt_version
|
|
252
|
+
ORDER BY variant, prompt_version
|
|
253
|
+
`;
|
|
254
|
+
const rows = this.variantsDb.prepare(query).all(...this.projectScopeParams);
|
|
255
|
+
if (rows.length === 0) return [];
|
|
256
|
+
const confByVariantPrompt = options.includeFScore ? this.computeConfusionByVariantPrompt() : /* @__PURE__ */ new Map();
|
|
257
|
+
const byPrompt = /* @__PURE__ */ new Map();
|
|
258
|
+
rows.forEach((r) => {
|
|
259
|
+
const arr = byPrompt.get(r.prompt_version) || [];
|
|
260
|
+
const enriched = {
|
|
261
|
+
variant: r.variant,
|
|
262
|
+
prompt_version: r.prompt_version,
|
|
263
|
+
total_tasks: r.sample_size,
|
|
264
|
+
successes: Math.round(r.success_rate * r.sample_size),
|
|
265
|
+
success_rate: r.success_rate,
|
|
266
|
+
avg_completeness: null,
|
|
267
|
+
// Not available in this query
|
|
268
|
+
sample_size: r.sample_size
|
|
269
|
+
};
|
|
270
|
+
if (options.includeCI) {
|
|
271
|
+
const { lower, upper } = this.wilsonCI(r.success_rate, r.sample_size);
|
|
272
|
+
enriched.ci_lower = lower;
|
|
273
|
+
enriched.ci_upper = upper;
|
|
274
|
+
}
|
|
275
|
+
if (options.includeFScore) {
|
|
276
|
+
const key = `${r.variant}@@${r.prompt_version}`;
|
|
277
|
+
const conf = confByVariantPrompt.get(key);
|
|
278
|
+
if (conf) {
|
|
279
|
+
const { tp, fp, fn } = conf;
|
|
280
|
+
const precision = tp + fp > 0 ? tp / (tp + fp) : null;
|
|
281
|
+
const recall = tp + fn > 0 ? tp / (tp + fn) : null;
|
|
282
|
+
const f1 = precision && recall && precision + recall > 0 ? 2 * precision * recall / (precision + recall) : null;
|
|
283
|
+
const b05 = 0.5, b2 = 2;
|
|
284
|
+
const f05 = precision && recall && b05 * b05 * precision + recall > 0 ? (1 + b05 * b05) * precision * recall / (b05 * b05 * precision + recall) : null;
|
|
285
|
+
const f2 = precision && recall && b2 * b2 * precision + recall > 0 ? (1 + b2 * b2) * precision * recall / (b2 * b2 * precision + recall) : null;
|
|
286
|
+
Object.assign(enriched, { precision, recall, f1, f05, f2 });
|
|
287
|
+
} else {
|
|
288
|
+
Object.assign(enriched, {
|
|
289
|
+
precision: null,
|
|
290
|
+
recall: null,
|
|
291
|
+
f1: null,
|
|
292
|
+
f05: null,
|
|
293
|
+
f2: null
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
arr.push(enriched);
|
|
298
|
+
byPrompt.set(r.prompt_version, arr);
|
|
299
|
+
});
|
|
300
|
+
const result = [];
|
|
301
|
+
for (const [prompt, arr] of byPrompt.entries()) {
|
|
302
|
+
const avgSuccessRate = arr.reduce((s, v) => s + v.success_rate, 0) / arr.length;
|
|
303
|
+
const totalSamples = arr.reduce((s, v) => s + v.sample_size, 0);
|
|
304
|
+
const mean = avgSuccessRate;
|
|
305
|
+
const variance = arr.reduce((s, v) => s + (v.success_rate - mean) ** 2, 0) / arr.length;
|
|
306
|
+
const consistencyScore = Math.max(0, 1 - Math.sqrt(variance));
|
|
307
|
+
const shouldPrune = avgSuccessRate < 0.5 || totalSamples < 3 || consistencyScore < 0.3;
|
|
308
|
+
result.push({
|
|
309
|
+
prompt_version: prompt,
|
|
310
|
+
total_samples: totalSamples,
|
|
311
|
+
avg_success_rate: avgSuccessRate,
|
|
312
|
+
consistency_score: consistencyScore,
|
|
313
|
+
should_prune: shouldPrune,
|
|
314
|
+
variants: arr.map((v) => ({
|
|
315
|
+
variant: String(v.variant),
|
|
316
|
+
sample_size: v.sample_size,
|
|
317
|
+
success_rate: v.success_rate,
|
|
318
|
+
ci_lower: v.ci_lower,
|
|
319
|
+
ci_upper: v.ci_upper,
|
|
320
|
+
precision: v.precision,
|
|
321
|
+
recall: v.recall,
|
|
322
|
+
f1: v.f1,
|
|
323
|
+
f05: v.f05,
|
|
324
|
+
f2: v.f2
|
|
325
|
+
}))
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
return result.sort(
|
|
329
|
+
(a, b) => b.avg_success_rate * 0.7 + b.consistency_score * 0.3 - (a.avg_success_rate * 0.7 + a.consistency_score * 0.3)
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Retrieve trend data with optional CI and validation fusion (warnings/errors).
|
|
334
|
+
*/
|
|
335
|
+
getTrendsData(limit = 10, options = {}) {
|
|
336
|
+
const query = `
|
|
337
|
+
SELECT task_id, variant, verdict, completeness, started_at, total_duration_sec
|
|
338
|
+
FROM variant_executions
|
|
339
|
+
WHERE ${this.projectScopeWhere}
|
|
340
|
+
AND completed_at IS NOT NULL
|
|
341
|
+
AND ${_TelemetryDashboard.REAL_DATA_FILTER}
|
|
342
|
+
ORDER BY started_at DESC
|
|
343
|
+
LIMIT ?
|
|
344
|
+
`;
|
|
345
|
+
const rows = this.variantsDb.prepare(query).all(...this.projectScopeParams, limit * 3);
|
|
346
|
+
if (rows.length === 0) return [];
|
|
347
|
+
const byVariant = {};
|
|
348
|
+
rows.forEach((r) => {
|
|
349
|
+
if (!byVariant[r.variant]) {
|
|
350
|
+
byVariant[r.variant] = [];
|
|
351
|
+
}
|
|
352
|
+
const variantArray = byVariant[r.variant];
|
|
353
|
+
if (variantArray) {
|
|
354
|
+
variantArray.push(r);
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
const out = [];
|
|
358
|
+
for (const variant of Object.keys(byVariant)) {
|
|
359
|
+
const variantData = byVariant[variant];
|
|
360
|
+
if (!variantData) continue;
|
|
361
|
+
const tasks = variantData.slice(0, limit);
|
|
362
|
+
const successes = tasks.filter((t) => t.verdict === "success").length;
|
|
363
|
+
const successRate = tasks.length > 0 ? successes / tasks.length : 0;
|
|
364
|
+
const avgCompleteness = tasks.reduce((s, t) => s + (t.completeness || 0), 0) / (tasks.length || 1);
|
|
365
|
+
const recentWindow = Math.min(5, Math.floor(tasks.length / 2));
|
|
366
|
+
const olderWindow = Math.min(5, tasks.length - recentWindow);
|
|
367
|
+
const recentTasks = tasks.slice(0, recentWindow);
|
|
368
|
+
const olderTasks = tasks.slice(recentWindow, recentWindow + olderWindow);
|
|
369
|
+
const recentSuccess = recentTasks.length ? recentTasks.filter((t) => t.verdict === "success").length / recentTasks.length : 0;
|
|
370
|
+
const olderSuccess = olderTasks.length ? olderTasks.filter((t) => t.verdict === "success").length / olderTasks.length : recentSuccess;
|
|
371
|
+
const delta = (recentSuccess - olderSuccess) * 100;
|
|
372
|
+
const entry = {
|
|
373
|
+
variant,
|
|
374
|
+
tasks: tasks.length,
|
|
375
|
+
success_rate: successRate,
|
|
376
|
+
avg_completeness: avgCompleteness,
|
|
377
|
+
recent_success_rate: recentSuccess,
|
|
378
|
+
older_success_rate: olderSuccess,
|
|
379
|
+
delta_pp: delta,
|
|
380
|
+
trend: delta > 5 ? "improving" : delta < -5 ? "declining" : "stable"
|
|
381
|
+
};
|
|
382
|
+
if (options.includeCI) {
|
|
383
|
+
const { lower, upper } = this.wilsonCI(successRate, tasks.length);
|
|
384
|
+
entry.ci_lower = lower;
|
|
385
|
+
entry.ci_upper = upper;
|
|
386
|
+
}
|
|
387
|
+
if (options.includeValidationFusion) {
|
|
388
|
+
const taskIds = tasks.map((t) => t.task_id);
|
|
389
|
+
if (taskIds.length) {
|
|
390
|
+
const placeholders = taskIds.map(() => "?").join(",");
|
|
391
|
+
const validations = this.validationsDb.prepare(
|
|
392
|
+
`SELECT task_id, AVG(warnings_count) as avg_warn, AVG(errors_count) as avg_err
|
|
393
|
+
FROM validations WHERE ${this.projectScopeWhere}
|
|
394
|
+
AND task_id IN (${placeholders}) GROUP BY task_id`
|
|
395
|
+
).all(...this.projectScopeParams, ...taskIds);
|
|
396
|
+
const avgWarn = validations.reduce((s, v) => s + (v.avg_warn || 0), 0) / (validations.length || 1);
|
|
397
|
+
const avgErr = validations.reduce((s, v) => s + (v.avg_err || 0), 0) / (validations.length || 1);
|
|
398
|
+
entry.avg_validation_warnings = avgWarn;
|
|
399
|
+
entry.avg_validation_errors = avgErr;
|
|
400
|
+
entry.brittle_success = successRate >= 0.8 && (avgErr > 0 || avgWarn >= 2);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
out.push(entry);
|
|
404
|
+
}
|
|
405
|
+
return out;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Generate variant performance leaderboard
|
|
409
|
+
*
|
|
410
|
+
* Queries the variant_executions table to rank all variants by a weighted score
|
|
411
|
+
* combining success rate and completeness. Displays comprehensive performance
|
|
412
|
+
* metrics in a formatted table with insights.
|
|
413
|
+
*
|
|
414
|
+
* **SQL Query Details:**
|
|
415
|
+
* - **Table:** variant_executions
|
|
416
|
+
* - **Filters:** completed_at IS NOT NULL (excludes in-flight executions)
|
|
417
|
+
* - **Groups by:** variant
|
|
418
|
+
* - **Orders by:** Weighted score DESC
|
|
419
|
+
*
|
|
420
|
+
* **Scoring Formula:**
|
|
421
|
+
* ```
|
|
422
|
+
* score = (success_rate × 0.5) + (avg_completeness / 100 × 0.5)
|
|
423
|
+
* ```
|
|
424
|
+
*
|
|
425
|
+
* **Metrics Calculated:**
|
|
426
|
+
* - Total tasks executed
|
|
427
|
+
* - Success count and rate
|
|
428
|
+
* - Average completeness percentage
|
|
429
|
+
* - Average execution duration
|
|
430
|
+
* - First and last execution timestamps
|
|
431
|
+
*
|
|
432
|
+
* **Output Format:**
|
|
433
|
+
* - Table header with scoring explanation
|
|
434
|
+
* - Ranked rows: Rank | Variant | Score | Success Rate | Completeness | Duration | Tasks
|
|
435
|
+
* - Performance insights: Best performer and improvement opportunity
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```typescript
|
|
439
|
+
* dashboard.leaderboard();
|
|
440
|
+
* // Output:
|
|
441
|
+
* //
|
|
442
|
+
* // Ranked by weighted score: (success_rate × 0.5) + (completeness × 0.5)
|
|
443
|
+
* //
|
|
444
|
+
* // Rank | Variant | Score | Success Rate | Completeness | Duration | Tasks
|
|
445
|
+
* //
|
|
446
|
+
* // 1 | CLAUDE | 87.3 | 85.0% | 89.5% | 45s | 20
|
|
447
|
+
* // 2 | CURSOR | 82.1 | 80.0% | 84.2% | 38s | 15
|
|
448
|
+
* // ...
|
|
449
|
+
* ```
|
|
450
|
+
*
|
|
451
|
+
* @returns {void} Prints formatted leaderboard to console
|
|
452
|
+
*/
|
|
453
|
+
leaderboard(options = {}) {
|
|
454
|
+
try {
|
|
455
|
+
const results = this.getLeaderboardData({
|
|
456
|
+
includeCI: true,
|
|
457
|
+
includeFScore: true,
|
|
458
|
+
taskId: options.taskId,
|
|
459
|
+
limit: options.limit
|
|
460
|
+
});
|
|
461
|
+
if (results.length === 0) {
|
|
462
|
+
console.log("No variant execution data available.");
|
|
463
|
+
console.log(" Run some tasks to generate telemetry data.");
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
console.log("\nVariant Performance Leaderboard");
|
|
467
|
+
console.log("Ranked by weighted score: (success_rate \xD7 0.5) + (completeness \xD7 0.5)");
|
|
468
|
+
console.log("Rank | Variant | Score | Success Rate | Completeness | Duration | Tasks");
|
|
469
|
+
const computeScore = (r) => r.avg_completeness != null ? r.success_rate * 0.5 + r.avg_completeness / 100 * 0.5 : r.success_rate;
|
|
470
|
+
results.slice().sort((a, b) => computeScore(a) < computeScore(b) ? 1 : -1).forEach((row, i) => {
|
|
471
|
+
const score = computeScore(row) * 100;
|
|
472
|
+
const successRate = (row.success_rate * 100).toFixed(1);
|
|
473
|
+
const completeness = row.avg_completeness != null ? row.avg_completeness.toFixed(1) : "N/A";
|
|
474
|
+
const duration = row.avg_duration_sec ? `${Math.round(row.avg_duration_sec)}s` : "N/A";
|
|
475
|
+
const variantPadded = row.variant.toUpperCase().padEnd(12);
|
|
476
|
+
const scorePadded = `${score.toFixed(1)}`.padStart(5);
|
|
477
|
+
const successPadded = `${successRate}%`.padStart(12);
|
|
478
|
+
const completenessPadded = `${completeness}%`.padStart(12);
|
|
479
|
+
const durationPadded = duration.padStart(8);
|
|
480
|
+
const tasksPadded = row.total_tasks.toString().padStart(5);
|
|
481
|
+
console.log(
|
|
482
|
+
`${(i + 1).toString().padStart(4)} | ${variantPadded} | ${scorePadded} | ${successPadded} | ${completenessPadded} | ${durationPadded} | ${tasksPadded}`
|
|
483
|
+
);
|
|
484
|
+
const ciLower = row.ci_lower !== void 0 ? (row.ci_lower * 100).toFixed(1) : null;
|
|
485
|
+
const ciUpper = row.ci_upper !== void 0 ? (row.ci_upper * 100).toFixed(1) : null;
|
|
486
|
+
if (ciLower !== null && ciUpper !== null) {
|
|
487
|
+
console.log(
|
|
488
|
+
` CI95: [${ciLower}%, ${ciUpper}%] ` + (row.f1 != null ? `F1: ${(row.f1 * 100).toFixed(1)} F0.5: ${row.f05 != null ? (row.f05 * 100).toFixed(1) : "\u2014"} F2: ${row.f2 != null ? (row.f2 * 100).toFixed(1) : "\u2014"}` : "")
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
const sorted = results.slice().sort((a, b) => computeScore(a) < computeScore(b) ? 1 : -1);
|
|
493
|
+
const best = sorted[0];
|
|
494
|
+
const worst = sorted[sorted.length - 1];
|
|
495
|
+
if (best && worst) {
|
|
496
|
+
console.log(
|
|
497
|
+
`
|
|
498
|
+
Best Performer: ${best.variant.toUpperCase()} (${(computeScore(best) * 100).toFixed(1)}/100)`
|
|
499
|
+
);
|
|
500
|
+
console.log(
|
|
501
|
+
`Improvement Opportunity: ${worst.variant.toUpperCase()} (${(computeScore(worst) * 100).toFixed(1)}/100)`
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
if (sorted.length >= 2) {
|
|
505
|
+
const a = sorted[0];
|
|
506
|
+
const b = sorted[1];
|
|
507
|
+
if (!a || !b) return;
|
|
508
|
+
const { lower: aL, upper: aU } = this.wilsonCI(a.success_rate, a.total_tasks);
|
|
509
|
+
const { lower: bL, upper: bU } = this.wilsonCI(b.success_rate, b.total_tasks);
|
|
510
|
+
const overlap = !(aL > bU || bL > aU);
|
|
511
|
+
const p = this.twoProportionPValue(
|
|
512
|
+
a.successes,
|
|
513
|
+
a.total_tasks - a.successes,
|
|
514
|
+
b.successes,
|
|
515
|
+
b.total_tasks - b.successes
|
|
516
|
+
);
|
|
517
|
+
if (!overlap && p < 0.05) {
|
|
518
|
+
console.log(
|
|
519
|
+
"Significance: Statistically higher than runner-up (p<0.05). Likely truly better."
|
|
520
|
+
);
|
|
521
|
+
} else {
|
|
522
|
+
console.log("Significance: Likely indistinguishable at 95% CI. Collect more data.");
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
} catch (error) {
|
|
526
|
+
console.error("Error generating leaderboard:", error.message);
|
|
527
|
+
console.log(" Ensure telemetry database exists and contains data.");
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Analyze prompt performance across variants
|
|
532
|
+
*
|
|
533
|
+
* Queries variant_executions grouped by prompt_version to identify:
|
|
534
|
+
* - Reliable prompts (high success rate, low variance)
|
|
535
|
+
* - Unreliable prompts (low success rate, high variance)
|
|
536
|
+
* - Prompts that should be pruned
|
|
537
|
+
*
|
|
538
|
+
* **SQL Query Details:**
|
|
539
|
+
* - **Table:** variant_executions
|
|
540
|
+
* - **Filters:** completed_at IS NOT NULL AND prompt_version IS NOT NULL
|
|
541
|
+
* - **Groups by:** variant, prompt_version
|
|
542
|
+
* - **Orders by:** variant, prompt_version
|
|
543
|
+
*
|
|
544
|
+
* **Analysis Methodology:**
|
|
545
|
+
* 1. **Success Rate:** Average success across all variants for this prompt
|
|
546
|
+
* 2. **Consistency Score:** 1 - sqrt(variance) where variance measures success rate spread
|
|
547
|
+
* 3. **Overall Score:** success_rate × 0.7 + consistency_score × 0.3
|
|
548
|
+
* 4. **Prune Recommendations:** Flags prompts with:
|
|
549
|
+
* - Success rate < 50%
|
|
550
|
+
* - Sample size < 3
|
|
551
|
+
* - Consistency score < 0.3
|
|
552
|
+
*
|
|
553
|
+
* **Metrics Per Prompt:**
|
|
554
|
+
* - Overall success rate across all variants
|
|
555
|
+
* - Consistency score (0-100, higher = more consistent)
|
|
556
|
+
* - Total sample size (sum across variants)
|
|
557
|
+
* - Per-variant breakdown with success rates
|
|
558
|
+
* - Pruning recommendation if applicable
|
|
559
|
+
*
|
|
560
|
+
* **Status Indicators:**
|
|
561
|
+
* - EXCELLENT: ≥80% success rate
|
|
562
|
+
* - GOOD: ≥60% success rate
|
|
563
|
+
* - Fair: FAIR: ≥50% success rate
|
|
564
|
+
* - PRUNE: <50% success rate or poor consistency
|
|
565
|
+
*
|
|
566
|
+
* @example
|
|
567
|
+
* ```typescript
|
|
568
|
+
* dashboard.promptPerformance();
|
|
569
|
+
* // Output:
|
|
570
|
+
* // Prompt: v2.1.0 EXCELLENT
|
|
571
|
+
* //
|
|
572
|
+
* // Overall Success Rate: 85.0%
|
|
573
|
+
* // Consistency Score: 92.3%
|
|
574
|
+
* // Total Sample Size: 45
|
|
575
|
+
* // Variant Breakdown:
|
|
576
|
+
* // claude : 87.5% success (n=16)
|
|
577
|
+
* // cursor : 82.4% success (n=17)
|
|
578
|
+
* // codex : 75.0% success (n=12)
|
|
579
|
+
* // ...
|
|
580
|
+
* ```
|
|
581
|
+
*
|
|
582
|
+
* @returns {void} Prints formatted prompt analysis to console
|
|
583
|
+
*/
|
|
584
|
+
promptPerformance() {
|
|
585
|
+
try {
|
|
586
|
+
const query = `
|
|
587
|
+
SELECT
|
|
588
|
+
variant,
|
|
589
|
+
prompt_version,
|
|
590
|
+
COUNT(*) as sample_size,
|
|
591
|
+
CAST(SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) as success_rate,
|
|
592
|
+
AVG(completeness) as avg_completeness,
|
|
593
|
+
MIN(started_at) as first_used,
|
|
594
|
+
MAX(started_at) as last_used
|
|
595
|
+
FROM variant_executions
|
|
596
|
+
WHERE ${this.projectScopeWhere}
|
|
597
|
+
AND completed_at IS NOT NULL AND prompt_version IS NOT NULL
|
|
598
|
+
AND ${_TelemetryDashboard.REAL_DATA_FILTER}
|
|
599
|
+
GROUP BY variant, prompt_version
|
|
600
|
+
ORDER BY variant, prompt_version
|
|
601
|
+
`;
|
|
602
|
+
const results = this.variantsDb.prepare(query).all(...this.projectScopeParams);
|
|
603
|
+
if (results.length === 0) {
|
|
604
|
+
console.log("No prompt performance data available.");
|
|
605
|
+
console.log(" Run tasks with different prompt versions to generate data.");
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
console.log("\nPrompt Performance Analysis");
|
|
609
|
+
const byPrompt = {};
|
|
610
|
+
results.forEach((row) => {
|
|
611
|
+
if (!byPrompt[row.prompt_version]) {
|
|
612
|
+
byPrompt[row.prompt_version] = [];
|
|
613
|
+
}
|
|
614
|
+
const promptArray = byPrompt[row.prompt_version];
|
|
615
|
+
if (promptArray) {
|
|
616
|
+
promptArray.push(row);
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
const promptAnalysis = Object.keys(byPrompt).map((promptVersion) => {
|
|
620
|
+
const variants = byPrompt[promptVersion];
|
|
621
|
+
if (!variants) return null;
|
|
622
|
+
const avgSuccessRate = variants.reduce((sum, v) => sum + v.success_rate, 0) / variants.length;
|
|
623
|
+
const totalSamples = variants.reduce(
|
|
624
|
+
(sum, v) => sum + v.sample_size,
|
|
625
|
+
0
|
|
626
|
+
);
|
|
627
|
+
const successRates = variants.map((v) => v.success_rate);
|
|
628
|
+
const mean = avgSuccessRate;
|
|
629
|
+
const variance = successRates.reduce((sum, rate) => sum + (rate - mean) ** 2, 0) / successRates.length;
|
|
630
|
+
const consistencyScore = Math.max(0, 1 - Math.sqrt(variance));
|
|
631
|
+
const shouldPrune = avgSuccessRate < 0.5 || totalSamples < 3 || consistencyScore < 0.3;
|
|
632
|
+
return {
|
|
633
|
+
promptVersion,
|
|
634
|
+
variants,
|
|
635
|
+
avgSuccessRate,
|
|
636
|
+
totalSamples,
|
|
637
|
+
consistencyScore,
|
|
638
|
+
shouldPrune
|
|
639
|
+
};
|
|
640
|
+
}).filter((a) => a !== null);
|
|
641
|
+
promptAnalysis.sort((a, b) => {
|
|
642
|
+
const scoreA = a.avgSuccessRate * 0.7 + a.consistencyScore * 0.3;
|
|
643
|
+
const scoreB = b.avgSuccessRate * 0.7 + b.consistencyScore * 0.3;
|
|
644
|
+
return scoreB - scoreA;
|
|
645
|
+
});
|
|
646
|
+
promptAnalysis.forEach((analysis) => {
|
|
647
|
+
const {
|
|
648
|
+
promptVersion,
|
|
649
|
+
variants,
|
|
650
|
+
avgSuccessRate,
|
|
651
|
+
totalSamples,
|
|
652
|
+
consistencyScore,
|
|
653
|
+
shouldPrune
|
|
654
|
+
} = analysis;
|
|
655
|
+
const status = shouldPrune ? "PRUNE" : avgSuccessRate >= 0.8 ? "EXCELLENT" : avgSuccessRate >= 0.6 ? "GOOD" : "FAIR";
|
|
656
|
+
console.log(`
|
|
657
|
+
Prompt: ${promptVersion} ${status}`);
|
|
658
|
+
console.log(`Overall Success Rate: ${(avgSuccessRate * 100).toFixed(1)}%`);
|
|
659
|
+
console.log(`Consistency Score: ${(consistencyScore * 100).toFixed(1)}%`);
|
|
660
|
+
console.log(`Total Sample Size: ${totalSamples}`);
|
|
661
|
+
console.log("Variant Breakdown:");
|
|
662
|
+
if (variants) {
|
|
663
|
+
variants.forEach((v) => {
|
|
664
|
+
const performance = v.success_rate >= 0.8 ? "EXCELLENT" : v.success_rate >= 0.6 ? "GOOD" : "PRUNE";
|
|
665
|
+
console.log(
|
|
666
|
+
` ${performance} ${String(v.variant).padEnd(12)}: ${(v.success_rate * 100).toFixed(1)}% success (n=${v.sample_size})`
|
|
667
|
+
);
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
if (shouldPrune) {
|
|
671
|
+
console.log("\nRECOMMENDATION: Consider pruning this prompt version");
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
} catch (error) {
|
|
675
|
+
console.error("Error analyzing prompt performance:", error.message);
|
|
676
|
+
console.log(" Ensure telemetry database exists and contains data.");
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Show historical performance trends over time
|
|
681
|
+
*
|
|
682
|
+
* Queries recent variant executions to analyze performance trends by comparing
|
|
683
|
+
* recent vs. older task outcomes. Useful for identifying improving or declining
|
|
684
|
+
* variant performance over time.
|
|
685
|
+
*
|
|
686
|
+
* **SQL Query Details:**
|
|
687
|
+
* - **Table:** variant_executions
|
|
688
|
+
* - **Filters:** completed_at IS NOT NULL
|
|
689
|
+
* - **Orders by:** started_at DESC (most recent first)
|
|
690
|
+
* - **Limit:** limit × 3 (allows showing limit tasks per variant)
|
|
691
|
+
*
|
|
692
|
+
* **Trend Analysis Methodology:**
|
|
693
|
+
* 1. Splits tasks into two windows per variant:
|
|
694
|
+
* - **Recent window:** Last N/2 tasks (up to 5 tasks)
|
|
695
|
+
* - **Older window:** Previous N/2 tasks (up to 5 tasks)
|
|
696
|
+
* 2. Compares success rates between windows
|
|
697
|
+
* 3. Classifies trend as:
|
|
698
|
+
* - **Improving:** Recent success rate >10% higher
|
|
699
|
+
* - **Stable:** Within ±10% change
|
|
700
|
+
* - **Declining:** Recent success rate >10% lower
|
|
701
|
+
*
|
|
702
|
+
* **Metrics Per Variant:**
|
|
703
|
+
* - Overall success rate (all tasks in window)
|
|
704
|
+
* - Average completeness percentage
|
|
705
|
+
* - Recent window success rate
|
|
706
|
+
* - Older window success rate
|
|
707
|
+
* - Percentage point change with trend indicator
|
|
708
|
+
*
|
|
709
|
+
* @param limit - Maximum number of tasks to show per variant (default: 10)
|
|
710
|
+
*
|
|
711
|
+
* @example
|
|
712
|
+
* ```typescript
|
|
713
|
+
* dashboard.trends(15);
|
|
714
|
+
* // Output:
|
|
715
|
+
* // CLAUDE
|
|
716
|
+
* //
|
|
717
|
+
* // Overall Performance (15 tasks):
|
|
718
|
+
* // Success Rate: 86.7% (13/15)
|
|
719
|
+
* // Avg Completeness: 88.3%
|
|
720
|
+
* //
|
|
721
|
+
* // Trend Analysis (improving):
|
|
722
|
+
* // Recent Success: 90.0% (last 5 tasks)
|
|
723
|
+
* // Previous Success: 75.0% (previous 5 tasks)
|
|
724
|
+
* // Change: +15.0 percentage points
|
|
725
|
+
* // ...
|
|
726
|
+
* ```
|
|
727
|
+
*
|
|
728
|
+
* @returns {void} Prints formatted trend analysis to console
|
|
729
|
+
*/
|
|
730
|
+
trends(limit = 10) {
|
|
731
|
+
try {
|
|
732
|
+
const query = `
|
|
733
|
+
SELECT
|
|
734
|
+
task_id,
|
|
735
|
+
variant,
|
|
736
|
+
verdict,
|
|
737
|
+
completeness,
|
|
738
|
+
started_at,
|
|
739
|
+
total_duration_sec
|
|
740
|
+
FROM variant_executions
|
|
741
|
+
WHERE ${this.projectScopeWhere}
|
|
742
|
+
AND completed_at IS NOT NULL
|
|
743
|
+
AND ${_TelemetryDashboard.REAL_DATA_FILTER}
|
|
744
|
+
ORDER BY started_at DESC
|
|
745
|
+
LIMIT ?
|
|
746
|
+
`;
|
|
747
|
+
const results = this.variantsDb.prepare(query).all(...this.projectScopeParams, limit * 3);
|
|
748
|
+
if (results.length === 0) {
|
|
749
|
+
console.log("No historical trend data available.");
|
|
750
|
+
console.log(" Run some tasks to generate trend data.");
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
console.log(`
|
|
754
|
+
Historical Trends (last ${limit} tasks per variant)`);
|
|
755
|
+
const byVariant = {};
|
|
756
|
+
results.forEach((row) => {
|
|
757
|
+
if (!byVariant[row.variant]) {
|
|
758
|
+
byVariant[row.variant] = [];
|
|
759
|
+
}
|
|
760
|
+
const variantArray = byVariant[row.variant];
|
|
761
|
+
if (variantArray) {
|
|
762
|
+
variantArray.push(row);
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
Object.keys(byVariant).forEach((variant) => {
|
|
766
|
+
const variantData = byVariant[variant];
|
|
767
|
+
if (!variantData) return;
|
|
768
|
+
const tasks = variantData.slice(0, limit);
|
|
769
|
+
if (tasks.length === 0) {
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
const successes = tasks.filter((t) => t.verdict === "success").length;
|
|
773
|
+
const avgCompleteness = tasks.reduce((sum, t) => sum + (t.completeness || 0), 0) / tasks.length;
|
|
774
|
+
const recentWindow = Math.min(5, Math.floor(tasks.length / 2));
|
|
775
|
+
const olderWindow = Math.min(5, tasks.length - recentWindow);
|
|
776
|
+
const recentTasks = tasks.slice(0, recentWindow);
|
|
777
|
+
const olderTasks = tasks.slice(recentWindow, recentWindow + olderWindow);
|
|
778
|
+
const recentSuccessRate = recentTasks.length > 0 ? recentTasks.filter((t) => t.verdict === "success").length / recentTasks.length : 0;
|
|
779
|
+
const olderSuccessRate = olderTasks.length > 0 ? olderTasks.filter((t) => t.verdict === "success").length / olderTasks.length : recentSuccessRate;
|
|
780
|
+
const successTrend = recentSuccessRate - olderSuccessRate;
|
|
781
|
+
const trendIcon = Math.abs(successTrend) < 0.1 ? "stable" : successTrend > 0 ? "improving" : "declining";
|
|
782
|
+
const trendText = Math.abs(successTrend) < 0.1 ? "stable" : successTrend > 0 ? "improving" : "declining";
|
|
783
|
+
console.log(`
|
|
784
|
+
${variant.toUpperCase()} ${trendIcon}`);
|
|
785
|
+
console.log(`Overall Performance (${tasks.length} tasks):`);
|
|
786
|
+
console.log(
|
|
787
|
+
` Success Rate: ${(successes / tasks.length * 100).toFixed(1)}% (${successes}/${tasks.length})`
|
|
788
|
+
);
|
|
789
|
+
console.log(` Avg Completeness: ${avgCompleteness.toFixed(1)}%`);
|
|
790
|
+
console.log(`
|
|
791
|
+
Trend Analysis (${trendText}):`);
|
|
792
|
+
console.log(
|
|
793
|
+
` Recent Success: ${(recentSuccessRate * 100).toFixed(1)}% (last ${recentWindow} tasks)`
|
|
794
|
+
);
|
|
795
|
+
console.log(
|
|
796
|
+
` Previous Success: ${(olderSuccessRate * 100).toFixed(1)}% (previous ${olderWindow} tasks)`
|
|
797
|
+
);
|
|
798
|
+
console.log(
|
|
799
|
+
` Change: ${successTrend > 0 ? "+" : ""}${(successTrend * 100).toFixed(1)} percentage points`
|
|
800
|
+
);
|
|
801
|
+
});
|
|
802
|
+
} catch (error) {
|
|
803
|
+
console.error("Error analyzing trends:", error.message);
|
|
804
|
+
console.log(" Ensure telemetry database exists and contains data.");
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Generate context-aware variant recommendations
|
|
809
|
+
*
|
|
810
|
+
* Queries variant_executions with optional context filters to recommend the best
|
|
811
|
+
* variant for specific project characteristics (language, framework, etc.). Uses
|
|
812
|
+
* a weighted scoring system with context matching bonuses and statistical confidence.
|
|
813
|
+
*
|
|
814
|
+
* **SQL Query Details:**
|
|
815
|
+
* - **Table:** variant_executions
|
|
816
|
+
* - **Filters:**
|
|
817
|
+
* - completed_at IS NOT NULL (required)
|
|
818
|
+
* - project_language = ? OR project_language IS NULL (if language specified)
|
|
819
|
+
* - project_framework = ? OR project_framework IS NULL (if framework specified)
|
|
820
|
+
* - **Groups by:** variant
|
|
821
|
+
* - **Orders by:** success_rate DESC, avg_completeness DESC
|
|
822
|
+
*
|
|
823
|
+
* **Scoring Methodology:**
|
|
824
|
+
* 1. **Base Score:** success_rate × 0.6 + avg_completeness × 0.4
|
|
825
|
+
* 2. **Context Bonuses:**
|
|
826
|
+
* - Language match: +10% bonus
|
|
827
|
+
* - Framework match: +10% bonus
|
|
828
|
+
* 3. **Final Score:** min(1.0, base_score + bonuses)
|
|
829
|
+
* 4. **Confidence:** Calculated via Wilson score interval based on sample size
|
|
830
|
+
*
|
|
831
|
+
* **Confidence Levels (Wilson Score):**
|
|
832
|
+
* - **HIGH:** Sample size ≥10 with tight confidence interval (<0.2)
|
|
833
|
+
* - **MEDIUM:** Sample size 3-9 or moderate interval (0.2-0.4)
|
|
834
|
+
* - **LOW:** Sample size <3 or wide interval (>0.4)
|
|
835
|
+
*
|
|
836
|
+
* **Performance Tiers:**
|
|
837
|
+
* - EXCELLENT: Score ≥80%
|
|
838
|
+
* - GOOD: Score ≥60%
|
|
839
|
+
* - FAIR: Score ≥40%
|
|
840
|
+
* - POOR: Score <40%
|
|
841
|
+
*
|
|
842
|
+
* @param context - Context filters for recommendations
|
|
843
|
+
*
|
|
844
|
+
* @example
|
|
845
|
+
* ```typescript
|
|
846
|
+
* // Get recommendations for TypeScript React projects
|
|
847
|
+
* dashboard.recommend({
|
|
848
|
+
* language: 'typescript',
|
|
849
|
+
* framework: 'react'
|
|
850
|
+
* });
|
|
851
|
+
* // Output:
|
|
852
|
+
* // Variant Recommendations
|
|
853
|
+
* //
|
|
854
|
+
* // Context: typescript / react / any complexity / any type
|
|
855
|
+
* //
|
|
856
|
+
* //
|
|
857
|
+
* // 1. CLAUDE EXCELLENT
|
|
858
|
+
* //
|
|
859
|
+
* // Overall Score: 92.5/100
|
|
860
|
+
* // Success Rate: 88.0% (25 tasks)
|
|
861
|
+
* // Completeness: 90.2%
|
|
862
|
+
* // Avg Duration: 42s
|
|
863
|
+
* // Confidence: HIGH (High confidence)
|
|
864
|
+
* // Context Match: +20% bonus for matching context
|
|
865
|
+
* // ...
|
|
866
|
+
* ```
|
|
867
|
+
*
|
|
868
|
+
* @returns {void} Prints formatted recommendations to console
|
|
869
|
+
*/
|
|
870
|
+
recommend(context = {}) {
|
|
871
|
+
try {
|
|
872
|
+
const { language, framework, taskComplexity, taskType } = context;
|
|
873
|
+
console.log("\nVariant Recommendations");
|
|
874
|
+
console.log(
|
|
875
|
+
`Context: ${language || "any"} / ${framework || "any"} / ${taskComplexity || "any"} complexity / ${taskType || "any"} type`
|
|
876
|
+
);
|
|
877
|
+
let query = `
|
|
878
|
+
SELECT
|
|
879
|
+
variant,
|
|
880
|
+
COUNT(*) as total_tasks,
|
|
881
|
+
CAST(SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) as success_rate,
|
|
882
|
+
AVG(completeness) as avg_completeness,
|
|
883
|
+
AVG(total_duration_sec) as avg_duration_sec,
|
|
884
|
+
MAX(project_language) as project_language,
|
|
885
|
+
MAX(project_framework) as project_framework
|
|
886
|
+
FROM variant_executions
|
|
887
|
+
WHERE ${this.projectScopeWhere}
|
|
888
|
+
AND completed_at IS NOT NULL
|
|
889
|
+
AND ${_TelemetryDashboard.REAL_DATA_FILTER}
|
|
890
|
+
`;
|
|
891
|
+
const params = [...this.projectScopeParams];
|
|
892
|
+
if (language && language !== "any") {
|
|
893
|
+
query += " AND (project_language = ? OR project_language IS NULL)";
|
|
894
|
+
params.push(language);
|
|
895
|
+
}
|
|
896
|
+
if (framework && framework !== "any") {
|
|
897
|
+
query += " AND (project_framework = ? OR project_framework IS NULL)";
|
|
898
|
+
params.push(framework);
|
|
899
|
+
}
|
|
900
|
+
query += " GROUP BY variant ORDER BY success_rate DESC, avg_completeness DESC";
|
|
901
|
+
const results = this.variantsDb.prepare(query).all(...params);
|
|
902
|
+
if (results.length === 0) {
|
|
903
|
+
console.log("No data available for the specified context.");
|
|
904
|
+
console.log(" Try with broader context filters or run more tasks.");
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
const recommendations = results.map((row, i) => {
|
|
908
|
+
const baseScore = row.avg_completeness != null ? row.success_rate * 0.6 + row.avg_completeness / 100 * 0.4 : row.success_rate;
|
|
909
|
+
let contextBonus = 0;
|
|
910
|
+
if (language && language !== "any" && row.project_language === language) {
|
|
911
|
+
contextBonus += 0.1;
|
|
912
|
+
}
|
|
913
|
+
if (framework && framework !== "any" && row.project_framework === framework) {
|
|
914
|
+
contextBonus += 0.1;
|
|
915
|
+
}
|
|
916
|
+
const finalScore = Math.min(1, baseScore + contextBonus);
|
|
917
|
+
const confidence = this.calculateConfidence(row.total_tasks, row.success_rate);
|
|
918
|
+
const tier = finalScore >= 0.8 ? "EXCELLENT" : finalScore >= 0.6 ? "GOOD" : finalScore >= 0.4 ? "FAIR" : "POOR";
|
|
919
|
+
return {
|
|
920
|
+
...row,
|
|
921
|
+
rank: i + 1,
|
|
922
|
+
finalScore,
|
|
923
|
+
contextBonus,
|
|
924
|
+
confidence,
|
|
925
|
+
tier
|
|
926
|
+
};
|
|
927
|
+
});
|
|
928
|
+
recommendations.forEach((rec) => {
|
|
929
|
+
console.log(`
|
|
930
|
+
${rec.rank}. ${rec.variant.toUpperCase()} ${rec.tier}`);
|
|
931
|
+
console.log(`Overall Score: ${(rec.finalScore * 100).toFixed(1)}/100`);
|
|
932
|
+
console.log(
|
|
933
|
+
`Success Rate: ${(rec.success_rate * 100).toFixed(1)}% (${rec.total_tasks} tasks)`
|
|
934
|
+
);
|
|
935
|
+
console.log(`Completeness: ${rec.avg_completeness.toFixed(1)}%`);
|
|
936
|
+
console.log(
|
|
937
|
+
`Avg Duration: ${rec.avg_duration_sec ? `${Math.round(rec.avg_duration_sec)}s` : "N/A"}`
|
|
938
|
+
);
|
|
939
|
+
console.log(`Confidence: ${rec.confidence.level} (${rec.confidence.description})`);
|
|
940
|
+
if (rec.contextBonus > 0) {
|
|
941
|
+
console.log(
|
|
942
|
+
`Context Match: +${(rec.contextBonus * 100).toFixed(0)}% bonus for matching context`
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
const best = recommendations[0];
|
|
947
|
+
if (best) {
|
|
948
|
+
console.log("\nSummary");
|
|
949
|
+
console.log(`Recommended: ${best.variant.toUpperCase()}`);
|
|
950
|
+
console.log(
|
|
951
|
+
` Best overall performance with ${(best.finalScore * 100).toFixed(1)}/100 score`
|
|
952
|
+
);
|
|
953
|
+
console.log(
|
|
954
|
+
` ${(best.success_rate * 100).toFixed(1)}% success rate across ${best.total_tasks} tasks`
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
} catch (error) {
|
|
958
|
+
console.error("Error generating recommendations:", error.message);
|
|
959
|
+
console.log(" Ensure telemetry database exists and contains data.");
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Calculate statistical confidence level for variant recommendations
|
|
964
|
+
*
|
|
965
|
+
* Uses the Wilson score interval method (at 95% confidence) to determine how
|
|
966
|
+
* reliable a variant's performance metrics are based on sample size and success
|
|
967
|
+
* rate. Larger sample sizes and tighter confidence intervals produce higher
|
|
968
|
+
* confidence levels.
|
|
969
|
+
*
|
|
970
|
+
* **Methodology:**
|
|
971
|
+
* 1. **Quick Checks (Sample Size):**
|
|
972
|
+
* - <3 samples → LOW (very few samples)
|
|
973
|
+
* - 3-4 samples → MEDIUM (limited samples)
|
|
974
|
+
* - 5-9 samples → MEDIUM (moderate samples)
|
|
975
|
+
* 2. **Statistical Analysis (≥10 samples):**
|
|
976
|
+
* - Calculate Wilson score interval at 95% confidence (z=1.96)
|
|
977
|
+
* - Measure interval width (upperBound - lowerBound)
|
|
978
|
+
* - Classify by interval width:
|
|
979
|
+
* - <0.2 → HIGH confidence
|
|
980
|
+
* - 0.2-0.4 → MEDIUM confidence
|
|
981
|
+
* - >0.4 → LOW confidence
|
|
982
|
+
*
|
|
983
|
+
* **Wilson Score Interval Formula:**
|
|
984
|
+
* ```
|
|
985
|
+
* center = (p + z²/2n) / (1 + z²/n)
|
|
986
|
+
* margin = (z / (1 + z²/n)) × √(p(1-p)/n + z²/4n²)
|
|
987
|
+
* interval = [max(0, center - margin), min(1, center + margin)]
|
|
988
|
+
* ```
|
|
989
|
+
* Where:
|
|
990
|
+
* - p = success rate (proportion)
|
|
991
|
+
* - n = sample size
|
|
992
|
+
* - z = 1.96 (95% confidence level)
|
|
993
|
+
*
|
|
994
|
+
* @param sampleSize - Number of completed tasks for this variant
|
|
995
|
+
* @param successRate - Success rate as decimal (0.0 to 1.0)
|
|
996
|
+
*
|
|
997
|
+
* @returns {ConfidenceLevel} Object with level ('LOW' | 'MEDIUM' | 'HIGH') and description
|
|
998
|
+
*
|
|
999
|
+
* @example
|
|
1000
|
+
* ```typescript
|
|
1001
|
+
* // Very few samples
|
|
1002
|
+
* calculateConfidence(2, 1.0);
|
|
1003
|
+
* // Returns: { level: 'LOW', description: 'Very few samples' }
|
|
1004
|
+
*
|
|
1005
|
+
* // Limited samples
|
|
1006
|
+
* calculateConfidence(4, 0.75);
|
|
1007
|
+
* // Returns: { level: 'MEDIUM', description: 'Limited samples' }
|
|
1008
|
+
*
|
|
1009
|
+
* // High confidence with many successful samples
|
|
1010
|
+
* calculateConfidence(100, 0.90);
|
|
1011
|
+
* // Returns: { level: 'HIGH', description: 'High confidence' }
|
|
1012
|
+
*
|
|
1013
|
+
* // Low confidence despite many samples (high variance)
|
|
1014
|
+
* calculateConfidence(50, 0.50);
|
|
1015
|
+
* // Returns: { level: 'LOW', description: 'Low confidence' } (wide interval)
|
|
1016
|
+
* ```
|
|
1017
|
+
*
|
|
1018
|
+
* @remarks
|
|
1019
|
+
* The Wilson score interval is preferred over simple binomial confidence intervals
|
|
1020
|
+
* because it performs better with small sample sizes and extreme success rates
|
|
1021
|
+
* (near 0% or 100%). It provides more conservative estimates than the normal
|
|
1022
|
+
* approximation method.
|
|
1023
|
+
*
|
|
1024
|
+
* @see {@link https://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Wilson_score_interval}
|
|
1025
|
+
* @private
|
|
1026
|
+
*/
|
|
1027
|
+
calculateConfidence(sampleSize, successRate) {
|
|
1028
|
+
if (sampleSize < 3) {
|
|
1029
|
+
return { level: "LOW", description: "Very few samples" };
|
|
1030
|
+
}
|
|
1031
|
+
if (sampleSize < 5) {
|
|
1032
|
+
return { level: "MEDIUM", description: "Limited samples" };
|
|
1033
|
+
}
|
|
1034
|
+
if (sampleSize < 10) {
|
|
1035
|
+
return { level: "MEDIUM", description: "Moderate samples" };
|
|
1036
|
+
}
|
|
1037
|
+
const { width: interval } = this.wilsonCI(successRate, sampleSize);
|
|
1038
|
+
if (interval < 0.2) {
|
|
1039
|
+
return { level: "HIGH", description: "High confidence" };
|
|
1040
|
+
} else if (interval < 0.4) {
|
|
1041
|
+
return { level: "MEDIUM", description: "Moderate confidence" };
|
|
1042
|
+
} else {
|
|
1043
|
+
return { level: "LOW", description: "Low confidence" };
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
/** Compute Wilson 95% CI for success rate */
|
|
1047
|
+
wilsonCI(p, n) {
|
|
1048
|
+
if (!n || n <= 0) return { lower: 0, upper: 1, width: 1 };
|
|
1049
|
+
const z = 1.96;
|
|
1050
|
+
const denom = 1 + z * z / n;
|
|
1051
|
+
const center = (p + z * z / (2 * n)) / denom;
|
|
1052
|
+
const margin = z / denom * Math.sqrt(p * (1 - p) / n + z * z / (4 * n * n));
|
|
1053
|
+
const lower = Math.max(0, center - margin);
|
|
1054
|
+
const upper = Math.min(1, center + margin);
|
|
1055
|
+
return { lower, upper, width: upper - lower };
|
|
1056
|
+
}
|
|
1057
|
+
/** Two-proportion z-test p-value (two-tailed). Inputs: successes/failures for A and B */
|
|
1058
|
+
twoProportionPValue(aSucc, aFail, bSucc, bFail) {
|
|
1059
|
+
const n1 = aSucc + aFail;
|
|
1060
|
+
const n2 = bSucc + bFail;
|
|
1061
|
+
if (n1 === 0 || n2 === 0) return 1;
|
|
1062
|
+
const p1 = aSucc / n1;
|
|
1063
|
+
const p2 = bSucc / n2;
|
|
1064
|
+
const pPool = (aSucc + bSucc) / (n1 + n2);
|
|
1065
|
+
const se = Math.sqrt(pPool * (1 - pPool) * (1 / n1 + 1 / n2));
|
|
1066
|
+
if (se === 0) return 1;
|
|
1067
|
+
const z = Math.abs((p1 - p2) / se);
|
|
1068
|
+
const p = 2 * (1 - this.normalCdf(z));
|
|
1069
|
+
return Math.max(0, Math.min(1, p));
|
|
1070
|
+
}
|
|
1071
|
+
/** Standard normal CDF approximation */
|
|
1072
|
+
normalCdf(z) {
|
|
1073
|
+
const t = 1 / (1 + 0.2316419 * z);
|
|
1074
|
+
const d = Math.exp(-0.5 * z * z) / Math.sqrt(2 * Math.PI);
|
|
1075
|
+
const poly = (((1.330274429 * t - 1.821255978) * t + 1.781477937) * t - 0.356563782) * t + 0.31938153;
|
|
1076
|
+
const approx = 1 - d * poly;
|
|
1077
|
+
return z >= 0 ? approx : 1 - approx;
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Compute confusion-matrix aggregates by variant, using validations as predictor
|
|
1081
|
+
* (predicted success = all validations for a task passed; conservative heuristic).
|
|
1082
|
+
*/
|
|
1083
|
+
computeConfusionByVariant() {
|
|
1084
|
+
const validations = this.validationsDb.prepare(
|
|
1085
|
+
`SELECT task_id, MIN(passed) as all_passed, COUNT(*) as cnt
|
|
1086
|
+
FROM validations WHERE ${this.projectScopeWhere} GROUP BY task_id`
|
|
1087
|
+
).all(...this.projectScopeParams);
|
|
1088
|
+
const predMap = /* @__PURE__ */ new Map();
|
|
1089
|
+
validations.forEach((v) => {
|
|
1090
|
+
if (v.cnt > 0) predMap.set(v.task_id, v.all_passed);
|
|
1091
|
+
});
|
|
1092
|
+
const execRows = this.variantsDb.prepare(
|
|
1093
|
+
`SELECT task_id, variant, CASE WHEN verdict = 'success' THEN 1 ELSE 0 END as actual_success
|
|
1094
|
+
FROM variant_executions WHERE ${this.projectScopeWhere}
|
|
1095
|
+
AND completed_at IS NOT NULL AND ${_TelemetryDashboard.REAL_DATA_FILTER}`
|
|
1096
|
+
).all(...this.projectScopeParams);
|
|
1097
|
+
const confByVariant = /* @__PURE__ */ new Map();
|
|
1098
|
+
for (const r of execRows) {
|
|
1099
|
+
const pred = predMap.get(r.task_id);
|
|
1100
|
+
if (pred === void 0) continue;
|
|
1101
|
+
const key = r.variant;
|
|
1102
|
+
let agg = confByVariant.get(key);
|
|
1103
|
+
if (!agg) {
|
|
1104
|
+
agg = { tp: 0, fp: 0, tn: 0, fn: 0 };
|
|
1105
|
+
confByVariant.set(key, agg);
|
|
1106
|
+
}
|
|
1107
|
+
if (pred === 1 && r.actual_success === 1) agg.tp++;
|
|
1108
|
+
else if (pred === 1 && r.actual_success === 0) agg.fp++;
|
|
1109
|
+
else if (pred === 0 && r.actual_success === 0) agg.tn++;
|
|
1110
|
+
else if (pred === 0 && r.actual_success === 1) agg.fn++;
|
|
1111
|
+
}
|
|
1112
|
+
return confByVariant;
|
|
1113
|
+
}
|
|
1114
|
+
/** Confusion by variant+prompt_version for prompt analytics */
|
|
1115
|
+
computeConfusionByVariantPrompt() {
|
|
1116
|
+
const validations = this.validationsDb.prepare(
|
|
1117
|
+
`SELECT task_id, MIN(passed) as all_passed, COUNT(*) as cnt
|
|
1118
|
+
FROM validations WHERE ${this.projectScopeWhere} GROUP BY task_id`
|
|
1119
|
+
).all(...this.projectScopeParams);
|
|
1120
|
+
const predMap = /* @__PURE__ */ new Map();
|
|
1121
|
+
validations.forEach((v) => {
|
|
1122
|
+
if (v.cnt > 0) predMap.set(v.task_id, v.all_passed);
|
|
1123
|
+
});
|
|
1124
|
+
const execRows = this.variantsDb.prepare(
|
|
1125
|
+
`SELECT task_id, variant, prompt_version, CASE WHEN verdict = 'success' THEN 1 ELSE 0 END as actual_success
|
|
1126
|
+
FROM variant_executions WHERE ${this.projectScopeWhere}
|
|
1127
|
+
AND completed_at IS NOT NULL AND prompt_version IS NOT NULL
|
|
1128
|
+
AND ${_TelemetryDashboard.REAL_DATA_FILTER}`
|
|
1129
|
+
).all(...this.projectScopeParams);
|
|
1130
|
+
const map = /* @__PURE__ */ new Map();
|
|
1131
|
+
for (const r of execRows) {
|
|
1132
|
+
const pred = predMap.has(r.task_id) ? predMap.get(r.task_id) : null;
|
|
1133
|
+
if (pred === null) continue;
|
|
1134
|
+
const key = `${r.variant}@@${r.prompt_version}`;
|
|
1135
|
+
if (!map.has(key)) map.set(key, { tp: 0, fp: 0, tn: 0, fn: 0 });
|
|
1136
|
+
const agg = map.get(key);
|
|
1137
|
+
if (pred === 1 && r.actual_success === 1) agg.tp++;
|
|
1138
|
+
else if (pred === 1 && r.actual_success === 0) agg.fp++;
|
|
1139
|
+
else if (pred === 0 && r.actual_success === 0) agg.tn++;
|
|
1140
|
+
else if (pred === 0 && r.actual_success === 1) agg.fn++;
|
|
1141
|
+
}
|
|
1142
|
+
return map;
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Start telemetry dashboard
|
|
1146
|
+
*
|
|
1147
|
+
* Initializes the dashboard system and prepares it for metric collection
|
|
1148
|
+
* and real-time updates. This method must be called before using other
|
|
1149
|
+
* dashboard functionality.
|
|
1150
|
+
*
|
|
1151
|
+
* @returns {void}
|
|
1152
|
+
*
|
|
1153
|
+
* @example
|
|
1154
|
+
* ```typescript
|
|
1155
|
+
* const dashboard = new TelemetryDashboard();
|
|
1156
|
+
* dashboard.start();
|
|
1157
|
+
* // Now the dashboard is ready to collect metrics
|
|
1158
|
+
* ```
|
|
1159
|
+
*/
|
|
1160
|
+
start() {
|
|
1161
|
+
if (!this.enabled) {
|
|
1162
|
+
console.warn("TelemetryDashboard is disabled - using in-memory fallback");
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1165
|
+
console.log("Starting TelemetryDashboard...");
|
|
1166
|
+
try {
|
|
1167
|
+
this.variantsDb.prepare("SELECT 1").get();
|
|
1168
|
+
this.validationsDb.prepare("SELECT 1").get();
|
|
1169
|
+
console.log("TelemetryDashboard started successfully");
|
|
1170
|
+
} catch (error) {
|
|
1171
|
+
console.error("Failed to start TelemetryDashboard:", error);
|
|
1172
|
+
throw new Error("TelemetryDashboard database connections are not available");
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Add a new metric to dashboard for tracking
|
|
1177
|
+
*
|
|
1178
|
+
* Registers a metric with the dashboard system, enabling real-time
|
|
1179
|
+
* tracking and visualization of the specified metric.
|
|
1180
|
+
*
|
|
1181
|
+
* @param name - Unique identifier for the metric
|
|
1182
|
+
* @param config - Metric configuration including type, labels, and description
|
|
1183
|
+
* @returns {void}
|
|
1184
|
+
*
|
|
1185
|
+
* @example
|
|
1186
|
+
* ```typescript
|
|
1187
|
+
* dashboard.addMetric('task_completion', {
|
|
1188
|
+
* name: 'Task Completion Rate',
|
|
1189
|
+
* description: 'Real-time task completion percentage',
|
|
1190
|
+
* type: 'gauge',
|
|
1191
|
+
* labels: ['task_type', 'provider']
|
|
1192
|
+
* });
|
|
1193
|
+
* ```
|
|
1194
|
+
*/
|
|
1195
|
+
addMetric(name, config) {
|
|
1196
|
+
if (!this.enabled) {
|
|
1197
|
+
console.warn(`Dashboard disabled - skipping metric registration: ${name}`);
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
try {
|
|
1201
|
+
const createTableQuery = `
|
|
1202
|
+
CREATE TABLE IF NOT EXISTS metric_registry (
|
|
1203
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1204
|
+
name TEXT UNIQUE NOT NULL,
|
|
1205
|
+
display_name TEXT NOT NULL,
|
|
1206
|
+
description TEXT NOT NULL,
|
|
1207
|
+
type TEXT NOT NULL,
|
|
1208
|
+
labels TEXT,
|
|
1209
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
1210
|
+
)
|
|
1211
|
+
`;
|
|
1212
|
+
this.variantsDb.prepare(createTableQuery).run();
|
|
1213
|
+
const insertQuery = `
|
|
1214
|
+
INSERT OR REPLACE INTO metric_registry (name, display_name, description, type, labels)
|
|
1215
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1216
|
+
`;
|
|
1217
|
+
this.variantsDb.prepare(insertQuery).run(
|
|
1218
|
+
name,
|
|
1219
|
+
config.name,
|
|
1220
|
+
config.description,
|
|
1221
|
+
config.type,
|
|
1222
|
+
JSON.stringify(config.labels || [])
|
|
1223
|
+
);
|
|
1224
|
+
console.log(`Registered metric: ${name} (${config.type})`);
|
|
1225
|
+
} catch (error) {
|
|
1226
|
+
console.error(`Failed to register metric ${name}:`, error);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
/**
|
|
1230
|
+
* Update a metric with a new value
|
|
1231
|
+
*
|
|
1232
|
+
* Updates the specified metric with a new value, storing it for
|
|
1233
|
+
* real-time tracking and historical analysis.
|
|
1234
|
+
*
|
|
1235
|
+
* @param name - Name of the metric to update
|
|
1236
|
+
* @param value - New value for the metric
|
|
1237
|
+
* @param labels - Optional label values for metric segmentation
|
|
1238
|
+
* @returns {void}
|
|
1239
|
+
*
|
|
1240
|
+
* @example
|
|
1241
|
+
* ```typescript
|
|
1242
|
+
* dashboard.updateMetric('task_completion', 85.5, {
|
|
1243
|
+
* task_type: 'feature',
|
|
1244
|
+
* provider: 'claude'
|
|
1245
|
+
* });
|
|
1246
|
+
* ```
|
|
1247
|
+
*/
|
|
1248
|
+
updateMetric(name, value, labels) {
|
|
1249
|
+
if (!this.enabled) {
|
|
1250
|
+
console.warn(`Dashboard disabled - skipping metric update: ${name} = ${value}`);
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
try {
|
|
1254
|
+
const createTableQuery = `
|
|
1255
|
+
CREATE TABLE IF NOT EXISTS metric_values (
|
|
1256
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1257
|
+
metric_name TEXT NOT NULL,
|
|
1258
|
+
value REAL NOT NULL,
|
|
1259
|
+
labels TEXT,
|
|
1260
|
+
timestamp TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
1261
|
+
FOREIGN KEY (metric_name) REFERENCES metric_registry(name)
|
|
1262
|
+
)
|
|
1263
|
+
`;
|
|
1264
|
+
this.variantsDb.prepare(createTableQuery).run();
|
|
1265
|
+
const insertQuery = `
|
|
1266
|
+
INSERT INTO metric_values (metric_name, value, labels)
|
|
1267
|
+
VALUES (?, ?, ?)
|
|
1268
|
+
`;
|
|
1269
|
+
this.variantsDb.prepare(insertQuery).run(name, value, JSON.stringify(labels || {}));
|
|
1270
|
+
const cleanupQuery = `
|
|
1271
|
+
DELETE FROM metric_values
|
|
1272
|
+
WHERE metric_name = ? AND id NOT IN (
|
|
1273
|
+
SELECT id FROM metric_values
|
|
1274
|
+
WHERE metric_name = ?
|
|
1275
|
+
ORDER BY timestamp DESC
|
|
1276
|
+
LIMIT 1000
|
|
1277
|
+
)
|
|
1278
|
+
`;
|
|
1279
|
+
this.variantsDb.prepare(cleanupQuery).run(name, name);
|
|
1280
|
+
} catch (error) {
|
|
1281
|
+
console.error(`Failed to update metric ${name}:`, error);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* Close all database connections
|
|
1286
|
+
*
|
|
1287
|
+
* Cleanly closes the SQLite database connections for both variants and validations
|
|
1288
|
+
* databases. Should be called when the dashboard is no longer needed to free resources.
|
|
1289
|
+
*
|
|
1290
|
+
* @returns {void}
|
|
1291
|
+
*
|
|
1292
|
+
* @example
|
|
1293
|
+
* ```typescript
|
|
1294
|
+
* const dashboard = new TelemetryDashboard();
|
|
1295
|
+
* try {
|
|
1296
|
+
* dashboard.leaderboard();
|
|
1297
|
+
* dashboard.recommend({ language: 'typescript' });
|
|
1298
|
+
* } finally {
|
|
1299
|
+
* // Always close connections
|
|
1300
|
+
* dashboard.close();
|
|
1301
|
+
* }
|
|
1302
|
+
* ```
|
|
1303
|
+
*
|
|
1304
|
+
* @remarks
|
|
1305
|
+
* This method is idempotent - calling it multiple times is safe and will not
|
|
1306
|
+
* throw errors. However, attempting to use dashboard methods after closing will
|
|
1307
|
+
* result in database errors.
|
|
1308
|
+
*/
|
|
1309
|
+
close() {
|
|
1310
|
+
this.variantsDb.close();
|
|
1311
|
+
this.validationsDb.close();
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
|
|
1315
|
+
// src/telemetry/event-types.ts
|
|
1316
|
+
function isCoreVariantEvent(event) {
|
|
1317
|
+
return ["started", "first_commit", "completed", "failed", "evaluated"].includes(event);
|
|
1318
|
+
}
|
|
1319
|
+
function validateEventType(event) {
|
|
1320
|
+
if (isCoreVariantEvent(event)) {
|
|
1321
|
+
return event;
|
|
1322
|
+
}
|
|
1323
|
+
throw new Error(`Unrecognized telemetry event type: ${event}`);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
// src/telemetry/insights.ts
|
|
1327
|
+
import fs2 from "fs";
|
|
1328
|
+
import path2 from "path";
|
|
1329
|
+
import Database2 from "better-sqlite3";
|
|
1330
|
+
var TelemetryInsightEngine = class _TelemetryInsightEngine {
|
|
1331
|
+
static REAL_DATA_FILTER = "verdict IS NOT NULL AND verdict != '' AND task_id NOT LIKE 'test-%' AND task_id NOT LIKE 'task-%'";
|
|
1332
|
+
poeticDir;
|
|
1333
|
+
telemetryDir;
|
|
1334
|
+
variantsDb;
|
|
1335
|
+
enabled = true;
|
|
1336
|
+
enableRealTime;
|
|
1337
|
+
calculationInterval;
|
|
1338
|
+
intervalId;
|
|
1339
|
+
/**
|
|
1340
|
+
* Initialize the TelemetryInsightEngine with configuration options.
|
|
1341
|
+
*
|
|
1342
|
+
* @param options - Configuration options for the insight engine
|
|
1343
|
+
*/
|
|
1344
|
+
constructor(options = {}) {
|
|
1345
|
+
this.poeticDir = options.poeticDir || path2.join(process.cwd(), ".poetic");
|
|
1346
|
+
this.telemetryDir = LabPathResolver.getInstance().getTelemetryDir(this.poeticDir);
|
|
1347
|
+
this.enableRealTime = options.enableRealTime ?? false;
|
|
1348
|
+
this.calculationInterval = options.calculationInterval ?? 3e5;
|
|
1349
|
+
const dbDir = path2.join(this.telemetryDir, "db");
|
|
1350
|
+
try {
|
|
1351
|
+
let parentDir = path2.dirname(dbDir);
|
|
1352
|
+
while (!fs2.existsSync(parentDir) && parentDir !== path2.dirname(parentDir)) {
|
|
1353
|
+
parentDir = path2.dirname(parentDir);
|
|
1354
|
+
}
|
|
1355
|
+
if (!fs2.existsSync(parentDir) || parentDir === path2.sep) {
|
|
1356
|
+
throw new Error(`Telemetry base directory cannot be created at: ${dbDir}`);
|
|
1357
|
+
}
|
|
1358
|
+
const parentStats = fs2.statSync(parentDir);
|
|
1359
|
+
if ((parentStats.mode & 146) === 0) {
|
|
1360
|
+
throw new Error(`Telemetry parent directory is not writable: ${parentDir}`);
|
|
1361
|
+
}
|
|
1362
|
+
if (!fs2.existsSync(dbDir)) {
|
|
1363
|
+
fs2.mkdirSync(dbDir, { recursive: true });
|
|
1364
|
+
}
|
|
1365
|
+
const stats = fs2.statSync(dbDir);
|
|
1366
|
+
const writable = (stats.mode & 146) !== 0;
|
|
1367
|
+
if (!writable) {
|
|
1368
|
+
throw new Error(`Telemetry DB directory is not writable: ${dbDir}`);
|
|
1369
|
+
}
|
|
1370
|
+
this.variantsDb = new Database2(path2.join(dbDir, "variants.db"));
|
|
1371
|
+
this.variantsDb.pragma("journal_mode = WAL");
|
|
1372
|
+
this.variantsDb.pragma(`busy_timeout = ${getSqliteBusyTimeoutMs()}`);
|
|
1373
|
+
this.bootstrapSchema();
|
|
1374
|
+
this.enabled = true;
|
|
1375
|
+
} catch (err) {
|
|
1376
|
+
import("./warning-EGQGUUIO.js").then(({ emitTelemetryFallbackWarning: emitTelemetryFallbackWarning2 }) => {
|
|
1377
|
+
emitTelemetryFallbackWarning2(
|
|
1378
|
+
"could not initialize DB directory, using in-memory fallback",
|
|
1379
|
+
err
|
|
1380
|
+
);
|
|
1381
|
+
}).catch(() => {
|
|
1382
|
+
});
|
|
1383
|
+
this.enabled = false;
|
|
1384
|
+
this.variantsDb = new Database2(":memory:");
|
|
1385
|
+
this.bootstrapSchema();
|
|
1386
|
+
}
|
|
1387
|
+
if (this.enableRealTime) {
|
|
1388
|
+
this.startRealTimeMonitoring();
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
bootstrapSchema() {
|
|
1392
|
+
const statements = [
|
|
1393
|
+
`CREATE TABLE IF NOT EXISTS variant_executions (
|
|
1394
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1395
|
+
task_id TEXT,
|
|
1396
|
+
variant TEXT,
|
|
1397
|
+
prompt_version TEXT,
|
|
1398
|
+
completeness REAL,
|
|
1399
|
+
verdict TEXT,
|
|
1400
|
+
total_duration_sec REAL,
|
|
1401
|
+
started_at TEXT,
|
|
1402
|
+
completed_at TEXT,
|
|
1403
|
+
project_language TEXT,
|
|
1404
|
+
project_framework TEXT,
|
|
1405
|
+
provider TEXT,
|
|
1406
|
+
model TEXT,
|
|
1407
|
+
task_complexity TEXT,
|
|
1408
|
+
success_reason TEXT,
|
|
1409
|
+
failure_reason TEXT,
|
|
1410
|
+
code_quality_score REAL,
|
|
1411
|
+
testing_score REAL,
|
|
1412
|
+
documentation_score REAL,
|
|
1413
|
+
architecture_score REAL,
|
|
1414
|
+
anomaly_score REAL
|
|
1415
|
+
)`,
|
|
1416
|
+
"CREATE INDEX IF NOT EXISTS idx_variant_executions_variant ON variant_executions(variant)",
|
|
1417
|
+
"CREATE INDEX IF NOT EXISTS idx_variant_executions_prompt_version ON variant_executions(prompt_version)",
|
|
1418
|
+
"CREATE INDEX IF NOT EXISTS idx_variant_executions_completed_at ON variant_executions(completed_at)",
|
|
1419
|
+
"CREATE INDEX IF NOT EXISTS idx_variant_executions_project_language ON variant_executions(project_language)",
|
|
1420
|
+
"CREATE INDEX IF NOT EXISTS idx_variant_executions_task_id ON variant_executions(task_id)"
|
|
1421
|
+
];
|
|
1422
|
+
for (const stmt of statements) {
|
|
1423
|
+
try {
|
|
1424
|
+
this.variantsDb.prepare(stmt).run();
|
|
1425
|
+
} catch (error) {
|
|
1426
|
+
emitTelemetryFallbackWarning("Schema bootstrap statement failed", error);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
/** Returns true if the insight engine successfully initialized on-disk storage */
|
|
1431
|
+
isEnabled() {
|
|
1432
|
+
return this.enabled;
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Generate comprehensive insights from telemetry data.
|
|
1436
|
+
*
|
|
1437
|
+
* Analyzes all available telemetry data to produce actionable insights
|
|
1438
|
+
* across multiple dimensions: performance, optimization, prediction, and anomaly detection.
|
|
1439
|
+
*
|
|
1440
|
+
* @returns Array of insight results with recommendations
|
|
1441
|
+
*/
|
|
1442
|
+
async generateInsights() {
|
|
1443
|
+
const insights = [];
|
|
1444
|
+
try {
|
|
1445
|
+
insights.push(...this.analyzePerformanceTrends());
|
|
1446
|
+
insights.push(...this.generateOptimizationRecommendations());
|
|
1447
|
+
insights.push(...this.generatePredictiveInsights());
|
|
1448
|
+
insights.push(...this.detectAnomalies());
|
|
1449
|
+
insights.sort((a, b) => {
|
|
1450
|
+
const severityWeight = { critical: 3, warning: 2, info: 1 };
|
|
1451
|
+
const aSeverity = severityWeight[a.severity];
|
|
1452
|
+
const bSeverity = severityWeight[b.severity];
|
|
1453
|
+
if (aSeverity !== bSeverity) {
|
|
1454
|
+
return bSeverity - aSeverity;
|
|
1455
|
+
}
|
|
1456
|
+
return b.confidence - a.confidence;
|
|
1457
|
+
});
|
|
1458
|
+
return insights;
|
|
1459
|
+
} catch (error) {
|
|
1460
|
+
emitTelemetryFallbackWarning("Failed to generate insights", error);
|
|
1461
|
+
return [];
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
/**
|
|
1465
|
+
* Analyze performance trends across variants and providers.
|
|
1466
|
+
*/
|
|
1467
|
+
analyzePerformanceTrends() {
|
|
1468
|
+
const insights = [];
|
|
1469
|
+
const query = `
|
|
1470
|
+
SELECT
|
|
1471
|
+
variant,
|
|
1472
|
+
prompt_version,
|
|
1473
|
+
COUNT(*) as total_tasks,
|
|
1474
|
+
AVG(completeness) as avg_completeness,
|
|
1475
|
+
CAST(SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) as success_rate,
|
|
1476
|
+
AVG(total_duration_sec) as avg_duration,
|
|
1477
|
+
MIN(started_at) as first_execution,
|
|
1478
|
+
MAX(started_at) as last_execution
|
|
1479
|
+
FROM variant_executions
|
|
1480
|
+
WHERE completed_at IS NOT NULL
|
|
1481
|
+
AND ${_TelemetryInsightEngine.REAL_DATA_FILTER}
|
|
1482
|
+
AND started_at > datetime('now', '-30 days')
|
|
1483
|
+
GROUP BY variant, prompt_version
|
|
1484
|
+
HAVING total_tasks >= 3
|
|
1485
|
+
ORDER BY success_rate DESC, avg_completeness DESC
|
|
1486
|
+
`;
|
|
1487
|
+
const results = this.variantsDb.prepare(query).all();
|
|
1488
|
+
if (results.length >= 2) {
|
|
1489
|
+
const topPerformer = results[0];
|
|
1490
|
+
const worstPerformer = results[results.length - 1];
|
|
1491
|
+
const performanceGap = topPerformer.success_rate - worstPerformer.success_rate;
|
|
1492
|
+
if (performanceGap > 0.3) {
|
|
1493
|
+
insights.push({
|
|
1494
|
+
type: "performance",
|
|
1495
|
+
severity: "warning",
|
|
1496
|
+
title: "Significant Performance Gap Detected",
|
|
1497
|
+
description: `Variant ${topPerformer.variant} (v${topPerformer.prompt_version || "unknown"}) significantly outperforms ${worstPerformer.variant} (v${worstPerformer.prompt_version || "unknown"})`,
|
|
1498
|
+
data: {
|
|
1499
|
+
topPerformer: {
|
|
1500
|
+
variant: topPerformer.variant,
|
|
1501
|
+
version: topPerformer.prompt_version || "unknown",
|
|
1502
|
+
successRate: topPerformer.success_rate,
|
|
1503
|
+
completeness: topPerformer.avg_completeness
|
|
1504
|
+
},
|
|
1505
|
+
worstPerformer: {
|
|
1506
|
+
variant: worstPerformer.variant,
|
|
1507
|
+
version: worstPerformer.prompt_version || "unknown",
|
|
1508
|
+
successRate: worstPerformer.success_rate,
|
|
1509
|
+
completeness: worstPerformer.avg_completeness
|
|
1510
|
+
},
|
|
1511
|
+
gap: performanceGap
|
|
1512
|
+
},
|
|
1513
|
+
recommendations: [
|
|
1514
|
+
`Consider using ${topPerformer.variant} variant for similar tasks`,
|
|
1515
|
+
`Review and optimize ${worstPerformer.variant} prompt strategy`,
|
|
1516
|
+
"Analyze successful patterns from top performer"
|
|
1517
|
+
],
|
|
1518
|
+
confidence: 0.85,
|
|
1519
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
return insights;
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Generate optimization recommendations based on performance data.
|
|
1527
|
+
*/
|
|
1528
|
+
generateOptimizationRecommendations() {
|
|
1529
|
+
const insights = [];
|
|
1530
|
+
const promptQuery = `
|
|
1531
|
+
SELECT
|
|
1532
|
+
variant,
|
|
1533
|
+
prompt_version,
|
|
1534
|
+
COUNT(*) as sample_size,
|
|
1535
|
+
AVG(completeness) as avg_completeness,
|
|
1536
|
+
CAST(SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) as success_rate
|
|
1537
|
+
FROM variant_executions
|
|
1538
|
+
WHERE completed_at IS NOT NULL
|
|
1539
|
+
AND prompt_version IS NOT NULL
|
|
1540
|
+
AND ${_TelemetryInsightEngine.REAL_DATA_FILTER}
|
|
1541
|
+
GROUP BY variant, prompt_version
|
|
1542
|
+
HAVING sample_size >= 5
|
|
1543
|
+
ORDER BY success_rate DESC
|
|
1544
|
+
`;
|
|
1545
|
+
const promptResults = this.variantsDb.prepare(promptQuery).all();
|
|
1546
|
+
const byVariant = /* @__PURE__ */ new Map();
|
|
1547
|
+
promptResults.forEach((row) => {
|
|
1548
|
+
const entries = byVariant.get(row.variant) || [];
|
|
1549
|
+
entries.push(row);
|
|
1550
|
+
byVariant.set(row.variant, entries);
|
|
1551
|
+
});
|
|
1552
|
+
for (const [variant, versions] of Array.from(byVariant.entries())) {
|
|
1553
|
+
if (versions.length >= 2) {
|
|
1554
|
+
const best = versions[0];
|
|
1555
|
+
const current = versions.find(
|
|
1556
|
+
(v) => v.prompt_version.includes("latest") || v.prompt_version.includes("current")
|
|
1557
|
+
) || versions[versions.length - 1];
|
|
1558
|
+
if (best.success_rate - current.success_rate > 0.15) {
|
|
1559
|
+
insights.push({
|
|
1560
|
+
type: "optimization",
|
|
1561
|
+
severity: "warning",
|
|
1562
|
+
title: `Prompt Optimization Opportunity for ${variant}`,
|
|
1563
|
+
description: `Version ${best.prompt_version} significantly outperforms current version ${current.prompt_version}`,
|
|
1564
|
+
data: {
|
|
1565
|
+
variant,
|
|
1566
|
+
bestVersion: best.prompt_version,
|
|
1567
|
+
currentVersion: current.prompt_version,
|
|
1568
|
+
improvement: best.success_rate - current.success_rate,
|
|
1569
|
+
bestSuccessRate: best.success_rate,
|
|
1570
|
+
currentSuccessRate: current.success_rate
|
|
1571
|
+
},
|
|
1572
|
+
recommendations: [
|
|
1573
|
+
`Consider promoting version ${best.prompt_version} to current`,
|
|
1574
|
+
`Analyze differences between ${best.prompt_version} and ${current.prompt_version}`,
|
|
1575
|
+
`Apply successful patterns from ${best.prompt_version} to future prompts`
|
|
1576
|
+
],
|
|
1577
|
+
confidence: 0.78,
|
|
1578
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1579
|
+
});
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
return insights;
|
|
1584
|
+
}
|
|
1585
|
+
/**
|
|
1586
|
+
* Generate predictive insights based on historical patterns.
|
|
1587
|
+
*/
|
|
1588
|
+
generatePredictiveInsights() {
|
|
1589
|
+
const insights = [];
|
|
1590
|
+
const predictionQuery = `
|
|
1591
|
+
SELECT
|
|
1592
|
+
project_language,
|
|
1593
|
+
project_framework,
|
|
1594
|
+
COUNT(*) as total_tasks,
|
|
1595
|
+
CAST(SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) as success_rate,
|
|
1596
|
+
AVG(completeness) as avg_completeness,
|
|
1597
|
+
AVG(total_duration_sec) as avg_duration
|
|
1598
|
+
FROM variant_executions
|
|
1599
|
+
WHERE completed_at IS NOT NULL
|
|
1600
|
+
AND project_language IS NOT NULL
|
|
1601
|
+
AND ${_TelemetryInsightEngine.REAL_DATA_FILTER}
|
|
1602
|
+
GROUP BY project_language, project_framework
|
|
1603
|
+
HAVING total_tasks >= 10
|
|
1604
|
+
ORDER BY success_rate DESC
|
|
1605
|
+
`;
|
|
1606
|
+
const predictions = this.variantsDb.prepare(predictionQuery).all();
|
|
1607
|
+
const successfulScenarios = predictions.filter((p) => p.success_rate > 0.8);
|
|
1608
|
+
const challengingScenarios = predictions.filter((p) => p.success_rate < 0.5);
|
|
1609
|
+
if (successfulScenarios.length > 0 && challengingScenarios.length > 0) {
|
|
1610
|
+
insights.push({
|
|
1611
|
+
type: "prediction",
|
|
1612
|
+
severity: "info",
|
|
1613
|
+
title: "Project Type Success Patterns Identified",
|
|
1614
|
+
description: `Analysis of ${predictions.length} project scenarios reveals distinct success patterns`,
|
|
1615
|
+
data: {
|
|
1616
|
+
successfulPatterns: successfulScenarios.slice(0, 3),
|
|
1617
|
+
challengingPatterns: challengingScenarios.slice(0, 3),
|
|
1618
|
+
totalAnalyzed: predictions.length
|
|
1619
|
+
},
|
|
1620
|
+
recommendations: [
|
|
1621
|
+
"Leverage successful patterns for similar project types",
|
|
1622
|
+
"Consider additional support for challenging scenarios",
|
|
1623
|
+
"Adjust prompt strategies based on project characteristics"
|
|
1624
|
+
],
|
|
1625
|
+
confidence: 0.72,
|
|
1626
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
return insights;
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Detect anomalies in performance data.
|
|
1633
|
+
*/
|
|
1634
|
+
detectAnomalies() {
|
|
1635
|
+
const insights = [];
|
|
1636
|
+
const durationQuery = `
|
|
1637
|
+
SELECT
|
|
1638
|
+
variant,
|
|
1639
|
+
task_id,
|
|
1640
|
+
total_duration_sec,
|
|
1641
|
+
verdict,
|
|
1642
|
+
completeness,
|
|
1643
|
+
started_at
|
|
1644
|
+
FROM variant_executions
|
|
1645
|
+
WHERE completed_at IS NOT NULL
|
|
1646
|
+
AND total_duration_sec IS NOT NULL
|
|
1647
|
+
AND ${_TelemetryInsightEngine.REAL_DATA_FILTER}
|
|
1648
|
+
AND started_at > datetime('now', '-7 days')
|
|
1649
|
+
ORDER BY total_duration_sec DESC
|
|
1650
|
+
LIMIT 20
|
|
1651
|
+
`;
|
|
1652
|
+
const durationResults = this.variantsDb.prepare(durationQuery).all();
|
|
1653
|
+
if (durationResults.length >= 5) {
|
|
1654
|
+
const durations = durationResults.map((r) => r.total_duration_sec);
|
|
1655
|
+
const mean = durations.reduce((a, b) => a + b, 0) / durations.length;
|
|
1656
|
+
const stdDev = Math.sqrt(
|
|
1657
|
+
durations.reduce((sq, n) => sq + (n - mean) ** 2, 0) / durations.length
|
|
1658
|
+
);
|
|
1659
|
+
const anomalies = durationResults.filter(
|
|
1660
|
+
(r) => Math.abs(r.total_duration_sec - mean) > 2 * stdDev
|
|
1661
|
+
);
|
|
1662
|
+
if (anomalies.length > 0) {
|
|
1663
|
+
insights.push({
|
|
1664
|
+
type: "anomaly",
|
|
1665
|
+
severity: "warning",
|
|
1666
|
+
title: "Unusual Execution Duration Patterns Detected",
|
|
1667
|
+
description: `Found ${anomalies.length} executions with unusual duration patterns`,
|
|
1668
|
+
data: {
|
|
1669
|
+
anomalies: anomalies.map((a) => ({
|
|
1670
|
+
taskId: a.task_id,
|
|
1671
|
+
variant: a.variant,
|
|
1672
|
+
duration: a.total_duration_sec,
|
|
1673
|
+
verdict: a.verdict,
|
|
1674
|
+
deviation: Math.abs(a.total_duration_sec - mean) / stdDev
|
|
1675
|
+
})),
|
|
1676
|
+
averageDuration: mean,
|
|
1677
|
+
standardDeviation: stdDev
|
|
1678
|
+
},
|
|
1679
|
+
recommendations: [
|
|
1680
|
+
"Investigate unusually long or short executions",
|
|
1681
|
+
"Check for timeout issues or incomplete work",
|
|
1682
|
+
"Review task complexity estimates"
|
|
1683
|
+
],
|
|
1684
|
+
confidence: 0.68,
|
|
1685
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1686
|
+
});
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
return insights;
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Start real-time monitoring for continuous insight generation.
|
|
1693
|
+
*/
|
|
1694
|
+
startRealTimeMonitoring() {
|
|
1695
|
+
this.intervalId = setInterval(async () => {
|
|
1696
|
+
try {
|
|
1697
|
+
await this.generateInsights();
|
|
1698
|
+
} catch (error) {
|
|
1699
|
+
emitTelemetryFallbackWarning("Real-time insight generation failed", error);
|
|
1700
|
+
}
|
|
1701
|
+
}, this.calculationInterval);
|
|
1702
|
+
}
|
|
1703
|
+
/**
|
|
1704
|
+
* Stop real-time monitoring.
|
|
1705
|
+
*/
|
|
1706
|
+
stopRealTimeMonitoring() {
|
|
1707
|
+
if (this.intervalId) {
|
|
1708
|
+
clearInterval(this.intervalId);
|
|
1709
|
+
this.intervalId = void 0;
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
/**
|
|
1713
|
+
* Get provider performance DNA analysis.
|
|
1714
|
+
*
|
|
1715
|
+
* @internal Preview / not fully implemented. Only `provider`, a coarse
|
|
1716
|
+
* `codeGeneration` capability, and `consistencyScore` are derived from real
|
|
1717
|
+
* data; `model` is reported as `'unknown'` and `optimalUseCases`,
|
|
1718
|
+
* `limitations`, and most adaptation fields are placeholders (empty/`null`).
|
|
1719
|
+
* Public CLI surfaces must label this output as a preview and must not present
|
|
1720
|
+
* the placeholder fields as real analytics.
|
|
1721
|
+
*/
|
|
1722
|
+
async getProviderPerformanceDNA() {
|
|
1723
|
+
const query = `
|
|
1724
|
+
SELECT
|
|
1725
|
+
CASE WHEN INSTR(variant, ':') > 0
|
|
1726
|
+
THEN SUBSTR(variant, 1, INSTR(variant, ':') - 1)
|
|
1727
|
+
ELSE variant
|
|
1728
|
+
END as provider,
|
|
1729
|
+
COUNT(*) as total_tasks,
|
|
1730
|
+
CAST(SUM(CASE WHEN verdict = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) as success_rate,
|
|
1731
|
+
AVG(completeness) as avg_completeness,
|
|
1732
|
+
AVG(total_duration_sec) as avg_duration
|
|
1733
|
+
FROM variant_executions
|
|
1734
|
+
WHERE completed_at IS NOT NULL
|
|
1735
|
+
GROUP BY CASE WHEN INSTR(variant, ':') > 0
|
|
1736
|
+
THEN SUBSTR(variant, 1, INSTR(variant, ':') - 1)
|
|
1737
|
+
ELSE variant
|
|
1738
|
+
END
|
|
1739
|
+
HAVING total_tasks >= 5
|
|
1740
|
+
`;
|
|
1741
|
+
const results = this.variantsDb.prepare(query).all();
|
|
1742
|
+
return results.map((row) => ({
|
|
1743
|
+
provider: row.provider,
|
|
1744
|
+
model: "unknown",
|
|
1745
|
+
// Would need more detailed tracking
|
|
1746
|
+
capabilities: {
|
|
1747
|
+
codeGeneration: row.success_rate,
|
|
1748
|
+
debugging: null,
|
|
1749
|
+
refactoring: null,
|
|
1750
|
+
testing: null,
|
|
1751
|
+
documentation: null,
|
|
1752
|
+
architecture: null
|
|
1753
|
+
},
|
|
1754
|
+
optimalUseCases: [],
|
|
1755
|
+
// Would need more detailed analysis
|
|
1756
|
+
limitations: [],
|
|
1757
|
+
// Would need failure pattern analysis
|
|
1758
|
+
adaptationPatterns: {
|
|
1759
|
+
learningRate: null,
|
|
1760
|
+
consistencyScore: Math.min(row.success_rate / 0.8, 1),
|
|
1761
|
+
contextRetention: null
|
|
1762
|
+
}
|
|
1763
|
+
}));
|
|
1764
|
+
}
|
|
1765
|
+
/**
|
|
1766
|
+
* Analyze behavioral patterns from execution data.
|
|
1767
|
+
*
|
|
1768
|
+
* @internal Not yet implemented. Always returns an empty array; behavioral
|
|
1769
|
+
* telemetry collection is not wired up. Do not present as real analytics.
|
|
1770
|
+
*/
|
|
1771
|
+
async analyzeBehavioralPatterns() {
|
|
1772
|
+
return [];
|
|
1773
|
+
}
|
|
1774
|
+
/**
|
|
1775
|
+
* Generate semantic task profiles.
|
|
1776
|
+
*
|
|
1777
|
+
* @internal Not yet implemented. Always returns an empty array; semantic
|
|
1778
|
+
* analysis is not wired up. Do not present as real analytics.
|
|
1779
|
+
*/
|
|
1780
|
+
async generateSemanticProfiles() {
|
|
1781
|
+
return [];
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Start the telemetry insight engine
|
|
1785
|
+
*
|
|
1786
|
+
* Initializes the insight engine and prepares it for generating insights
|
|
1787
|
+
* from telemetry data. This method must be called before using other
|
|
1788
|
+
* insight engine functionality.
|
|
1789
|
+
*
|
|
1790
|
+
* @returns {void}
|
|
1791
|
+
*
|
|
1792
|
+
* @example
|
|
1793
|
+
* ```typescript
|
|
1794
|
+
* const engine = new TelemetryInsightEngine();
|
|
1795
|
+
* engine.start();
|
|
1796
|
+
* // Now the engine is ready to generate insights
|
|
1797
|
+
* ```
|
|
1798
|
+
*/
|
|
1799
|
+
start() {
|
|
1800
|
+
if (!this.enabled) {
|
|
1801
|
+
emitTelemetryFallbackWarning("TelemetryInsightEngine is disabled - using in-memory fallback");
|
|
1802
|
+
return;
|
|
1803
|
+
}
|
|
1804
|
+
try {
|
|
1805
|
+
this.variantsDb.prepare("SELECT 1").get();
|
|
1806
|
+
if (this.enableRealTime) {
|
|
1807
|
+
this.startRealTimeMonitoring();
|
|
1808
|
+
}
|
|
1809
|
+
} catch (error) {
|
|
1810
|
+
emitTelemetryFallbackWarning("Failed to start TelemetryInsightEngine", error);
|
|
1811
|
+
throw new Error("TelemetryInsightEngine database connection is not available");
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Add a data source to the insight engine
|
|
1816
|
+
*
|
|
1817
|
+
* Registers a new data source that the insight engine can use for
|
|
1818
|
+
* generating insights and analysis. Data sources provide structured
|
|
1819
|
+
* information about different aspects of the system.
|
|
1820
|
+
*
|
|
1821
|
+
* @param name - Unique identifier for the data source
|
|
1822
|
+
* @param config - Configuration describing the data source
|
|
1823
|
+
* @returns {void}
|
|
1824
|
+
*
|
|
1825
|
+
* @example
|
|
1826
|
+
* ```typescript
|
|
1827
|
+
* engine.addDataSource('progress_tracker', {
|
|
1828
|
+
* name: 'Progress Tracker Data',
|
|
1829
|
+
* description: 'Progress tracking and performance data',
|
|
1830
|
+
* type: 'time_series'
|
|
1831
|
+
* });
|
|
1832
|
+
* ```
|
|
1833
|
+
*/
|
|
1834
|
+
addDataSource(name, config) {
|
|
1835
|
+
if (!this.enabled) {
|
|
1836
|
+
emitTelemetryFallbackWarning(`Insight engine disabled - skipping data source: ${name}`);
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
try {
|
|
1840
|
+
const createTableQuery = `
|
|
1841
|
+
CREATE TABLE IF NOT EXISTS data_sources (
|
|
1842
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1843
|
+
name TEXT UNIQUE NOT NULL,
|
|
1844
|
+
display_name TEXT NOT NULL,
|
|
1845
|
+
description TEXT NOT NULL,
|
|
1846
|
+
type TEXT NOT NULL,
|
|
1847
|
+
schema TEXT,
|
|
1848
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
1849
|
+
status TEXT DEFAULT 'active'
|
|
1850
|
+
)
|
|
1851
|
+
`;
|
|
1852
|
+
this.variantsDb.prepare(createTableQuery).run();
|
|
1853
|
+
const insertQuery = `
|
|
1854
|
+
INSERT OR REPLACE INTO data_sources (name, display_name, description, type, schema)
|
|
1855
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1856
|
+
`;
|
|
1857
|
+
this.variantsDb.prepare(insertQuery).run(
|
|
1858
|
+
name,
|
|
1859
|
+
config.name,
|
|
1860
|
+
config.description,
|
|
1861
|
+
config.type,
|
|
1862
|
+
JSON.stringify(config.schema || {})
|
|
1863
|
+
);
|
|
1864
|
+
} catch (error) {
|
|
1865
|
+
emitTelemetryFallbackWarning(`Failed to register data source ${name}`, error);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
/**
|
|
1869
|
+
* Clean up resources and stop monitoring.
|
|
1870
|
+
*/
|
|
1871
|
+
close() {
|
|
1872
|
+
this.stopRealTimeMonitoring();
|
|
1873
|
+
this.variantsDb.close();
|
|
1874
|
+
}
|
|
1875
|
+
};
|
|
1876
|
+
|
|
1877
|
+
// src/telemetry/integrity-check.ts
|
|
1878
|
+
function getSchemaColumns(db) {
|
|
1879
|
+
return getTableColumns(db, "variant_executions");
|
|
1880
|
+
}
|
|
1881
|
+
function getTableColumns(db, table) {
|
|
1882
|
+
try {
|
|
1883
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
1884
|
+
return new Set(rows.map((r) => r.name));
|
|
1885
|
+
} catch {
|
|
1886
|
+
return /* @__PURE__ */ new Set();
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
function getWhitelistColumns() {
|
|
1890
|
+
return new Set(VARIANT_EXECUTION_COLUMNS);
|
|
1891
|
+
}
|
|
1892
|
+
function validateTelemetryIntegrity(db) {
|
|
1893
|
+
const schemaColumns = getSchemaColumns(db);
|
|
1894
|
+
const whitelistColumns = getWhitelistColumns();
|
|
1895
|
+
const excludedColumns = /* @__PURE__ */ new Set([
|
|
1896
|
+
"id",
|
|
1897
|
+
// Auto-increment primary key
|
|
1898
|
+
"project_id",
|
|
1899
|
+
// Scope dimension, always set by context-aware writers
|
|
1900
|
+
"lab_id",
|
|
1901
|
+
// Optional lab scoping dimension
|
|
1902
|
+
"lab_run_id",
|
|
1903
|
+
// Optional lab run scoping dimension
|
|
1904
|
+
"task_id",
|
|
1905
|
+
// Part of UNIQUE constraint, not dynamically updated
|
|
1906
|
+
"variant",
|
|
1907
|
+
// Part of UNIQUE constraint, not dynamically updated
|
|
1908
|
+
"created_at",
|
|
1909
|
+
// Auto-managed by DEFAULT CURRENT_TIMESTAMP
|
|
1910
|
+
"updated_at",
|
|
1911
|
+
// Auto-managed by DEFAULT CURRENT_TIMESTAMP
|
|
1912
|
+
"commit_sha_before",
|
|
1913
|
+
// Managed separately via git integration
|
|
1914
|
+
"commit_sha_after",
|
|
1915
|
+
// Managed separately via git integration
|
|
1916
|
+
"workspace_edit_success_rate",
|
|
1917
|
+
// Derived metric
|
|
1918
|
+
"score_breakdown_json"
|
|
1919
|
+
// Managed by judge evaluation system
|
|
1920
|
+
]);
|
|
1921
|
+
const schemaNotInWhitelist = [];
|
|
1922
|
+
const whitelistNotInSchema = [];
|
|
1923
|
+
for (const col of schemaColumns) {
|
|
1924
|
+
if (!whitelistColumns.has(col) && !excludedColumns.has(col)) {
|
|
1925
|
+
schemaNotInWhitelist.push(col);
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
for (const col of whitelistColumns) {
|
|
1929
|
+
if (!schemaColumns.has(col)) {
|
|
1930
|
+
whitelistNotInSchema.push(col);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
const tableColumnCache = /* @__PURE__ */ new Map();
|
|
1934
|
+
for (const inv of SCHEMA_INVARIANTS) {
|
|
1935
|
+
let cols = tableColumnCache.get(inv.table);
|
|
1936
|
+
if (!cols) {
|
|
1937
|
+
cols = getTableColumns(db, inv.table);
|
|
1938
|
+
tableColumnCache.set(inv.table, cols);
|
|
1939
|
+
}
|
|
1940
|
+
if (cols.size === 0) continue;
|
|
1941
|
+
if (!cols.has(inv.column)) {
|
|
1942
|
+
schemaNotInWhitelist.push(`${inv.table}.${inv.column}`);
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
return {
|
|
1946
|
+
schemaNotInWhitelist,
|
|
1947
|
+
whitelistNotInSchema
|
|
1948
|
+
};
|
|
1949
|
+
}
|
|
1950
|
+
function formatIntegrityReport(issues) {
|
|
1951
|
+
const lines = [];
|
|
1952
|
+
if (issues.schemaNotInWhitelist.length > 0) {
|
|
1953
|
+
lines.push(
|
|
1954
|
+
`Warning: Schema columns not in whitelist: ${issues.schemaNotInWhitelist.join(", ")}`
|
|
1955
|
+
);
|
|
1956
|
+
lines.push(" These columns exist but cannot be queried safely.");
|
|
1957
|
+
lines.push(" Action: Add to VARIANT_EXECUTION_COLUMNS in variant-execution-columns.ts");
|
|
1958
|
+
}
|
|
1959
|
+
if (issues.whitelistNotInSchema.length > 0) {
|
|
1960
|
+
lines.push(
|
|
1961
|
+
`Warning: Whitelist columns not in schema: ${issues.whitelistNotInSchema.join(", ")}`
|
|
1962
|
+
);
|
|
1963
|
+
lines.push(" These whitelisted columns do not exist in the schema.");
|
|
1964
|
+
lines.push(" Action: Remove from VARIANT_EXECUTION_COLUMNS or add to schema");
|
|
1965
|
+
}
|
|
1966
|
+
if (lines.length === 0) {
|
|
1967
|
+
lines.push("OK: Telemetry integrity check passed");
|
|
1968
|
+
}
|
|
1969
|
+
return lines.join("\n");
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
// src/telemetry/observability-metrics.ts
|
|
1973
|
+
import { EventEmitter } from "events";
|
|
1974
|
+
var ObservabilityMetricsTracker = class _ObservabilityMetricsTracker extends EventEmitter {
|
|
1975
|
+
static DEFAULT_MAX_METRIC_KEYS = 500;
|
|
1976
|
+
static DEFAULT_POOL_EXHAUSTION_ALERT_THRESHOLD = 10;
|
|
1977
|
+
static DEFAULT_CONCURRENCY_ALERT_THRESHOLD = 5;
|
|
1978
|
+
static DEFAULT_TIMEOUT_ALERT_THRESHOLD = 20;
|
|
1979
|
+
metrics;
|
|
1980
|
+
logger;
|
|
1981
|
+
maxMetricKeys;
|
|
1982
|
+
poolExhaustionAlertThreshold;
|
|
1983
|
+
concurrencyAlertThreshold;
|
|
1984
|
+
timeoutAlertThreshold;
|
|
1985
|
+
static parsePositiveIntEnv(envVar, fallback) {
|
|
1986
|
+
const raw = process.env[envVar];
|
|
1987
|
+
if (!raw) {
|
|
1988
|
+
return fallback;
|
|
1989
|
+
}
|
|
1990
|
+
const parsed = Number.parseInt(raw, 10);
|
|
1991
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
1992
|
+
}
|
|
1993
|
+
constructor(logger) {
|
|
1994
|
+
super();
|
|
1995
|
+
this.logger = logger;
|
|
1996
|
+
this.maxMetricKeys = _ObservabilityMetricsTracker.parsePositiveIntEnv(
|
|
1997
|
+
"POETIC_TELEMETRY_OBSERVABILITY_MAX_KEYS",
|
|
1998
|
+
_ObservabilityMetricsTracker.DEFAULT_MAX_METRIC_KEYS
|
|
1999
|
+
);
|
|
2000
|
+
this.poolExhaustionAlertThreshold = _ObservabilityMetricsTracker.parsePositiveIntEnv(
|
|
2001
|
+
"POETIC_TELEMETRY_POOL_EXHAUSTION_ALERT_THRESHOLD",
|
|
2002
|
+
_ObservabilityMetricsTracker.DEFAULT_POOL_EXHAUSTION_ALERT_THRESHOLD
|
|
2003
|
+
);
|
|
2004
|
+
this.concurrencyAlertThreshold = _ObservabilityMetricsTracker.parsePositiveIntEnv(
|
|
2005
|
+
"POETIC_TELEMETRY_CONCURRENCY_ALERT_THRESHOLD",
|
|
2006
|
+
_ObservabilityMetricsTracker.DEFAULT_CONCURRENCY_ALERT_THRESHOLD
|
|
2007
|
+
);
|
|
2008
|
+
this.timeoutAlertThreshold = _ObservabilityMetricsTracker.parsePositiveIntEnv(
|
|
2009
|
+
"POETIC_TELEMETRY_TIMEOUT_ALERT_THRESHOLD",
|
|
2010
|
+
_ObservabilityMetricsTracker.DEFAULT_TIMEOUT_ALERT_THRESHOLD
|
|
2011
|
+
);
|
|
2012
|
+
this.metrics = {
|
|
2013
|
+
poolExhaustions: /* @__PURE__ */ new Map(),
|
|
2014
|
+
concurrencyViolations: /* @__PURE__ */ new Map(),
|
|
2015
|
+
timeouts: /* @__PURE__ */ new Map(),
|
|
2016
|
+
lastUpdated: Date.now()
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
/**
|
|
2020
|
+
* Record a pool exhaustion event
|
|
2021
|
+
*/
|
|
2022
|
+
recordPoolExhaustion(params) {
|
|
2023
|
+
const { poolType, maxSize, activeCount } = params;
|
|
2024
|
+
const key = poolType;
|
|
2025
|
+
const existing = this.metrics.poolExhaustions.get(key);
|
|
2026
|
+
const metrics = {
|
|
2027
|
+
totalExhaustions: (existing?.totalExhaustions ?? 0) + 1,
|
|
2028
|
+
lastExhaustionAt: Date.now(),
|
|
2029
|
+
poolType,
|
|
2030
|
+
maxSize,
|
|
2031
|
+
activeCount
|
|
2032
|
+
};
|
|
2033
|
+
this.metrics.poolExhaustions.set(key, metrics);
|
|
2034
|
+
this.enforceBoundedMap(this.metrics.poolExhaustions, (entry) => entry.lastExhaustionAt);
|
|
2035
|
+
this.metrics.lastUpdated = Date.now();
|
|
2036
|
+
this.logger?.logCostEvent("pool_exhaustion", {
|
|
2037
|
+
poolType,
|
|
2038
|
+
maxSize,
|
|
2039
|
+
activeCount,
|
|
2040
|
+
totalExhaustions: metrics.totalExhaustions
|
|
2041
|
+
});
|
|
2042
|
+
this.emit("pool_exhaustion", metrics);
|
|
2043
|
+
if (metrics.totalExhaustions > this.poolExhaustionAlertThreshold) {
|
|
2044
|
+
this.emit("pool_exhaustion_alert", {
|
|
2045
|
+
...metrics,
|
|
2046
|
+
severity: "high",
|
|
2047
|
+
message: `Pool ${poolType} has exhausted ${metrics.totalExhaustions} times`
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Record a concurrency limit violation
|
|
2053
|
+
*/
|
|
2054
|
+
recordConcurrencyViolation(params) {
|
|
2055
|
+
const { resource, configuredLimit, actualCount } = params;
|
|
2056
|
+
const key = resource;
|
|
2057
|
+
const existing = this.metrics.concurrencyViolations.get(key);
|
|
2058
|
+
const metrics = {
|
|
2059
|
+
totalViolations: (existing?.totalViolations ?? 0) + 1,
|
|
2060
|
+
lastViolationAt: Date.now(),
|
|
2061
|
+
resource,
|
|
2062
|
+
configuredLimit,
|
|
2063
|
+
actualCount
|
|
2064
|
+
};
|
|
2065
|
+
this.metrics.concurrencyViolations.set(key, metrics);
|
|
2066
|
+
this.enforceBoundedMap(this.metrics.concurrencyViolations, (entry) => entry.lastViolationAt);
|
|
2067
|
+
this.metrics.lastUpdated = Date.now();
|
|
2068
|
+
this.logger?.logCostEvent("concurrency_limit_violation", {
|
|
2069
|
+
resource,
|
|
2070
|
+
configuredLimit,
|
|
2071
|
+
actualCount,
|
|
2072
|
+
totalViolations: metrics.totalViolations
|
|
2073
|
+
});
|
|
2074
|
+
this.emit("concurrency_violation", metrics);
|
|
2075
|
+
if (metrics.totalViolations > this.concurrencyAlertThreshold) {
|
|
2076
|
+
this.emit("concurrency_violation_alert", {
|
|
2077
|
+
...metrics,
|
|
2078
|
+
severity: "high",
|
|
2079
|
+
message: `Resource ${resource} has violated concurrency limit ${metrics.totalViolations} times`
|
|
2080
|
+
});
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
/**
|
|
2084
|
+
* Record a timeout event
|
|
2085
|
+
*/
|
|
2086
|
+
recordTimeout(params) {
|
|
2087
|
+
const { operationType, configuredTimeoutMs, actualDurationMs } = params;
|
|
2088
|
+
const key = operationType;
|
|
2089
|
+
const existing = this.metrics.timeouts.get(key);
|
|
2090
|
+
const metrics = {
|
|
2091
|
+
totalTimeouts: (existing?.totalTimeouts ?? 0) + 1,
|
|
2092
|
+
lastTimeoutAt: Date.now(),
|
|
2093
|
+
operationType,
|
|
2094
|
+
configuredTimeoutMs,
|
|
2095
|
+
actualDurationMs
|
|
2096
|
+
};
|
|
2097
|
+
this.metrics.timeouts.set(key, metrics);
|
|
2098
|
+
this.enforceBoundedMap(this.metrics.timeouts, (entry) => entry.lastTimeoutAt);
|
|
2099
|
+
this.metrics.lastUpdated = Date.now();
|
|
2100
|
+
this.logger?.logCostEvent("timeout_hit", {
|
|
2101
|
+
operationType,
|
|
2102
|
+
configuredTimeoutMs,
|
|
2103
|
+
actualDurationMs,
|
|
2104
|
+
totalTimeouts: metrics.totalTimeouts
|
|
2105
|
+
});
|
|
2106
|
+
this.emit("timeout", metrics);
|
|
2107
|
+
if (metrics.totalTimeouts > this.timeoutAlertThreshold) {
|
|
2108
|
+
this.emit("timeout_alert", {
|
|
2109
|
+
...metrics,
|
|
2110
|
+
severity: "high",
|
|
2111
|
+
message: `Operation ${operationType} has timed out ${metrics.totalTimeouts} times`
|
|
2112
|
+
});
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
/**
|
|
2116
|
+
* Get current metrics snapshot
|
|
2117
|
+
*/
|
|
2118
|
+
getMetrics() {
|
|
2119
|
+
return {
|
|
2120
|
+
poolExhaustions: new Map(this.metrics.poolExhaustions),
|
|
2121
|
+
concurrencyViolations: new Map(this.metrics.concurrencyViolations),
|
|
2122
|
+
timeouts: new Map(this.metrics.timeouts),
|
|
2123
|
+
lastUpdated: this.metrics.lastUpdated
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
2126
|
+
/**
|
|
2127
|
+
* Get metrics summary for reporting
|
|
2128
|
+
*/
|
|
2129
|
+
getSummary() {
|
|
2130
|
+
const totalPoolExhaustions = Array.from(this.metrics.poolExhaustions.values()).reduce(
|
|
2131
|
+
(sum, m) => sum + m.totalExhaustions,
|
|
2132
|
+
0
|
|
2133
|
+
);
|
|
2134
|
+
const totalConcurrencyViolations = Array.from(
|
|
2135
|
+
this.metrics.concurrencyViolations.values()
|
|
2136
|
+
).reduce((sum, m) => sum + m.totalViolations, 0);
|
|
2137
|
+
const totalTimeouts = Array.from(this.metrics.timeouts.values()).reduce(
|
|
2138
|
+
(sum, m) => sum + m.totalTimeouts,
|
|
2139
|
+
0
|
|
2140
|
+
);
|
|
2141
|
+
return {
|
|
2142
|
+
totalPoolExhaustions,
|
|
2143
|
+
totalConcurrencyViolations,
|
|
2144
|
+
totalTimeouts,
|
|
2145
|
+
poolTypes: Array.from(this.metrics.poolExhaustions.keys()),
|
|
2146
|
+
resources: Array.from(this.metrics.concurrencyViolations.keys()),
|
|
2147
|
+
operationTypes: Array.from(this.metrics.timeouts.keys())
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
/**
|
|
2151
|
+
* Reset all metrics
|
|
2152
|
+
*/
|
|
2153
|
+
reset() {
|
|
2154
|
+
this.metrics = {
|
|
2155
|
+
poolExhaustions: /* @__PURE__ */ new Map(),
|
|
2156
|
+
concurrencyViolations: /* @__PURE__ */ new Map(),
|
|
2157
|
+
timeouts: /* @__PURE__ */ new Map(),
|
|
2158
|
+
lastUpdated: Date.now()
|
|
2159
|
+
};
|
|
2160
|
+
this.emit("metrics_reset");
|
|
2161
|
+
}
|
|
2162
|
+
enforceBoundedMap(map, getTimestamp) {
|
|
2163
|
+
if (map.size <= this.maxMetricKeys) {
|
|
2164
|
+
return;
|
|
2165
|
+
}
|
|
2166
|
+
const entries = Array.from(map.entries()).sort(([, a], [, b]) => {
|
|
2167
|
+
const aTs = getTimestamp(a) ?? 0;
|
|
2168
|
+
const bTs = getTimestamp(b) ?? 0;
|
|
2169
|
+
return aTs - bTs;
|
|
2170
|
+
});
|
|
2171
|
+
const toDelete = map.size - this.maxMetricKeys;
|
|
2172
|
+
for (let i = 0; i < toDelete; i++) {
|
|
2173
|
+
const key = entries[i]?.[0];
|
|
2174
|
+
if (key) {
|
|
2175
|
+
map.delete(key);
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
};
|
|
2180
|
+
var globalObservabilityTracker = null;
|
|
2181
|
+
function getObservabilityTracker(logger) {
|
|
2182
|
+
if (!globalObservabilityTracker) {
|
|
2183
|
+
globalObservabilityTracker = new ObservabilityMetricsTracker(logger);
|
|
2184
|
+
}
|
|
2185
|
+
return globalObservabilityTracker;
|
|
2186
|
+
}
|
|
2187
|
+
function recordMetric(name, value, tags) {
|
|
2188
|
+
try {
|
|
2189
|
+
getTelemetryLogger().logEvent(`metric:${name}`, { value, ...tags ?? {} });
|
|
2190
|
+
} catch {
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
|
|
2194
|
+
export {
|
|
2195
|
+
TelemetryDashboard,
|
|
2196
|
+
isCoreVariantEvent,
|
|
2197
|
+
validateEventType,
|
|
2198
|
+
TelemetryInsightEngine,
|
|
2199
|
+
getSchemaColumns,
|
|
2200
|
+
getWhitelistColumns,
|
|
2201
|
+
validateTelemetryIntegrity,
|
|
2202
|
+
formatIntegrityReport,
|
|
2203
|
+
getObservabilityTracker,
|
|
2204
|
+
recordMetric
|
|
2205
|
+
};
|
|
2206
|
+
//# sourceMappingURL=chunk-5RBHQYDB.js.map
|