@iowarp/clio-coder 0.4.7 → 0.4.8
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +29 -0
- package/CONTRIBUTING.md +83 -74
- package/README.md +66 -45
- package/dist/{acp-W3Y3TRHD.js → acp-JWPQZM2D.js} +14 -14
- package/dist/{agents-J4ICNLQ3.js → agents-4GCDIRVX.js} +55 -54
- package/dist/assets/codewiki.json +1 -1
- package/dist/assets/web-notices/@hono__node-server-LICENSE +21 -0
- package/dist/assets/web-notices/hono-LICENSE +21 -0
- package/dist/{auth-X2UJUMOC.js → auth-SYAKTDQE.js} +22 -22
- package/dist/background-OW67WMYR.js +37 -0
- package/dist/{builtins-XLXWWSRF.js → builtins-TKS63VNV.js} +4 -4
- package/dist/chunk-2JSCCEKO.js +85 -0
- package/dist/{chunk-QKWL7SYE.js → chunk-2SXGG2IV.js} +49 -38
- package/dist/{chunk-MZHXENL7.js → chunk-2U2U5POA.js} +5 -5
- package/dist/{chunk-NCCQ6DVS.js → chunk-2ZWLMA3T.js} +6 -6
- package/dist/{chunk-FQOOGXBH.js → chunk-36XSBPXL.js} +7 -7
- package/dist/{chunk-5AJPUR72.js → chunk-3IQOZRQ6.js} +7 -7
- package/dist/{chunk-4MFBBY2Z.js → chunk-44U2OUSM.js} +3 -3
- package/dist/{chunk-5ZSZEYJK.js → chunk-4P6M2TTE.js} +2 -2
- package/dist/{chunk-IZYTT3CD.js → chunk-526ABLHD.js} +6 -6
- package/dist/{chunk-BO4XV5VX.js → chunk-5C2OQHLR.js} +4 -4
- package/dist/chunk-5D2FNBMG.js +185 -0
- package/dist/{chunk-M6Z2V6YU.js → chunk-5HULHKT2.js} +5 -5
- package/dist/{chunk-PFLOULP3.js → chunk-5UG6EZI3.js} +4 -4
- package/dist/{chunk-WN552PKN.js → chunk-5W4FRA5Q.js} +280 -900
- package/dist/{chunk-KAFMW7WM.js → chunk-6R5MBXBJ.js} +1 -1
- package/dist/{chunk-24S3DN22.js → chunk-6TKOFFGE.js} +4 -4
- package/dist/{chunk-YKRJTYNP.js → chunk-6UJ7RDI7.js} +4 -4
- package/dist/{chunk-GXIWHXDB.js → chunk-6X7VOCDY.js} +3 -3
- package/dist/{chunk-KKEYGFX4.js → chunk-7QQRPB2E.js} +11 -11
- package/dist/{chunk-34XHRVKG.js → chunk-ARRUMZ7X.js} +2 -2
- package/dist/{chunk-3T4DXWP6.js → chunk-ATB3Q7YO.js} +1 -6
- package/dist/chunk-AUHVBIDW.js +19 -0
- package/dist/{chunk-L3Z5ANCV.js → chunk-BE4I3UJ2.js} +7 -7
- package/dist/chunk-BFPHMSK7.js +169 -0
- package/dist/{chunk-LVFANMOH.js → chunk-BHJMMCXS.js} +4 -4
- package/dist/{chunk-D2T66PDV.js → chunk-BIY22UUK.js} +35 -203
- package/dist/{chunk-VMATUZB6.js → chunk-D55WO5J7.js} +11 -11
- package/dist/{chunk-2O2LVQQK.js → chunk-E2NSPYLC.js} +4 -4
- package/dist/{chunk-IJMW64DX.js → chunk-EFXMQYI6.js} +32 -32
- package/dist/{chunk-GVZFCJHE.js → chunk-EPYATQMG.js} +18 -18
- package/dist/{chunk-MZNWZUJM.js → chunk-EXKUF426.js} +11 -11
- package/dist/{chunk-IMOD2YPV.js → chunk-F7Y6QTPL.js} +9 -19
- package/dist/{chunk-IQCNVLO6.js → chunk-FB3KTE2J.js} +10 -7
- package/dist/{chunk-3LXJOICS.js → chunk-FNVPQQYT.js} +2 -2
- package/dist/{chunk-UUQ5G6EZ.js → chunk-GEYX2NZ5.js} +2 -2
- package/dist/{chunk-CP3HIR5H.js → chunk-GJBJHJNY.js} +19 -18
- package/dist/{chunk-LZBMXNLP.js → chunk-GM4TY6VN.js} +43 -6
- package/dist/{chunk-WT5TRMO4.js → chunk-GVU4CXPJ.js} +179 -65
- package/dist/{chunk-TZ6UVP2H.js → chunk-H5DPSUBB.js} +8 -8
- package/dist/{chunk-EUEXGXXR.js → chunk-H77XBUBM.js} +5 -5
- package/dist/{config-YXARKGTX.js → chunk-HMGAKB7E.js} +15 -259
- package/dist/{chunk-EUZRMP4Y.js → chunk-HP7KJ5O2.js} +19 -19
- package/dist/chunk-HVCAY2FH.js +67 -0
- package/dist/{chunk-CPXGJI2A.js → chunk-ICYIUNO4.js} +4 -4
- package/dist/{chunk-GI5RRMAH.js → chunk-IILXVWJY.js} +7 -7
- package/dist/{chunk-MNQN3X6Y.js → chunk-JCVIL6TY.js} +5 -5
- package/dist/chunk-JIMWEYWO.js +63 -0
- package/dist/{chunk-C3G5PNUO.js → chunk-JLBVCROW.js} +25 -25
- package/dist/chunk-JOBN2YQQ.js +176 -0
- package/dist/chunk-JOL2QRLE.js +152 -0
- package/dist/{chunk-N37QC5FV.js → chunk-JRA6OBHY.js} +5 -5
- package/dist/{chunk-C6GEXX4L.js → chunk-JV25I7ID.js} +7 -7
- package/dist/{chunk-SEDI5K5B.js → chunk-JYKUMHCQ.js} +16 -16
- package/dist/{chunk-UA6W4XFJ.js → chunk-K3W6BF5C.js} +2 -2
- package/dist/chunk-K45LHSCI.js +194 -0
- package/dist/{chunk-UA3W4FGC.js → chunk-K53E2PTW.js} +5 -5
- package/dist/{chunk-VCRVEDUC.js → chunk-K5UJD6MM.js} +5 -5
- package/dist/{chunk-65BGHOUR.js → chunk-KGP3UQGJ.js} +5 -5
- package/dist/chunk-KKRXONXG.js +43 -0
- package/dist/{chunk-LBFQMYS3.js → chunk-KWJXCL2X.js} +5 -3
- package/dist/{chunk-RTLNFZMD.js → chunk-L75H5B3B.js} +3 -3
- package/dist/{chunk-G4LGUTOE.js → chunk-LLCGGVSW.js} +6 -6
- package/dist/{chunk-HRAKUPIH.js → chunk-LZCCBLRC.js} +5 -5
- package/dist/{chunk-WURGVOZJ.js → chunk-LZDLYSUN.js} +18 -14
- package/dist/{chunk-ISNCCX42.js → chunk-MATCRH3M.js} +7 -6
- package/dist/{chunk-BAU36233.js → chunk-MEHBW2SP.js} +7 -7
- package/dist/{chunk-BQQ5MXUC.js → chunk-MUXNDNMZ.js} +3 -3
- package/dist/{chunk-NO7J45X6.js → chunk-MWMW53WW.js} +90 -51
- package/dist/chunk-MZDPF35R.js +45 -0
- package/dist/{chunk-P4DL2LM5.js → chunk-MZKYVIWW.js} +8 -119
- package/dist/{chunk-T334FW2H.js → chunk-O2QJDRWP.js} +5 -5
- package/dist/{chunk-T7QQBNLH.js → chunk-O3HSB2YL.js} +9 -7
- package/dist/{chunk-WB7POC6M.js → chunk-OEMFEL26.js} +6 -6
- package/dist/{chunk-77CZRFTE.js → chunk-OPC4DQD6.js} +2 -2
- package/dist/{chunk-4UHVS5T7.js → chunk-ORRNGQDV.js} +8 -8
- package/dist/{chunk-TZHN5ITX.js → chunk-P4JS3MH5.js} +5 -5
- package/dist/{chunk-WBVKKTUT.js → chunk-P7GTE4FX.js} +2 -2
- package/dist/{chunk-6TAATXXH.js → chunk-PAQVETLA.js} +6 -6
- package/dist/{chunk-6CA2BHOR.js → chunk-PFZJMXIY.js} +4 -4
- package/dist/{chunk-4QKAITQT.js → chunk-PGEFOTJB.js} +70 -7
- package/dist/{chunk-MBJO5VNZ.js → chunk-PJ5H5B7A.js} +25 -25
- package/dist/{chunk-DO7M3LSX.js → chunk-PMUUAABD.js} +43 -96
- package/dist/{chunk-A67NR5AT.js → chunk-Q32C6AWI.js} +11 -8
- package/dist/{chunk-ECOMVOHP.js → chunk-QGIC5SX5.js} +2 -2
- package/dist/{chunk-5CMARGPF.js → chunk-QLAGXTTV.js} +7 -2
- package/dist/{chunk-GFQ7P2UF.js → chunk-QLKCCC2J.js} +9 -9
- package/dist/{chunk-SELG4SUR.js → chunk-QWUSS2QP.js} +7 -4
- package/dist/{chunk-P5SC4DLJ.js → chunk-QYSAZMSH.js} +2 -2
- package/dist/{fleet-decisions-S3PTZV2D.js → chunk-R5NRX5N4.js} +5 -41
- package/dist/{chunk-DLIYANB7.js → chunk-RAUOKUZV.js} +11 -11
- package/dist/{chunk-UFYNOQK4.js → chunk-RBES4TCZ.js} +7 -7
- package/dist/{chunk-T52TPHYC.js → chunk-RFULVPBX.js} +4 -4
- package/dist/{chunk-TLTGZTXI.js → chunk-RKFNU5UA.js} +3 -3
- package/dist/{chunk-T4TY5GG3.js → chunk-RM3XJX7P.js} +3 -3
- package/dist/{chunk-6YA46L5A.js → chunk-RNLAPBJL.js} +2 -2
- package/dist/chunk-RPMNIFRY.js +65 -0
- package/dist/{chunk-DACXIVVF.js → chunk-RRZFRIJP.js} +5 -5
- package/dist/{chunk-CE64C5K5.js → chunk-RXI7K4J5.js} +61 -61
- package/dist/{chunk-CULVKYTK.js → chunk-STC6CWUZ.js} +5 -5
- package/dist/{chunk-6YHPAAZR.js → chunk-TEHVMHOK.js} +3 -3
- package/dist/{chunk-VTYHHQ57.js → chunk-TOPICHGR.js} +2 -2
- package/dist/{chunk-UWD3JD5X.js → chunk-UB33F3YW.js} +10 -10
- package/dist/{chunk-TN5FW4XY.js → chunk-UDAK6GR2.js} +12 -9
- package/dist/chunk-USBBEKHW.js +177 -0
- package/dist/{chunk-6CB2IL4N.js → chunk-W5RM7YAH.js} +1 -1
- package/dist/{chunk-6LRLOJHQ.js → chunk-W7KNI3F5.js} +11 -62
- package/dist/chunk-WFTSK7N3.js +637 -0
- package/dist/{chunk-YPRSNUTC.js → chunk-WJWNZXRM.js} +2 -2
- package/dist/chunk-WS4FOGLY.js +686 -0
- package/dist/{chunk-ZGIGW4ZG.js → chunk-WTZVSMQZ.js} +5 -5
- package/dist/{chunk-XR3XJN2M.js → chunk-WWRV5RJI.js} +4 -4
- package/dist/{chunk-24TOGHPO.js → chunk-X6FLVUM5.js} +4 -4
- package/dist/chunk-XC5POIL4.js +68 -0
- package/dist/{chunk-XZ6UFQ52.js → chunk-XTLJDC2X.js} +22 -17
- package/dist/{chunk-7EEGBKV4.js → chunk-YGIV24MF.js} +8 -8
- package/dist/{chunk-RXFPB32E.js → chunk-YJCCMYYT.js} +2 -2
- package/dist/{chunk-4N2RZ4TO.js → chunk-YKIIWURD.js} +3 -3
- package/dist/{chunk-USZA7GWL.js → chunk-YQ3GFEUY.js} +2 -2
- package/dist/{chunk-KS7ETA3P.js → chunk-YXANQGCX.js} +6 -6
- package/dist/{chunk-HOX4YZ2K.js → chunk-YXFKLMX2.js} +5 -5
- package/dist/chunk-ZST3FRCV.js +132 -0
- package/dist/cli/index.js +39 -37
- package/dist/{clio-L2P7S2R2.js → clio-BPBAPZGA.js} +9 -9
- package/dist/{code-nav-B5LNX4KU.js → code-nav-KBQ3RIFK.js} +33 -33
- package/dist/{components-63MMQKUT.js → components-6DKAXWFN.js} +10 -10
- package/dist/config-FWL5JK2H.js +270 -0
- package/dist/config-graph-ACDB26L2.js +156 -0
- package/dist/{configure-LMVQJ46J.js → configure-ZIZ4YV62.js} +48 -48
- package/dist/{context-7HJEWTTP.js → context-EZZPT2ZV.js} +49 -49
- package/dist/{context-YG2LZDYZ.js → context-VIL5MFRH.js} +86 -84
- package/dist/{context-XSZKKFBW.js → context-Z3GOBHDK.js} +16 -16
- package/dist/{context-clear-AC5NXHM2.js → context-clear-ZPB3L7MN.js} +72 -70
- package/dist/{context-index-KKTPRV5G.js → context-index-W6A4V7OC.js} +4 -4
- package/dist/{context-map-T7ROR5D5.js → context-map-DKL3QT6D.js} +3 -3
- package/dist/{context-working-set-F4Q4J3NS.js → context-working-set-2GLBVF7L.js} +23 -22
- package/dist/{detail-H73BEF2N.js → detail-VSBWYSGZ.js} +73 -71
- package/dist/{dispatch-runner-3RY5FSJC.js → dispatch-runner-EEEHGKX4.js} +78 -76
- package/dist/docs-VMMWFVHL.js +101 -0
- package/dist/{doctor-EQYJOGUG.js → doctor-V5L4IQGP.js} +63 -62
- package/dist/{eval-4P7O6CCE.js → eval-VJYJ2BV3.js} +80 -65
- package/dist/{eval-inventory-QOYZERXJ.js → eval-inventory-CX24K2JT.js} +5 -60
- package/dist/evals-J2H5V6DD.js +104 -0
- package/dist/{evidence-D6GUSYJW.js → evidence-POWAEBEW.js} +72 -70
- package/dist/evidence-XCCCLS36.js +242 -0
- package/dist/{evidence-O76QF7TZ.js → evidence-Y35YSXH6.js} +80 -78
- package/dist/{evolve-H47BCETS.js → evolve-GPG72VB6.js} +74 -72
- package/dist/{extensions-NNL3ZOCU.js → extensions-YIZ7W3DA.js} +12 -11
- package/dist/fleet-2MDCQ2VK.js +264 -0
- package/dist/{fleet-KMNS6NOM.js → fleet-W2AF3TOJ.js} +127 -123
- package/dist/{fleet-commands-DOWSYCBX.js → fleet-commands-WS56G26H.js} +11 -11
- package/dist/fleet-decisions-MYGZ3JW7.js +52 -0
- package/dist/{fleet-graph-F2DE2TME.js → fleet-graph-ELTBXBAV.js} +22 -22
- package/dist/{fleet-inspect-EN2Q6IVB.js → fleet-inspect-45IK73L4.js} +84 -248
- package/dist/{fleet-preflight-FRLETDD3.js → fleet-preflight-T5NCZKHE.js} +4 -4
- package/dist/{fleet-validate-B2XDLS57.js → fleet-validate-VG4JBLA4.js} +26 -26
- package/dist/{fleet-verify-4JKUWGJ7.js → fleet-verify-VTSABAYO.js} +72 -70
- package/dist/{fleet-view-BHJFW26B.js → fleet-view-XC7WMKSS.js} +75 -73
- package/dist/{init-XAT5N5YM.js → init-VTJNNTIP.js} +95 -92
- package/dist/install-6PIF6F6W.js +19 -0
- package/dist/{interop-FVECHFKG.js → interop-IU6BNA7C.js} +25 -25
- package/dist/{inventory-7KFQGLCV.js → inventory-QPQUTUUZ.js} +75 -73
- package/dist/{library-NY2XOT75.js → library-HUTAS57T.js} +33 -33
- package/dist/{library-QAPAO23R.js → library-LF7DLU6S.js} +13 -13
- package/dist/library-Q3NWL5CM.js +75 -0
- package/dist/{library-import-5Y6MAS3R.js → library-import-PPW4YUC5.js} +25 -25
- package/dist/{library-inventory-JT6HWITQ.js → library-inventory-DIRVFRZU.js} +19 -19
- package/dist/{library-validation-EQUH25DC.js → library-validation-XHUZ3INE.js} +17 -17
- package/dist/{memory-DYVTTCP6.js → memory-Z2LSKNV6.js} +74 -72
- package/dist/{models-MASFJ6Y2.js → models-3FTREYPY.js} +53 -52
- package/dist/{monitor-YMP4NXJJ.js → monitor-HF2MQRB3.js} +83 -80
- package/dist/{orchestrator-AFQRRTEI.js → orchestrator-UYPA6W4S.js} +498 -358
- package/dist/{panes-NICTHQCV.js → panes-736XB73K.js} +14 -14
- package/dist/{panes-D3Y2KFG5.js → panes-C4P3PIWT.js} +4 -4
- package/dist/{paths-PSFAUIGO.js → paths-JQ4QYIYB.js} +6 -6
- package/dist/{preload-5Q7VXRFJ.js → preload-XSLRYH3Y.js} +72 -70
- package/dist/{reset-7NKZK7JN.js → reset-V7QSPZYE.js} +9 -9
- package/dist/{resources-NILSIZAT.js → resources-OJGDFHYT.js} +22 -22
- package/dist/{run-BPZGEBZV.js → run-T354SMDW.js} +129 -125
- package/dist/settings-MWZXO6RV.js +72 -0
- package/dist/{share-EZ6ERBMH.js → share-Y5ZKJPND.js} +26 -26
- package/dist/{skills-BTVVNYVM.js → skills-4GLZC4LN.js} +28 -28
- package/dist/{skills-eval-UY34MNK7.js → skills-eval-L5T7GODM.js} +87 -85
- package/dist/{skills-inventory-JDHSIA7I.js → skills-inventory-LASKXEZI.js} +22 -22
- package/dist/{slash-commands-K4FNQ2AT.js → slash-commands-OIMRU36D.js} +49 -49
- package/dist/{steer-2B3EQGFH.js → steer-KMAM2Y2C.js} +4 -4
- package/dist/{support-L2SOL3IE.js → support-AWC3XKPX.js} +8 -8
- package/dist/system-CD75NYBU.js +116 -0
- package/dist/{targets-44VKGFLN.js → targets-VSZX2J2S.js} +66 -65
- package/dist/{tasks-3KODKFU7.js → tasks-AN567LYH.js} +14 -14
- package/dist/{terminal-lease-LXA7MMPO.js → terminal-lease-6KTWNHVY.js} +3 -3
- package/dist/{tools-3UB7TEVR.js → tools-AGRK3V5J.js} +13 -13
- package/dist/{trace-TAMIU4OJ.js → trace-P4MQZD33.js} +18 -67
- package/dist/{uninstall-QYVRPEM4.js → uninstall-BRUTEPIC.js} +37 -12
- package/dist/{upgrade-7PMKM2JH.js → upgrade-SBCGHQGJ.js} +22 -21
- package/dist/{usage-6EQV7EQK.js → usage-BIDVTO6V.js} +93 -87
- package/dist/{verifiers-JLITWSHU.js → verifiers-LTGCAMXS.js} +12 -12
- package/dist/{verify-T7NAEVIG.js → verify-OZU4LLNP.js} +9 -9
- package/dist/web/client/THIRD_PARTY_LICENSES.md +1809 -0
- package/dist/web/client/assets/abnfDiagram-VCTEODGH-C5wfoHm3.js +1 -0
- package/dist/web/client/assets/arc-oH91sfLl.js +1 -0
- package/dist/web/client/assets/architecture-7GRP2DOG-EGozsYEO.js +1 -0
- package/dist/web/client/assets/architectureDiagram-5GKGNRK7-z9FokbJl.js +36 -0
- package/dist/web/client/assets/array-BifhSqXX.js +1 -0
- package/dist/web/client/assets/atkinson-hyperlegible-next-latin-ext-wght-normal-C6vrW8VD.woff2 +0 -0
- package/dist/web/client/assets/atkinson-hyperlegible-next-latin-wght-normal-BcXVPD7q.woff2 +0 -0
- package/dist/web/client/assets/blockDiagram-I7D4REHJ-wi0_CYHL.js +129 -0
- package/dist/web/client/assets/c4Diagram-7LVT6UL2-DV7NYc2W.js +38 -0
- package/dist/web/client/assets/channel-CiUWbHN9.js +1 -0
- package/dist/web/client/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/dist/web/client/assets/chunk-4HAMMTFA-Bhsegh3F.js +62 -0
- package/dist/web/client/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/dist/web/client/assets/chunk-75Z2AOVW-RQCckcQG.js +2 -0
- package/dist/web/client/assets/chunk-DU6HZSFF-C5USiOAy.js +125 -0
- package/dist/web/client/assets/chunk-F27PBJKO-BcNqv2x1.js +1 -0
- package/dist/web/client/assets/chunk-FOHPRMQF-CoA4358r.js +161 -0
- package/dist/web/client/assets/chunk-GMAD6QVW-Bq8JWiZT.js +72 -0
- package/dist/web/client/assets/chunk-GVQU2GXP-DbchrAeJ.js +1 -0
- package/dist/web/client/assets/chunk-IMKFNOWR-DrpvjocK.js +231 -0
- package/dist/web/client/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/dist/web/client/assets/chunk-L3NEJ4N5-DHLmTnCe.js +1 -0
- package/dist/web/client/assets/chunk-OSK3NFVY-CsRbtN9n.js +10 -0
- package/dist/web/client/assets/chunk-P2QGCYS3-aqPbxoMh.js +1 -0
- package/dist/web/client/assets/chunk-POPQ4Y6H-Dl5vw0h0.js +1 -0
- package/dist/web/client/assets/chunk-PWAF6VOD-D7OBRSdO.js +1 -0
- package/dist/web/client/assets/chunk-SHT3W25Y-CdKCIwuB.js +168 -0
- package/dist/web/client/assets/chunk-SVP7TREG-B94Nu_1-.js +88 -0
- package/dist/web/client/assets/chunk-TICWLB2K-jjRQI_hk.js +206 -0
- package/dist/web/client/assets/chunk-XXDRQBXY-azkbKE37.js +1 -0
- package/dist/web/client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/dist/web/client/assets/classDiagram-ZZMXUADV-CMODalmo.js +1 -0
- package/dist/web/client/assets/classDiagram-v2-VYDZK3BY-CMODalmo.js +1 -0
- package/dist/web/client/assets/commit-mono-latin-400-normal-s0S3qwFW.woff +0 -0
- package/dist/web/client/assets/commit-mono-latin-400-normal-wzhe4RuD.woff2 +0 -0
- package/dist/web/client/assets/cose-bilkent-JH36ORCC-RbQL23qS.js +1 -0
- package/dist/web/client/assets/cynefin-OW5HDTMX--i9RDU5f.js +1 -0
- package/dist/web/client/assets/cynefinDiagram-5FMLGOSQ-cRcvyBdp.js +62 -0
- package/dist/web/client/assets/cytoscape.esm-c2aL46s-.js +321 -0
- package/dist/web/client/assets/dagre-C-rnJpZF.js +1 -0
- package/dist/web/client/assets/dagre-GXQ25YYZ-C9mZmAPe.js +4 -0
- package/dist/web/client/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dist/web/client/assets/diagram-S7CK7UJ4-Oj_zlLDY.js +30 -0
- package/dist/web/client/assets/diagram-UQ7AKVKN-BWKbbfcR.js +41 -0
- package/dist/web/client/assets/diagram-VSXAHHWV-C3N3f7DO.js +3 -0
- package/dist/web/client/assets/diagram-VX7I27RA-CtDKDAWe.js +24 -0
- package/dist/web/client/assets/diagram-Z3DM3KII-B8bkBRCz.js +24 -0
- package/dist/web/client/assets/dist-D0_q-A2b.js +1 -0
- package/dist/web/client/assets/ebnfDiagram-PWID7BFC-CskW-Whx.js +1 -0
- package/dist/web/client/assets/erDiagram-RLTQ6QDP-C-83cgCW.js +99 -0
- package/dist/web/client/assets/eventmodeling-NTZA5JFV-DjVq8wKU.js +1 -0
- package/dist/web/client/assets/flowDiagram-HODETNUW-BUiCBGXt.js +1 -0
- package/dist/web/client/assets/ganttDiagram-EL5Y4UJY-B2lb8lvF.js +292 -0
- package/dist/web/client/assets/gitGraph-4MIJSDKK-B40cQtBE.js +1 -0
- package/dist/web/client/assets/gitGraphDiagram-WWUBYQGX-CH-7P7Di.js +106 -0
- package/dist/web/client/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/web/client/assets/index-Dsi52apB.css +1 -0
- package/dist/web/client/assets/index-FSIC94pi.js +83 -0
- package/dist/web/client/assets/info-A6RAGUB7-eCCE9D_Q.js +1 -0
- package/dist/web/client/assets/infoDiagram-27XIBGKW-DRnvqMjM.js +2 -0
- package/dist/web/client/assets/init-C-OQMol4.js +1 -0
- package/dist/web/client/assets/ishikawaDiagram-5VMMS53U-DBA_55wp.js +70 -0
- package/dist/web/client/assets/journeyDiagram-3NMN7TZE-C-ewpNl7.js +139 -0
- package/dist/web/client/assets/kanban-definition-UXKFOSKX-B1taGsu0.js +89 -0
- package/dist/web/client/assets/katex-ZlcWpGUi.js +257 -0
- package/dist/web/client/assets/line-lZ0kyxDI.js +1 -0
- package/dist/web/client/assets/linear-DIc8FgZj.js +1 -0
- package/dist/web/client/assets/mermaid-parser.core-SXolxpXw.js +7 -0
- package/dist/web/client/assets/mermaid.core-DXgQtkNg.js +44 -0
- package/dist/web/client/assets/mindmap-definition-YA3MSWOX-DXJas9K7.js +96 -0
- package/dist/web/client/assets/newsreader-latin-ext-wght-normal-C-3rgBeH.woff2 +0 -0
- package/dist/web/client/assets/newsreader-latin-wght-normal-CCVVNp6i.woff2 +0 -0
- package/dist/web/client/assets/newsreader-vietnamese-wght-normal-Czsa-EzN.woff2 +0 -0
- package/dist/web/client/assets/ordinal-BDEzSJ7C.js +1 -0
- package/dist/web/client/assets/packet-AYTQ26CC-OqVl_07o.js +1 -0
- package/dist/web/client/assets/path-fybaL0A-.js +1 -0
- package/dist/web/client/assets/pegDiagram-XKGWAZYB-CPE_zdfN.js +1 -0
- package/dist/web/client/assets/pie-WAS4IAKB-DAxnMBLe.js +1 -0
- package/dist/web/client/assets/pieDiagram-E7YTZNPT-Uwjpufxv.js +39 -0
- package/dist/web/client/assets/prism-bash-D6zCJ74D.js +1 -0
- package/dist/web/client/assets/prism-c-04YixN25.js +1 -0
- package/dist/web/client/assets/prism-clike-DapgWyxx.js +1 -0
- package/dist/web/client/assets/prism-core-BngLtbUd.js +1 -0
- package/dist/web/client/assets/prism-cpp-C-lJbC-6.js +1 -0
- package/dist/web/client/assets/prism-css-CPgOzxXp.js +1 -0
- package/dist/web/client/assets/prism-diff-BF8m0_mq.js +3 -0
- package/dist/web/client/assets/prism-docker-DkT6yOFj.js +1 -0
- package/dist/web/client/assets/prism-fortran-Be5x3y1V.js +1 -0
- package/dist/web/client/assets/prism-go-C_8qAH5n.js +1 -0
- package/dist/web/client/assets/prism-ini-BESK3y0r.js +1 -0
- package/dist/web/client/assets/prism-javascript-BnO-swvr.js +1 -0
- package/dist/web/client/assets/prism-json-Dp_-W-Hv.js +1 -0
- package/dist/web/client/assets/prism-jsx-D-D0NWtC.js +1 -0
- package/dist/web/client/assets/prism-julia-DIjOgiAV.js +1 -0
- package/dist/web/client/assets/prism-latex-DNMbqcH_.js +1 -0
- package/dist/web/client/assets/prism-makefile-CRKWLQ8l.js +1 -0
- package/dist/web/client/assets/prism-markdown-C0FPJ1Iz.js +1 -0
- package/dist/web/client/assets/prism-markup-Cp04rIa1.js +1 -0
- package/dist/web/client/assets/prism-matlab-D-nk08al.js +1 -0
- package/dist/web/client/assets/prism-python-CfiSVtM6.js +1 -0
- package/dist/web/client/assets/prism-r-QmNGR8LX.js +1 -0
- package/dist/web/client/assets/prism-rust-Bu9N8X3N.js +1 -0
- package/dist/web/client/assets/prism-shell-session-Be4UuYoM.js +1 -0
- package/dist/web/client/assets/prism-sql-CYhVDMEE.js +1 -0
- package/dist/web/client/assets/prism-toml-DKb54GAT.js +1 -0
- package/dist/web/client/assets/prism-tsx-p6J2Kc_4.js +1 -0
- package/dist/web/client/assets/prism-typescript-BMqONzxf.js +1 -0
- package/dist/web/client/assets/prism-yaml-C0JHu8gr.js +1 -0
- package/dist/web/client/assets/purify.es-ChwZkWde.js +3 -0
- package/dist/web/client/assets/quadrantDiagram-AXDQQJYC-Bjs4yjgs.js +7 -0
- package/dist/web/client/assets/radar-RG4KPBEZ-CuCKjHM3.js +1 -0
- package/dist/web/client/assets/railroad-74A4TZTK-CnQK-Cc1.js +1 -0
- package/dist/web/client/assets/railroad-abnf-HS5TGJTU-BcW01NZG.js +1 -0
- package/dist/web/client/assets/railroad-ebnf-LZEXJU2U-B7YCEDDd.js +1 -0
- package/dist/web/client/assets/railroad-peg-WCYAUIDC-DjNZbSTZ.js +1 -0
- package/dist/web/client/assets/railroadDiagram-O6MQD6OU-BDDIPNLL.js +1 -0
- package/dist/web/client/assets/requirementDiagram-BXWQKSXE-B5Ydyxc1.js +84 -0
- package/dist/web/client/assets/rough.esm-Dy-Kn_BL.js +1 -0
- package/dist/web/client/assets/sankeyDiagram-P5KCCOFB-Bw2Qym75.js +40 -0
- package/dist/web/client/assets/sequenceDiagram-WJ2MYXX4-BZf36nO0.js +162 -0
- package/dist/web/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
- package/dist/web/client/assets/src-yeptRXpt.js +1 -0
- package/dist/web/client/assets/stateDiagram-D77RDMKH-DnH6JRkp.js +1 -0
- package/dist/web/client/assets/stateDiagram-v2-MP3YSRHH-C7QtHeK4.js +1 -0
- package/dist/web/client/assets/swimlanes-42K2YHIH-D9PZmtZg.js +1 -0
- package/dist/web/client/assets/swimlanesDiagram-VR7AAH4N-CBZlPFky.js +8 -0
- package/dist/web/client/assets/timeline-definition-24CTP7MA-CrkZZBo7.js +120 -0
- package/dist/web/client/assets/treeView-Q6P3EWNA-C9zDShoC.js +1 -0
- package/dist/web/client/assets/treemap-WGGIJYW6-B-plj9yK.js +1 -0
- package/dist/web/client/assets/vennDiagram-4TSXK5OY-VeOdaphN.js +34 -0
- package/dist/web/client/assets/wardley-WFR3VGLG-Wl1P_m6L.js +1 -0
- package/dist/web/client/assets/wardleyDiagram-VM6X3IG4-B85-R9t2.js +78 -0
- package/dist/web/client/assets/xychartDiagram-S5SC5T6Z-BrD8OW8m.js +7 -0
- package/dist/web/client/clio-coder-logo.webp +0 -0
- package/dist/web/client/icon-192.png +0 -0
- package/dist/web/client/icon-512.png +0 -0
- package/dist/web/client/index.html +4 -0
- package/dist/web/client/manifest.webmanifest +15 -0
- package/dist/web/client/offline.css +55 -0
- package/dist/web/client/offline.html +5 -0
- package/dist/web/client/offline.js +27 -0
- package/dist/web/client/sw.js +34 -0
- package/dist/web/ops-worker.js +37 -0
- package/dist/web/reads-worker.js +1726 -0
- package/dist/web/server.js +8499 -0
- package/dist/web-EU6ATJWA.js +13 -0
- package/dist/{web-fetch-W4TNW4Q7.js → web-fetch-U22Q7HV4.js} +3 -3
- package/dist/{wiki-generate-T2TJQJUA.js → wiki-generate-LZRLFG6I.js} +98 -95
- package/dist/{with-panes-CHFC7HGI.js → with-panes-X5CZOGML.js} +9 -9
- package/dist/worker/entry.js +68 -68
- package/docs/README.md +27 -26
- package/docs/architecture/acp.md +5 -9
- package/docs/architecture/alcf-provider.md +0 -3
- package/docs/architecture/architecture.md +0 -3
- package/docs/architecture/artifact-placement.md +0 -3
- package/docs/architecture/artifact-versions.md +0 -3
- package/docs/architecture/capacity-and-scheduling.md +0 -3
- package/docs/architecture/context-engine.md +0 -3
- package/docs/architecture/context-working-set.md +0 -3
- package/docs/architecture/dispatch-architecture-rationale.md +0 -3
- package/docs/architecture/dispatch-typed-intent.md +0 -3
- package/docs/architecture/evidence-and-memory.md +0 -3
- package/docs/architecture/library.md +0 -2
- package/docs/architecture/middleware-and-components.md +0 -3
- package/docs/architecture/model-catalog.md +1 -4
- package/docs/architecture/observability.md +0 -3
- package/docs/architecture/pi-boundary.md +6 -9
- package/docs/architecture/prompt-envelope-and-tools.md +1 -4
- package/docs/architecture/provider-adapter-cookbook.md +1 -4
- package/docs/architecture/safety-model.md +0 -3
- package/docs/architecture/session-lifecycle.md +0 -3
- package/docs/architecture/time-conventions.md +0 -3
- package/docs/architecture/trace-store.md +28 -20
- package/docs/architecture/tui-design.md +1 -4
- package/docs/architecture/worker-context.md +1 -3
- package/docs/architecture/worker-dispatch-mechanics.md +1 -4
- package/docs/guide/authoring-plugins.md +1 -3
- package/docs/guide/built-in-agents.md +0 -3
- package/docs/guide/commands-and-modes.md +2 -6
- package/docs/guide/configuration-and-targets.md +197 -4
- package/docs/guide/configuration-reference.md +9 -4
- package/docs/guide/environment-variables.md +0 -3
- package/docs/guide/exit-codes-and-output.md +0 -3
- package/docs/guide/extensions-and-sharing.md +0 -3
- package/docs/guide/fleet-dispatch.md +0 -3
- package/docs/guide/glossary.md +0 -3
- package/docs/guide/harness-extensions.md +0 -2
- package/docs/guide/installation-and-lifecycle.md +1 -4
- package/docs/guide/interop.md +0 -2
- package/docs/guide/panes-and-files.md +0 -3
- package/docs/guide/plugins.md +0 -3
- package/docs/guide/proactive-memory.md +0 -3
- package/docs/guide/resource-library.md +0 -2
- package/docs/guide/skills-marketplace.md +0 -2
- package/docs/guide/tool-usage.md +0 -3
- package/docs/guide/troubleshooting.md +0 -3
- package/docs/history/config-knobs-audit.md +0 -3
- package/docs/history/release-cut-checklist.md +0 -3
- package/docs/process/development-pipeline.md +0 -3
- package/docs/process/documentation-coverage.md +3 -3
- package/docs/process/documentation-guide.md +15 -22
- package/docs/process/eval-runner.md +0 -3
- package/docs/process/evals-internal.md +0 -3
- package/docs/process/evolution.md +0 -3
- package/docs/process/fleet-demo-runbook.md +0 -3
- package/docs/process/git-commit-provenance.md +0 -3
- package/docs/process/performance-methodology.md +1 -4
- package/docs/process/release-cut-checklist.md +114 -221
- package/docs/process/scientific-validation.md +1 -4
- package/library/registry.yaml +2 -2
- package/library/skills/meta/clio-coder-test/SKILL.md +25 -15
- package/library/skills/meta/clio-coder-test/evals.md +16 -2
- package/library/skills/meta/clio-coder-test/plugin.json +1 -1
- package/library/skills/meta/clio-coder-test/references/test-map.md +19 -18
- package/library/skills/registry.yaml +2 -2
- package/library/skills/skill-marketplace.json +1 -1
- package/package.json +13 -11
- package/src/cli/docs.ts +65 -328
- package/src/cli/index.ts +3 -1
- package/src/cli/trace.ts +4 -65
- package/src/cli/uninstall.ts +26 -0
- package/src/cli/usage.ts +3 -0
- package/src/cli/web.ts +79 -0
- package/src/core/bus-events.ts +3 -4
- package/src/core/config.ts +71 -0
- package/src/core/domain-loader.ts +37 -28
- package/src/core/termination.ts +13 -9
- package/src/domains/agents/contract.ts +1 -1
- package/src/domains/agents/extension.ts +18 -10
- package/src/domains/config/extension.ts +5 -4
- package/src/domains/dispatch/extension.ts +75 -12
- package/src/domains/dispatch/index.ts +1 -0
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +3 -0
- package/src/domains/dispatch/state.ts +1 -2
- package/src/domains/dispatch/types.ts +2 -0
- package/src/domains/eval/metrics/tracked.ts +22 -2
- package/src/domains/extensions/operator-runtime.ts +3 -1
- package/src/domains/middleware/hooks.ts +2 -2
- package/src/domains/observability/background-memory-usage.ts +3 -0
- package/src/domains/observability/compaction-usage.ts +2 -0
- package/src/domains/observability/cost.ts +5 -0
- package/src/domains/observability/extension.ts +1 -0
- package/src/domains/observability/out-of-turn-usage.ts +2 -0
- package/src/domains/observability/trace-store.ts +65 -5
- package/src/domains/prompts/extension.ts +4 -17
- package/src/domains/providers/cache-deployment.ts +147 -0
- package/src/domains/providers/catalog.ts +12 -7
- package/src/domains/providers/extension.ts +27 -5
- package/src/domains/providers/index.ts +1 -0
- package/src/domains/providers/plugins.ts +3 -13
- package/src/domains/providers/runtimes/common/local-synth.ts +4 -0
- package/src/domains/providers/types/target-descriptor.ts +17 -0
- package/src/domains/session/compaction/compact.ts +4 -1
- package/src/domains/session/entries.ts +1 -0
- package/src/domains/session/usage.ts +6 -7
- package/src/engine/acp/server.ts +11 -0
- package/src/engine/ai.ts +2 -0
- package/src/engine/apis/openai-completions.ts +9 -4
- package/src/engine/prewarm.ts +232 -0
- package/src/engine/provider-diagnostics.ts +6 -1
- package/src/entry/orchestrator.ts +20 -16
- package/src/interactive/chat-loop-messages.ts +3 -0
- package/src/interactive/chat-loop.ts +2 -8
- package/src/interactive/prewarm.ts +11 -197
- package/src/interactive/session-usage-reseed.ts +2 -0
- package/src/interactive/side-question.ts +2 -0
- package/src/interactive/turn-context.ts +1 -0
- package/src/interactive/turn-persistence.ts +3 -0
- package/src/interactive/turn-prewarm.ts +126 -19
- package/src/interactive/turn-runtime.ts +14 -0
- package/src/tools/builtin-tool-catalog.ts +8 -4
- package/src/tools/registry.ts +12 -2
- package/src/worker/spec-contract.ts +27 -0
- package/dist/docs-BL7ROUFN.js +0 -292
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One bounded-output warm through the eventual caller's engine request path.
|
|
3
|
+
* Copies portable context, applies public Pi transforms and payload hooks,
|
|
4
|
+
* and consumes the response without running tools or appending conversation.
|
|
5
|
+
* Admission and lifecycle remain with the caller. A matching serialized
|
|
6
|
+
* prefix is only a reuse candidate; the backend decides actual cache reuse.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Agent } from "@earendil-works/pi-agent-core";
|
|
10
|
+
import type { BackendCompletionTimings } from "../core/cache-telemetry.js";
|
|
11
|
+
import { streamSimple } from "./ai.js";
|
|
12
|
+
import { estimateInputTokensFromContext } from "./apis/output-budget.js";
|
|
13
|
+
import type { AgentMessage, AgentTool, EngineModel, Usage } from "./types.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The one user message appended so the chat template renders the prefix up to
|
|
17
|
+
* the user turn. One character: it has to exist for the template to close the
|
|
18
|
+
* prefix, and everything after the last shared byte is re-evaluated by the real
|
|
19
|
+
* turn anyway.
|
|
20
|
+
*/
|
|
21
|
+
export const PREWARM_USER_TEXT = ".";
|
|
22
|
+
|
|
23
|
+
/** Output budget for the round. The tokens the model produces are not the point. */
|
|
24
|
+
export const PREWARM_MAX_TOKENS = 1;
|
|
25
|
+
|
|
26
|
+
/** Which trigger asked for the pre-warm. Recorded on the ledger entry. */
|
|
27
|
+
export type PrewarmTrigger = "session-start" | "resume" | "compaction";
|
|
28
|
+
|
|
29
|
+
export interface PrewarmContext {
|
|
30
|
+
systemPrompt: string;
|
|
31
|
+
messages: ReadonlyArray<AgentMessage>;
|
|
32
|
+
tools: ReadonlyArray<AgentTool>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The roles pi-agent-core's default `convertToLlm` keeps when it turns the
|
|
37
|
+
* agent's message list into provider messages. The pre-warm applies the same
|
|
38
|
+
* filter so its message array is the one a turn would send, not the agent's
|
|
39
|
+
* internal list.
|
|
40
|
+
*/
|
|
41
|
+
const LLM_MESSAGE_ROLES: ReadonlySet<string> = new Set(["user", "assistant", "toolResult"]);
|
|
42
|
+
|
|
43
|
+
export interface PrewarmRoundInput {
|
|
44
|
+
model: EngineModel;
|
|
45
|
+
/** Live agent state the next turn would send. Read-only; the round copies it. */
|
|
46
|
+
state: {
|
|
47
|
+
systemPrompt: string;
|
|
48
|
+
messages: ReadonlyArray<AgentMessage>;
|
|
49
|
+
tools: ReadonlyArray<AgentTool>;
|
|
50
|
+
thinkingLevel: string;
|
|
51
|
+
};
|
|
52
|
+
apiKey?: string;
|
|
53
|
+
signal?: AbortSignal;
|
|
54
|
+
/** Admission bound on the engine's input estimate, after context selection. */
|
|
55
|
+
maxInputTokens?: number;
|
|
56
|
+
/** Public Pi preparation hooks of the eventual caller. No tools or agent loop are executed. */
|
|
57
|
+
agent?: Pick<
|
|
58
|
+
Agent,
|
|
59
|
+
| "transformContext"
|
|
60
|
+
| "convertToLlm"
|
|
61
|
+
| "streamFunction"
|
|
62
|
+
| "onPayload"
|
|
63
|
+
| "onResponse"
|
|
64
|
+
| "sessionId"
|
|
65
|
+
| "thinkingBudgets"
|
|
66
|
+
| "transport"
|
|
67
|
+
| "maxRetryDelayMs"
|
|
68
|
+
>;
|
|
69
|
+
/** Test seam. Production uses the engine dispatcher a turn runs on. */
|
|
70
|
+
streamFn?: typeof streamSimple;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface PrewarmRoundResult {
|
|
74
|
+
/** True when the operator submitted (or the session moved) before the round settled. */
|
|
75
|
+
aborted: boolean;
|
|
76
|
+
/** Provider usage for the round; null when the backend reported none. */
|
|
77
|
+
usage: Usage | null;
|
|
78
|
+
/** Backend prefill and prediction timings when the server reported them. */
|
|
79
|
+
backend: BackendCompletionTimings | null;
|
|
80
|
+
/** Wall clock the round spent, in the shape a turn's assistant entry uses. */
|
|
81
|
+
timing: { ttftMs: number | null; apiMs: number };
|
|
82
|
+
/** Provider error text when the round failed outright. */
|
|
83
|
+
errorMessage: string | null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function usageOf(message: unknown): Usage | null {
|
|
87
|
+
if (message === null || typeof message !== "object") return null;
|
|
88
|
+
const usage = (message as { usage?: unknown }).usage;
|
|
89
|
+
if (usage === null || typeof usage !== "object") return null;
|
|
90
|
+
const record = usage as Usage;
|
|
91
|
+
// Pi initializes missing usage to zero, including on aborted/error calls.
|
|
92
|
+
// A warm with no observed tokens cannot be called a measured free request.
|
|
93
|
+
return [record.input, record.output, record.cacheRead, record.cacheWrite, record.cost?.total].some(
|
|
94
|
+
(value) => typeof value === "number" && Number.isFinite(value) && value > 0,
|
|
95
|
+
)
|
|
96
|
+
? record
|
|
97
|
+
: null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function backendOf(message: unknown): BackendCompletionTimings | null {
|
|
101
|
+
if (message === null || typeof message !== "object") return null;
|
|
102
|
+
const backend = (message as { backendTimings?: unknown }).backendTimings;
|
|
103
|
+
return backend !== null && typeof backend === "object" ? (backend as BackendCompletionTimings) : null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Prompt tokens the backend actually processed for one pre-warm. The server's
|
|
108
|
+
* own prompt count is authoritative when it reported one; otherwise the
|
|
109
|
+
* provider usage prompt side, cached tokens folded in, is the honest figure.
|
|
110
|
+
* Null when neither exists, which is different from a measured zero.
|
|
111
|
+
*/
|
|
112
|
+
export function prewarmPromptTokens(result: Pick<PrewarmRoundResult, "usage" | "backend">): number | null {
|
|
113
|
+
if (result.backend) return result.backend.promptTokens;
|
|
114
|
+
const usage = result.usage;
|
|
115
|
+
if (!usage) return null;
|
|
116
|
+
const total = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
|
|
117
|
+
return total > 0 ? total : null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Send the prefix and wait for the backend to acknowledge it. Resolves rather
|
|
122
|
+
* than rejects on a provider failure: a pre-warm is an optimization, and a
|
|
123
|
+
* backend that refuses it must not be able to break the session it was warming.
|
|
124
|
+
*/
|
|
125
|
+
export async function runPrewarmRound(input: PrewarmRoundInput): Promise<PrewarmRoundResult> {
|
|
126
|
+
// pi-agent-core maps `thinkingLevel: "off"` onto an absent `reasoning`; the
|
|
127
|
+
// pre-warm has to make the same mapping or the thinking composition resolves
|
|
128
|
+
// against a different level and the rendered template moves.
|
|
129
|
+
const options: Record<string, unknown> = { maxTokens: PREWARM_MAX_TOKENS };
|
|
130
|
+
// Narrow residency authority without changing prompt rendering. A warm may
|
|
131
|
+
// not inherit the foreground turn's implicit load/unload authorization.
|
|
132
|
+
const metadata = (input.model as EngineModel & { clioCoder?: Record<string, unknown> }).clioCoder;
|
|
133
|
+
const model = metadata ? { ...input.model, clioCoder: { ...metadata, lifecycle: "user-managed" } } : input.model;
|
|
134
|
+
if (metadata?.runtimeId === "llamacpp") {
|
|
135
|
+
// A worker that disappeared after admission must not be JIT-loaded by
|
|
136
|
+
// the pinned llama router. This query is independent of prompt bytes.
|
|
137
|
+
options.fetch = (request: string | URL | Request, init?: RequestInit) => {
|
|
138
|
+
const url = new URL(request instanceof Request ? request.url : request);
|
|
139
|
+
url.searchParams.set("autoload", "false");
|
|
140
|
+
return fetch(request instanceof Request ? new Request(url, request) : url, init);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (input.state.thinkingLevel !== "off") options.reasoning = input.state.thinkingLevel;
|
|
144
|
+
if (input.apiKey !== undefined) options.apiKey = input.apiKey;
|
|
145
|
+
if (input.signal !== undefined) options.signal = input.signal;
|
|
146
|
+
if (input.agent) {
|
|
147
|
+
for (const key of [
|
|
148
|
+
"onPayload",
|
|
149
|
+
"onResponse",
|
|
150
|
+
"sessionId",
|
|
151
|
+
"thinkingBudgets",
|
|
152
|
+
"transport",
|
|
153
|
+
"maxRetryDelayMs",
|
|
154
|
+
] as const) {
|
|
155
|
+
if (input.agent[key] !== undefined) options[key] = input.agent[key];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const send = input.streamFn ?? input.agent?.streamFunction ?? streamSimple;
|
|
160
|
+
const startedAt = performance.now();
|
|
161
|
+
let firstDeltaAt: number | null = null;
|
|
162
|
+
const elapsed = (): number => Math.round(Math.max(0, performance.now() - startedAt));
|
|
163
|
+
const ttft = (): number | null => (firstDeltaAt === null ? null : Math.round(Math.max(0, firstDeltaAt - startedAt)));
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
input.signal?.throwIfAborted();
|
|
167
|
+
let messages: AgentMessage[] = [
|
|
168
|
+
...structuredClone([...input.state.messages]),
|
|
169
|
+
{ role: "user", content: [{ type: "text", text: PREWARM_USER_TEXT }], timestamp: Date.now() },
|
|
170
|
+
];
|
|
171
|
+
if (input.agent?.transformContext) messages = await input.agent.transformContext(messages, input.signal);
|
|
172
|
+
const converted = input.agent
|
|
173
|
+
? await input.agent.convertToLlm(messages)
|
|
174
|
+
: messages.filter((message) => LLM_MESSAGE_ROLES.has(message.role));
|
|
175
|
+
input.signal?.throwIfAborted();
|
|
176
|
+
const context = {
|
|
177
|
+
systemPrompt: input.state.systemPrompt,
|
|
178
|
+
messages: converted,
|
|
179
|
+
tools: [...input.state.tools],
|
|
180
|
+
} as Parameters<typeof streamSimple>[1];
|
|
181
|
+
if (input.maxInputTokens !== undefined && estimateInputTokensFromContext(context) > input.maxInputTokens) {
|
|
182
|
+
throw new Error("pre-warm input estimate exceeds its token budget");
|
|
183
|
+
}
|
|
184
|
+
const events = await send(
|
|
185
|
+
model,
|
|
186
|
+
context as unknown as Parameters<typeof streamSimple>[1],
|
|
187
|
+
options as unknown as Parameters<typeof streamSimple>[2],
|
|
188
|
+
);
|
|
189
|
+
for await (const event of events) {
|
|
190
|
+
const hasDelta =
|
|
191
|
+
event.type === "toolcall_start" ||
|
|
192
|
+
((event.type === "text_delta" || event.type === "thinking_delta" || event.type === "toolcall_delta") &&
|
|
193
|
+
event.delta.length > 0);
|
|
194
|
+
if (firstDeltaAt === null && hasDelta) firstDeltaAt = performance.now();
|
|
195
|
+
if (event.type === "done") {
|
|
196
|
+
return {
|
|
197
|
+
aborted: false,
|
|
198
|
+
usage: usageOf(event.message),
|
|
199
|
+
backend: backendOf(event.message),
|
|
200
|
+
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
201
|
+
errorMessage: null,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
if (event.type === "error") {
|
|
205
|
+
const failed = event.error as { stopReason?: unknown; errorMessage?: unknown };
|
|
206
|
+
const aborted = event.reason === "aborted" || failed.stopReason === "aborted" || input.signal?.aborted === true;
|
|
207
|
+
return {
|
|
208
|
+
aborted,
|
|
209
|
+
usage: usageOf(event.error),
|
|
210
|
+
backend: backendOf(event.error),
|
|
211
|
+
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
212
|
+
errorMessage: aborted ? null : typeof failed.errorMessage === "string" ? failed.errorMessage : "pre-warm failed",
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
} catch (error) {
|
|
217
|
+
return {
|
|
218
|
+
aborted: input.signal?.aborted === true,
|
|
219
|
+
usage: null,
|
|
220
|
+
backend: null,
|
|
221
|
+
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
222
|
+
errorMessage: input.signal?.aborted === true ? null : error instanceof Error ? error.message : String(error),
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
aborted: input.signal?.aborted === true,
|
|
227
|
+
usage: null,
|
|
228
|
+
backend: null,
|
|
229
|
+
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
230
|
+
errorMessage: null,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { closeSync, constants, fstatSync, openSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { isAbsolute } from "node:path";
|
|
4
4
|
import type { Api, AssistantMessageEventStream, Model, StreamOptions } from "@earendil-works/pi-ai";
|
|
5
|
+
import type { TargetCacheSettings } from "../domains/providers/types/target-descriptor.js";
|
|
5
6
|
import { findEngineEnvKeys } from "./env-api-keys.js";
|
|
6
7
|
|
|
7
8
|
/** Process-owned opt-in reaches every native engine call, including prewarm and workers. */
|
|
@@ -11,7 +12,11 @@ export function instrumentProviderCall<T extends StreamOptions>(
|
|
|
11
12
|
invoke: (options: T | undefined) => AssistantMessageEventStream,
|
|
12
13
|
): AssistantMessageEventStream {
|
|
13
14
|
let effective = options;
|
|
14
|
-
|
|
15
|
+
const configured = (model as Model<Api> & { clioCoder?: { cache?: TargetCacheSettings } }).clioCoder?.cache?.retention;
|
|
16
|
+
if (options?.cacheRetention === undefined && configured !== undefined) {
|
|
17
|
+
effective = { ...options, cacheRetention: configured } as T;
|
|
18
|
+
}
|
|
19
|
+
if (model.api === "anthropic-messages" && effective?.cacheRetention === undefined) {
|
|
15
20
|
const retention = process.env.CLIO_CODER_ANTHROPIC_CACHE_RETENTION;
|
|
16
21
|
if (retention !== undefined && retention !== "") {
|
|
17
22
|
if (retention !== "none" && retention !== "short" && retention !== "long") {
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
import { getSharedBus } from "../core/shared-bus.js";
|
|
37
37
|
import { isSkillActivation } from "../core/skill-activation.js";
|
|
38
38
|
import { StartupTimer } from "../core/startup-timer.js";
|
|
39
|
-
import { getTerminationCoordinator } from "../core/termination.js";
|
|
39
|
+
import { getTerminationCoordinator, resolveShutdownHookBudgetMs } from "../core/termination.js";
|
|
40
40
|
import { captureProjectSurface, projectSurfaceTrustNotice } from "../core/workspace-trust.js";
|
|
41
41
|
import { clioDataDir, clioStateDir } from "../core/xdg.js";
|
|
42
42
|
import { renderAgentCatalogSectionsFromSpecs } from "../domains/agents/catalog.js";
|
|
@@ -1203,8 +1203,10 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1203
1203
|
await dispatch.drain();
|
|
1204
1204
|
});
|
|
1205
1205
|
}
|
|
1206
|
-
|
|
1207
|
-
|
|
1206
|
+
// The loader caps each domain separately. The outer hook must allow the
|
|
1207
|
+
// whole sequence to finish, including cleanup after a timed-out domain.
|
|
1208
|
+
termination.onPersist(() => result.stop(), {
|
|
1209
|
+
timeoutMs: Math.min(2 ** 31 - 1, (result.loaded.length + 1) * resolveShutdownHookBudgetMs()),
|
|
1208
1210
|
});
|
|
1209
1211
|
|
|
1210
1212
|
bus.emit(BusChannels.SessionStart, { at: Date.now() });
|
|
@@ -1373,12 +1375,10 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1373
1375
|
// this boot projection below.
|
|
1374
1376
|
configureRunEventJournal(resolvedSettings.fleet.history.journal);
|
|
1375
1377
|
|
|
1376
|
-
//
|
|
1377
|
-
//
|
|
1378
|
-
//
|
|
1379
|
-
//
|
|
1380
|
-
// worker-runtime.ts; the orchestrator instances carry the bus and the
|
|
1381
|
-
// session persistence sink.
|
|
1378
|
+
// Register the loop and dispatch guards first. The protected-artifact guard
|
|
1379
|
+
// is constructed here but registered after user hooks below, so it can
|
|
1380
|
+
// absorb their protect_path effects. Workers register their own guards in
|
|
1381
|
+
// worker-runtime.ts; these instances carry the bus and session persistence.
|
|
1382
1382
|
middleware.registerHook(
|
|
1383
1383
|
createLoopGuardRegistration({
|
|
1384
1384
|
safety,
|
|
@@ -1427,7 +1427,6 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1427
1427
|
}
|
|
1428
1428
|
return protectedArtifactsGuard.state();
|
|
1429
1429
|
};
|
|
1430
|
-
middleware.registerHook(protectedArtifactsGuard);
|
|
1431
1430
|
middleware.registerHook(createDispatchDedupRegistration());
|
|
1432
1431
|
// Observers run after the guards; they emit no effects and their sinks are
|
|
1433
1432
|
// best-effort (session ledger, codewiki refresh).
|
|
@@ -1525,9 +1524,9 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1525
1524
|
}
|
|
1526
1525
|
// User-defined hooks: extensions and the project (.clio-coder/hooks.yaml,
|
|
1527
1526
|
// .clio-coder/hooks.local.yaml) declare a conservative, receipted hook set on the
|
|
1528
|
-
// same effect machinery.
|
|
1529
|
-
//
|
|
1530
|
-
//
|
|
1527
|
+
// same effect machinery. A hook may add effects (including request block_tool)
|
|
1528
|
+
// but cannot grant a permission safety would deny. The protected-artifact
|
|
1529
|
+
// guard follows them to consume protect_path before tool execution.
|
|
1531
1530
|
// The coordinator is the only writer of the "user-hooks" owner and the only
|
|
1532
1531
|
// caller of the extensions reload; it publishes the extension generation
|
|
1533
1532
|
// and the hook registrations with two adjacent assignments on one stack
|
|
@@ -1535,7 +1534,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1535
1534
|
// published here too (the extensions bundle publishes nothing at start),
|
|
1536
1535
|
// so no consumer ever sees extension resources paired with hooks from a
|
|
1537
1536
|
// different generation. The owner slot is anchored here, so user hooks
|
|
1538
|
-
// keep evaluating
|
|
1537
|
+
// keep evaluating before the protection consumer and assessors below.
|
|
1539
1538
|
const hookReceiptLog = createHookReceiptLog({ persistPath: join(clioStateDir(), "hook-receipts.json") });
|
|
1540
1539
|
let bootHookNotices = true;
|
|
1541
1540
|
const reloadPlugins = () =>
|
|
@@ -1556,6 +1555,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1556
1555
|
},
|
|
1557
1556
|
});
|
|
1558
1557
|
extensionReload.applyBoot();
|
|
1558
|
+
middleware.registerHook(protectedArtifactsGuard);
|
|
1559
1559
|
bootHookNotices = false;
|
|
1560
1560
|
termination.onDrain(() => hookReceiptLog.flush());
|
|
1561
1561
|
// Autonomy is hot-reloaded for interactive and headless admissions. ACP
|
|
@@ -1836,8 +1836,12 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1836
1836
|
// The config bundle publishes saved values on reload; session-scoped
|
|
1837
1837
|
// overrides must win, so re-derive every process-local projection from the
|
|
1838
1838
|
// effective session view after it.
|
|
1839
|
-
const unsubscribeSettingsProjectionSync =
|
|
1840
|
-
|
|
1839
|
+
const unsubscribeSettingsProjectionSync = [BusChannels.ConfigHotReload, BusChannels.ConfigNextTurn].map((channel) =>
|
|
1840
|
+
bus.on(channel, () => bumpSessionState()),
|
|
1841
|
+
);
|
|
1842
|
+
termination.onDrain(() => {
|
|
1843
|
+
for (const unsubscribe of unsubscribeSettingsProjectionSync) unsubscribe();
|
|
1844
|
+
});
|
|
1841
1845
|
const getTaskMemorySeedOffer = (): { source: string; count: number } | null => {
|
|
1842
1846
|
return taskMemoryHandoffSeedOffer(process.cwd(), getCurrentSettings().context.memory.enabled);
|
|
1843
1847
|
};
|
|
@@ -362,6 +362,7 @@ export interface RunUsageSummary {
|
|
|
362
362
|
output: number;
|
|
363
363
|
cacheRead: number;
|
|
364
364
|
cacheWrite: number;
|
|
365
|
+
cacheWrite1h?: number;
|
|
365
366
|
reasoning: number;
|
|
366
367
|
apiCalls: number;
|
|
367
368
|
hadReasoning: boolean;
|
|
@@ -407,6 +408,7 @@ export function sumRunUsage(messages: ReadonlyArray<AgentMessage>): RunUsageSumm
|
|
|
407
408
|
output?: unknown;
|
|
408
409
|
cacheRead?: unknown;
|
|
409
410
|
cacheWrite?: unknown;
|
|
411
|
+
cacheWrite1h?: unknown;
|
|
410
412
|
totalTokens?: unknown;
|
|
411
413
|
cost?: { total?: unknown };
|
|
412
414
|
};
|
|
@@ -432,6 +434,7 @@ export function sumRunUsage(messages: ReadonlyArray<AgentMessage>): RunUsageSumm
|
|
|
432
434
|
summary.output += output;
|
|
433
435
|
summary.cacheRead += cacheRead;
|
|
434
436
|
summary.cacheWrite += cacheWrite;
|
|
437
|
+
if (typeof usage.cacheWrite1h === "number") summary.cacheWrite1h = (summary.cacheWrite1h ?? 0) + usage.cacheWrite1h;
|
|
435
438
|
const reasoning = extractReasoningTokens(usage);
|
|
436
439
|
if (reasoning !== null) {
|
|
437
440
|
summary.reasoning += reasoning;
|
|
@@ -862,13 +862,6 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
862
862
|
deps.bus?.on(BusChannels.ConfigHotReload, () => {
|
|
863
863
|
context.invalidateSessionPromptCache();
|
|
864
864
|
}) ?? null;
|
|
865
|
-
// A committed extension generation with new content can change the skill
|
|
866
|
-
// and prompt inputs the session prompt compiles from; same invalidation.
|
|
867
|
-
const unsubscribeExtensionsReload =
|
|
868
|
-
deps.bus?.on(BusChannels.ExtensionsReloaded, (payload) => {
|
|
869
|
-
if (payload.changed) context.invalidateSessionPromptCache();
|
|
870
|
-
}) ?? null;
|
|
871
|
-
|
|
872
865
|
const unsubscribePluginsReload =
|
|
873
866
|
deps.bus?.on(BusChannels.PluginsReloaded, () => {
|
|
874
867
|
context.invalidateSessionPromptCache();
|
|
@@ -981,6 +974,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
981
974
|
output: usage.output,
|
|
982
975
|
cacheRead: usage.cacheRead,
|
|
983
976
|
cacheWrite: usage.cacheWrite,
|
|
977
|
+
...(usage.cacheWrite1h === undefined ? {} : { cacheWrite1h: usage.cacheWrite1h }),
|
|
984
978
|
reasoningTokens: usage.reasoning,
|
|
985
979
|
totalTokens: usage.totalTokens,
|
|
986
980
|
apiCalls: 1,
|
|
@@ -1004,6 +998,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
1004
998
|
output: usage.output,
|
|
1005
999
|
cacheRead: usage.cacheRead,
|
|
1006
1000
|
cacheWrite: usage.cacheWrite,
|
|
1001
|
+
...(usage.cacheWrite1h === undefined ? {} : { cacheWrite1h: usage.cacheWrite1h }),
|
|
1007
1002
|
reasoning: usage.reasoning,
|
|
1008
1003
|
totalTokens: usage.totalTokens,
|
|
1009
1004
|
costUsd: usage.costUsd,
|
|
@@ -1572,7 +1567,6 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
1572
1567
|
|
|
1573
1568
|
dispose(): void {
|
|
1574
1569
|
unsubscribeConfigReload?.();
|
|
1575
|
-
unsubscribeExtensionsReload?.();
|
|
1576
1570
|
unsubscribePluginsReload?.();
|
|
1577
1571
|
unsubscribeSynthesisLock?.();
|
|
1578
1572
|
unsubscribePrewarmCompaction();
|
|
@@ -1,197 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
* The payload is not hand-assembled. It goes through `streamSimple`, the same
|
|
14
|
-
* dispatcher `createEngineAgent` hands pi-agent-core as its `streamFn`, with the
|
|
15
|
-
* same system prompt, the same tool schemas, the same replayed messages, and the
|
|
16
|
-
* same thinking level, so `withSamplingOverrides`, the thinking composition, and
|
|
17
|
-
* `cache_prompt` resolve exactly as they do for a turn. Any byte that differs
|
|
18
|
-
* ahead of the user turn would defeat the purpose.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import type { BackendCompletionTimings } from "../core/cache-telemetry.js";
|
|
22
|
-
import { streamSimple } from "../engine/ai.js";
|
|
23
|
-
import type { AgentMessage, AgentTool, EngineModel, Usage } from "../engine/types.js";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* The one user message appended so the chat template renders the prefix up to
|
|
27
|
-
* the user turn. One character: it has to exist for the template to close the
|
|
28
|
-
* prefix, and everything after the last shared byte is re-evaluated by the real
|
|
29
|
-
* turn anyway.
|
|
30
|
-
*/
|
|
31
|
-
export const PREWARM_USER_TEXT = ".";
|
|
32
|
-
|
|
33
|
-
/** Output budget for the round. The tokens the model produces are not the point. */
|
|
34
|
-
export const PREWARM_MAX_TOKENS = 1;
|
|
35
|
-
|
|
36
|
-
/** Which trigger asked for the pre-warm. Recorded on the ledger entry. */
|
|
37
|
-
export type PrewarmTrigger = "session-start" | "resume" | "compaction";
|
|
38
|
-
|
|
39
|
-
export interface PrewarmContext {
|
|
40
|
-
systemPrompt: string;
|
|
41
|
-
messages: ReadonlyArray<AgentMessage>;
|
|
42
|
-
tools: ReadonlyArray<AgentTool>;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* The roles pi-agent-core's default `convertToLlm` keeps when it turns the
|
|
47
|
-
* agent's message list into provider messages. The pre-warm applies the same
|
|
48
|
-
* filter so its message array is the one a turn would send, not the agent's
|
|
49
|
-
* internal list.
|
|
50
|
-
*/
|
|
51
|
-
const LLM_MESSAGE_ROLES: ReadonlySet<string> = new Set(["user", "assistant", "toolResult"]);
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* The prefix of the next turn's request: system prompt, tool schemas, and the
|
|
55
|
-
* replayed conversation, with no user turn yet.
|
|
56
|
-
*/
|
|
57
|
-
function prewarmPrefix(state: {
|
|
58
|
-
systemPrompt: string;
|
|
59
|
-
messages: ReadonlyArray<AgentMessage>;
|
|
60
|
-
tools: ReadonlyArray<AgentTool>;
|
|
61
|
-
}): PrewarmContext {
|
|
62
|
-
return {
|
|
63
|
-
systemPrompt: state.systemPrompt,
|
|
64
|
-
messages: state.messages.filter((message) => LLM_MESSAGE_ROLES.has((message as { role?: string }).role ?? "")),
|
|
65
|
-
tools: [...state.tools],
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface PrewarmRoundInput {
|
|
70
|
-
model: EngineModel;
|
|
71
|
-
/** Live agent state the next turn would send. Read-only; the round copies it. */
|
|
72
|
-
state: {
|
|
73
|
-
systemPrompt: string;
|
|
74
|
-
messages: ReadonlyArray<AgentMessage>;
|
|
75
|
-
tools: ReadonlyArray<AgentTool>;
|
|
76
|
-
thinkingLevel: string;
|
|
77
|
-
};
|
|
78
|
-
apiKey?: string;
|
|
79
|
-
signal?: AbortSignal;
|
|
80
|
-
/** Test seam. Production uses the engine dispatcher a turn runs on. */
|
|
81
|
-
streamFn?: typeof streamSimple;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export interface PrewarmRoundResult {
|
|
85
|
-
/** True when the operator submitted (or the session moved) before the round settled. */
|
|
86
|
-
aborted: boolean;
|
|
87
|
-
/** Provider usage for the round; null when the backend reported none. */
|
|
88
|
-
usage: Usage | null;
|
|
89
|
-
/** Backend prefill and prediction timings when the server reported them. */
|
|
90
|
-
backend: BackendCompletionTimings | null;
|
|
91
|
-
/** Wall clock the round spent, in the shape a turn's assistant entry uses. */
|
|
92
|
-
timing: { ttftMs: number | null; apiMs: number };
|
|
93
|
-
/** Provider error text when the round failed outright. */
|
|
94
|
-
errorMessage: string | null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function usageOf(message: unknown): Usage | null {
|
|
98
|
-
if (message === null || typeof message !== "object") return null;
|
|
99
|
-
const usage = (message as { usage?: unknown }).usage;
|
|
100
|
-
return usage !== null && typeof usage === "object" ? (usage as Usage) : null;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function backendOf(message: unknown): BackendCompletionTimings | null {
|
|
104
|
-
if (message === null || typeof message !== "object") return null;
|
|
105
|
-
const backend = (message as { backendTimings?: unknown }).backendTimings;
|
|
106
|
-
return backend !== null && typeof backend === "object" ? (backend as BackendCompletionTimings) : null;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Prompt tokens the backend actually processed for one pre-warm. The server's
|
|
111
|
-
* own prompt count is authoritative when it reported one; otherwise the
|
|
112
|
-
* provider usage prompt side, cached tokens folded in, is the honest figure.
|
|
113
|
-
* Null when neither exists, which is different from a measured zero.
|
|
114
|
-
*/
|
|
115
|
-
export function prewarmPromptTokens(result: Pick<PrewarmRoundResult, "usage" | "backend">): number | null {
|
|
116
|
-
if (result.backend) return result.backend.promptTokens;
|
|
117
|
-
const usage = result.usage;
|
|
118
|
-
if (!usage) return null;
|
|
119
|
-
const total = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
|
|
120
|
-
return total > 0 ? total : null;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Send the prefix and wait for the backend to acknowledge it. Resolves rather
|
|
125
|
-
* than rejects on a provider failure: a pre-warm is an optimization, and a
|
|
126
|
-
* backend that refuses it must not be able to break the session it was warming.
|
|
127
|
-
*/
|
|
128
|
-
export async function runPrewarmRound(input: PrewarmRoundInput): Promise<PrewarmRoundResult> {
|
|
129
|
-
const prefix = prewarmPrefix(input.state);
|
|
130
|
-
const context = {
|
|
131
|
-
systemPrompt: prefix.systemPrompt,
|
|
132
|
-
messages: [
|
|
133
|
-
...prefix.messages,
|
|
134
|
-
{ role: "user", content: [{ type: "text", text: PREWARM_USER_TEXT }], timestamp: Date.now() },
|
|
135
|
-
],
|
|
136
|
-
tools: prefix.tools,
|
|
137
|
-
};
|
|
138
|
-
// pi-agent-core maps `thinkingLevel: "off"` onto an absent `reasoning`; the
|
|
139
|
-
// pre-warm has to make the same mapping or the thinking composition resolves
|
|
140
|
-
// against a different level and the rendered template moves.
|
|
141
|
-
const options: Record<string, unknown> = { maxTokens: PREWARM_MAX_TOKENS };
|
|
142
|
-
if (input.state.thinkingLevel !== "off") options.reasoning = input.state.thinkingLevel;
|
|
143
|
-
if (input.apiKey !== undefined) options.apiKey = input.apiKey;
|
|
144
|
-
if (input.signal !== undefined) options.signal = input.signal;
|
|
145
|
-
|
|
146
|
-
const send = input.streamFn ?? streamSimple;
|
|
147
|
-
const startedAt = performance.now();
|
|
148
|
-
let firstDeltaAt: number | null = null;
|
|
149
|
-
const elapsed = (): number => Math.round(Math.max(0, performance.now() - startedAt));
|
|
150
|
-
const ttft = (): number | null => (firstDeltaAt === null ? null : Math.round(Math.max(0, firstDeltaAt - startedAt)));
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
const events = send(
|
|
154
|
-
input.model,
|
|
155
|
-
context as unknown as Parameters<typeof streamSimple>[1],
|
|
156
|
-
options as unknown as Parameters<typeof streamSimple>[2],
|
|
157
|
-
);
|
|
158
|
-
for await (const event of events) {
|
|
159
|
-
if (firstDeltaAt === null && event.type !== "start") firstDeltaAt = performance.now();
|
|
160
|
-
if (event.type === "done") {
|
|
161
|
-
return {
|
|
162
|
-
aborted: false,
|
|
163
|
-
usage: usageOf(event.message),
|
|
164
|
-
backend: backendOf(event.message),
|
|
165
|
-
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
166
|
-
errorMessage: null,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
if (event.type === "error") {
|
|
170
|
-
const failed = event.error as { stopReason?: unknown; errorMessage?: unknown };
|
|
171
|
-
const aborted = event.reason === "aborted" || failed.stopReason === "aborted" || input.signal?.aborted === true;
|
|
172
|
-
return {
|
|
173
|
-
aborted,
|
|
174
|
-
usage: usageOf(event.error),
|
|
175
|
-
backend: backendOf(event.error),
|
|
176
|
-
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
177
|
-
errorMessage: aborted ? null : typeof failed.errorMessage === "string" ? failed.errorMessage : "pre-warm failed",
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
} catch (error) {
|
|
182
|
-
return {
|
|
183
|
-
aborted: input.signal?.aborted === true,
|
|
184
|
-
usage: null,
|
|
185
|
-
backend: null,
|
|
186
|
-
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
187
|
-
errorMessage: input.signal?.aborted === true ? null : error instanceof Error ? error.message : String(error),
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
return {
|
|
191
|
-
aborted: input.signal?.aborted === true,
|
|
192
|
-
usage: null,
|
|
193
|
-
backend: null,
|
|
194
|
-
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
195
|
-
errorMessage: null,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
1
|
+
/** Compatibility entry point; engine preparation is shared with headless callers. */
|
|
2
|
+
export {
|
|
3
|
+
PREWARM_MAX_TOKENS,
|
|
4
|
+
PREWARM_USER_TEXT,
|
|
5
|
+
type PrewarmContext,
|
|
6
|
+
type PrewarmRoundInput,
|
|
7
|
+
type PrewarmRoundResult,
|
|
8
|
+
type PrewarmTrigger,
|
|
9
|
+
prewarmPromptTokens,
|
|
10
|
+
runPrewarmRound,
|
|
11
|
+
} from "../engine/prewarm.js";
|
|
@@ -35,6 +35,7 @@ export interface SessionUsageSink {
|
|
|
35
35
|
output: number;
|
|
36
36
|
cacheRead: number;
|
|
37
37
|
cacheWrite: number;
|
|
38
|
+
cacheWrite1h?: number;
|
|
38
39
|
reasoningTokens: number;
|
|
39
40
|
totalTokens: number;
|
|
40
41
|
apiCalls?: number;
|
|
@@ -86,6 +87,7 @@ export function reseedSessionUsageFromLedger(
|
|
|
86
87
|
output: call.output,
|
|
87
88
|
cacheRead: call.cacheRead,
|
|
88
89
|
cacheWrite: call.cacheWrite,
|
|
90
|
+
...(call.cacheWrite1h === undefined ? {} : { cacheWrite1h: call.cacheWrite1h }),
|
|
89
91
|
reasoningTokens: call.reasoningTokens,
|
|
90
92
|
totalTokens: call.totalTokens,
|
|
91
93
|
apiCalls: call.apiCalls ?? 1,
|
|
@@ -41,6 +41,7 @@ export interface SideQuestionUsage {
|
|
|
41
41
|
output: number;
|
|
42
42
|
cacheRead: number;
|
|
43
43
|
cacheWrite: number;
|
|
44
|
+
cacheWrite1h?: number;
|
|
44
45
|
reasoning: number;
|
|
45
46
|
totalTokens: number;
|
|
46
47
|
costUsd: number;
|
|
@@ -117,6 +118,7 @@ export function sideQuestionUsage(raw: unknown): SideQuestionUsage | null {
|
|
|
117
118
|
output,
|
|
118
119
|
cacheRead,
|
|
119
120
|
cacheWrite,
|
|
121
|
+
...(usage.cacheWrite1h === undefined ? {} : { cacheWrite1h: positive(usage.cacheWrite1h) }),
|
|
120
122
|
reasoning: positive(usage.reasoning),
|
|
121
123
|
totalTokens,
|
|
122
124
|
costUsd: positive(usage.cost?.total),
|
|
@@ -705,6 +705,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
705
705
|
output: usage.output,
|
|
706
706
|
cacheRead: usage.cacheRead,
|
|
707
707
|
cacheWrite: usage.cacheWrite,
|
|
708
|
+
...(usage.cacheWrite1h === undefined ? {} : { cacheWrite1h: usage.cacheWrite1h }),
|
|
708
709
|
reasoningTokens: usage.reasoning,
|
|
709
710
|
totalTokens: usage.totalTokens,
|
|
710
711
|
apiCalls: Math.max(1, Math.round(usage.apiCalls)),
|
|
@@ -213,6 +213,9 @@ export function createTurnPersistence(deps: TurnPersistenceDeps): TurnPersistenc
|
|
|
213
213
|
outputTokens: total.outputTokens + summary.output,
|
|
214
214
|
cacheReadTokens: total.cacheReadTokens + summary.cacheRead,
|
|
215
215
|
cacheWriteTokens: total.cacheWriteTokens + summary.cacheWrite,
|
|
216
|
+
...(total.cacheWrite1hTokens === undefined && summary.cacheWrite1h === undefined
|
|
217
|
+
? {}
|
|
218
|
+
: { cacheWrite1hTokens: (total.cacheWrite1hTokens ?? 0) + (summary.cacheWrite1h ?? 0) }),
|
|
216
219
|
reasoningTokens: total.reasoningTokens + summary.reasoning,
|
|
217
220
|
totalTokens: total.totalTokens + summary.tokens,
|
|
218
221
|
costUsd: (total.costUsd ?? 0) + summary.costUsd,
|