abtars 0.3.4-alpha.8 → 0.3.4
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/bundle/{_registry.generated-YP5GLSG7.js → _registry.generated-AVR7DK2A.js} +15 -15
- package/bundle/{abmind-lazy-7Z44NODV.js → abmind-lazy-E3YCFKQ5.js} +15 -5
- package/bundle/abtars-browser.js +4 -4
- package/bundle/abtars-cli.js +23 -13
- package/bundle/abtars-cli.js.map +2 -2
- package/bundle/abtars-restart.js +3 -3
- package/bundle/abtars-task.js +3 -3
- package/bundle/abtars.js +385 -466
- package/bundle/abtars.js.map +4 -4
- package/bundle/{acp-raw-client-E6FM45NC.js → acp-raw-client-UCNK3OTU.js} +2 -2
- package/bundle/{action-gate-G2V47NHW.js → action-gate-V4FCBHFB.js} +2 -2
- package/bundle/{agent-api-adapter-WRGEQ6DV.js → agent-api-adapter-7HEPYSIN.js} +3 -3
- package/bundle/{agent-api-rate-limit-WCFXJMGY.js → agent-api-rate-limit-RZSAM3SW.js} +4 -4
- package/bundle/{agent-registry-GHNG2PH3.js → agent-registry-46A2R5KP.js} +7 -7
- package/bundle/{bootstrap-PZIDBPEJ.js → bootstrap-MIHJJSWU.js} +2 -2
- package/bundle/{bridge-lock-transport-4ZH7QTJP.js → bridge-lock-transport-7RSN7OLJ.js} +4 -4
- package/bundle/{browser-D3LZV7ZK.js → browser-F6BCWJWW.js} +6 -6
- package/bundle/{budget-45QOBDWA.js → budget-WUM3SPKW.js} +3 -3
- package/bundle/{capability-JFWX3IQF.js → capability-QVRKGRFC.js} +5 -5
- package/bundle/{chunk-YSKCQH6E.js → chunk-2IYJ4I66.js} +2 -2
- package/bundle/{chunk-W2R2HFOQ.js → chunk-2NLUT5S2.js} +6 -6
- package/bundle/chunk-3BG3AIDP.js +191 -0
- package/bundle/chunk-3BG3AIDP.js.map +7 -0
- package/bundle/{chunk-OKAQICWY.js → chunk-3GQX34S2.js} +3 -3
- package/bundle/{chunk-QROWBWLL.js → chunk-3XZ773BS.js} +2 -2
- package/bundle/{chunk-DYBW4XXL.js → chunk-467SRLLR.js} +2 -2
- package/bundle/{chunk-374NCXFZ.js → chunk-4AILRHUI.js} +10 -8
- package/bundle/chunk-4AILRHUI.js.map +7 -0
- package/bundle/{chunk-GPZNXY2U.js → chunk-4S3H4OK7.js} +4 -4
- package/bundle/{chunk-NDCRWEEJ.js → chunk-4Y5MJQRE.js} +6 -6
- package/bundle/{chunk-FRKW6LWB.js → chunk-55UWKI5C.js} +3 -3
- package/bundle/{chunk-7JN2MMU7.js → chunk-5PNJFDSW.js} +8 -8
- package/bundle/{chunk-LUNA6PM5.js → chunk-5RVOEFGT.js} +4 -2
- package/bundle/{chunk-LUNA6PM5.js.map → chunk-5RVOEFGT.js.map} +2 -2
- package/bundle/{chunk-OXTSWQCX.js → chunk-5Y3FJ2Y7.js} +2 -2
- package/bundle/{chunk-TMUYFERL.js → chunk-6B5ZFUPD.js} +2 -2
- package/bundle/{chunk-65VCEC32.js → chunk-6PA5JBUU.js} +2 -2
- package/bundle/{chunk-C7K6VZNY.js → chunk-BNXV7SZI.js} +21 -12
- package/bundle/chunk-BNXV7SZI.js.map +7 -0
- package/bundle/{chunk-AFREM7FX.js → chunk-CK7YTA2F.js} +2 -2
- package/bundle/{chunk-NRUSRJXR.js → chunk-DZJ5QZFD.js} +2 -2
- package/bundle/{chunk-YRSMGJFP.js → chunk-E67KESEG.js} +2 -2
- package/bundle/{chunk-ZV4IWKDJ.js → chunk-E7XD5UGB.js} +3 -3
- package/bundle/{chunk-CXXU3HAU.js → chunk-EAX5ZZUL.js} +63 -39
- package/bundle/chunk-EAX5ZZUL.js.map +7 -0
- package/bundle/{chunk-PEDX56EL.js → chunk-EFGBM555.js} +2 -2
- package/bundle/{chunk-EQSG2CRM.js → chunk-FGYDIX54.js} +22 -15
- package/bundle/chunk-FGYDIX54.js.map +7 -0
- package/bundle/{chunk-YPAQEQSC.js → chunk-GF6NVNA7.js} +15 -5
- package/bundle/chunk-GF6NVNA7.js.map +7 -0
- package/bundle/{chunk-UNM3OXHB.js → chunk-HGSHCQ5F.js} +110 -72
- package/bundle/{chunk-UNM3OXHB.js.map → chunk-HGSHCQ5F.js.map} +2 -2
- package/bundle/{chunk-VXCETPZU.js → chunk-IMIGG5EO.js} +39 -39
- package/bundle/chunk-IMIGG5EO.js.map +7 -0
- package/bundle/{chunk-P2K2K6XL.js → chunk-ITOFPJAV.js} +44 -32
- package/bundle/chunk-ITOFPJAV.js.map +7 -0
- package/bundle/{chunk-75ATTOW4.js → chunk-IY6UKLPS.js} +3 -3
- package/bundle/{chunk-EUZDKV3C.js → chunk-J4RUFAPK.js} +3 -3
- package/bundle/{chunk-HZDLFLRP.js → chunk-J7DRPVMU.js} +35 -5
- package/bundle/chunk-J7DRPVMU.js.map +7 -0
- package/bundle/{chunk-EGL6UMAO.js → chunk-JG4BKXBN.js} +7 -1
- package/bundle/chunk-JG4BKXBN.js.map +7 -0
- package/bundle/{chunk-N4EB6LA7.js → chunk-JLWYPGWI.js} +5 -5
- package/bundle/{chunk-5QUTMUIK.js → chunk-JXYWDAHD.js} +12 -12
- package/bundle/{chunk-GRVWZO4C.js → chunk-KOSFXW2S.js} +24 -3
- package/bundle/{chunk-GRVWZO4C.js.map → chunk-KOSFXW2S.js.map} +1 -1
- package/bundle/{chunk-M3JEX6L4.js → chunk-L72RIPEC.js} +9 -9
- package/bundle/{chunk-TEFZ4JA4.js → chunk-NHPLD3C7.js} +2 -2
- package/bundle/{chunk-2KC5G3EA.js → chunk-OWUO5RS3.js} +5 -5
- package/bundle/{chunk-4MULJ5SS.js → chunk-OY4Q6AMY.js} +71 -49
- package/bundle/chunk-OY4Q6AMY.js.map +7 -0
- package/bundle/{chunk-WBTJ2E62.js → chunk-P3NODAHF.js} +2 -5
- package/bundle/{chunk-WBTJ2E62.js.map → chunk-P3NODAHF.js.map} +2 -2
- package/bundle/{chunk-SMPHE3ZM.js → chunk-PB5GF4FG.js} +215 -163
- package/bundle/chunk-PB5GF4FG.js.map +7 -0
- package/bundle/{chunk-WYHGNI56.js → chunk-PMD5BLFS.js} +6 -6
- package/bundle/{chunk-URQPDCK5.js → chunk-Q66LQMMZ.js} +3 -3
- package/bundle/{chunk-IHYKTDIP.js → chunk-SC2Y5NR2.js} +36 -119
- package/bundle/chunk-SC2Y5NR2.js.map +7 -0
- package/bundle/chunk-SFL4EPCZ.js +555 -0
- package/bundle/chunk-SFL4EPCZ.js.map +7 -0
- package/bundle/{chunk-LDUOOKQY.js → chunk-SJPUNDZ3.js} +5 -5
- package/bundle/{chunk-LDUOOKQY.js.map → chunk-SJPUNDZ3.js.map} +1 -1
- package/bundle/{chunk-JQDJPUHM.js → chunk-TWB2ZGVH.js} +2 -2
- package/bundle/{chunk-IJT4KWXT.js → chunk-U4U47YE7.js} +2 -2
- package/bundle/{chunk-2FAZIA37.js → chunk-W546CU3A.js} +3 -3
- package/bundle/chunk-WC5O5KOE.js +211 -0
- package/bundle/chunk-WC5O5KOE.js.map +7 -0
- package/bundle/{chunk-JNIHEDKF.js → chunk-XPWYDNWL.js} +2 -2
- package/bundle/{chunk-GWILHZPT.js → chunk-XRTXYN66.js} +10 -7
- package/bundle/{chunk-GWILHZPT.js.map → chunk-XRTXYN66.js.map} +2 -2
- package/bundle/{chunk-EFJVUJBE.js → chunk-Y5FEFKGM.js} +6 -6
- package/bundle/chunk-YJZE4OK3.js +169 -0
- package/bundle/chunk-YJZE4OK3.js.map +7 -0
- package/bundle/{chunk-GVM5YU5I.js → chunk-Z4FZPB42.js} +2 -2
- package/bundle/{chunk-7BSQ5UQO.js → chunk-ZSIDQ66D.js} +3 -3
- package/bundle/{chunk-XX6BGTPO.js → chunk-ZZZCJJEO.js} +4 -4
- package/bundle/{commands-OIISYHTD.js → commands-2ZW6CMLC.js} +17 -16
- package/bundle/{config-M3P5IOAI.js → config-YMY5YHKN.js} +6 -6
- package/bundle/{context-2RJHC2LE.js → context-CL2RSLII.js} +7 -5
- package/bundle/context-CL2RSLII.js.map +7 -0
- package/bundle/{daemon-TB23FFWY.js → daemon-D7SU63OY.js} +3 -3
- package/bundle/{delegation-tools-YATZFKYO.js → delegation-tools-WS7Z56KZ.js} +12 -12
- package/bundle/{deploy-T6R45OZJ.js → deploy-AMTVKIMU.js} +2 -2
- package/bundle/{deps-WVK553KF.js → deps-T63AVJKJ.js} +3 -3
- package/bundle/{direct-api-transport-S2RDH2I7.js → direct-api-transport-QNNY2WWP.js} +51 -32
- package/bundle/direct-api-transport-QNNY2WWP.js.map +7 -0
- package/bundle/{discord-adapter-UTXUWX3A.js → discord-adapter-ABAD56Y2.js} +21 -20
- package/bundle/{discord-adapter-UTXUWX3A.js.map → discord-adapter-ABAD56Y2.js.map} +1 -1
- package/bundle/{dns-wakeup-IDOJIXBX.js → dns-wakeup-V3LEFXPE.js} +9 -33
- package/bundle/dns-wakeup-V3LEFXPE.js.map +7 -0
- package/bundle/{doctor-probes-B54JFIW3.js → doctor-probes-O6YI6XSZ.js} +6 -2
- package/bundle/{env-schema-4JXQUOH4.js → env-schema-B5RB32DC.js} +3 -3
- package/bundle/{gossip-3C3BSNPN.js → gossip-SKRCPOBS.js} +9 -5
- package/bundle/{guardrails-DL7ZSWVN.js → guardrails-64GQ5Y5K.js} +4 -4
- package/bundle/{heartbeat-system-MVTRS4GP.js → heartbeat-system-X4MUTKJD.js} +6 -6
- package/bundle/{heartbeat-tier3-6KH45CL6.js → heartbeat-tier3-2PTPWEQQ.js} +53 -76
- package/bundle/heartbeat-tier3-2PTPWEQQ.js.map +7 -0
- package/bundle/{hook-system-M3POLUIB.js → hook-system-YB635OC4.js} +3 -3
- package/bundle/{hotskills-FWX4QI7V.js → hotskills-Q75D2DK3.js} +5 -5
- package/bundle/{install-OS3CU7NF.js → install-RFKKFSGS.js} +17 -30
- package/bundle/install-RFKKFSGS.js.map +7 -0
- package/bundle/{install-manifest-5PPWMD2W.js → install-manifest-J7ICPCJN.js} +2 -2
- package/bundle/{irc-adapter-PTTZD32W.js → irc-adapter-TVEV4R6H.js} +3 -3
- package/bundle/{irc-config-CP7ZMUOX.js → irc-config-M676FOFI.js} +4 -4
- package/bundle/{kanban-board-M326B2XJ.js → kanban-board-DLEJUCNN.js} +9 -7
- package/bundle/{kanban-channel-IJ52OMNA.js → kanban-channel-XOLUHJZJ.js} +6 -6
- package/bundle/kanban-delivery-C4QPBNPX.js +45 -0
- package/bundle/kanban-delivery-C4QPBNPX.js.map +7 -0
- package/bundle/{lazy-require-KCRVT4SI.js → lazy-require-JKQSALXN.js} +3 -3
- package/bundle/{logger-OWCSNYCA.js → logger-3EGHBD4R.js} +2 -2
- package/bundle/{main-chat-ZNUZCTNS.js → main-chat-3H63REKK.js} +4 -4
- package/bundle/{master-user-HSKM4ZFN.js → master-user-MUBUP3KD.js} +5 -5
- package/bundle/{media-utils-3ZYOD7SK.js → media-utils-HUUIALAJ.js} +3 -3
- package/bundle/{message-pipeline-AUIUNM5R.js → message-pipeline-GRDRWONR.js} +17 -16
- package/bundle/meta.json +2773 -2241
- package/bundle/{metrics-collector-L3VPEHII.js → metrics-collector-YMUGY3PI.js} +31 -2
- package/bundle/metrics-collector-YMUGY3PI.js.map +7 -0
- package/bundle/{model-health-registry-MLEIZSTV.js → model-health-registry-QADMFQFQ.js} +2 -2
- package/bundle/{nerve-IGSXBKZZ.js → nerve-QPAEBRKX.js} +3 -3
- package/bundle/{notification-BFSIEECG.js → notification-3JICGXWU.js} +6 -6
- package/bundle/{openrouter-credits-NTVZDRYM.js → openrouter-credits-7NEIPYJN.js} +3 -3
- package/bundle/{orc-tools-TOD4WHTM.js → orc-tools-UZVPONKY.js} +5 -3
- package/bundle/{peer-auth-QC4EF2PM.js → peer-auth-RI43DKJE.js} +24 -15
- package/bundle/{peer-client-RGEU5HOK.js → peer-client-UITTMWJ2.js} +34 -29
- package/bundle/peer-client-UITTMWJ2.js.map +7 -0
- package/bundle/{peer-config-TN55LFDC.js → peer-config-URM7DCW6.js} +9 -4
- package/bundle/{peer-transport-5VKK2I7P.js → peer-transport-SI7I72DB.js} +12 -10
- package/bundle/{phase-transport-FS6NL4A5.js → phase-transport-ESWWACZI.js} +17 -17
- package/bundle/{reconcile-CTFCLQRN.js → reconcile-GFDQYNBD.js} +3 -3
- package/bundle/{reconciler-NZ4O4BCP.js → reconciler-IEUJXJN2.js} +12 -12
- package/bundle/{restore-IFHPI7I7.js → restore-FARTGLQQ.js} +3 -3
- package/bundle/{rollback-ANRI3T5Z.js → rollback-GEWPZABG.js} +2 -2
- package/bundle/{sandbox-runtime-QROWHDCS.js → sandbox-runtime-DV6E25J6.js} +2 -2
- package/bundle/{self-healer-utils-IFAYOQO2.js → self-healer-utils-P4SKNNEM.js} +3 -3
- package/bundle/{sha-tracker-ZWBP6CIJ.js → sha-tracker-77SHLYNY.js} +3 -3
- package/bundle/{skill-session-VJXTKOKL.js → skill-session-5HSMXY54.js} +3 -3
- package/bundle/{skill-stats-JORH5DGM.js → skill-stats-MI3RSWWL.js} +4 -4
- package/bundle/{skill-watcher-E4MGLKLS.js → skill-watcher-5L7JE6TN.js} +4 -4
- package/bundle/{sleep-BEWAUFCL.js → sleep-I4JFASCY.js} +11 -11
- package/bundle/{soul-bundle-VWAVHCZ6.js → soul-bundle-522C3IRH.js} +9 -8
- package/bundle/{spin-E3ZDEDKT.js → spin-VHNGNWTD.js} +11 -11
- package/bundle/{spin-notifications-SE2HVZI7.js → spin-notifications-7NC5XZEM.js} +5 -5
- package/bundle/{spin-types-OIE67MJK.js → spin-types-C5KOQOPD.js} +7 -3
- package/bundle/{sse-parser-anthropic-A6R4Z2TB.js → sse-parser-anthropic-MMTVWHLI.js} +3 -3
- package/bundle/{sse-parser-responses-HSZY3QGJ.js → sse-parser-responses-3AOFN64C.js} +3 -3
- package/bundle/{ssrf-guard-O6SHIK6Q.js → ssrf-guard-U2JA72TC.js} +3 -3
- package/bundle/{start-7QZIWO3S.js → start-H5IUFAWF.js} +4 -2
- package/bundle/{start-7QZIWO3S.js.map → start-H5IUFAWF.js.map} +2 -2
- package/bundle/{stt-LGVPXMVR.js → stt-PSOPPBV4.js} +4 -4
- package/bundle/{system-status-FAVNIUFJ.js → system-status-4LYGOFNO.js} +38 -24
- package/bundle/system-status-4LYGOFNO.js.map +7 -0
- package/bundle/{task-store-W5BFIAIH.js → task-store-MNCW42BW.js} +4 -4
- package/bundle/{telegram-adapter-4TX7QWKC.js → telegram-adapter-O6KIZDY6.js} +62 -45
- package/bundle/telegram-adapter-O6KIZDY6.js.map +7 -0
- package/bundle/{tool-registry-7FK3OQGL.js → tool-registry-JJMWCQKZ.js} +26 -24
- package/bundle/{tool-sandbox-4UC6GAKA.js → tool-sandbox-CNL6V6IH.js} +4 -4
- package/bundle/{transport-config-KBF5W2DP.js → transport-config-6MB2K2XC.js} +7 -7
- package/bundle/tribe-GDTFYJTK.js +111 -0
- package/bundle/tribe-GDTFYJTK.js.map +7 -0
- package/bundle/{update-CKFP6LBE.js → update-HGQAOC5L.js} +3 -3
- package/bundle/{usage-tracker-NXD364VX.js → usage-tracker-SR4BI6ZT.js} +2 -2
- package/bundle/{user-registry-35BW4XKM.js → user-registry-4PACZJIJ.js} +4 -4
- package/bundle/wire-platform-KKPWNNNQ.js +88 -0
- package/bundle/wire-platform-KKPWNNNQ.js.map +7 -0
- package/bundle/ws-peer-client-U3NNPOK7.js +370 -0
- package/bundle/ws-peer-client-U3NNPOK7.js.map +7 -0
- package/package.json +1 -1
- package/scripts/abtars-watchdog.sh +1 -5
- package/scripts/emergency-deploy.sh +2 -2
- package/scripts/emergency-update.sh +36 -37
- package/bundle/chunk-374NCXFZ.js.map +0 -7
- package/bundle/chunk-4MULJ5SS.js.map +0 -7
- package/bundle/chunk-4S554KLW.js +0 -105
- package/bundle/chunk-4S554KLW.js.map +0 -7
- package/bundle/chunk-C7K6VZNY.js.map +0 -7
- package/bundle/chunk-CXXU3HAU.js.map +0 -7
- package/bundle/chunk-EGL6UMAO.js.map +0 -7
- package/bundle/chunk-EQSG2CRM.js.map +0 -7
- package/bundle/chunk-HT2BPTZY.js +0 -241
- package/bundle/chunk-HT2BPTZY.js.map +0 -7
- package/bundle/chunk-HZDLFLRP.js.map +0 -7
- package/bundle/chunk-IHYKTDIP.js.map +0 -7
- package/bundle/chunk-IKUZPMVA.js +0 -82
- package/bundle/chunk-IKUZPMVA.js.map +0 -7
- package/bundle/chunk-P2K2K6XL.js.map +0 -7
- package/bundle/chunk-PU5HSKWH.js +0 -257
- package/bundle/chunk-PU5HSKWH.js.map +0 -7
- package/bundle/chunk-RWRRGE4U.js +0 -72
- package/bundle/chunk-RWRRGE4U.js.map +0 -7
- package/bundle/chunk-SMPHE3ZM.js.map +0 -7
- package/bundle/chunk-VUIX5AGB.js +0 -65
- package/bundle/chunk-VUIX5AGB.js.map +0 -7
- package/bundle/chunk-VXCETPZU.js.map +0 -7
- package/bundle/chunk-YPAQEQSC.js.map +0 -7
- package/bundle/context-2RJHC2LE.js.map +0 -7
- package/bundle/direct-api-transport-S2RDH2I7.js.map +0 -7
- package/bundle/dns-wakeup-IDOJIXBX.js.map +0 -7
- package/bundle/heartbeat-tier3-6KH45CL6.js.map +0 -7
- package/bundle/install-OS3CU7NF.js.map +0 -7
- package/bundle/metrics-collector-L3VPEHII.js.map +0 -7
- package/bundle/peer-client-RGEU5HOK.js.map +0 -7
- package/bundle/peer-jwt-NCCPXJRX.js +0 -18
- package/bundle/stream-single-RFJNUTL6.js +0 -34
- package/bundle/stream-single-RFJNUTL6.js.map +0 -7
- package/bundle/system-status-FAVNIUFJ.js.map +0 -7
- package/bundle/telegram-adapter-4TX7QWKC.js.map +0 -7
- package/bundle/user-registry-35BW4XKM.js.map +0 -7
- package/bundle/ws-peer-client-AIXCXF7V.js +0 -173
- package/bundle/ws-peer-client-AIXCXF7V.js.map +0 -7
- /package/bundle/{_registry.generated-YP5GLSG7.js.map → _registry.generated-AVR7DK2A.js.map} +0 -0
- /package/bundle/{abmind-lazy-7Z44NODV.js.map → abmind-lazy-E3YCFKQ5.js.map} +0 -0
- /package/bundle/{acp-raw-client-E6FM45NC.js.map → acp-raw-client-UCNK3OTU.js.map} +0 -0
- /package/bundle/{action-gate-G2V47NHW.js.map → action-gate-V4FCBHFB.js.map} +0 -0
- /package/bundle/{agent-api-adapter-WRGEQ6DV.js.map → agent-api-adapter-7HEPYSIN.js.map} +0 -0
- /package/bundle/{agent-api-rate-limit-WCFXJMGY.js.map → agent-api-rate-limit-RZSAM3SW.js.map} +0 -0
- /package/bundle/{agent-registry-GHNG2PH3.js.map → agent-registry-46A2R5KP.js.map} +0 -0
- /package/bundle/{bootstrap-PZIDBPEJ.js.map → bootstrap-MIHJJSWU.js.map} +0 -0
- /package/bundle/{bridge-lock-transport-4ZH7QTJP.js.map → bridge-lock-transport-7RSN7OLJ.js.map} +0 -0
- /package/bundle/{browser-D3LZV7ZK.js.map → browser-F6BCWJWW.js.map} +0 -0
- /package/bundle/{budget-45QOBDWA.js.map → budget-WUM3SPKW.js.map} +0 -0
- /package/bundle/{capability-JFWX3IQF.js.map → capability-QVRKGRFC.js.map} +0 -0
- /package/bundle/{chunk-YSKCQH6E.js.map → chunk-2IYJ4I66.js.map} +0 -0
- /package/bundle/{chunk-W2R2HFOQ.js.map → chunk-2NLUT5S2.js.map} +0 -0
- /package/bundle/{chunk-OKAQICWY.js.map → chunk-3GQX34S2.js.map} +0 -0
- /package/bundle/{chunk-QROWBWLL.js.map → chunk-3XZ773BS.js.map} +0 -0
- /package/bundle/{chunk-DYBW4XXL.js.map → chunk-467SRLLR.js.map} +0 -0
- /package/bundle/{chunk-GPZNXY2U.js.map → chunk-4S3H4OK7.js.map} +0 -0
- /package/bundle/{chunk-NDCRWEEJ.js.map → chunk-4Y5MJQRE.js.map} +0 -0
- /package/bundle/{chunk-FRKW6LWB.js.map → chunk-55UWKI5C.js.map} +0 -0
- /package/bundle/{chunk-7JN2MMU7.js.map → chunk-5PNJFDSW.js.map} +0 -0
- /package/bundle/{chunk-OXTSWQCX.js.map → chunk-5Y3FJ2Y7.js.map} +0 -0
- /package/bundle/{chunk-TMUYFERL.js.map → chunk-6B5ZFUPD.js.map} +0 -0
- /package/bundle/{chunk-65VCEC32.js.map → chunk-6PA5JBUU.js.map} +0 -0
- /package/bundle/{chunk-AFREM7FX.js.map → chunk-CK7YTA2F.js.map} +0 -0
- /package/bundle/{chunk-NRUSRJXR.js.map → chunk-DZJ5QZFD.js.map} +0 -0
- /package/bundle/{chunk-YRSMGJFP.js.map → chunk-E67KESEG.js.map} +0 -0
- /package/bundle/{chunk-ZV4IWKDJ.js.map → chunk-E7XD5UGB.js.map} +0 -0
- /package/bundle/{chunk-PEDX56EL.js.map → chunk-EFGBM555.js.map} +0 -0
- /package/bundle/{chunk-75ATTOW4.js.map → chunk-IY6UKLPS.js.map} +0 -0
- /package/bundle/{chunk-EUZDKV3C.js.map → chunk-J4RUFAPK.js.map} +0 -0
- /package/bundle/{chunk-N4EB6LA7.js.map → chunk-JLWYPGWI.js.map} +0 -0
- /package/bundle/{chunk-5QUTMUIK.js.map → chunk-JXYWDAHD.js.map} +0 -0
- /package/bundle/{chunk-M3JEX6L4.js.map → chunk-L72RIPEC.js.map} +0 -0
- /package/bundle/{chunk-TEFZ4JA4.js.map → chunk-NHPLD3C7.js.map} +0 -0
- /package/bundle/{chunk-2KC5G3EA.js.map → chunk-OWUO5RS3.js.map} +0 -0
- /package/bundle/{chunk-WYHGNI56.js.map → chunk-PMD5BLFS.js.map} +0 -0
- /package/bundle/{chunk-URQPDCK5.js.map → chunk-Q66LQMMZ.js.map} +0 -0
- /package/bundle/{chunk-JQDJPUHM.js.map → chunk-TWB2ZGVH.js.map} +0 -0
- /package/bundle/{chunk-IJT4KWXT.js.map → chunk-U4U47YE7.js.map} +0 -0
- /package/bundle/{chunk-2FAZIA37.js.map → chunk-W546CU3A.js.map} +0 -0
- /package/bundle/{chunk-JNIHEDKF.js.map → chunk-XPWYDNWL.js.map} +0 -0
- /package/bundle/{chunk-EFJVUJBE.js.map → chunk-Y5FEFKGM.js.map} +0 -0
- /package/bundle/{chunk-GVM5YU5I.js.map → chunk-Z4FZPB42.js.map} +0 -0
- /package/bundle/{chunk-7BSQ5UQO.js.map → chunk-ZSIDQ66D.js.map} +0 -0
- /package/bundle/{chunk-XX6BGTPO.js.map → chunk-ZZZCJJEO.js.map} +0 -0
- /package/bundle/{commands-OIISYHTD.js.map → commands-2ZW6CMLC.js.map} +0 -0
- /package/bundle/{config-M3P5IOAI.js.map → config-YMY5YHKN.js.map} +0 -0
- /package/bundle/{daemon-TB23FFWY.js.map → daemon-D7SU63OY.js.map} +0 -0
- /package/bundle/{delegation-tools-YATZFKYO.js.map → delegation-tools-WS7Z56KZ.js.map} +0 -0
- /package/bundle/{deploy-T6R45OZJ.js.map → deploy-AMTVKIMU.js.map} +0 -0
- /package/bundle/{deps-WVK553KF.js.map → deps-T63AVJKJ.js.map} +0 -0
- /package/bundle/{doctor-probes-B54JFIW3.js.map → doctor-probes-O6YI6XSZ.js.map} +0 -0
- /package/bundle/{env-schema-4JXQUOH4.js.map → env-schema-B5RB32DC.js.map} +0 -0
- /package/bundle/{gossip-3C3BSNPN.js.map → gossip-SKRCPOBS.js.map} +0 -0
- /package/bundle/{guardrails-DL7ZSWVN.js.map → guardrails-64GQ5Y5K.js.map} +0 -0
- /package/bundle/{heartbeat-system-MVTRS4GP.js.map → heartbeat-system-X4MUTKJD.js.map} +0 -0
- /package/bundle/{hook-system-M3POLUIB.js.map → hook-system-YB635OC4.js.map} +0 -0
- /package/bundle/{hotskills-FWX4QI7V.js.map → hotskills-Q75D2DK3.js.map} +0 -0
- /package/bundle/{install-manifest-5PPWMD2W.js.map → install-manifest-J7ICPCJN.js.map} +0 -0
- /package/bundle/{irc-adapter-PTTZD32W.js.map → irc-adapter-TVEV4R6H.js.map} +0 -0
- /package/bundle/{irc-config-CP7ZMUOX.js.map → irc-config-M676FOFI.js.map} +0 -0
- /package/bundle/{kanban-board-M326B2XJ.js.map → kanban-board-DLEJUCNN.js.map} +0 -0
- /package/bundle/{kanban-channel-IJ52OMNA.js.map → kanban-channel-XOLUHJZJ.js.map} +0 -0
- /package/bundle/{lazy-require-KCRVT4SI.js.map → lazy-require-JKQSALXN.js.map} +0 -0
- /package/bundle/{logger-OWCSNYCA.js.map → logger-3EGHBD4R.js.map} +0 -0
- /package/bundle/{main-chat-ZNUZCTNS.js.map → main-chat-3H63REKK.js.map} +0 -0
- /package/bundle/{master-user-HSKM4ZFN.js.map → master-user-MUBUP3KD.js.map} +0 -0
- /package/bundle/{media-utils-3ZYOD7SK.js.map → media-utils-HUUIALAJ.js.map} +0 -0
- /package/bundle/{message-pipeline-AUIUNM5R.js.map → message-pipeline-GRDRWONR.js.map} +0 -0
- /package/bundle/{model-health-registry-MLEIZSTV.js.map → model-health-registry-QADMFQFQ.js.map} +0 -0
- /package/bundle/{nerve-IGSXBKZZ.js.map → nerve-QPAEBRKX.js.map} +0 -0
- /package/bundle/{notification-BFSIEECG.js.map → notification-3JICGXWU.js.map} +0 -0
- /package/bundle/{openrouter-credits-NTVZDRYM.js.map → openrouter-credits-7NEIPYJN.js.map} +0 -0
- /package/bundle/{orc-tools-TOD4WHTM.js.map → orc-tools-UZVPONKY.js.map} +0 -0
- /package/bundle/{peer-auth-QC4EF2PM.js.map → peer-auth-RI43DKJE.js.map} +0 -0
- /package/bundle/{peer-config-TN55LFDC.js.map → peer-config-URM7DCW6.js.map} +0 -0
- /package/bundle/{peer-jwt-NCCPXJRX.js.map → peer-transport-SI7I72DB.js.map} +0 -0
- /package/bundle/{peer-transport-5VKK2I7P.js.map → phase-transport-ESWWACZI.js.map} +0 -0
- /package/bundle/{phase-transport-FS6NL4A5.js.map → reconcile-GFDQYNBD.js.map} +0 -0
- /package/bundle/{reconciler-NZ4O4BCP.js.map → reconciler-IEUJXJN2.js.map} +0 -0
- /package/bundle/{restore-IFHPI7I7.js.map → restore-FARTGLQQ.js.map} +0 -0
- /package/bundle/{reconcile-CTFCLQRN.js.map → rollback-GEWPZABG.js.map} +0 -0
- /package/bundle/{sandbox-runtime-QROWHDCS.js.map → sandbox-runtime-DV6E25J6.js.map} +0 -0
- /package/bundle/{self-healer-utils-IFAYOQO2.js.map → self-healer-utils-P4SKNNEM.js.map} +0 -0
- /package/bundle/{rollback-ANRI3T5Z.js.map → sha-tracker-77SHLYNY.js.map} +0 -0
- /package/bundle/{skill-session-VJXTKOKL.js.map → skill-session-5HSMXY54.js.map} +0 -0
- /package/bundle/{sha-tracker-ZWBP6CIJ.js.map → skill-stats-MI3RSWWL.js.map} +0 -0
- /package/bundle/{skill-stats-JORH5DGM.js.map → skill-watcher-5L7JE6TN.js.map} +0 -0
- /package/bundle/{skill-watcher-E4MGLKLS.js.map → sleep-I4JFASCY.js.map} +0 -0
- /package/bundle/{sleep-BEWAUFCL.js.map → soul-bundle-522C3IRH.js.map} +0 -0
- /package/bundle/{soul-bundle-VWAVHCZ6.js.map → spin-VHNGNWTD.js.map} +0 -0
- /package/bundle/{spin-notifications-SE2HVZI7.js.map → spin-notifications-7NC5XZEM.js.map} +0 -0
- /package/bundle/{spin-E3ZDEDKT.js.map → spin-types-C5KOQOPD.js.map} +0 -0
- /package/bundle/{sse-parser-anthropic-A6R4Z2TB.js.map → sse-parser-anthropic-MMTVWHLI.js.map} +0 -0
- /package/bundle/{sse-parser-responses-HSZY3QGJ.js.map → sse-parser-responses-3AOFN64C.js.map} +0 -0
- /package/bundle/{ssrf-guard-O6SHIK6Q.js.map → ssrf-guard-U2JA72TC.js.map} +0 -0
- /package/bundle/{spin-types-OIE67MJK.js.map → stt-PSOPPBV4.js.map} +0 -0
- /package/bundle/{stt-LGVPXMVR.js.map → task-store-MNCW42BW.js.map} +0 -0
- /package/bundle/{task-store-W5BFIAIH.js.map → tool-registry-JJMWCQKZ.js.map} +0 -0
- /package/bundle/{tool-registry-7FK3OQGL.js.map → tool-sandbox-CNL6V6IH.js.map} +0 -0
- /package/bundle/{tool-sandbox-4UC6GAKA.js.map → transport-config-6MB2K2XC.js.map} +0 -0
- /package/bundle/{transport-config-KBF5W2DP.js.map → update-HGQAOC5L.js.map} +0 -0
- /package/bundle/{update-CKFP6LBE.js.map → usage-tracker-SR4BI6ZT.js.map} +0 -0
- /package/bundle/{usage-tracker-NXD364VX.js.map → user-registry-4PACZJIJ.js.map} +0 -0
package/bundle/chunk-VUIX5AGB.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
|
|
3
|
-
import {
|
|
4
|
-
init_peer_config,
|
|
5
|
-
loadPeerConfig
|
|
6
|
-
} from "./chunk-4S554KLW.js";
|
|
7
|
-
import {
|
|
8
|
-
init_peer_jwt,
|
|
9
|
-
signJwt
|
|
10
|
-
} from "./chunk-RWRRGE4U.js";
|
|
11
|
-
import {
|
|
12
|
-
__esm
|
|
13
|
-
} from "./chunk-7K2YZTLD.js";
|
|
14
|
-
|
|
15
|
-
// src/components/peer-transport/peer-auth.ts
|
|
16
|
-
function mintPeerJwt(peerName) {
|
|
17
|
-
const config = loadPeerConfig();
|
|
18
|
-
const entry = config.peers[peerName];
|
|
19
|
-
if (!entry) throw new Error(`Unknown peer: ${peerName}`);
|
|
20
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
21
|
-
return signJwt({ iss: config.self.name, aud: peerName, iat: now, exp: now + 60 }, entry.token);
|
|
22
|
-
}
|
|
23
|
-
async function signBody(peerName, body, signingKey, selfName) {
|
|
24
|
-
if (!signingKey || !selfName) {
|
|
25
|
-
const config = loadPeerConfig();
|
|
26
|
-
signingKey = signingKey ?? config.self.signingKey;
|
|
27
|
-
selfName = selfName ?? config.self.name;
|
|
28
|
-
}
|
|
29
|
-
if (!signingKey) return body;
|
|
30
|
-
const { signMessage } = await import("./digital-signature-4JH7SRW2.js");
|
|
31
|
-
const { tag } = signMessage(signingKey, selfName, peerName, body);
|
|
32
|
-
const parsed = JSON.parse(body);
|
|
33
|
-
parsed._sig = tag;
|
|
34
|
-
return JSON.stringify(parsed);
|
|
35
|
-
}
|
|
36
|
-
function tlsOptions(entry) {
|
|
37
|
-
if (!entry.certFingerprint && !entry.certPem) {
|
|
38
|
-
throw new Error(`Peer has no TLS cert configured \u2014 refusing connection. Set certFingerprint or certPem in peers.json.`);
|
|
39
|
-
}
|
|
40
|
-
return {
|
|
41
|
-
minVersion: "TLSv1.3",
|
|
42
|
-
rejectUnauthorized: true,
|
|
43
|
-
...entry.certPem ? { ca: [entry.certPem] } : {},
|
|
44
|
-
checkServerIdentity: (_host, cert) => {
|
|
45
|
-
if (entry.certFingerprint && cert.fingerprint256 !== entry.certFingerprint) {
|
|
46
|
-
return new Error("Cert fingerprint mismatch");
|
|
47
|
-
}
|
|
48
|
-
return void 0;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
var init_peer_auth = __esm({
|
|
53
|
-
"src/components/peer-transport/peer-auth.ts"() {
|
|
54
|
-
init_peer_jwt();
|
|
55
|
-
init_peer_config();
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
export {
|
|
60
|
-
mintPeerJwt,
|
|
61
|
-
signBody,
|
|
62
|
-
tlsOptions,
|
|
63
|
-
init_peer_auth
|
|
64
|
-
};
|
|
65
|
-
//# sourceMappingURL=chunk-VUIX5AGB.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/components/peer-transport/peer-auth.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * peer-auth.ts \u2014 Shared auth/TLS helpers for peer transport (#972).\n * Used by both HTTP and WebSocket transports.\n */\nimport { signJwt } from \"../peer-jwt.js\";\nimport { loadPeerConfig, type PeerEntry } from \"../peer-config.js\";\nimport type { TlsOptions } from \"node:tls\";\n\n/** Mint a short-lived JWT for peer authentication. */\nexport function mintPeerJwt(peerName: string): string {\n const config = loadPeerConfig();\n const entry = config.peers[peerName];\n if (!entry) throw new Error(`Unknown peer: ${peerName}`);\n const now = Math.floor(Date.now() / 1000);\n return signJwt({ iss: config.self.name, aud: peerName, iat: now, exp: now + 60 }, entry.token);\n}\n\n/** Sign a JSON body with Ed25519 (returns body with _sig field appended). */\nexport async function signBody(peerName: string, body: string, signingKey?: string, selfName?: string): Promise<string> {\n if (!signingKey || !selfName) {\n const config = loadPeerConfig();\n signingKey = signingKey ?? config.self.signingKey;\n selfName = selfName ?? config.self.name;\n }\n if (!signingKey) return body;\n const { signMessage } = await import(\"../digital-signature.js\");\n const { tag } = signMessage(signingKey, selfName!, peerName, body);\n const parsed = JSON.parse(body);\n parsed._sig = tag;\n return JSON.stringify(parsed);\n}\n\n/** TLS options for connecting to a peer (cert pinning, TLS 1.3 mandatory). */\nexport function tlsOptions(entry: PeerEntry): TlsOptions {\n if (!entry.certFingerprint && !entry.certPem) {\n throw new Error(`Peer has no TLS cert configured \u2014 refusing connection. Set certFingerprint or certPem in peers.json.`);\n }\n return {\n minVersion: \"TLSv1.3\",\n rejectUnauthorized: true,\n ...(entry.certPem ? { ca: [entry.certPem] } : {}),\n checkServerIdentity: (_host: string, cert: { fingerprint256?: string }) => {\n if (entry.certFingerprint && cert.fingerprint256 !== entry.certFingerprint) {\n return new Error(\"Cert fingerprint mismatch\");\n }\n return undefined;\n },\n } as TlsOptions;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;AASO,SAAS,YAAY,UAA0B;AACpD,QAAM,SAAS,eAAe;AAC9B,QAAM,QAAQ,OAAO,MAAM,QAAQ;AACnC,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,iBAAiB,QAAQ,EAAE;AACvD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,SAAO,QAAQ,EAAE,KAAK,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,KAAK,KAAK,MAAM,GAAG,GAAG,MAAM,KAAK;AAC/F;AAGA,eAAsB,SAAS,UAAkB,MAAc,YAAqB,UAAoC;AACtH,MAAI,CAAC,cAAc,CAAC,UAAU;AAC5B,UAAM,SAAS,eAAe;AAC9B,iBAAa,cAAc,OAAO,KAAK;AACvC,eAAW,YAAY,OAAO,KAAK;AAAA,EACrC;AACA,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,iCAAyB;AAC9D,QAAM,EAAE,IAAI,IAAI,YAAY,YAAY,UAAW,UAAU,IAAI;AACjE,QAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,SAAO,OAAO;AACd,SAAO,KAAK,UAAU,MAAM;AAC9B;AAGO,SAAS,WAAW,OAA8B;AACvD,MAAI,CAAC,MAAM,mBAAmB,CAAC,MAAM,SAAS;AAC5C,UAAM,IAAI,MAAM,2GAAsG;AAAA,EACxH;AACA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,GAAI,MAAM,UAAU,EAAE,IAAI,CAAC,MAAM,OAAO,EAAE,IAAI,CAAC;AAAA,IAC/C,qBAAqB,CAAC,OAAe,SAAsC;AACzE,UAAI,MAAM,mBAAmB,KAAK,mBAAmB,MAAM,iBAAiB;AAC1E,eAAO,IAAI,MAAM,2BAA2B;AAAA,MAC9C;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAhDA;AAAA;AAIA;AACA;AAAA;AAAA;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/boot/phase-transport.ts", "../src/components/transport/tmux-client.ts"],
|
|
4
|
-
"sourcesContent": ["import { logAndSwallow } from \"../components/log-and-swallow.js\";\nimport { getEnv } from \"../components/env-schema.js\";\n/**\n * phase-transport \u2014 boot phase 3: select, initialize, and wrap the agent transport.\n *\n * Also exports buildTransport/rebuildTransport for /reset to pick up transport.json changes\n * (including provider switches that can't be live-patched).\n */\n\nimport { execSync } from \"node:child_process\";\nimport { TmuxClient } from \"../components/transport/tmux-client.js\";\nimport { createAgentTransport } from \"../components/agent-registry.js\";\nimport { logDebug, logInfo, logWarn, logError, isLogLevel } from \"../components/logger.js\";\nimport { loadUsers } from \"../components/user-registry.js\";\nimport { updateCtxStart } from \"./ctx-start.js\";\nimport { abmind } from \"../utils/abmind-lazy.js\";\nimport type { BootCtx, PhaseResult } from \"./context.js\";\nimport type { IKiroTransport } from \"../components/transport/kiro-transport.js\";\n\nconst TAG = \"transport\";\n\nexport async function phaseTransport(ctx: BootCtx): Promise<PhaseResult> {\n const { memoryConfig } = ctx;\n\n await buildTransport(ctx);\n\n // Docker detection (#478)\n const { isDockerActive, isSeatbeltActive } = await import(\"../components/guardrails.js\");\n if (isDockerActive()) {\n const { dockerAvailable } = await import(\"../components/sandbox-runtime.js\");\n if (dockerAvailable()) {\n ctx.sandboxEnabled = true;\n logInfo(\"main\", \"\uD83D\uDC33 Docker mode active \u2014 W/B/C sessions will run in Docker containers\");\n } else {\n logWarn(\"main\", \"SECURITY_MODE=docker but Docker not available \u2014 falling back to seatbelt\");\n }\n }\n\n // Seatbelt detection (#906)\n if (isSeatbeltActive()) {\n const { isAvailable, mechanismName } = await import(\"../components/seatbelt/index.js\");\n if (isAvailable()) {\n ctx.seatbeltActive = true;\n logInfo(\"main\", `\uD83D\uDEE1\uFE0F Seatbelt active \u2014 bash commands sandboxed via ${mechanismName()}`);\n } else {\n logWarn(\"main\", `SECURITY_MODE=seatbelt but ${mechanismName()} not available \u2014 falling back to guardrails`);\n }\n }\n\n // Initialize context-window-start for all known users\n if (memoryConfig.memoryEnabled) {\n const reg = loadUsers();\n for (const user of reg.users) updateCtxStart(memoryConfig.memoryDir, user.userId, ctx.startedAt);\n }\n return \"ran\";\n}\n\n/**\n * Construct professor transport from current transport.json + env and attach to ctx.transport.\n * Idempotent: destroys any existing ctx.transport first.\n *\n * #367 \u2014 Validates the resolved provider BEFORE destroying the old transport.\n * If validation fails:\n * - During `/reset` (old transport exists): logs ERROR, keeps the old transport up\n * - At boot (no old transport): falls back to .env config if possible, or throws\n * - In either case: bridge stays alive in degraded mode rather than crash-looping\n */\nexport async function buildTransport(ctx: BootCtx): Promise<PhaseResult> {\n const { config } = ctx;\n\n let transport: IKiroTransport;\n\n const { resolveAgent, getEnvFallback, loadTransport, resolveHailMary, clearTransportCache, validateProviderReady } = await import(\"../components/transport-config.js\");\n const { existsSync, renameSync } = await import(\"node:fs\");\n const { join: pathJoin } = await import(\"node:path\");\n clearTransportCache(); // always re-read (picks up /models change writes)\n let tc = loadTransport();\n\n // Recovery: if transport.json missing/corrupt, try transport.old.json\n if (!tc) {\n const configDir = pathJoin(getEnv().abtarsHome, \"config\");\n const primary = pathJoin(configDir, \"transport.json\");\n const old = pathJoin(configDir, \"transport.old.json\");\n if (existsSync(old)) {\n logDebug(\"main\", \"transport.json missing/corrupt \u2014 recovering from transport.old.json\");\n renameSync(old, primary);\n clearTransportCache();\n tc = loadTransport();\n }\n }\n\n const prof = tc ? resolveAgent(\"professor\", tc) : null;\n\n const hm = resolveHailMary(tc);\n if (hm) {\n ctx.hailMary = {\n model: hm.model,\n endpoint: hm.endpoint,\n apiKey: hm.apiKeyEnv ? getEnv().getApiKey(hm.apiKeyEnv) : undefined,\n };\n logInfo(\"main\", `\uD83D\uDEA8 hailMary configured: ${hm.model} (manual /model emergency only)`);\n } else {\n ctx.hailMary = null;\n }\n\n let resolved: typeof prof = null;\n\n if (!tc) {\n // No transport.json and no .old.json \u2014 emergency mode from .env\n const fb = getEnvFallback();\n const fbValidation = validateProviderReady(fb.providerName, fb.provider, getEnv());\n if (!fbValidation.ok) {\n logError(\"main\", `No transport.json, no backup, and .env emergency model also invalid: ${fbValidation.reason}`);\n logWarn(\"main\", \"Transport unavailable \u2014 running in Tier 2 (no agent responses)\");\n ctx.transport = null;\n return \"skipped\";\n }\n logWarn(\"main\", `\u26A0\uFE0F No transport.json \u2014 emergency mode: ${fb.model} via ${fb.providerName}`);\n resolved = { model: fb.model, provider: fb.provider, providerName: fb.providerName, contextWindow: fb.contextWindow, maxOutput: fb.maxOutput, fallbacks: [] };\n // Notify user (deferred \u2014 transport not yet built)\n setTimeout(() => {\n import(\"../components/notification.js\").then(({ sendNotification }) =>\n sendNotification(ctx, `\u26A0\uFE0F transport.json missing, no backup. Running emergency model: ${fb.model}. Fix: /update deploy`))\n .catch(() => {});\n }, 10_000);\n } else {\n // transport.json valid \u2014 walk primary + fb chain\n const validation = validateProviderReady(prof!.providerName, prof!.provider, getEnv());\n if (validation.ok) {\n logDebug(\"main\", `Model init OK: ${prof!.model} via ${prof!.providerName}`);\n resolved = prof;\n } else {\n logDebug(\"main\", `Model init failed: ${prof!.model} \u2014 ${validation.reason}`);\n logWarn(\"main\", `${prof!.model}: ${validation.reason} \u2014 trying fallbacks`);\n // Walk fallback chain\n for (const fb of prof!.fallbacks) {\n const fbResolved = resolveAgent(\"_fb\", { ...tc!, agents: { ...tc!.agents, _fb: { model: fb.model, provider: fb.provider } } });\n if (!fbResolved) continue;\n const fbVal = validateProviderReady(fbResolved.providerName, fbResolved.provider, getEnv());\n if (fbVal.ok) {\n logDebug(\"main\", `Fallback init OK: ${fbResolved.model} via ${fbResolved.providerName}`);\n resolved = fbResolved;\n break;\n }\n logDebug(\"main\", `Fallback init failed: ${fbResolved.model} \u2014 ${fbVal.reason}`);\n logWarn(\"main\", `${fbResolved.model}: ${fbVal.reason} \u2014 trying next`);\n }\n }\n\n if (!resolved) {\n // ALL configured models failed \u2014 hard error (boot) or keep existing (reset)\n const tried = [prof!.model, ...prof!.fallbacks.map(f => f.model)].join(\", \");\n if (ctx.transport) {\n logError(\"main\", `All models failed init (${tried}) \u2014 keeping existing transport up`);\n return \"ran\";\n }\n logError(\"main\", `All configured models failed init (${tried}). Fix transport.json or use /emergency`);\n logWarn(\"main\", \"Transport unavailable \u2014 running in Tier 2 (no agent responses)\");\n ctx.transport = null;\n return \"skipped\";\n }\n }\n\n // #367 \u2014 if existing transport is up and new config rebuild needed, keep old on error\n // (This path is only hit via /reset rebuild, not boot)\n\n // Destroy old (if any) \u2014 now that we know the new config is valid\n if (ctx.transport) {\n try { await ctx.transport.destroy(); } catch (err) {\n logWarn(\"main\", `Old transport destroy failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n ctx.transport = null;\n }\n\n if (resolved.provider.transport === \"tmux\") {\n const defaults = tc?.transportDefaults?.tmux;\n logInfo(\"main\", `\uD83D\uDDA5\uFE0F tmux transport (${resolved.providerName})`);\n transport = new TmuxClient(\n defaults?.session ?? config.transport.tmuxSession,\n defaults?.captureDelaySec ?? config.transport.tmuxCaptureDelaySec,\n defaults?.maxWaitSec ?? config.transport.tmuxMaxWaitSec,\n );\n } else if (resolved.provider.transport === \"api\") {\n const { DirectApiTransport } = await import(\"../components/transport/direct-api-transport.js\");\n const { ModelHealthRegistry } = await import(\"../components/transport/model-health-registry.js\");\n const { FallbackPolicy } = await import(\"../components/transport/fallback-policy.js\");\n const apiKey = getEnv().getApiKey(resolved.provider.apiKeyEnv ?? \"API_KEY\");\n\n const candidates: Array<{ model: string; endpoint: string; apiKey?: string; maxContext: number }> = [\n { endpoint: resolved.provider.endpoint ?? \"http://localhost:11434/v1\", apiKey, model: resolved.model, maxContext: resolved.contextWindow },\n ];\n for (const fb of resolved.fallbacks) {\n const fbResolved = tc ? resolveAgent(\"_fallback\", { ...tc, agents: { ...tc.agents, _fallback: { model: fb.model, provider: fb.provider } } }) : null;\n candidates.push({\n endpoint: fbResolved?.provider.endpoint ?? resolved.provider.endpoint!,\n apiKey: fbResolved?.provider.apiKeyEnv ? getEnv().getApiKey(fbResolved.provider.apiKeyEnv) : apiKey,\n model: fb.model,\n maxContext: fbResolved?.contextWindow ?? resolved.contextWindow,\n });\n }\n\n if (!ctx.modelHealthRegistry) {\n ctx.modelHealthRegistry = new ModelHealthRegistry(tc?.healthPolicy);\n }\n // Wire auto-demotion\n if (!ctx.modelHealthRegistry.onDemote) {\n ctx.modelHealthRegistry.onDemote = (model, _endpoint, reason) => {\n import(\"../components/transport-config.js\").then(({ demoteModel }) => demoteModel(model, reason));\n import(\"../components/notification.js\").then(({ sendNotification }) =>\n sendNotification(ctx, `\u26A0\uFE0F ${model} demoted (${reason}). Next healthy model promoted.`)).catch(err => logAndSwallow(TAG, \"sendNotification model-demote\", err));\n };\n }\n const policy = new FallbackPolicy(candidates, ctx.modelHealthRegistry);\n\n transport = new DirectApiTransport({\n endpoint: resolved.provider.endpoint ?? \"http://localhost:11434/v1\",\n apiKey,\n model: resolved.model,\n maxContext: resolved.contextWindow,\n maxOutput: resolved.maxOutput,\n maxTurns: tc?.maxTurns ?? 50,\n maxToolRounds: tc?.maxToolRounds ?? 25,\n apiFormat: resolved.provider.apiFormat,\n thinking: resolved.provider.thinking,\n }, policy);\n logInfo(\"main\", `\uD83D\uDD0C Direct API transport (${resolved.providerName}, model=${resolved.model}, ${candidates.length} candidates)`);\n } else {\n // Kill stale ACP processes from previous run (#921, #1012)\n const { readAndClearAcpPids } = await import(\"../components/transport/bridge-lock-transport.js\");\n const stalePids = readAndClearAcpPids();\n for (const pid of stalePids) {\n try { process.kill(pid, \"SIGTERM\"); } catch { /* already dead */ }\n }\n if (stalePids.length) logDebug(\"main\", `Killed ${stalePids.length} stale ACP process(es)`);\n // #1012: Defense-in-depth \u2014 kill kiro-cli acp processes whose CWD is inside ~/.abtars/\n // Safe: agent sessions (AG1-5) have CWD outside ~/.abtars/, won't be touched.\n try {\n const { abtarsHome } = await import(\"../paths.js\");\n const home = abtarsHome();\n const { readlinkSync } = await import(\"node:fs\");\n const candidates = execSync(\"ps ax -o pid,args 2>/dev/null | grep '[k]iro-cli.*acp' | awk '{print $1}' || true\", { encoding: \"utf-8\", timeout: 3000 }).trim().split(\"\\n\").filter(Boolean);\n let killed = 0;\n for (const p of candidates) {\n const pid = parseInt(p, 10);\n if (!pid || pid === process.pid) continue;\n try {\n const cwd = readlinkSync(`/proc/${pid}/cwd`);\n if (cwd.startsWith(home)) { process.kill(pid, \"SIGTERM\"); killed++; }\n } catch {} // dead, no /proc (macOS), or no permission\n }\n if (killed) logDebug(\"main\", `CWD-checked kill: ${killed} orphan(s)`);\n } catch { /* best effort */ }\n logInfo(\"main\", `\uD83D\uDD0C ACP transport (${resolved.provider.cli ?? \"kiro-cli\"}, model=${resolved.model})`);\n transport = createAgentTransport(\"professor\", {\n cliPath: resolved.provider.cli ?? config.transport.agentCliPath,\n workingDir: config.transport.workingDir,\n agentCli: resolved.provider.cli ?? \"kiro-cli\",\n model: resolved.model,\n });\n }\n\n await transport.initialize();\n\n // SOUL bundle set in phase-pipelineDeps (after memory state resolved) #998\n\n if (resolved.fallbacks.length > 0 && resolved.provider.transport !== \"api\") {\n logWarn(\"main\", `\u26A0\uFE0F Fallbacks configured for ${resolved.provider.transport} transport \u2014 only API transport supports model fallback`);\n }\n\n ctx.transport = transport;\n // Flush message queues on reinit \u2014 model lost context\n if (\"onReinit\" in transport) {\n (transport as any).onReinit = () => {\n const { spin } = require(\"../components/spin.js\") as typeof import(\"../components/spin.js\");\n for (const s of spin.listAllSessions()) {\n if (s.queue.length) {\n logWarn(\"transport\", `Reinit: flushing ${s.queue.length} queued message(s)`);\n s.queue.length = 0;\n }\n }\n };\n }\n ctx.modelName = resolved.model;\n ctx.modelProvider = resolved.providerName;\n ctx.fallbackChain = resolved.fallbacks.map((f: { model: string }) => f.model);\n\n if (ctx.modelHealthRegistry) {\n ctx.runtime.setRegistry(ctx.modelHealthRegistry);\n }\n ctx.runtime.setMainTransport(transport);\n ctx.runtime.setSessionManager(ctx.sessionManager);\n if (ctx.sandboxEnabled) ctx.runtime.setSandboxEnabled(true);\n\n // Wire async delegation tools (#570)\n if (getEnv().enableAsyncDelegation) {\n const { setDelegationDeps } = await import(\"../components/transport/delegation-tools.js\");\n setDelegationDeps(ctx.runtime);\n }\n\n logInfo(\"main\", \"\u2713 Transport ready\");\n\n // Wire ActionGate for auth-required commands\n const { join } = await import(\"node:path\");\n const { abtarsHome } = await import(\"../paths.js\");\n const { ActionGate } = await import(\"../components/action-gate.js\");\n const { setActionGate } = await import(\"../components/transport/tool-registry.js\");\n const authDir = join(abtarsHome(), \"auth\");\n ctx.actionGate = new ActionGate(authDir);\n setActionGate(ctx.actionGate);\n logDebug(\"main\", \"\uD83D\uDD12 ActionGate wired\");\n\n // #906: Wire seatbelt into tool-registry\n if (ctx.seatbeltActive) {\n const { setSeatbelt } = await import(\"../components/transport/tool-registry.js\");\n const { getPolicy } = await import(\"../components/seatbelt/index.js\");\n const home = abtarsHome();\n const policy = getPolicy(\"A\", join(home, \"workspace\"), home); // Main session policy\n setSeatbelt(true, policy);\n logDebug(\"main\", \"\uD83D\uDEE1\uFE0F Seatbelt wired to tool-registry\");\n }\n\n // #843: Wire memory to DirectApiTransport for session hydration on restart.\n // Transport-specific \u2014 only DirectApiTransport has this field.\n if (resolved.provider.transport === \"api\" && ctx.memory) {\n (transport as import(\"../components/transport/direct-api-transport.js\").DirectApiTransport).memoryBackend = ctx.memory!;\n\n // Wire context engine for automatic compaction (DirectApiTransport-specific).\n const db = ctx.memory!.getDb?.() ?? ctx.memory!.getDatabase?.();\n if (db && resolved.contextWindow >= 128000) {\n const mod = abmind();\n if (mod) {\n const { ContextEngine } = mod;\n const { createContextOrchestrator } = await import(\"../components/context/index.js\");\n const contextEngine = new ContextEngine(db);\n const orchestrator = createContextOrchestrator(\n contextEngine,\n async (systemPrompt: string, userPrompt: string) => {\n const { streamSingleCompletion } = await import(\"../components/transport/stream-single.js\");\n return streamSingleCompletion({\n endpoint: resolved.provider.endpoint ?? \"http://localhost:11434/v1\",\n apiKey: getEnv().getApiKey(resolved.provider.apiKeyEnv ?? \"API_KEY\") ?? undefined,\n model: resolved.model,\n systemPrompt,\n userPrompt,\n maxTokens: 4096,\n });\n },\n (_chatId: string) => {\n try { return ctx.memory?.getLastMessageTimestamp(true) ?? null; } catch (err) { logAndSwallow(TAG, \"getLastMessageTimestamp\", err); return null; }\n },\n );\n (transport as import(\"../components/transport/direct-api-transport.js\").DirectApiTransport).contextOrchestrator = orchestrator;\n logInfo(\"main\", \"\uD83D\uDCE6 Context engine wired (auto-compaction active)\");\n }\n }\n }\n\n if (\"onFallback\" in transport) {\n let lastNotifiedModel: string | null = null;\n (transport as unknown as { onFallback: (model: string, ctxPct: number, reason?: string) => void }).onFallback = (model, ctxPct, reason) => {\n const reasonTag = reason ? ` (${reason})` : \"\";\n const msg = `\u26A1 Fallback${reasonTag}: ${model}${ctxPct >= 0 ? ` (ctx: ~${ctxPct}%)` : \"\"}`;\n logInfo(\"main\", msg);\n if (model !== lastNotifiedModel || isLogLevel(\"debug\")) {\n lastNotifiedModel = model;\n import(\"../components/notification.js\").then(({ sendNotification }) => sendNotification(ctx, msg)).catch(err => logAndSwallow(TAG, \"sendNotification fallback\", err));\n }\n };\n }\n return \"ran\";\n}\n\n/**\n * Rebuild professor transport in place (picks up transport.json changes).\n * Patches downstream references that captured the old transport (pipelineDeps, idleSave).\n */\nexport async function rebuildTransport(ctx: BootCtx): Promise<PhaseResult> {\n logInfo(\"main\", \"\uD83D\uDD04 Rebuilding transport...\");\n await buildTransport(ctx);\n if (ctx.pipelineDeps && ctx.transport) {\n (ctx.pipelineDeps as { transport: IKiroTransport }).transport = ctx.transport;\n }\n if (ctx.idleSave && ctx.transport) {\n (ctx.idleSave as unknown as { transport: IKiroTransport }).transport = ctx.transport;\n }\n logInfo(\"main\", \"\u2713 Transport rebuilt\");\n return \"ran\";\n}\n", "import { execSync } from \"node:child_process\";\nimport { writeFileSync, unlinkSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { IKiroTransport } from \"./kiro-transport.js\";\nimport { logInfo, logDebug, logWarn } from \"../logger.js\";\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { abtarsHome } from \"../../paths.js\";\n\nconst TAG = \"tmux\";\n\n// Kiro CLI prompt pattern: \"N% >\" or \"N% !>\" where N is a number (context usage percentage)\n// The \"!\" appears in trust-all-tools mode\nconst KIRO_PROMPT_RE = /^\\d+%\\s*!?>/;\n\n// Also match common shell prompts as fallback\nconst SHELL_PROMPT_RE = /[$\u276F%#]\\s*$/;\n\n/**\n * Communicates with kiro-cli running inside a tmux session.\n * Uses `tmux send-keys` to send prompts and `tmux capture-pane`\n * to read responses.\n */\nexport class TmuxClient implements IKiroTransport {\n private readonly sessionName: string;\n private readonly captureDelaySec: number;\n private readonly maxWaitSec: number;\n private ready = false;\n\n /** Optional callback for streaming intermediate responses before final prompt. */\n onIntermediateResponse?: (text: string) => void;\n\n /** Tracks the cumulative text delivered via intermediate chunks (for tail detection). */\n private lastIntermediateDelivered = \"\";\n\n constructor(sessionName: string, captureDelaySec: number, maxWaitSec: number) {\n this.sessionName = sessionName;\n this.captureDelaySec = captureDelaySec;\n this.maxWaitSec = maxWaitSec;\n }\n\n async initialize(): Promise<void> {\n if (!this.sessionExists()) {\n throw new Error(\n `tmux session \"${this.sessionName}\" not found. ` +\n `Run: scripts/tmux-session.sh to start it.`,\n );\n }\n this.ready = true;\n logInfo(\"tmux\", `Session \"${this.sessionName}\" found`);\n }\n\n get isReady(): boolean {\n return this.ready && this.sessionExists();\n }\n\n readonly transportCommands: string[] = [];\n\n async sendPrompt(_sessionKey: string, message: string): Promise<string> {\n if (!this.isReady) {\n throw new Error(\"tmux session not available\");\n }\n\n this.lastIntermediateDelivered = \"\";\n const maxAttempts = 2;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n // Snapshot pane content before sending\n const before = this.capturePaneRaw();\n if (attempt === 1) {\n logDebug(\"tmux\", `Sending: \"${message.slice(0, 80)}\"`);\n } else {\n logInfo(\"tmux\", `Retry #${attempt}: resending prompt`);\n }\n\n // Send the message \u2014 use temp file for long prompts to avoid tmux command length limit\n try {\n if (message.length > 4000) {\n const tmpDir = join(abtarsHome(), \"tmp\");\n mkdirSync(tmpDir, { recursive: true });\n const tmpFile = join(tmpDir, `prompt-${Date.now()}.txt`);\n writeFileSync(tmpFile, message);\n const readCmd = `My full message is in ${tmpFile} \u2014 please read it and respond.`;\n const escaped = readCmd.replace(/'/g, \"'\\\\''\");\n this.exec(`tmux send-keys -t ${this.sessionName} '${escaped}' Enter`);\n setTimeout(() => { try { unlinkSync(tmpFile); } catch (err) { logAndSwallow(TAG, \"unlink tmpFile\", err); } }, 120_000);\n } else {\n const escaped = message.replace(/'/g, \"'\\\\''\");\n this.exec(`tmux send-keys -t ${this.sessionName} '${escaped}' Enter`);\n }\n } catch (err) {\n logWarn(\"tmux\", `send-keys failed: ${err instanceof Error ? err.message : String(err)}`);\n return \"\u26A0\uFE0F Failed to send message to Kiro session. The tmux session may be in copy mode or unresponsive. Try /reset.\";\n }\n\n // Wait for initial processing\n await sleep(this.captureDelaySec * 1000);\n\n // Poll until Kiro finishes\n const response = await this.pollForResponse(before);\n\n // Check for Kiro transient error \u2014 retry once\n if (response.startsWith(\"Kiro is having trouble\") && attempt < maxAttempts) {\n logInfo(\"tmux\", `Kiro trouble detected, will retry in 5s...`);\n await sleep(5000);\n continue;\n }\n\n logDebug(\"tmux\", `Got response (${response.length} chars)`);\n return response;\n }\n\n // Should not reach here, but just in case\n return \"\u26A0\uFE0F Kiro is having trouble responding. Try again or /reset.\";\n }\n\n async resetSession(_sessionKey: string): Promise<void> {\n if (!this.sessionExists()) return;\n this.exec(`tmux send-keys -t ${this.sessionName} C-c`);\n await sleep(1000);\n this.exec(`tmux send-keys -t ${this.sessionName} '/clear' Enter`);\n await sleep(2000);\n // Kiro asks \"Are you sure? [y/n]:\" \u2014 confirm with 'y'\n this.exec(`tmux send-keys -t ${this.sessionName} 'y' Enter`);\n await sleep(1000);\n }\n\n async restartSession(workingDir: string, kiroModel?: string): Promise<void> {\n // Kill existing tmux session and start fresh\n if (this.sessionExists()) {\n this.exec(`tmux kill-session -t ${this.sessionName}`);\n await sleep(1000);\n }\n let cmd = `kiro-cli chat --trust-all-tools`;\n if (kiroModel) cmd += ` --model ${kiroModel}`;\n this.exec(`tmux new-session -d -s ${this.sessionName} -c '${workingDir}' '${cmd}'`);\n this.exec(`tmux set-option -t ${this.sessionName} history-limit 5000`);\n await sleep(3000);\n // Enable thinking tool\n this.exec(`tmux send-keys -t ${this.sessionName} '/settings chat.enableThinking true' Enter`);\n await sleep(2000);\n this.ready = this.sessionExists();\n logInfo(\"tmux\", `Session restarted (ready=${this.ready})`);\n }\n\n async sendInterrupt(): Promise<void> {\n if (!this.sessionExists()) return;\n logInfo(\"tmux\", \"Sending Ctrl+C interrupt\");\n this.exec(`tmux send-keys -t ${this.sessionName} C-c`);\n }\n\n destroy(): void {\n this.ready = false;\n }\n\n /**\n * Poll capture-pane until Kiro's prompt reappears (N% >).\n * Delivers intermediate purple-line responses via onIntermediateResponse callback\n * so the user sees partial answers while Kiro continues with tools.\n * Only returns when the actual Kiro prompt appears or timeout.\n */\n private async pollForResponse(beforeSnapshot: string): Promise<string> {\n const startTime = Date.now();\n const maxWaitMs = this.maxWaitSec * 1000;\n let lastCapture = \"\";\n let stableCount = 0;\n let lastDeliveredAnswer = \"\";\n\n while (Date.now() - startTime < maxWaitMs) {\n const capture = this.capturePaneRaw();\n\n // Get only the NEW content (diff from before)\n const newContent = this.diffOutput(beforeSnapshot, capture);\n\n if (newContent.length === 0) {\n await sleep(2000);\n continue;\n }\n\n // Check if the last non-empty line is a Kiro prompt (N% >)\n const lines = capture.split(\"\\n\");\n const lastNonEmpty = this.getLastNonEmptyLine(lines);\n const lastClean = this.stripAnsi(lastNonEmpty);\n\n if (KIRO_PROMPT_RE.test(lastClean)) {\n const pctMatch = lastClean.match(/^(\\d+)%/);\n if (pctMatch) {\n this.lastContextPercent = parseInt(pctMatch[1]!, 10);\n logDebug(\"tmux\", `Context window: ${this.lastContextPercent}%`);\n }\n logDebug(\"tmux\", `Detected Kiro prompt: \"${lastClean}\"`);\n return this.extractResponse(newContent);\n }\n\n // Check for shell prompt as fallback\n if (SHELL_PROMPT_RE.test(lastClean) && newContent.length > 10) {\n logDebug(\"tmux\", `Detected shell prompt: \"${lastClean}\"`);\n return this.extractResponse(newContent);\n }\n\n // No prompt yet \u2014 deliver intermediate answer if we have new purple lines\n if (this.onIntermediateResponse && capture !== lastCapture) {\n const intermediateAnswer = this.extractAnswerOnly(newContent);\n if (intermediateAnswer && intermediateAnswer !== lastDeliveredAnswer) {\n const newPart = intermediateAnswer.startsWith(lastDeliveredAnswer)\n ? intermediateAnswer.slice(lastDeliveredAnswer.length).trim()\n : intermediateAnswer;\n if (newPart) {\n logDebug(\"tmux\", `Delivering intermediate chunk (${newPart.length} chars)`);\n this.onIntermediateResponse(newPart);\n lastDeliveredAnswer = intermediateAnswer;\n this.lastIntermediateDelivered = intermediateAnswer;\n }\n }\n }\n\n // Track stabilization but do NOT return on it \u2014 only N% > ends the poll\n if (capture === lastCapture) {\n stableCount++;\n } else {\n stableCount = 0;\n lastCapture = capture;\n }\n\n await sleep(2000);\n }\n\n // Timeout\n const finalCapture = this.capturePaneRaw();\n const finalNew = this.diffOutput(beforeSnapshot, finalCapture);\n if (finalNew.length > 0) {\n return this.extractResponse(finalNew) + \"\\n\\n\u23F1\uFE0F (response may be incomplete \u2014 timed out)\";\n }\n return \"\u23F1\uFE0F Kiro is still processing. Check the tmux session directly.\";\n }\n\n /**\n * Extract the meaningful response from the diff.\n * Removes the echoed user input line and Kiro's prompt lines.\n * Stores the \"answer only\" portion (lines that were \"> \" prefixed)\n * separately for TTS use.\n *\n * Kiro output format:\n * N% > <echoed user input>\n * > <response line 1>\n * > <response line 2>\n * \u25B8 Time: Ns\n * M% >\n */\n private lastAnswerOnly = \"\";\n private lastContextPercent = -1;\n\n /** Get just the Kiro answer lines (\"> \" prefixed) from the last response \u2014 for TTS. */\n get answerOnly(): string {\n return this.lastAnswerOnly;\n }\n get toolCallsSucceeded(): number { return 0; }\n\n /** Get the context window usage percentage from the last Kiro prompt (e.g. 10 for \"10% >\"). Returns -1 if unknown. */\n get contextPercent(): number {\n return this.lastContextPercent;\n }\n /** Get the cumulative text that was delivered via intermediate streaming. */\n get intermediateDeliveredText(): string {\n return this.lastIntermediateDelivered;\n }\n\n /** Extract just the purple \"> \" answer lines from raw tmux output (no side effects). */\n private extractAnswerOnly(raw: string): string {\n const PURPLE_PREFIX = /\\x1b\\[38;5;141m>\\s/;\n const lines = raw.split(\"\\n\");\n\n // Find last contiguous block of purple lines\n let blockStart = -1;\n for (let i = lines.length - 1; i >= 0; i--) {\n if (PURPLE_PREFIX.test(lines[i]!)) {\n blockStart = i;\n while (blockStart > 0 && PURPLE_PREFIX.test(lines[blockStart - 1]!)) blockStart--;\n break;\n }\n }\n if (blockStart < 0) return \"\";\n\n const answerLines: string[] = [];\n for (let i = blockStart; i < lines.length; i++) {\n const clean = this.stripAnsi(lines[i]!).trim();\n if (KIRO_PROMPT_RE.test(clean)) break;\n if (clean.startsWith(\"\u25B8 Time:\")) break;\n if (clean.startsWith(\"> \")) answerLines.push(clean.slice(2));\n else if (clean === \">\") answerLines.push(\"\");\n else if (clean === \"\") answerLines.push(\"\");\n else answerLines.push(clean);\n }\n return answerLines.join(\"\\n\").trim();\n }\n\n private extractResponse(raw: string): string {\n // ANSI color 141 (light purple) marks the \"> \" prefix on actual LLM response lines.\n // We detect these BEFORE stripping ANSI to reliably distinguish LLM output from\n // injected context (gray, color 245) and other noise.\n const PURPLE_PREFIX = /\\x1b\\[38;5;141m>\\s/;\n\n const lines = raw.split(\"\\n\");\n\n // First pass: identify lines that are genuine LLM responses (purple \"> \" prefix)\n const answerLines: string[] = [];\n let lastPurpleBlockStart = -1;\n\n for (let i = 0; i < lines.length; i++) {\n if (PURPLE_PREFIX.test(lines[i]!)) {\n if (lastPurpleBlockStart === -1) lastPurpleBlockStart = i;\n }\n }\n\n // Find the LAST contiguous block of purple \"> \" lines \u2014 that's the real answer.\n // Walk backwards to find the start of the last block.\n let blockStart = -1;\n for (let i = lines.length - 1; i >= 0; i--) {\n if (PURPLE_PREFIX.test(lines[i]!)) {\n blockStart = i;\n // Keep walking back through contiguous purple lines and continuation lines\n while (blockStart > 0) {\n const prev = lines[blockStart - 1]!;\n if (PURPLE_PREFIX.test(prev) || (!KIRO_PROMPT_RE.test(this.stripAnsi(prev).trim()) && !prev.includes(\"\u25B8 Time:\") && this.stripAnsi(prev).trim() !== \"\" && !PURPLE_PREFIX.test(prev) && blockStart === i)) {\n // Only extend back through purple lines\n if (PURPLE_PREFIX.test(prev)) {\n blockStart--;\n } else {\n break;\n }\n } else {\n break;\n }\n }\n break;\n }\n }\n\n if (blockStart >= 0) {\n // Extract from the last purple block to the end, stripping ANSI and \"> \" prefix\n for (let i = blockStart; i < lines.length; i++) {\n const line = lines[i]!;\n const clean = this.stripAnsi(line).trim();\n // Stop at Kiro prompt or Time summary\n if (KIRO_PROMPT_RE.test(clean)) break;\n if (clean.startsWith(\"\u25B8 Time:\") || clean.startsWith(\"\u25B8 Time:\")) break;\n if (clean === \"\") {\n answerLines.push(\"\");\n continue;\n }\n // Strip \"> \" prefix\n if (clean.startsWith(\"> \")) {\n answerLines.push(clean.slice(2));\n } else if (clean === \">\") {\n answerLines.push(\"\");\n } else {\n answerLines.push(clean);\n }\n }\n this.lastAnswerOnly = answerLines.join(\"\\n\").trim();\n } else {\n this.lastAnswerOnly = \"\";\n }\n\n // Full response: strip ANSI, then remove prompt lines and noise (legacy behavior)\n const cleaned = this.stripAnsi(raw);\n const allLines = cleaned.split(\"\\n\");\n const result: string[] = [];\n\n for (const line of allLines) {\n const trimmed = line.trim();\n if (result.length === 0 && trimmed === \"\") continue;\n if (KIRO_PROMPT_RE.test(trimmed)) continue;\n if (trimmed.startsWith(\"\u25B8 Time:\") || trimmed.startsWith(\"\u25B8 Time:\")) continue;\n if (/^-{4,}$/.test(trimmed)) continue;\n result.push(line);\n }\n\n const stripped = result.map((line) => {\n const trimmed = line.trimStart();\n if (trimmed.startsWith(\"> \")) return trimmed.slice(2);\n if (trimmed === \">\") return \"\";\n return line;\n });\n\n const final = stripped.join(\"\\n\").trim();\n logDebug(\"tmux\", `extractResponse: ${result.length} lines \u2192 \"${final.slice(0, 120)}\"`);\n if (this.lastAnswerOnly) {\n logDebug(\"tmux\", `answerOnly (${this.lastAnswerOnly.length} chars): \"${this.lastAnswerOnly.slice(0, 120)}\"`);\n }\n return final;\n }\n\n /** Get new content by diffing before/after snapshots. */\n private diffOutput(before: string, after: string): string {\n const beforeLines = before.split(\"\\n\");\n const afterLines = after.split(\"\\n\");\n\n // Find where the new content starts\n let commonPrefix = 0;\n while (\n commonPrefix < beforeLines.length &&\n commonPrefix < afterLines.length &&\n beforeLines[commonPrefix] === afterLines[commonPrefix]\n ) {\n commonPrefix++;\n }\n\n return afterLines.slice(commonPrefix).join(\"\\n\").trim();\n }\n\n /** Get the last non-empty line from an array. */\n private getLastNonEmptyLine(lines: string[]): string {\n for (let i = lines.length - 1; i >= 0; i--) {\n const trimmed = lines[i]!.trim();\n if (trimmed.length > 0) return trimmed;\n }\n return \"\";\n }\n\n /** Strip ANSI escape codes. */\n private stripAnsi(text: string): string {\n // eslint-disable-next-line no-control-regex\n return text.replace(/\\x1B\\[[0-9;]*[a-zA-Z]/g, \"\")\n .replace(/\\x1B\\][^\\x07]*\\x07/g, \"\"); // OSC sequences\n }\n\n private capturePaneRaw(): string {\n try {\n return this.exec(`tmux capture-pane -t ${this.sessionName} -p -e -S -2000`);\n } catch (err) {\n logAndSwallow(TAG, \"capturePaneRaw\", err);\n return \"\";\n }\n }\n\n private sessionExists(): boolean {\n try {\n this.exec(`tmux has-session -t ${this.sessionName}`);\n return true;\n } catch (err) {\n logAndSwallow(TAG, \"sessionExists check\", err);\n return false;\n }\n }\n\n private exec(command: string): string {\n return execSync(command, {\n encoding: \"utf-8\",\n timeout: 15_000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["execSync", "TAG", "abtarsHome", "execSync", "join"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/components/transport/orc-tools.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * orc-tools.ts \u2014 Orc-specific tools for spawning/managing workers (#1005).\n *\n * Module-scoped activeOrcCardId \u2014 set by executeOrc before prompt, cleared in finally.\n * Tools always registered; return error if no active Orc project.\n */\n\nimport type { ToolDefinition } from \"./tool-registry.js\";\nimport { logInfo } from \"../logger.js\";\n\nconst TAG = \"orc-tools\";\n\nlet _activeOrcCardId: number | null = null;\n\nexport function setActiveOrcCard(id: number | null): void {\n _activeOrcCardId = id;\n}\n\nexport function getActiveOrcCard(): number | null {\n return _activeOrcCardId;\n}\n\n// \u2500\u2500 spawn_worker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst spawnWorkerTool: ToolDefinition = {\n name: \"spawn_worker\",\n description: \"Spawn a worker to execute a task in parallel. Workers run independently and report results.\",\n parameters: {\n type: \"object\",\n properties: {\n goal: { type: \"string\", description: \"What the worker should accomplish (detailed instruction)\" },\n title: { type: \"string\", description: \"Short label for the worker card (optional)\" },\n priority: { type: \"string\", description: \"CRITICAL | HIGH | MEDIUM | LOW\", enum: [\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"] },\n },\n required: [\"goal\"],\n },\n async execute(args: Record<string, string>): Promise<string> {\n if (!_activeOrcCardId) return \"[err] No active Orc project. spawn_worker only works during orchestration.\";\n const goal = args.goal;\n if (!goal) return \"[err] goal is required\";\n const { spin } = await import(\"../spin.js\");\n const cardId = spin.spawnChild(_activeOrcCardId, {\n goal,\n title: args.title || goal.slice(0, 40),\n source: \"agent\",\n priority: args.priority as any,\n });\n logInfo(TAG, `spawn_worker card:${cardId} parent:${_activeOrcCardId} \u2014 ${(args.title || goal).slice(0, 60)}`);\n return `+ Worker card #${cardId} created: \"${args.title || goal.slice(0, 40)}\"`;\n },\n};\n\n// \u2500\u2500 check_workers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst checkWorkersTool: ToolDefinition = {\n name: \"check_workers\",\n description: \"Check status of all workers on the current project. Returns their status and results.\",\n parameters: { type: \"object\", properties: {}, required: [] },\n async execute(): Promise<string> {\n if (!_activeOrcCardId) return \"[err] No active Orc project.\";\n const { kanbanGetChildren } = await import(\"../tasks/kanban-board.js\");\n const children = kanbanGetChildren(_activeOrcCardId);\n if (children.length === 0) return \"No workers spawned yet.\";\n const lines = children.map(c => {\n const icon = c.status === \"done\" ? \"*\" : c.status === \"running\" ? \"~\" : c.status === \"failed\" ? \"x\" : \"+\";\n const result = c.result_summary ? ` \u2014 ${c.result_summary.slice(0, 100)}` : \"\";\n const tokens = c.tokens_used ? ` (${c.tokens_used} tok)` : \"\";\n const source = c.type === \"remote\" ? (() => { try { return ` [${JSON.parse(c.notes ?? \"{}\").peer}]`; } catch { return \"\"; } })() : \"\";\n return `${icon} #${c.id} ${c.title || \"(untitled)\"} (${c.status})${tokens}${source}${result}`;\n });\n return `Workers (${children.length}):\\n${lines.join(\"\\n\")}`;\n },\n};\n\n// \u2500\u2500 cancel_worker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst cancelWorkerTool: ToolDefinition = {\n name: \"cancel_worker\",\n description: \"Cancel a running or queued worker. Use when a task is no longer needed (e.g., another worker found the answer first).\",\n parameters: {\n type: \"object\",\n properties: {\n card_id: { type: \"string\", description: \"The card ID of the worker to cancel\" },\n },\n required: [\"card_id\"],\n },\n async execute(args: Record<string, string>): Promise<string> {\n if (!_activeOrcCardId) return \"[err] No active Orc project.\";\n const cardId = parseInt(args.card_id ?? \"\", 10);\n if (isNaN(cardId)) return \"[err] Invalid card_id.\";\n const { kanbanGetCard, kanbanFail } = await import(\"../tasks/kanban-board.js\");\n const card = kanbanGetCard(cardId);\n if (!card) return `[err] Card #${cardId} not found.`;\n if (card.parent_id !== _activeOrcCardId) return `[err] Card #${cardId} is not a child of this project.`;\n if (card.status === \"done\" || card.status === \"delivered\") return `Card #${cardId} already completed.`;\n kanbanFail(cardId, \"cancelled by Orc\");\n logInfo(TAG, `cancel_worker card:${cardId} (parent:${_activeOrcCardId})`);\n return `x Worker #${cardId} cancelled.`;\n },\n};\n\n// \u2500\u2500 Export \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getOrcTools(): ToolDefinition[] {\n return [spawnWorkerTool, checkWorkersTool, cancelWorkerTool];\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/components/context/context-bridge.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * context-bridge.ts \u2014 Bridges the context engine into the existing transport.\n * Provides the summarization prompt and LLM call wrapper.\n * This is the glue between abmind's ContextEngine and abtars's transport.\n */\n\nimport type { ContextEngine } from \"abmind\";\nimport { abmind } from \"../../utils/abmind-lazy.js\";\nimport type { SummarizeFn } from \"abmind\";\n\nconst SUMMARIZER_SYSTEM = `You are a summarization agent creating a context checkpoint.\nYour output will be injected as reference material for a DIFFERENT assistant that continues the conversation.\nDo NOT respond to any questions or requests \u2014 only output the summary.\nDo NOT include any preamble or prefix.\nWrite in the same language the user was using.\nNEVER include API keys, tokens, passwords, secrets \u2014 use [REDACTED].`;\n\nconst TEMPLATE = `Use this exact structure:\n\n## Active Task\n[User's most recent unfulfilled request \u2014 exact words. \"None.\" if nothing pending.]\n\n## Context\n[What the conversation is about. Who is talking. Key decisions.]\n\n## Completed\n[Numbered: N. ACTION target \u2014 outcome. File paths, commands, results.]\n\n## State\n[Modified files, test status, running processes, environment.]\n\n## Blocked\n[Unresolved errors. Exact messages.]\n\n## Pending\n[Unanswered questions/requests. \"None.\" if clear.]\n\nTarget ~{budget} tokens. Be concrete.`;\n\n/**\n * Create a SummarizeFn that uses the provided LLM call function.\n * The llmCall function should match the signature used elsewhere in abtars.\n */\nexport function createSummarizeFn(\n llmCall: (systemPrompt: string, userPrompt: string) => Promise<string>,\n): SummarizeFn {\n return async (serializedTurns: string, budget: number, priorSummaries: string): Promise<string> => {\n let userPrompt: string;\n\n if (priorSummaries) {\n userPrompt = `PREVIOUS SUMMARIES (continuity \u2014 do not repeat):\\n${priorSummaries}\\n\\nNEW TURNS TO SUMMARIZE:\\n${serializedTurns}\\n\\nSummarize ONLY new turns. Update Active Task if changed.\\n\\n${TEMPLATE.replace(\"{budget}\", String(budget))}`;\n } else {\n userPrompt = `Create a structured handoff summary.\\n\\nTURNS TO SUMMARIZE:\\n${serializedTurns}\\n\\n${TEMPLATE.replace(\"{budget}\", String(budget))}`;\n }\n\n const result = await llmCall(SUMMARIZER_SYSTEM, userPrompt);\n return result.trim();\n };\n}\n\n/**\n * Create a fully configured ContextOrchestrator.\n * Call this once at bridge startup when memory + transport are available.\n */\nexport function createContextOrchestrator(\n contextEngine: ContextEngine,\n llmCall: (systemPrompt: string, userPrompt: string) => Promise<string>,\n getLastAssistantTimestamp: (chatId: string) => number | null,\n): any {\n const CO = abmind()!.ContextOrchestrator;\n return new CO({\n contextEngine,\n summarize: createSummarizeFn(llmCall),\n getLastAssistantTimestamp,\n });\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;AAUA,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAO1B,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BV,SAAS,kBACd,SACa;AACb,SAAO,OAAO,iBAAyB,QAAgB,mBAA4C;AACjG,QAAI;AAEJ,QAAI,gBAAgB;AAClB,mBAAa;AAAA,EAAqD,cAAc;AAAA;AAAA;AAAA,EAAgC,eAAe;AAAA;AAAA;AAAA;AAAA,EAAmE,SAAS,QAAQ,YAAY,OAAO,MAAM,CAAC,CAAC;AAAA,IAChP,OAAO;AACL,mBAAa;AAAA;AAAA;AAAA,EAAgE,eAAe;AAAA;AAAA,EAAO,SAAS,QAAQ,YAAY,OAAO,MAAM,CAAC,CAAC;AAAA,IACjJ;AAEA,UAAM,SAAS,MAAM,QAAQ,mBAAmB,UAAU;AAC1D,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAMO,SAAS,0BACd,eACA,SACA,2BACK;AACL,QAAM,KAAK,OAAO,EAAG;AACrB,SAAO,IAAI,GAAG;AAAA,IACZ;AAAA,IACA,WAAW,kBAAkB,OAAO;AAAA,IACpC;AAAA,EACF,CAAC;AACH;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/components/transport/direct-api-transport.ts", "../src/components/retry.ts", "../src/components/transport/conversation-session.ts", "../src/components/transport/sse-parser.ts", "../src/components/transport/transport-utils.ts"],
|
|
4
|
-
"sourcesContent": ["import { getEnv } from \"../env-schema.js\";\n/**\n * Direct API Transport \u2014 talks to any OpenAI-compatible endpoint.\n * Implements IKiroTransport with its own agent loop (send \u2192 stream \u2192 tools \u2192 loop).\n */\n\nimport { logInfo, logWarn, logError, logDebug, logTrace } from \"../logger.js\";\nimport { logAndSwallow } from \"../log-and-swallow.js\";\nimport { withRetry, isFatal } from \"../retry.js\";\nimport { ConversationSession, type ToolCall, type ContentPart } from \"./conversation-session.js\";\nimport { parseSSEStream, type SSEToolCallDelta } from \"./sse-parser.js\";\nimport { getToolSchemas, executeToolCall } from \"./tool-registry.js\";\nimport { classifyError } from \"./model-health-registry.js\";\nimport { normalizeToolCalls, parseErrorStatus, parseRetryAfter, parseUsageLimitCooldown } from \"./transport-utils.js\";\nimport { recordUsage } from \"../usage-tracker.js\";\nimport type { FallbackPolicy } from \"./fallback-policy.js\";\nimport type { IKiroTransport } from \"./kiro-transport.js\";\n\nconst TAG = \"direct-api\";\n\n\nexport interface DirectApiConfig {\n endpoint: string;\n apiKey?: string;\n model: string;\n maxContext: number;\n maxOutput: number;\n maxTurns: number;\n maxToolRounds?: number;\n apiFormat?: \"chat\" | \"responses\" | \"anthropic\";\n thinking?: { style: \"effort\"; default: string } | { style: \"extended\"; default: number };\n fallbacks?: Array<{ endpoint: string; apiKey?: string; model: string; maxContext?: number }>;\n}\n\n\nexport class DirectApiTransport implements IKiroTransport {\n private readonly config: DirectApiConfig;\n private readonly sessions = new Map<string, ConversationSession>();\n private readonly abortControllers = new Map<string, AbortController>();\n private systemPrompt = \"\";\n private _contextPercent = -1;\n private _lastAnswer = \"\";\n private _timeoutOverrideMs: number | null = null;\n private _maxToolRoundsOverride: number | null = null;\n private _toolCallsSucceeded = 0;\n private _intermediateText = \"\";\n private _promptStartedAt: number | null = null;\n private _lastActivityAt: number | null = null;\n private activeEndpoint: string;\n private activeApiKey?: string;\n private activeModel: string;\n private _lastPromptTokens = 0;\n private _lastCompletionTokens = 0;\n private _activeSessionKey = \"\";\n private _activeUserId = \"master\";\n\n /** Agent name for budget tracking (set by caller). */\n agentLabel = \"professor\";\n\n /** Currently active model (may differ from config if on fallback). */\n get currentModel(): string { return this.activeModel; }\n\n onIntermediateResponse?: (text: string) => void;\n onToolCallStart?: (toolName: string) => void;\n onSegmentBreak?: (text: string) => void;\n /** Sandbox policy for tool access control (#681). Set by pipeline before prompt. */\n sandboxPolicy?: import(\"../tool-sandbox.js\").SandboxPolicy;\n /** Called when fallback model is selected \u2014 send notification before response. */\n onFallback?: (model: string, ctxPercent: number, reason?: string) => void;\n /** Cooperative pause check \u2014 if returns true, agent loop breaks between tool calls. */\n isPaused?: () => boolean;\n /** Returns a pending instruction from parent, if any. Consumed once. */\n getPendingInstruction?: () => string | undefined;\n\n /** Context orchestrator \u2014 when set, messages are built from DB instead of in-memory session. */\n contextOrchestrator?: import(\"abmind\").ContextOrchestrator;\n\n /** Memory backend \u2014 used for hydrating sessions after restart (#843). */\n memoryBackend?: { getRecentConversation(userId: string, since: number, limit: number): Array<{ role: string; content: string; timestamp: number }> };\n\n private policy: FallbackPolicy | null;\n private emergencyOverride: { endpoint: string; apiKey?: string; model: string; maxContext: number } | null = null;\n\n /** Activate emergency (hailMary) mode \u2014 next prompts bypass the fallback policy. */\n setEmergencyMode(override: { endpoint: string; apiKey?: string; model: string; maxContext: number } | null): void {\n if (!override && !this.emergencyOverride) return; // no-op if already off\n this.emergencyOverride = override;\n if (override) logWarn(TAG, `\uD83D\uDEA8 EMERGENCY MODE: using ${override.model} (paid) \u2014 bypassing fallback chain`);\n else { this.activeModel = this.config.model; logInfo(TAG, `Emergency mode cleared \u2014 restored ${this.config.model}`); }\n }\n\n /** True if emergency (hailMary) mode is active. */\n get isEmergencyMode(): boolean { return this.emergencyOverride !== null; }\n\n constructor(config: DirectApiConfig, policy?: FallbackPolicy) {\n this.config = config;\n this.activeEndpoint = config.endpoint;\n this.activeApiKey = config.apiKey;\n this.activeModel = config.model;\n this.policy = policy ?? null;\n }\n\n async initialize(): Promise<void> {\n const count = this.policy ? this.policy.candidates.length : (this.config.fallbacks?.length ?? 0) + 1;\n const fb = count > 1 ? ` (+${count - 1} fallback${count > 2 ? \"s\" : \"\"})` : \"\";\n logInfo(TAG, `\uD83D\uDD0C Direct API transport (${this.config.endpoint}, model: ${this.config.model}${fb})`);\n }\n\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n }\n\n async sendPrompt(sessionKey: string, message: string, image?: { mime: string; base64: string }, userId?: string): Promise<string> {\n const session = this.getOrCreateSession(sessionKey);\n this._activeSessionKey = sessionKey;\n this._activeUserId = userId || \"master\";\n\n // If context orchestrator is active, rebuild messages from DB\n if (this.contextOrchestrator) {\n try {\n const ctx = await this.contextOrchestrator.getContext(sessionKey, this.config.maxContext);\n // Replace session messages with DB-backed context + system prompt\n session.messages = [\n { role: \"system\" as const, content: this.systemPrompt },\n ...ctx.messages.map((m: { role: string; content: string }) => ({ role: m.role as \"user\" | \"assistant\" | \"tool\", content: m.content })),\n ];\n if (ctx.compacted) logDebug(TAG, `Context compacted for ${sessionKey}`);\n } catch (err) {\n logWarn(TAG, `Context engine failed, falling back to in-memory: ${err}`);\n }\n }\n\n session.addUser(message, image);\n\n this._lastAnswer = \"\";\n this._toolCallsSucceeded = 0;\n this._intermediateText = \"\";\n this._promptStartedAt = Date.now();\n this._lastActivityAt = Date.now();\n\n const ac = new AbortController();\n this.abortControllers.set(sessionKey, ac);\n\n try {\n if (this.emergencyOverride) return await this.sendEmergency(session, ac.signal);\n if (!this.policy) throw new Error(\"DirectApiTransport requires a FallbackPolicy\");\n return await this.sendWithPolicy(session, ac.signal);\n } finally {\n // AfterPrompt hook \u2014 observe-only, fire-and-forget\n const durationMs = Date.now() - (this._promptStartedAt ?? Date.now());\n // #832: metrics\n import(\"../metrics-collector.js\").then(({ recordLatency, recordCall }) => {\n recordLatency(`llm:${this.activeModel}`, durationMs);\n recordCall(`llm:${this.activeModel}`, this._lastAnswer.length > 0);\n }).catch(() => {});\n import(\"../hooks/hook-system.js\").then(({ hasHooks, fire }) => {\n if (!hasHooks(\"AfterPrompt\")) return;\n fire(\"AfterPrompt\", {\n event: \"AfterPrompt\", timestamp: new Date().toISOString(),\n sessionKey, platform: \"\", userId: \"\",\n model: this.activeModel, durationMs,\n inputTokens: this._lastPromptTokens || null,\n outputTokens: null, // not tracked per-prompt in DirectApi\n }).catch(err => logAndSwallow(TAG, \"fire AfterPrompt\", err));\n }).catch(err => logAndSwallow(TAG, \"import hook-system\", err));\n this._promptStartedAt = null;\n this.abortControllers.delete(sessionKey);\n }\n }\n\n private async sendEmergency(session: ConversationSession, signal: AbortSignal): Promise<string> {\n const em = this.emergencyOverride!;\n this.activeEndpoint = em.endpoint;\n this.activeApiKey = em.apiKey;\n this.activeModel = em.model;\n this._lastActivityAt = Date.now();\n logWarn(TAG, `\uD83D\uDEA8 Emergency mode: using ${em.model}`);\n const result = await this.agentLoop(session, signal);\n this._lastAnswer = result;\n return result;\n }\n\n private async sendWithPolicy(session: ConversationSession, signal: AbortSignal): Promise<string> {\n const policy = this.policy!;\n const failedAttempts: Array<{ model: string; kind: string; bucket: number }> = [];\n const isPrimary = (m: string): boolean => m === this.config.model;\n\n // Try each candidate via policy\n let candidate = policy.selectModel(this._lastPromptTokens);\n while (candidate) {\n this.activeEndpoint = candidate.endpoint;\n this.activeApiKey = candidate.apiKey;\n this.activeModel = candidate.model;\n this._lastActivityAt = Date.now();\n logDebug(TAG, `Trying model: ${candidate.model}`);\n\n if (!isPrimary(candidate.model) && this.onFallback) {\n const ctxPct = candidate.maxContext > 0 ? Math.round((this._lastPromptTokens / candidate.maxContext) * 100) : -1;\n const lastFail = failedAttempts[failedAttempts.length - 1];\n this.onFallback(candidate.model, ctxPct, lastFail?.kind);\n }\n\n try {\n const result = await this.agentLoop(session, signal);\n this._lastAnswer = result;\n if (!result || !result.trim()) {\n policy.recordError(candidate, \"empty\");\n } else {\n policy.recordSuccess(candidate);\n }\n return result;\n } catch (err) {\n if (signal.aborted) { session.rollbackToLastUser(); throw err; }\n const errMsg = err instanceof Error ? err.message : String(err);\n // Capability miss \u2014 strip image and retry text-only (#670)\n if (errMsg.includes(\"does not support image input\") || errMsg.includes(\"No endpoints found that support image\")) {\n session.rollbackToLastUser();\n // Strip image parts from session, retry same model text-only\n for (const m of session.messages) {\n if (Array.isArray(m.content)) {\n const textParts = (m.content as Array<{ type: string; text?: string }>).filter(p => p.type === \"text\");\n m.content = textParts.map(p => p.text ?? \"\").join(\"\\n\") || \"User sent an image (not supported by this model).\";\n }\n }\n logWarn(TAG, `${candidate.model} doesn't support images \u2014 retrying text-only`);\n if (this.onIntermediateResponse) this.onIntermediateResponse(\"\u26A0\uFE0F Model doesn't support images via this provider. Sending text-only.\\n\");\n try {\n const result = await this.agentLoop(session, signal);\n this._lastAnswer = result;\n policy.recordSuccess(candidate);\n return result;\n } catch (retryErr) {\n const retryStatus = this.parseErrorStatus(retryErr);\n const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);\n policy.recordError(candidate, classifyError(retryStatus, retryMsg));\n session.rollbackToLastUser();\n throw retryErr;\n }\n }\n const status = this.parseErrorStatus(err);\n const kind = classifyError(status, errMsg);\n const retryAfterMs = this.parseRetryAfter(err) ?? parseUsageLimitCooldown(errMsg);\n policy.recordError(candidate, kind, retryAfterMs);\n const bucket = policy.registry.getBucketLevel(candidate.model, candidate.endpoint);\n failedAttempts.push({ model: candidate.model, kind, bucket });\n session.rollbackToLastUser();\n logWarn(TAG, `${candidate.model} failed (${kind}, bucket: ${bucket}%${retryAfterMs ? `, retry-after: ${Math.round(retryAfterMs / 1000)}s` : \"\"}): ${errMsg.slice(0, 100)}`);\n }\n\n candidate = policy.selectModel(this._lastPromptTokens);\n }\n\n // Compaction fallback: pick smallest surviving candidate, truncate to fit\n const surviving = policy.survivingCandidates()\n .filter(c => c.maxContext > 0)\n .sort((a, b) => a.maxContext - b.maxContext);\n const smallest = surviving[0];\n\n if (smallest && this._lastPromptTokens > smallest.maxContext * 0.95) {\n logWarn(TAG, `Compacting session to fit ${smallest.model} (${smallest.maxContext} tokens)`);\n session.truncateToFit(smallest.maxContext);\n this.activeEndpoint = smallest.endpoint;\n this.activeApiKey = smallest.apiKey;\n this.activeModel = smallest.model;\n if (this.onFallback) {\n this.onFallback(`${smallest.model} (compacted)`, Math.round((session.estimateTokens() / smallest.maxContext) * 100));\n }\n try {\n const result = await this.agentLoop(session, signal);\n this._lastAnswer = result;\n if (!result || !result.trim()) policy.recordError(smallest, \"empty\");\n else policy.recordSuccess(smallest);\n return result;\n } catch (err) {\n const status = this.parseErrorStatus(err);\n const errMsg2 = err instanceof Error ? err.message : String(err);\n policy.recordError(smallest, classifyError(status, errMsg2));\n failedAttempts.push({ model: smallest.model, kind: classifyError(status, errMsg2), bucket: policy.registry.getBucketLevel(smallest.model, smallest.endpoint) });\n }\n }\n\n const summary = failedAttempts.map(a => ` - ${a.model}: ${a.kind} (bucket: ${a.bucket}%)`).join(\"\\n\");\n if (policy.lastDecision) {\n logDebug(TAG, `Last decision: ${JSON.stringify(policy.lastDecision)}`);\n }\n throw new Error(`All models exhausted:\\n${summary}`);\n }\n\n private async agentLoop(session: ConversationSession, signal: AbortSignal): Promise<string> {\n let zeroTokenRetries = 0;\n const loopStart = Date.now();\n const callSigs: string[] = []; // #1133: track across turns for loop detection\n for (let turn = 0; turn < this.config.maxTurns; turn++) {\n if (signal.aborted) return signal.reason === \"timeout\" ? \"Response timed out.\" : \"Interrupted.\";\n if (this.isPaused?.()) return \"\u23F8 Session paused. Use `/session resume` to continue.\";\n if (turn >= (this._maxToolRoundsOverride ?? this.config.maxToolRounds ?? 25)) {\n logError(TAG, `Tool loop circuit breaker: ${turn} rounds without final response \u2014 aborting`);\n return \"[SYSTEM] Tool loop limit reached. Stopped after \" + turn + \" rounds.\";\n }\n\n const pendingInstruction = this.getPendingInstruction?.();\n if (pendingInstruction) session.addUser(pendingInstruction);\n\n const { content, toolCalls, usage } = await this.streamCompletion(session, signal);\n\n if (usage) {\n session.updateTokens(usage.prompt_tokens);\n this._contextPercent = session.contextPercent;\n this._lastPromptTokens = usage.prompt_tokens;\n this._lastCompletionTokens = usage.completion_tokens ?? 0;\n this.contextOrchestrator?.onApiResponse(this._activeSessionKey, usage.prompt_tokens, this.config.maxContext);\n logTrace(TAG, `${this.activeModel} \u2014 ${usage.prompt_tokens}\u2192${usage.completion_tokens ?? 0} tokens, ${Date.now() - (this._lastActivityAt ?? Date.now())}ms`);\n recordUsage(this.activeModel, usage.prompt_tokens, usage.completion_tokens ?? 0, this.agentLabel);\n }\n\n if (toolCalls.length > 0) {\n session.addAssistant(content, toolCalls);\n logDebug(TAG, `Tool calls: ${toolCalls.map(tc => tc.function.name).join(\", \")}`);\n logTrace(TAG, `Tool args: ${toolCalls.map(tc => {\n // #621: redact abmind_store args based on classification\n if ((tc.function.name === \"abmind_store\" || tc.function.name === \"memory_store\") && /class(?:ification)?[\":\\s]+[23]/.test(tc.function.arguments)) {\n return `${tc.function.name}([REDACTED])`;\n }\n return `${tc.function.name}(${tc.function.arguments})`;\n }).join(\", \")}`);\n\n // Deliver pre-tool text immediately (segment break)\n if (content?.trim()) {\n this.onSegmentBreak?.(content.trim());\n }\n\n // #1133: Track tool call signatures for loop detection\n for (let ti = 0; ti < toolCalls.length; ti++) {\n const tc = toolCalls[ti]!;\n if (signal.aborted) {\n // #1003: inject cancelled results for remaining tools \u2014 keeps conversation valid\n for (const remaining of toolCalls.slice(ti)) {\n session.addToolResult(remaining.id, remaining.function.name,\n `[SYSTEM] Cancelled \u2014 ${remaining.function.name} skipped due to user interrupt`);\n }\n return signal.reason === \"timeout\" ? \"Response timed out.\" : \"Interrupted.\";\n }\n this._lastActivityAt = Date.now();\n\n // #948: drain /wait between batched tool calls\n const mid = this.getPendingInstruction?.();\n if (mid) session.addUser(mid);\n\n this.onToolCallStart?.(tc.function.name ?? \"tool\");\n\n let args: Record<string, string>;\n try { args = JSON.parse(tc.function.arguments); } catch {\n // #1133: Reject malformed args \u2014 never execute with broken arguments\n const errMsg = `Tool call rejected: malformed arguments (JSON parse error). Reformat and retry.`;\n logWarn(TAG, `Malformed tool args for ${tc.function.name}: ${tc.function.arguments.slice(0, 80)}`);\n session.addToolResult(tc.id, tc.function.name, JSON.stringify({ error: errMsg }));\n continue;\n }\n\n // #1133: Loop detection \u2014 abort if same call (name+args hash) repeats 3x across turns\n const { createHash } = await import(\"node:crypto\");\n const sig = `${tc.function.name}:${createHash(\"sha256\").update(tc.function.arguments).digest(\"hex\").slice(0, 8)}`;\n callSigs.push(sig);\n if (callSigs.filter(s => s === sig).length >= 3) {\n logWarn(TAG, `Tool loop detected: ${tc.function.name} repeated 3x \u2014 aborting`);\n session.addToolResult(tc.id, tc.function.name, JSON.stringify({ error: \"[SYSTEM] Repeated identical tool call detected (3x). Stop retrying and provide a final text response to the user.\" }));\n break;\n }\n\n const result = await executeToolCall(tc.function.name, args, { userId: this._activeUserId, signal, sandboxPolicy: this.sandboxPolicy });\n session.addToolResult(tc.id, tc.function.name, result);\n\n // #621: scrub secret values from conversation history after store\n if ((tc.function.name === \"abmind_store\" || tc.function.name === \"memory_store\") && parseInt(args.classification ?? args.class ?? \"1\", 10) >= 2) {\n const secretValue = args.content ?? args.value ?? args.translated;\n if (secretValue && secretValue.length > 4) {\n session.scrubFromHistory(secretValue);\n }\n }\n\n try { if (!JSON.parse(result).error) this._toolCallsSucceeded++; } catch (err) { logAndSwallow(TAG, \"JSON.parse tool result\", err); this._toolCallsSucceeded++; }\n }\n continue;\n }\n\n // No tool calls \u2014 final response\n const answer = content ?? \"\";\n // Budget-aware backoff on 0\u21920 token response (#732)\n if (!answer && usage && usage.prompt_tokens === 0) {\n const elapsed = Date.now() - loopStart;\n const remaining = (this._timeoutOverrideMs ?? getEnv().modelApiTimeoutMs) - elapsed;\n const retryDelay = 5000 + (zeroTokenRetries * 3000);\n if (remaining > retryDelay + 5000) {\n zeroTokenRetries++;\n logWarn(TAG, `API returned 0 tokens \u2014 retry #${zeroTokenRetries} after ${retryDelay / 1000}s (${Math.round(remaining / 1000)}s left)`);\n await new Promise(r => setTimeout(r, retryDelay));\n continue;\n }\n }\n session.addAssistant(answer);\n return answer;\n }\n\n logWarn(TAG, `Max turns (${this.config.maxTurns}) reached`);\n const last = session.messages.at(-1)?.content;\n return (typeof last === \"string\" ? last : null) ?? \"(max turns reached)\";\n }\n\n private parseErrorStatus(err: unknown): number { return parseErrorStatus(err); }\n\n /** Extract Retry-After from error (seconds or date). Returns ms or undefined. */\n private parseRetryAfter(err: unknown): number | undefined { return parseRetryAfter(err); }\n\n private async streamCompletion(\n session: ConversationSession,\n signal: AbortSignal,\n ): Promise<{ content: string | null; toolCalls: ToolCall[]; usage: { prompt_tokens: number; completion_tokens: number } | null }> {\n // Compose pipeline signal (user /stop) with per-request timeout (silence-based)\n const timeoutCtrl = new AbortController();\n const timeoutMs = this._timeoutOverrideMs ?? getEnv().modelApiTimeoutMs;\n this._lastActivityAt = Date.now();\n const timer = setInterval(() => {\n if (Date.now() - (this._lastActivityAt ?? 0) > timeoutMs) {\n clearInterval(timer);\n timeoutCtrl.abort(new Error(\"model API timeout\"));\n }\n }, 5000);\n const composed = AbortSignal.any([signal, timeoutCtrl.signal]);\n\n try {\n // Responses API format (#465, streaming #472)\n if (this.config.apiFormat === \"responses\") {\n const { toResponsesRequest } = await import(\"./responses-adapter.js\");\n const { parseResponsesSSE } = await import(\"./sse-parser-responses.js\");\n const msgs = session.messages.map(m => ({ role: m.role, content: m.content ?? \"\" as string | ContentPart[] }));\n const reqBody = { ...toResponsesRequest(this.activeModel, msgs, getToolSchemas(this.sandboxPolicy), this.config.maxOutput), stream: true };\n const hdrs: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (this.activeApiKey) hdrs[\"Authorization\"] = `Bearer ${this.activeApiKey}`;\n const res = await fetch(`${this.activeEndpoint}/responses`, {\n method: \"POST\", headers: hdrs, body: JSON.stringify(reqBody), signal: composed,\n });\n if (!res.ok) { const text = await res.text().catch(err => { logAndSwallow(TAG, \"read error body\", err); return \"\"; }); throw new Error(`API error ${res.status}: ${text.slice(0, 500)}`); }\n\n let content = \"\";\n let usage: { prompt_tokens: number; completion_tokens: number } | null = null;\n const toolCallAcc = new Map<string, { id: string; name: string; arguments: string }>();\n for await (const event of parseResponsesSSE(res, composed)) {\n this._lastActivityAt = Date.now();\n if (event.type === \"chunk\") { content += event.content; this._intermediateText += event.content; this.onIntermediateResponse?.(event.content); }\n else if (event.type === \"tool_call_delta\") { this.accumulateToolCall(toolCallAcc, event); }\n else if (event.type === \"done\") { usage = event.usage; }\n }\n clearInterval(timer);\n const toolCalls = this.finalizeToolCalls(toolCallAcc);\n return { content: content || null, toolCalls, usage };\n }\n\n // Anthropic Messages API format (#467, streaming #472)\n if (this.config.apiFormat === \"anthropic\") {\n const { toAnthropicRequest, buildAnthropicHeaders } = await import(\"./anthropic-adapter.js\");\n const { parseAnthropicSSE } = await import(\"./sse-parser-anthropic.js\");\n const msgs = session.messages.map(m => ({ role: m.role, content: m.content ?? \"\" as string | ContentPart[], tool_call_id: m.tool_call_id }));\n const reqBody = { ...toAnthropicRequest(this.activeModel, msgs, this.config.maxOutput, getToolSchemas(this.sandboxPolicy)), stream: true };\n const hdrs = buildAnthropicHeaders(this.activeApiKey ?? \"\");\n const res = await fetch(`${this.activeEndpoint}/messages`, {\n method: \"POST\", headers: hdrs, body: JSON.stringify(reqBody), signal: composed,\n });\n if (!res.ok) { const text = await res.text().catch(err => { logAndSwallow(TAG, \"read error body\", err); return \"\"; }); throw new Error(`API error ${res.status}: ${text.slice(0, 500)}`); }\n\n let content = \"\";\n let usage: { prompt_tokens: number; completion_tokens: number } | null = null;\n const toolCallAcc = new Map<string, { id: string; name: string; arguments: string }>();\n for await (const event of parseAnthropicSSE(res, composed)) {\n this._lastActivityAt = Date.now();\n if (event.type === \"chunk\") { content += event.content; this._intermediateText += event.content; this.onIntermediateResponse?.(event.content); }\n else if (event.type === \"tool_call_delta\") { this.accumulateToolCall(toolCallAcc, event); }\n else if (event.type === \"done\") { usage = event.usage; }\n }\n clearInterval(timer);\n const toolCalls = this.finalizeToolCalls(toolCallAcc);\n return { content: content || null, toolCalls, usage };\n }\n\n const body: Record<string, unknown> = {\n model: this.activeModel,\n messages: session.messages,\n tools: getToolSchemas(this.sandboxPolicy),\n max_tokens: this.config.maxOutput,\n stream: true,\n stream_options: { include_usage: true },\n };\n\n // #466: inject thinking/reasoning parameters\n if (this.config.thinking) {\n if (this.config.thinking.style === \"effort\") {\n body.reasoning_effort = this.config.thinking.default;\n } else if (this.config.thinking.style === \"extended\") {\n body.thinking = { type: \"enabled\", budget_tokens: this.config.thinking.default };\n }\n }\n // #869: session-level reasoning override (from /reasoning command)\n if (session.reasoningEffort) {\n const BUDGET_MAP: Record<string, number> = { low: 1024, medium: 4096, high: 16384 };\n if ((this.config.apiFormat as string) === \"anthropic\") {\n body.thinking = { type: \"enabled\", budget_tokens: BUDGET_MAP[session.reasoningEffort] ?? 4096 };\n } else {\n body.reasoning_effort = session.reasoningEffort;\n }\n }\n\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (this.activeApiKey) headers[\"Authorization\"] = `Bearer ${this.activeApiKey}`;\n\n const response = await withRetry(\n async () => {\n const res = await fetch(`${this.activeEndpoint}/chat/completions`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: composed,\n });\n if (!res.ok) {\n const text = await res.text().catch(err => { logAndSwallow(TAG, \"read error body\", err); return \"\"; });\n throw new Error(`API error ${res.status}: ${text.slice(0, 500)}`);\n }\n return res;\n },\n {\n attempts: 3, minDelayMs: 3000,\n isRecoverable: (err) => {\n const msg = err instanceof Error ? err.message : String(err);\n if (/model API timeout/.test(msg)) return false;\n // Don't retry 429/401/402/403 \u2014 let the bucket loop handle model switching\n if (/API error (429|401|402|403)/.test(msg)) return false;\n return !isFatal(err);\n },\n },\n );\n\n let content = \"\";\n const toolCallAccumulator = new Map<string, { id: string; name: string; arguments: string }>();\n let usage: { prompt_tokens: number; completion_tokens: number } | null = null;\n\n for await (const event of parseSSEStream(response, composed)) {\n this._lastActivityAt = Date.now();\n\n switch (event.type) {\n case \"chunk\":\n content += event.content;\n this._intermediateText += event.content;\n this.onIntermediateResponse?.(event.content);\n break;\n\n case \"tool_call_delta\":\n this.accumulateToolCall(toolCallAccumulator, event);\n break;\n\n case \"done\":\n usage = event.usage;\n break;\n }\n }\n\n const toolCalls = this.finalizeToolCalls(toolCallAccumulator);\n\n return { content: content || null, toolCalls, usage };\n } finally {\n clearInterval(timer);\n }\n }\n\n /** Accumulate streaming tool call deltas by ID (Ollama-safe: tracks by ID not index). */\n private accumulateToolCall(\n acc: Map<string, { id: string; name: string; arguments: string }>,\n delta: SSEToolCallDelta,\n ): void {\n // Use ID if available, fall back to index-based key\n const key = delta.id ?? `idx:${delta.index}`;\n const existing = acc.get(key);\n if (existing) {\n if (delta.arguments) existing.arguments += delta.arguments;\n } else {\n acc.set(key, { id: delta.id ?? `call_${acc.size}`, name: delta.name ?? \"\", arguments: delta.arguments ?? \"\" });\n }\n }\n\n /**\n * Convert accumulated tool call map \u2192 normalized ToolCall array.\n * Handles model fragmentation: some models (nemotron, mistral-free) split a\n * single tool call across multiple SSE entries with different indices/IDs.\n * Pattern: [name=\"execute_bash\" args=\"{}\"], [name=\"\" args=\"\"], [name=\"\" args='{\"command\":\"...\"}']\n * Fix: merge adjacent unnamed entries' args into the preceding named entry.\n */\n private finalizeToolCalls(acc: Map<string, { id: string; name: string; arguments: string }>): ToolCall[] {\n const raw: ToolCall[] = [...acc.values()].map(tc => ({\n id: tc.id, type: \"function\" as const, function: { name: tc.name, arguments: tc.arguments },\n }));\n return normalizeToolCalls(raw);\n }\n\n private getOrCreateSession(sessionKey: string): ConversationSession {\n let session = this.sessions.get(sessionKey);\n if (!session) {\n session = new ConversationSession(this.systemPrompt, this.config.maxContext);\n this.sessions.set(sessionKey, session);\n }\n return session;\n }\n\n async resetSession(sessionKey: string): Promise<void> {\n const session = this.sessions.get(sessionKey);\n if (session) session.reset(this.systemPrompt);\n else this.sessions.delete(sessionKey);\n logInfo(TAG, `Session ${sessionKey} reset`);\n }\n\n async sendInterrupt(reason?: string): Promise<void> {\n for (const ac of this.abortControllers.values()) ac.abort(reason ?? \"user\");\n }\n\n destroy(): void {\n for (const ac of this.abortControllers.values()) ac.abort();\n this.sessions.clear();\n this.abortControllers.clear();\n }\n\n get isReady(): boolean { return true; }\n get contextPercent(): number { return this._contextPercent; }\n get answerOnly(): string { return this._lastAnswer; }\n getActiveSession(): ConversationSession | null { return this.sessions.get(this._activeSessionKey) ?? null; }\n get toolCallsSucceeded(): number { return this._toolCallsSucceeded; }\n\n lastUsage(): { input: number; output: number } | null {\n return this._lastPromptTokens || this._lastCompletionTokens\n ? { input: this._lastPromptTokens, output: this._lastCompletionTokens }\n : null;\n }\n\n /** Hot-swap the active model. Takes effect on next API call. */\n setModel(model: string): void {\n this.activeModel = model;\n (this.config as { model: string }).model = model;\n logInfo(TAG, `Model switched (user): ${model}`);\n }\n\n /** Hot-swap provider+model+policy. Rejects if prompt is in flight. */\n switchProvider(opts: { endpoint: string; apiKey?: string; model: string; maxContext: number; policy: FallbackPolicy }): void {\n if (this._promptStartedAt !== null) {\n throw new Error(\"Cannot switch provider while a prompt is in progress \u2014 try after the response\");\n }\n this.activeEndpoint = opts.endpoint;\n this.activeApiKey = opts.apiKey;\n this.activeModel = opts.model;\n (this.config as { model: string; maxContext: number }).model = opts.model;\n (this.config as { maxContext: number }).maxContext = opts.maxContext;\n this.policy = opts.policy;\n logInfo(TAG, `Provider switched: ${opts.model} @ ${opts.endpoint} (maxCtx=${opts.maxContext})`);\n }\n\n /** Get current active model name. */\n getModel(): string { return this.activeModel; }\n get intermediateDeliveredText(): string { return this._intermediateText; }\n get transportCommands(): string[] { return []; }\n\n // Watchdog support\n get promptStartedAt(): number | null { return this._promptStartedAt; }\n setTimeoutOverride(ms: number | null): void { this._timeoutOverrideMs = ms; }\n setMaxToolRoundsOverride(n: number | null): void { this._maxToolRoundsOverride = n; }\n\n get lastActivityAt(): number | null { return this._lastActivityAt; }\n\n private readonly _stuckTimeout = getEnv().watchdogSilentSec * 1000;\n\n async healthCheck(): Promise<void> {\n if (!this._promptStartedAt) return;\n const idle = Date.now() - (this._lastActivityAt ?? this._promptStartedAt);\n if (idle > this._stuckTimeout) {\n logWarn(TAG, `[transport-health] Prompt stuck (${Math.round(idle / 1000)}s idle) \u2014 aborting`);\n await this.sendInterrupt();\n }\n }\n}\n", "/**\n * Generic retry utility with escalating backoff, jitter, and fatal error detection.\n */\n\nexport interface RetryPolicy {\n /** Max attempts (including first). Default: 3 */\n attempts?: number;\n /** Initial delay in ms. Default: 300 */\n minDelayMs?: number;\n /** Max delay cap in ms. Default: 30_000 */\n maxDelayMs?: number;\n /** Jitter factor 0-1 (0.1 = \u00B110%). Default: 0.1 */\n jitter?: number;\n /** Return false to stop retrying (fatal error). Default: always retry. */\n isRecoverable?: (err: unknown) => boolean;\n /** Extract delay hint from error (e.g. rate limit header). */\n getDelayHint?: (err: unknown) => number | undefined;\n /** Called before each retry. */\n onAttempt?: (info: { attempt: number; maxAttempts: number; err: unknown; delayMs: number }) => void;\n}\n\nconst DEFAULTS = { attempts: 3, minDelayMs: 300, maxDelayMs: 30_000, jitter: 0.1 };\n\n/** Known-fatal error patterns \u2014 don't retry these. */\nexport const FATAL_PATTERNS = [\n /auth.*fail|invalid.*key|unauthorized/i,\n /model.*not found|not supported/i,\n /account.*suspended|quota.*exceeded/i,\n /bot was blocked/i,\n];\n\n/** Check if an error matches a known-fatal pattern. */\nexport function isFatal(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err);\n return FATAL_PATTERNS.some(p => p.test(msg));\n}\n\n/** Execute `fn` with retry, escalating backoff, and jitter. */\nexport async function withRetry<T>(fn: () => Promise<T>, policy?: RetryPolicy): Promise<T> {\n const attempts = Math.max(1, policy?.attempts ?? DEFAULTS.attempts);\n const minDelay = Math.max(0, policy?.minDelayMs ?? DEFAULTS.minDelayMs);\n const maxDelay = Math.max(minDelay, policy?.maxDelayMs ?? DEFAULTS.maxDelayMs);\n const jitter = Math.max(0, Math.min(1, policy?.jitter ?? DEFAULTS.jitter));\n const isRecoverable = policy?.isRecoverable ?? ((err: unknown) => !isFatal(err));\n\n let lastErr: unknown;\n for (let i = 0; i < attempts; i++) {\n try {\n return await fn();\n } catch (err) {\n lastErr = err;\n if (i === attempts - 1) break;\n if (!isRecoverable(err)) break;\n\n const hint = policy?.getDelayHint?.(err);\n const baseDelay = hint ?? Math.min(maxDelay, minDelay * Math.pow(2, i));\n const offset = jitter > 0 ? (Math.random() * 2 - 1) * jitter * baseDelay : 0;\n const delayMs = Math.max(0, Math.round(baseDelay + offset));\n\n policy?.onAttempt?.({ attempt: i + 1, maxAttempts: attempts, err, delayMs });\n await new Promise(r => setTimeout(r, delayMs));\n }\n }\n throw lastErr;\n}\n", "/**\n * Per-session conversation state for DirectApiTransport.\n * Manages message history and token tracking.\n */\n\nexport type ContentPart =\n | { type: \"text\"; text: string }\n | { type: \"image_url\"; image_url: { url: string } };\n\nexport type ChatMessage = {\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | ContentPart[] | null;\n tool_calls?: ToolCall[];\n tool_call_id?: string;\n name?: string;\n};\n\nexport type ToolCall = {\n id: string;\n type: \"function\";\n function: { name: string; arguments: string };\n};\n\nexport class ConversationSession {\n messages: ChatMessage[] = [];\n totalPromptTokens = 0;\n reasoningEffort: \"low\" | \"medium\" | \"high\" | null = null;\n showReasoning = false;\n private readonly maxContext: number;\n\n constructor(systemPrompt: string, maxContext: number) {\n this.maxContext = maxContext;\n this.messages.push({ role: \"system\", content: systemPrompt });\n }\n\n addUser(content: string, image?: { mime: string; base64: string }): void {\n if (image) {\n this.messages.push({ role: \"user\", content: [\n { type: \"image_url\", image_url: { url: `data:${image.mime};base64,${image.base64}` } },\n { type: \"text\", text: content },\n ]});\n } else {\n this.messages.push({ role: \"user\", content });\n }\n }\n\n addAssistant(content: string | null, toolCalls?: ToolCall[]): void {\n const msg: ChatMessage = { role: \"assistant\", content };\n if (toolCalls?.length) msg.tool_calls = toolCalls;\n this.messages.push(msg);\n }\n\n addToolResult(toolCallId: string, name: string, content: string): void {\n this.messages.push({ role: \"tool\", content, tool_call_id: toolCallId, name });\n }\n\n updateTokens(promptTokens: number): void {\n this.totalPromptTokens = promptTokens;\n }\n\n get contextPercent(): number {\n if (this.maxContext <= 0) return 0;\n return Math.round((this.totalPromptTokens / this.maxContext) * 100);\n }\n\n reset(systemPrompt: string): void {\n this.messages = [{ role: \"system\", content: systemPrompt }];\n this.totalPromptTokens = 0;\n this.reasoningEffort = null;\n this.showReasoning = false;\n }\n\n /** Roll back to last user message \u2014 remove everything after it for clean fallback. */\n rollbackToLastUser(): void {\n for (let i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i]!.role === \"user\") {\n this.messages.splice(i + 1);\n return;\n }\n }\n }\n\n /** Rough token estimate: ~4 chars per token. */\n estimateTokens(): number {\n return Math.round(this.messages.reduce((sum, m) => sum + (typeof m.content === \"string\" ? m.content.length : 0), 0) / 4);\n }\n\n /** Drop oldest non-system messages until estimated tokens fit within limit. */\n truncateToFit(maxTokens: number): void {\n while (this.messages.length > 2 && this.estimateTokens() > maxTokens * 0.85) {\n this.messages.splice(1, 1); // remove oldest after system prompt\n }\n this.totalPromptTokens = this.estimateTokens();\n }\n\n /** #621: Replace a literal secret value with [REDACTED] across all messages. */\n scrubFromHistory(value: string): void {\n for (const msg of this.messages) {\n if (typeof msg.content === \"string\" && msg.content.includes(value)) {\n msg.content = msg.content.replaceAll(value, \"[REDACTED]\");\n }\n }\n }\n}\n", "/**\n * SSE stream parser for OpenAI-compatible chat completions.\n * Parses Server-Sent Events into typed events.\n */\n\nimport { logAndSwallow } from \"../log-and-swallow.js\";\n\nconst TAG = \"sse_parser\";\n\nexport type SSEChunkEvent = { type: \"chunk\"; content: string };\nexport type SSEToolCallDelta = { type: \"tool_call_delta\"; index: number; id?: string; name?: string; arguments?: string };\nexport type SSEDoneEvent = { type: \"done\"; usage: { prompt_tokens: number; completion_tokens: number } | null };\nexport type SSEEvent = SSEChunkEvent | SSEToolCallDelta | SSEDoneEvent;\n\nconst STALE_TIMEOUT_MS = 90_000;\n\nexport async function* parseSSEStream(\n response: Response,\n signal: AbortSignal,\n): AsyncGenerator<SSEEvent> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"Response body is not readable\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n let lastChunkAt = Date.now();\n let staleTimer: ReturnType<typeof setTimeout> | null = null;\n\n const resetStaleTimer = (): void => {\n lastChunkAt = Date.now();\n if (staleTimer) clearTimeout(staleTimer);\n staleTimer = setTimeout(() => {\n if (Date.now() - lastChunkAt >= STALE_TIMEOUT_MS) {\n reader.cancel(\"stale stream\").catch(err => logAndSwallow(TAG, \"reader.cancel stale\", err));\n }\n }, STALE_TIMEOUT_MS);\n };\n\n try {\n resetStaleTimer();\n while (true) {\n if (signal.aborted) break;\n const { done, value } = await reader.read();\n if (done) break;\n\n resetStaleTimer();\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n if (data === \"[DONE]\") return;\n\n let parsed: Record<string, unknown>;\n try { parsed = JSON.parse(data); } catch (err) { logAndSwallow(TAG, \"JSON.parse SSE chunk\", err); continue; }\n\n // Usage in final chunk (stream_options: { include_usage: true })\n if (parsed[\"usage\"]) {\n const u = parsed[\"usage\"] as Record<string, number>;\n yield { type: \"done\", usage: { prompt_tokens: u[\"prompt_tokens\"] ?? 0, completion_tokens: u[\"completion_tokens\"] ?? 0 } };\n }\n\n const choices = parsed[\"choices\"] as Array<Record<string, unknown>> | undefined;\n if (!choices?.length) continue;\n const delta = choices[0]![\"delta\"] as Record<string, unknown> | undefined;\n if (!delta) continue;\n\n // Text content\n if (typeof delta[\"content\"] === \"string\" && delta[\"content\"]) {\n yield { type: \"chunk\", content: delta[\"content\"] as string };\n }\n\n // Tool calls\n const toolCalls = delta[\"tool_calls\"] as Array<Record<string, unknown>> | undefined;\n if (toolCalls) {\n for (const tc of toolCalls) {\n const fn = tc[\"function\"] as Record<string, string> | undefined;\n yield {\n type: \"tool_call_delta\",\n index: (tc[\"index\"] as number) ?? 0,\n id: tc[\"id\"] as string | undefined,\n name: fn?.[\"name\"],\n arguments: fn?.[\"arguments\"],\n };\n }\n }\n }\n }\n } finally {\n if (staleTimer) clearTimeout(staleTimer);\n reader.releaseLock();\n }\n}\n", "/**\n * transport-utils.ts \u2014 Pure utility functions for the transport layer.\n * No I/O, no state, no side effects (except logging).\n */\n\nimport { logWarn } from \"../logger.js\";\nimport type { ToolCall } from \"./conversation-session.js\";\n\nconst TAG = \"direct-api\";\n\n/**\n * Normalize tool calls from models that fragment a single call across multiple entries.\n * Pattern: [name=\"execute_bash\" args=\"{}\"], [name=\"\" args=\"\"], [name=\"\" args='{\"command\":\"...\"}']\n * Fix: merge next unnamed entry's args into preceding named entry. Drop remaining unnamed.\n */\nexport function normalizeToolCalls(raw: ToolCall[]): ToolCall[] {\n if (raw.length <= 1) return raw;\n\n const result: ToolCall[] = [];\n for (let i = 0; i < raw.length; i++) {\n const tc = raw[i]!;\n if (tc.function.name) {\n if (!tc.function.arguments || tc.function.arguments === \"{}\") {\n // Look ahead for the next unnamed entry with real args\n for (let j = i + 1; j < raw.length; j++) {\n const next = raw[j]!;\n if (next.function.name) break; // hit another named entry, stop\n if (next.function.arguments && next.function.arguments !== \"{}\") {\n tc.function.arguments = next.function.arguments;\n i = j; // skip all entries up to and including the merged one\n break;\n }\n }\n }\n result.push(tc);\n }\n }\n\n if (result.length !== raw.length) {\n logWarn(TAG, `Normalized ${raw.length} tool call entries \u2192 ${result.length} (model fragmentation): ${raw.map(tc => `${tc.function.name || \"(unnamed)\"}(${tc.function.arguments.slice(0, 60)})`).join(\", \")}`);\n }\n return result;\n}\n\n/** Extract HTTP status code from error message. Returns 0 if not found. */\nexport function parseErrorStatus(err: unknown): number {\n const msg = err instanceof Error ? err.message : String(err);\n const m = /API error (\\d+)/.exec(msg);\n return m ? parseInt(m[1]!, 10) : 0;\n}\n\n/** Extract Retry-After from error (seconds or date). Returns ms or undefined. */\nexport function parseRetryAfter(err: unknown): number | undefined {\n const msg = err instanceof Error ? err.message : String(err);\n const jsonMatch = /retry[_-]after[\"\\s:]+(\\d+(?:\\.\\d+)?)/i.exec(msg);\n if (jsonMatch) return Math.ceil(parseFloat(jsonMatch[1]!) * 1000);\n const resetMatch = /x-ratelimit-reset[\"\\s:]+(\\d{10,13})/i.exec(msg);\n if (resetMatch) {\n const ts = parseInt(resetMatch[1]!, 10);\n const ms = ts < 1e12 ? ts * 1000 : ts;\n const delta = ms - Date.now();\n return delta > 0 ? delta : undefined;\n }\n return undefined;\n}\n\n/** Detect \"day/week/month limit\" in error message and return cooldown ms. */\nexport function parseUsageLimitCooldown(message: string): number | undefined {\n const lower = message.toLowerCase();\n if (!lower.includes(\"limit\")) return undefined;\n if (lower.includes(\"day\")) {\n const tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n tomorrow.setHours(0, 0, 0, 0);\n return tomorrow.getTime() - Date.now();\n }\n if (lower.includes(\"week\")) {\n const now = new Date();\n const daysUntilMonday = (8 - now.getDay()) % 7 || 7;\n const monday = new Date(now);\n monday.setDate(monday.getDate() + daysUntilMonday);\n monday.setHours(0, 0, 0, 0);\n return monday.getTime() - Date.now();\n }\n if (lower.includes(\"month\")) {\n const now = new Date();\n const nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1);\n return nextMonth.getTime() - Date.now();\n }\n return undefined;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAMA;AACA;;;ACcA,IAAM,WAAW,EAAE,UAAU,GAAG,YAAY,KAAK,YAAY,KAAQ,QAAQ,IAAI;AAG1E,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,SAAS,QAAQ,KAAuB;AAC7C,QAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,SAAO,eAAe,KAAK,OAAK,EAAE,KAAK,GAAG,CAAC;AAC7C;AAGA,eAAsB,UAAa,IAAsB,QAAkC;AACzF,QAAM,WAAW,KAAK,IAAI,GAAG,QAAQ,YAAY,SAAS,QAAQ;AAClE,QAAM,WAAW,KAAK,IAAI,GAAG,QAAQ,cAAc,SAAS,UAAU;AACtE,QAAM,WAAW,KAAK,IAAI,UAAU,QAAQ,cAAc,SAAS,UAAU;AAC7E,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,UAAU,SAAS,MAAM,CAAC;AACzE,QAAM,gBAAgB,QAAQ,kBAAkB,CAAC,QAAiB,CAAC,QAAQ,GAAG;AAE9E,MAAI;AACJ,WAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,KAAK;AACZ,gBAAU;AACV,UAAI,MAAM,WAAW,EAAG;AACxB,UAAI,CAAC,cAAc,GAAG,EAAG;AAEzB,YAAM,OAAO,QAAQ,eAAe,GAAG;AACvC,YAAM,YAAY,QAAQ,KAAK,IAAI,UAAU,WAAW,KAAK,IAAI,GAAG,CAAC,CAAC;AACtE,YAAM,SAAS,SAAS,KAAK,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS,YAAY;AAC3E,YAAM,UAAU,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,MAAM,CAAC;AAE1D,cAAQ,YAAY,EAAE,SAAS,IAAI,GAAG,aAAa,UAAU,KAAK,QAAQ,CAAC;AAC3E,YAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,OAAO,CAAC;AAAA,IAC/C;AAAA,EACF;AACA,QAAM;AACR;;;ACzCO,IAAM,sBAAN,MAA0B;AAAA,EAC/B,WAA0B,CAAC;AAAA,EAC3B,oBAAoB;AAAA,EACpB,kBAAoD;AAAA,EACpD,gBAAgB;AAAA,EACC;AAAA,EAEjB,YAAY,cAAsB,YAAoB;AACpD,SAAK,aAAa;AAClB,SAAK,SAAS,KAAK,EAAE,MAAM,UAAU,SAAS,aAAa,CAAC;AAAA,EAC9D;AAAA,EAEA,QAAQ,SAAiB,OAAgD;AACvE,QAAI,OAAO;AACT,WAAK,SAAS,KAAK,EAAE,MAAM,QAAQ,SAAS;AAAA,QAC1C,EAAE,MAAM,aAAa,WAAW,EAAE,KAAK,QAAQ,MAAM,IAAI,WAAW,MAAM,MAAM,GAAG,EAAE;AAAA,QACrF,EAAE,MAAM,QAAQ,MAAM,QAAQ;AAAA,MAChC,EAAC,CAAC;AAAA,IACJ,OAAO;AACL,WAAK,SAAS,KAAK,EAAE,MAAM,QAAQ,QAAQ,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,aAAa,SAAwB,WAA8B;AACjE,UAAM,MAAmB,EAAE,MAAM,aAAa,QAAQ;AACtD,QAAI,WAAW,OAAQ,KAAI,aAAa;AACxC,SAAK,SAAS,KAAK,GAAG;AAAA,EACxB;AAAA,EAEA,cAAc,YAAoB,MAAc,SAAuB;AACrE,SAAK,SAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAc,YAAY,KAAK,CAAC;AAAA,EAC9E;AAAA,EAEA,aAAa,cAA4B;AACvC,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,IAAI,iBAAyB;AAC3B,QAAI,KAAK,cAAc,EAAG,QAAO;AACjC,WAAO,KAAK,MAAO,KAAK,oBAAoB,KAAK,aAAc,GAAG;AAAA,EACpE;AAAA,EAEA,MAAM,cAA4B;AAChC,SAAK,WAAW,CAAC,EAAE,MAAM,UAAU,SAAS,aAAa,CAAC;AAC1D,SAAK,oBAAoB;AACzB,SAAK,kBAAkB;AACvB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAGA,qBAA2B;AACzB,aAAS,IAAI,KAAK,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAClD,UAAI,KAAK,SAAS,CAAC,EAAG,SAAS,QAAQ;AACrC,aAAK,SAAS,OAAO,IAAI,CAAC;AAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,iBAAyB;AACvB,WAAO,KAAK,MAAM,KAAK,SAAS,OAAO,CAAC,KAAK,MAAM,OAAO,OAAO,EAAE,YAAY,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC,IAAI,CAAC;AAAA,EACzH;AAAA;AAAA,EAGA,cAAc,WAAyB;AACrC,WAAO,KAAK,SAAS,SAAS,KAAK,KAAK,eAAe,IAAI,YAAY,MAAM;AAC3E,WAAK,SAAS,OAAO,GAAG,CAAC;AAAA,IAC3B;AACA,SAAK,oBAAoB,KAAK,eAAe;AAAA,EAC/C;AAAA;AAAA,EAGA,iBAAiB,OAAqB;AACpC,eAAW,OAAO,KAAK,UAAU;AAC/B,UAAI,OAAO,IAAI,YAAY,YAAY,IAAI,QAAQ,SAAS,KAAK,GAAG;AAClE,YAAI,UAAU,IAAI,QAAQ,WAAW,OAAO,YAAY;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AACF;;;AClGA;AAEA,IAAM,MAAM;AAOZ,IAAM,mBAAmB;AAEzB,gBAAuB,eACrB,UACA,QAC0B;AAC1B,QAAM,SAAS,SAAS,MAAM,UAAU;AACxC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AAE5D,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AACb,MAAI,cAAc,KAAK,IAAI;AAC3B,MAAI,aAAmD;AAEvD,QAAM,kBAAkB,MAAY;AAClC,kBAAc,KAAK,IAAI;AACvB,QAAI,WAAY,cAAa,UAAU;AACvC,iBAAa,WAAW,MAAM;AAC5B,UAAI,KAAK,IAAI,IAAI,eAAe,kBAAkB;AAChD,eAAO,OAAO,cAAc,EAAE,MAAM,SAAO,cAAc,KAAK,uBAAuB,GAAG,CAAC;AAAA,MAC3F;AAAA,IACF,GAAG,gBAAgB;AAAA,EACrB;AAEA,MAAI;AACF,oBAAgB;AAChB,WAAO,MAAM;AACX,UAAI,OAAO,QAAS;AACpB,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,sBAAgB;AAChB,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAEhD,YAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,WAAW,QAAQ,EAAG;AAChC,cAAM,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK;AAChC,YAAI,SAAS,SAAU;AAEvB,YAAI;AACJ,YAAI;AAAE,mBAAS,KAAK,MAAM,IAAI;AAAA,QAAG,SAAS,KAAK;AAAE,wBAAc,KAAK,wBAAwB,GAAG;AAAG;AAAA,QAAU;AAG5G,YAAI,OAAO,OAAO,GAAG;AACnB,gBAAM,IAAI,OAAO,OAAO;AACxB,gBAAM,EAAE,MAAM,QAAQ,OAAO,EAAE,eAAe,EAAE,eAAe,KAAK,GAAG,mBAAmB,EAAE,mBAAmB,KAAK,EAAE,EAAE;AAAA,QAC1H;AAEA,cAAM,UAAU,OAAO,SAAS;AAChC,YAAI,CAAC,SAAS,OAAQ;AACtB,cAAM,QAAQ,QAAQ,CAAC,EAAG,OAAO;AACjC,YAAI,CAAC,MAAO;AAGZ,YAAI,OAAO,MAAM,SAAS,MAAM,YAAY,MAAM,SAAS,GAAG;AAC5D,gBAAM,EAAE,MAAM,SAAS,SAAS,MAAM,SAAS,EAAY;AAAA,QAC7D;AAGA,cAAM,YAAY,MAAM,YAAY;AACpC,YAAI,WAAW;AACb,qBAAW,MAAM,WAAW;AAC1B,kBAAM,KAAK,GAAG,UAAU;AACxB,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,OAAQ,GAAG,OAAO,KAAgB;AAAA,cAClC,IAAI,GAAG,IAAI;AAAA,cACX,MAAM,KAAK,MAAM;AAAA,cACjB,WAAW,KAAK,WAAW;AAAA,YAC7B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,UAAE;AACA,QAAI,WAAY,cAAa,UAAU;AACvC,WAAO,YAAY;AAAA,EACrB;AACF;;;AC1FA;AAGA,IAAMA,OAAM;AAOL,SAAS,mBAAmB,KAA6B;AAC9D,MAAI,IAAI,UAAU,EAAG,QAAO;AAE5B,QAAM,SAAqB,CAAC;AAC5B,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAM,KAAK,IAAI,CAAC;AAChB,QAAI,GAAG,SAAS,MAAM;AACpB,UAAI,CAAC,GAAG,SAAS,aAAa,GAAG,SAAS,cAAc,MAAM;AAE5D,iBAAS,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACvC,gBAAM,OAAO,IAAI,CAAC;AAClB,cAAI,KAAK,SAAS,KAAM;AACxB,cAAI,KAAK,SAAS,aAAa,KAAK,SAAS,cAAc,MAAM;AAC/D,eAAG,SAAS,YAAY,KAAK,SAAS;AACtC,gBAAI;AACJ;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO,KAAK,EAAE;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,IAAI,QAAQ;AAChC,YAAQA,MAAK,cAAc,IAAI,MAAM,6BAAwB,OAAO,MAAM,2BAA2B,IAAI,IAAI,QAAM,GAAG,GAAG,SAAS,QAAQ,WAAW,IAAI,GAAG,SAAS,UAAU,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC9M;AACA,SAAO;AACT;AAGO,SAAS,iBAAiB,KAAsB;AACrD,QAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,QAAM,IAAI,kBAAkB,KAAK,GAAG;AACpC,SAAO,IAAI,SAAS,EAAE,CAAC,GAAI,EAAE,IAAI;AACnC;AAGO,SAAS,gBAAgB,KAAkC;AAChE,QAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,QAAM,YAAY,wCAAwC,KAAK,GAAG;AAClE,MAAI,UAAW,QAAO,KAAK,KAAK,WAAW,UAAU,CAAC,CAAE,IAAI,GAAI;AAChE,QAAM,aAAa,uCAAuC,KAAK,GAAG;AAClE,MAAI,YAAY;AACd,UAAM,KAAK,SAAS,WAAW,CAAC,GAAI,EAAE;AACtC,UAAM,KAAK,KAAK,OAAO,KAAK,MAAO;AACnC,UAAM,QAAQ,KAAK,KAAK,IAAI;AAC5B,WAAO,QAAQ,IAAI,QAAQ;AAAA,EAC7B;AACA,SAAO;AACT;AAGO,SAAS,wBAAwB,SAAqC;AAC3E,QAAM,QAAQ,QAAQ,YAAY;AAClC,MAAI,CAAC,MAAM,SAAS,OAAO,EAAG,QAAO;AACrC,MAAI,MAAM,SAAS,KAAK,GAAG;AACzB,UAAM,WAAW,oBAAI,KAAK;AAC1B,aAAS,QAAQ,SAAS,QAAQ,IAAI,CAAC;AACvC,aAAS,SAAS,GAAG,GAAG,GAAG,CAAC;AAC5B,WAAO,SAAS,QAAQ,IAAI,KAAK,IAAI;AAAA,EACvC;AACA,MAAI,MAAM,SAAS,MAAM,GAAG;AAC1B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,mBAAmB,IAAI,IAAI,OAAO,KAAK,KAAK;AAClD,UAAM,SAAS,IAAI,KAAK,GAAG;AAC3B,WAAO,QAAQ,OAAO,QAAQ,IAAI,eAAe;AACjD,WAAO,SAAS,GAAG,GAAG,GAAG,CAAC;AAC1B,WAAO,OAAO,QAAQ,IAAI,KAAK,IAAI;AAAA,EACrC;AACA,MAAI,MAAM,SAAS,OAAO,GAAG;AAC3B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,YAAY,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC;AACnE,WAAO,UAAU,QAAQ,IAAI,KAAK,IAAI;AAAA,EACxC;AACA,SAAO;AACT;;;AJxEA,IAAMC,OAAM;AAiBL,IAAM,qBAAN,MAAmD;AAAA,EACvC;AAAA,EACA,WAAW,oBAAI,IAAiC;AAAA,EAChD,mBAAmB,oBAAI,IAA6B;AAAA,EAC7D,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,qBAAoC;AAAA,EACpC,yBAAwC;AAAA,EACxC,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,mBAAkC;AAAA,EAClC,kBAAiC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,gBAAgB;AAAA;AAAA,EAGxB,aAAa;AAAA;AAAA,EAGb,IAAI,eAAuB;AAAE,WAAO,KAAK;AAAA,EAAa;AAAA,EAEtD;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA,EAEQ;AAAA,EACA,oBAAqG;AAAA;AAAA,EAG7G,iBAAiB,UAAiG;AAChH,QAAI,CAAC,YAAY,CAAC,KAAK,kBAAmB;AAC1C,SAAK,oBAAoB;AACzB,QAAI,SAAU,SAAQA,MAAK,mCAA4B,SAAS,KAAK,yCAAoC;AAAA,SACpG;AAAE,WAAK,cAAc,KAAK,OAAO;AAAO,cAAQA,MAAK,0CAAqC,KAAK,OAAO,KAAK,EAAE;AAAA,IAAG;AAAA,EACvH;AAAA;AAAA,EAGA,IAAI,kBAA2B;AAAE,WAAO,KAAK,sBAAsB;AAAA,EAAM;AAAA,EAEzE,YAAY,QAAyB,QAAyB;AAC5D,SAAK,SAAS;AACd,SAAK,iBAAiB,OAAO;AAC7B,SAAK,eAAe,OAAO;AAC3B,SAAK,cAAc,OAAO;AAC1B,SAAK,SAAS,UAAU;AAAA,EAC1B;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,QAAQ,KAAK,SAAS,KAAK,OAAO,WAAW,UAAU,KAAK,OAAO,WAAW,UAAU,KAAK;AACnG,UAAM,KAAK,QAAQ,IAAI,MAAM,QAAQ,CAAC,YAAY,QAAQ,IAAI,MAAM,EAAE,MAAM;AAC5E,YAAQA,MAAK,mCAA4B,KAAK,OAAO,QAAQ,YAAY,KAAK,OAAO,KAAK,GAAG,EAAE,GAAG;AAAA,EACpG;AAAA,EAEA,gBAAgB,QAAsB;AACpC,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,MAAM,WAAW,YAAoB,SAAiB,OAA0C,QAAkC;AAChI,UAAM,UAAU,KAAK,mBAAmB,UAAU;AAClD,SAAK,oBAAoB;AACzB,SAAK,gBAAgB,UAAU;AAG/B,QAAI,KAAK,qBAAqB;AAC5B,UAAI;AACF,cAAM,MAAM,MAAM,KAAK,oBAAoB,WAAW,YAAY,KAAK,OAAO,UAAU;AAExF,gBAAQ,WAAW;AAAA,UACjB,EAAE,MAAM,UAAmB,SAAS,KAAK,aAAa;AAAA,UACtD,GAAG,IAAI,SAAS,IAAI,CAAC,OAA0C,EAAE,MAAM,EAAE,MAAuC,SAAS,EAAE,QAAQ,EAAE;AAAA,QACvI;AACA,YAAI,IAAI,UAAW,UAASA,MAAK,yBAAyB,UAAU,EAAE;AAAA,MACxE,SAAS,KAAK;AACZ,gBAAQA,MAAK,qDAAqD,GAAG,EAAE;AAAA,MACzE;AAAA,IACF;AAEA,YAAQ,QAAQ,SAAS,KAAK;AAE9B,SAAK,cAAc;AACnB,SAAK,sBAAsB;AAC3B,SAAK,oBAAoB;AACzB,SAAK,mBAAmB,KAAK,IAAI;AACjC,SAAK,kBAAkB,KAAK,IAAI;AAEhC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,SAAK,iBAAiB,IAAI,YAAY,EAAE;AAExC,QAAI;AACF,UAAI,KAAK,kBAAmB,QAAO,MAAM,KAAK,cAAc,SAAS,GAAG,MAAM;AAC9E,UAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,8CAA8C;AAChF,aAAO,MAAM,KAAK,eAAe,SAAS,GAAG,MAAM;AAAA,IACrD,UAAE;AAEA,YAAM,aAAa,KAAK,IAAI,KAAK,KAAK,oBAAoB,KAAK,IAAI;AAEnE,aAAO,iCAAyB,EAAE,KAAK,CAAC,EAAE,eAAe,WAAW,MAAM;AACxE,sBAAc,OAAO,KAAK,WAAW,IAAI,UAAU;AACnD,mBAAW,OAAO,KAAK,WAAW,IAAI,KAAK,YAAY,SAAS,CAAC;AAAA,MACnE,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACjB,aAAO,2BAAyB,EAAE,KAAK,CAAC,EAAE,UAAU,KAAK,MAAM;AAC7D,YAAI,CAAC,SAAS,aAAa,EAAG;AAC9B,aAAK,eAAe;AAAA,UAClB,OAAO;AAAA,UAAe,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UACxD;AAAA,UAAY,UAAU;AAAA,UAAI,QAAQ;AAAA,UAClC,OAAO,KAAK;AAAA,UAAa;AAAA,UACzB,aAAa,KAAK,qBAAqB;AAAA,UACvC,cAAc;AAAA;AAAA,QAChB,CAAC,EAAE,MAAM,SAAO,cAAcA,MAAK,oBAAoB,GAAG,CAAC;AAAA,MAC7D,CAAC,EAAE,MAAM,SAAO,cAAcA,MAAK,sBAAsB,GAAG,CAAC;AAC7D,WAAK,mBAAmB;AACxB,WAAK,iBAAiB,OAAO,UAAU;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,SAA8B,QAAsC;AAC9F,UAAM,KAAK,KAAK;AAChB,SAAK,iBAAiB,GAAG;AACzB,SAAK,eAAe,GAAG;AACvB,SAAK,cAAc,GAAG;AACtB,SAAK,kBAAkB,KAAK,IAAI;AAChC,YAAQA,MAAK,mCAA4B,GAAG,KAAK,EAAE;AACnD,UAAM,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM;AACnD,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,SAA8B,QAAsC;AAC/F,UAAM,SAAS,KAAK;AACpB,UAAM,iBAAyE,CAAC;AAChF,UAAM,YAAY,CAAC,MAAuB,MAAM,KAAK,OAAO;AAG5D,QAAI,YAAY,OAAO,YAAY,KAAK,iBAAiB;AACzD,WAAO,WAAW;AAChB,WAAK,iBAAiB,UAAU;AAChC,WAAK,eAAe,UAAU;AAC9B,WAAK,cAAc,UAAU;AAC7B,WAAK,kBAAkB,KAAK,IAAI;AAChC,eAASA,MAAK,iBAAiB,UAAU,KAAK,EAAE;AAEhD,UAAI,CAAC,UAAU,UAAU,KAAK,KAAK,KAAK,YAAY;AAClD,cAAM,SAAS,UAAU,aAAa,IAAI,KAAK,MAAO,KAAK,oBAAoB,UAAU,aAAc,GAAG,IAAI;AAC9G,cAAM,WAAW,eAAe,eAAe,SAAS,CAAC;AACzD,aAAK,WAAW,UAAU,OAAO,QAAQ,UAAU,IAAI;AAAA,MACzD;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM;AACnD,aAAK,cAAc;AACnB,YAAI,CAAC,UAAU,CAAC,OAAO,KAAK,GAAG;AAC7B,iBAAO,YAAY,WAAW,OAAO;AAAA,QACvC,OAAO;AACL,iBAAO,cAAc,SAAS;AAAA,QAChC;AACA,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,YAAI,OAAO,SAAS;AAAE,kBAAQ,mBAAmB;AAAG,gBAAM;AAAA,QAAK;AAC/D,cAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAE9D,YAAI,OAAO,SAAS,8BAA8B,KAAK,OAAO,SAAS,uCAAuC,GAAG;AAC/G,kBAAQ,mBAAmB;AAE3B,qBAAW,KAAK,QAAQ,UAAU;AAChC,gBAAI,MAAM,QAAQ,EAAE,OAAO,GAAG;AAC5B,oBAAM,YAAa,EAAE,QAAmD,OAAO,OAAK,EAAE,SAAS,MAAM;AACrG,gBAAE,UAAU,UAAU,IAAI,OAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,IAAI,KAAK;AAAA,YAC7D;AAAA,UACF;AACA,kBAAQA,MAAK,GAAG,UAAU,KAAK,mDAA8C;AAC7E,cAAI,KAAK,uBAAwB,MAAK,uBAAuB,mFAAyE;AACtI,cAAI;AACF,kBAAM,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM;AACnD,iBAAK,cAAc;AACnB,mBAAO,cAAc,SAAS;AAC9B,mBAAO;AAAA,UACT,SAAS,UAAU;AACjB,kBAAM,cAAc,KAAK,iBAAiB,QAAQ;AAClD,kBAAM,WAAW,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ;AAC/E,mBAAO,YAAY,WAAW,cAAc,aAAa,QAAQ,CAAC;AAClE,oBAAQ,mBAAmB;AAC3B,kBAAM;AAAA,UACR;AAAA,QACF;AACA,cAAM,SAAS,KAAK,iBAAiB,GAAG;AACxC,cAAM,OAAO,cAAc,QAAQ,MAAM;AACzC,cAAM,eAAe,KAAK,gBAAgB,GAAG,KAAK,wBAAwB,MAAM;AAChF,eAAO,YAAY,WAAW,MAAM,YAAY;AAChD,cAAM,SAAS,OAAO,SAAS,eAAe,UAAU,OAAO,UAAU,QAAQ;AACjF,uBAAe,KAAK,EAAE,OAAO,UAAU,OAAO,MAAM,OAAO,CAAC;AAC5D,gBAAQ,mBAAmB;AAC3B,gBAAQA,MAAK,GAAG,UAAU,KAAK,YAAY,IAAI,aAAa,MAAM,IAAI,eAAe,kBAAkB,KAAK,MAAM,eAAe,GAAI,CAAC,MAAM,EAAE,MAAM,OAAO,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,MAC5K;AAEA,kBAAY,OAAO,YAAY,KAAK,iBAAiB;AAAA,IACvD;AAGA,UAAM,YAAY,OAAO,oBAAoB,EAC1C,OAAO,OAAK,EAAE,aAAa,CAAC,EAC5B,KAAK,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,UAAU;AAC7C,UAAM,WAAW,UAAU,CAAC;AAE5B,QAAI,YAAY,KAAK,oBAAoB,SAAS,aAAa,MAAM;AACnE,cAAQA,MAAK,6BAA6B,SAAS,KAAK,KAAK,SAAS,UAAU,UAAU;AAC1F,cAAQ,cAAc,SAAS,UAAU;AACzC,WAAK,iBAAiB,SAAS;AAC/B,WAAK,eAAe,SAAS;AAC7B,WAAK,cAAc,SAAS;AAC5B,UAAI,KAAK,YAAY;AACnB,aAAK,WAAW,GAAG,SAAS,KAAK,gBAAgB,KAAK,MAAO,QAAQ,eAAe,IAAI,SAAS,aAAc,GAAG,CAAC;AAAA,MACrH;AACA,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM;AACnD,aAAK,cAAc;AACnB,YAAI,CAAC,UAAU,CAAC,OAAO,KAAK,EAAG,QAAO,YAAY,UAAU,OAAO;AAAA,YAC9D,QAAO,cAAc,QAAQ;AAClC,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,cAAM,SAAS,KAAK,iBAAiB,GAAG;AACxC,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,YAAY,UAAU,cAAc,QAAQ,OAAO,CAAC;AAC3D,uBAAe,KAAK,EAAE,OAAO,SAAS,OAAO,MAAM,cAAc,QAAQ,OAAO,GAAG,QAAQ,OAAO,SAAS,eAAe,SAAS,OAAO,SAAS,QAAQ,EAAE,CAAC;AAAA,MAChK;AAAA,IACF;AAEA,UAAM,UAAU,eAAe,IAAI,OAAK,OAAO,EAAE,KAAK,KAAK,EAAE,IAAI,aAAa,EAAE,MAAM,IAAI,EAAE,KAAK,IAAI;AACrG,QAAI,OAAO,cAAc;AACvB,eAASA,MAAK,kBAAkB,KAAK,UAAU,OAAO,YAAY,CAAC,EAAE;AAAA,IACvE;AACA,UAAM,IAAI,MAAM;AAAA,EAA0B,OAAO,EAAE;AAAA,EACrD;AAAA,EAEA,MAAc,UAAU,SAA8B,QAAsC;AAC1F,QAAI,mBAAmB;AACvB,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,WAAqB,CAAC;AAC5B,aAAS,OAAO,GAAG,OAAO,KAAK,OAAO,UAAU,QAAQ;AACtD,UAAI,OAAO,QAAS,QAAO,OAAO,WAAW,YAAY,wBAAwB;AACjF,UAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,UAAI,SAAS,KAAK,0BAA0B,KAAK,OAAO,iBAAiB,KAAK;AAC5E,iBAASA,MAAK,8BAA8B,IAAI,gDAA2C;AAC3F,eAAO,qDAAqD,OAAO;AAAA,MACrE;AAEA,YAAM,qBAAqB,KAAK,wBAAwB;AACxD,UAAI,mBAAoB,SAAQ,QAAQ,kBAAkB;AAE1D,YAAM,EAAE,SAAS,WAAW,MAAM,IAAI,MAAM,KAAK,iBAAiB,SAAS,MAAM;AAEjF,UAAI,OAAO;AACT,gBAAQ,aAAa,MAAM,aAAa;AACxC,aAAK,kBAAkB,QAAQ;AAC/B,aAAK,oBAAoB,MAAM;AAC/B,aAAK,wBAAwB,MAAM,qBAAqB;AACxD,aAAK,qBAAqB,cAAc,KAAK,mBAAmB,MAAM,eAAe,KAAK,OAAO,UAAU;AAC3G,iBAASA,MAAK,GAAG,KAAK,WAAW,WAAM,MAAM,aAAa,SAAI,MAAM,qBAAqB,CAAC,YAAY,KAAK,IAAI,KAAK,KAAK,mBAAmB,KAAK,IAAI,EAAE,IAAI;AAC3J,oBAAY,KAAK,aAAa,MAAM,eAAe,MAAM,qBAAqB,GAAG,KAAK,UAAU;AAAA,MAClG;AAEA,UAAI,UAAU,SAAS,GAAG;AACxB,gBAAQ,aAAa,SAAS,SAAS;AACvC,iBAASA,MAAK,eAAe,UAAU,IAAI,QAAM,GAAG,SAAS,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAC/E,iBAASA,MAAK,cAAc,UAAU,IAAI,QAAM;AAE9C,eAAK,GAAG,SAAS,SAAS,kBAAkB,GAAG,SAAS,SAAS,mBAAmB,iCAAiC,KAAK,GAAG,SAAS,SAAS,GAAG;AAChJ,mBAAO,GAAG,GAAG,SAAS,IAAI;AAAA,UAC5B;AACA,iBAAO,GAAG,GAAG,SAAS,IAAI,IAAI,GAAG,SAAS,SAAS;AAAA,QACrD,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;AAGf,YAAI,SAAS,KAAK,GAAG;AACnB,eAAK,iBAAiB,QAAQ,KAAK,CAAC;AAAA,QACtC;AAGA,iBAAS,KAAK,GAAG,KAAK,UAAU,QAAQ,MAAM;AAC5C,gBAAM,KAAK,UAAU,EAAE;AACvB,cAAI,OAAO,SAAS;AAElB,uBAAW,aAAa,UAAU,MAAM,EAAE,GAAG;AAC3C,sBAAQ;AAAA,gBAAc,UAAU;AAAA,gBAAI,UAAU,SAAS;AAAA,gBACrD,6BAAwB,UAAU,SAAS,IAAI;AAAA,cAAgC;AAAA,YACnF;AACA,mBAAO,OAAO,WAAW,YAAY,wBAAwB;AAAA,UAC/D;AACA,eAAK,kBAAkB,KAAK,IAAI;AAGhC,gBAAM,MAAM,KAAK,wBAAwB;AACzC,cAAI,IAAK,SAAQ,QAAQ,GAAG;AAE5B,eAAK,kBAAkB,GAAG,SAAS,QAAQ,MAAM;AAEjD,cAAI;AACJ,cAAI;AAAE,mBAAO,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,UAAG,QAAQ;AAEtD,kBAAM,SAAS;AACf,oBAAQA,MAAK,2BAA2B,GAAG,SAAS,IAAI,KAAK,GAAG,SAAS,UAAU,MAAM,GAAG,EAAE,CAAC,EAAE;AACjG,oBAAQ,cAAc,GAAG,IAAI,GAAG,SAAS,MAAM,KAAK,UAAU,EAAE,OAAO,OAAO,CAAC,CAAC;AAChF;AAAA,UACF;AAGA,gBAAM,EAAE,WAAW,IAAI,MAAM,OAAO,aAAa;AACjD,gBAAM,MAAM,GAAG,GAAG,SAAS,IAAI,IAAI,WAAW,QAAQ,EAAE,OAAO,GAAG,SAAS,SAAS,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;AAC/G,mBAAS,KAAK,GAAG;AACjB,cAAI,SAAS,OAAO,OAAK,MAAM,GAAG,EAAE,UAAU,GAAG;AAC/C,oBAAQA,MAAK,uBAAuB,GAAG,SAAS,IAAI,8BAAyB;AAC7E,oBAAQ,cAAc,GAAG,IAAI,GAAG,SAAS,MAAM,KAAK,UAAU,EAAE,OAAO,oHAAoH,CAAC,CAAC;AAC7L;AAAA,UACF;AAEA,gBAAM,SAAS,MAAM,gBAAgB,GAAG,SAAS,MAAM,MAAM,EAAE,QAAQ,KAAK,eAAe,QAAQ,eAAe,KAAK,cAAc,CAAC;AACtI,kBAAQ,cAAc,GAAG,IAAI,GAAG,SAAS,MAAM,MAAM;AAGrD,eAAK,GAAG,SAAS,SAAS,kBAAkB,GAAG,SAAS,SAAS,mBAAmB,SAAS,KAAK,kBAAkB,KAAK,SAAS,KAAK,EAAE,KAAK,GAAG;AAC/I,kBAAM,cAAc,KAAK,WAAW,KAAK,SAAS,KAAK;AACvD,gBAAI,eAAe,YAAY,SAAS,GAAG;AACzC,sBAAQ,iBAAiB,WAAW;AAAA,YACtC;AAAA,UACF;AAEA,cAAI;AAAE,gBAAI,CAAC,KAAK,MAAM,MAAM,EAAE,MAAO,MAAK;AAAA,UAAuB,SAAS,KAAK;AAAE,0BAAcA,MAAK,0BAA0B,GAAG;AAAG,iBAAK;AAAA,UAAuB;AAAA,QAClK;AACA;AAAA,MACF;AAGA,YAAM,SAAS,WAAW;AAE1B,UAAI,CAAC,UAAU,SAAS,MAAM,kBAAkB,GAAG;AACjD,cAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,cAAM,aAAa,KAAK,sBAAsB,OAAO,EAAE,qBAAqB;AAC5E,cAAM,aAAa,MAAQ,mBAAmB;AAC9C,YAAI,YAAY,aAAa,KAAM;AACjC;AACA,kBAAQA,MAAK,uCAAkC,gBAAgB,UAAU,aAAa,GAAI,MAAM,KAAK,MAAM,YAAY,GAAI,CAAC,SAAS;AACrI,gBAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,UAAU,CAAC;AAChD;AAAA,QACF;AAAA,MACF;AACA,cAAQ,aAAa,MAAM;AAC3B,aAAO;AAAA,IACT;AAEA,YAAQA,MAAK,cAAc,KAAK,OAAO,QAAQ,WAAW;AAC1D,UAAM,OAAO,QAAQ,SAAS,GAAG,EAAE,GAAG;AACtC,YAAQ,OAAO,SAAS,WAAW,OAAO,SAAS;AAAA,EACrD;AAAA,EAEQ,iBAAiB,KAAsB;AAAE,WAAO,iBAAiB,GAAG;AAAA,EAAG;AAAA;AAAA,EAGvE,gBAAgB,KAAkC;AAAE,WAAO,gBAAgB,GAAG;AAAA,EAAG;AAAA,EAEzF,MAAc,iBACZ,SACA,QACgI;AAEhI,UAAM,cAAc,IAAI,gBAAgB;AACxC,UAAM,YAAY,KAAK,sBAAsB,OAAO,EAAE;AACtD,SAAK,kBAAkB,KAAK,IAAI;AAChC,UAAM,QAAQ,YAAY,MAAM;AAC9B,UAAI,KAAK,IAAI,KAAK,KAAK,mBAAmB,KAAK,WAAW;AACxD,sBAAc,KAAK;AACnB,oBAAY,MAAM,IAAI,MAAM,mBAAmB,CAAC;AAAA,MAClD;AAAA,IACF,GAAG,GAAI;AACP,UAAM,WAAW,YAAY,IAAI,CAAC,QAAQ,YAAY,MAAM,CAAC;AAE7D,QAAI;AAEJ,UAAI,KAAK,OAAO,cAAc,aAAa;AACzC,cAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,iCAAwB;AACpE,cAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,oCAA2B;AACtE,cAAM,OAAO,QAAQ,SAAS,IAAI,QAAM,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,WAAW,GAA6B,EAAE;AAC7G,cAAM,UAAU,EAAE,GAAG,mBAAmB,KAAK,aAAa,MAAM,eAAe,KAAK,aAAa,GAAG,KAAK,OAAO,SAAS,GAAG,QAAQ,KAAK;AACzI,cAAM,OAA+B,EAAE,gBAAgB,mBAAmB;AAC1E,YAAI,KAAK,aAAc,MAAK,eAAe,IAAI,UAAU,KAAK,YAAY;AAC1E,cAAM,MAAM,MAAM,MAAM,GAAG,KAAK,cAAc,cAAc;AAAA,UAC1D,QAAQ;AAAA,UAAQ,SAAS;AAAA,UAAM,MAAM,KAAK,UAAU,OAAO;AAAA,UAAG,QAAQ;AAAA,QACxE,CAAC;AACD,YAAI,CAAC,IAAI,IAAI;AAAE,gBAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,SAAO;AAAE,0BAAcA,MAAK,mBAAmB,GAAG;AAAG,mBAAO;AAAA,UAAI,CAAC;AAAG,gBAAM,IAAI,MAAM,aAAa,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,QAAG;AAE1L,YAAIC,WAAU;AACd,YAAIC,SAAqE;AACzE,cAAM,cAAc,oBAAI,IAA6D;AACrF,yBAAiB,SAAS,kBAAkB,KAAK,QAAQ,GAAG;AAC1D,eAAK,kBAAkB,KAAK,IAAI;AAChC,cAAI,MAAM,SAAS,SAAS;AAAE,YAAAD,YAAW,MAAM;AAAS,iBAAK,qBAAqB,MAAM;AAAS,iBAAK,yBAAyB,MAAM,OAAO;AAAA,UAAG,WACtI,MAAM,SAAS,mBAAmB;AAAE,iBAAK,mBAAmB,aAAa,KAAK;AAAA,UAAG,WACjF,MAAM,SAAS,QAAQ;AAAE,YAAAC,SAAQ,MAAM;AAAA,UAAO;AAAA,QACzD;AACA,sBAAc,KAAK;AACnB,cAAMC,aAAY,KAAK,kBAAkB,WAAW;AACpD,eAAO,EAAE,SAASF,YAAW,MAAM,WAAAE,YAAW,OAAAD,OAAM;AAAA,MACtD;AAGA,UAAI,KAAK,OAAO,cAAc,aAAa;AACzC,cAAM,EAAE,oBAAoB,sBAAsB,IAAI,MAAM,OAAO,iCAAwB;AAC3F,cAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,oCAA2B;AACtE,cAAM,OAAO,QAAQ,SAAS,IAAI,QAAM,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,WAAW,IAA8B,cAAc,EAAE,aAAa,EAAE;AAC3I,cAAM,UAAU,EAAE,GAAG,mBAAmB,KAAK,aAAa,MAAM,KAAK,OAAO,WAAW,eAAe,KAAK,aAAa,CAAC,GAAG,QAAQ,KAAK;AACzI,cAAM,OAAO,sBAAsB,KAAK,gBAAgB,EAAE;AAC1D,cAAM,MAAM,MAAM,MAAM,GAAG,KAAK,cAAc,aAAa;AAAA,UACzD,QAAQ;AAAA,UAAQ,SAAS;AAAA,UAAM,MAAM,KAAK,UAAU,OAAO;AAAA,UAAG,QAAQ;AAAA,QACxE,CAAC;AACD,YAAI,CAAC,IAAI,IAAI;AAAE,gBAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,SAAO;AAAE,0BAAcF,MAAK,mBAAmB,GAAG;AAAG,mBAAO;AAAA,UAAI,CAAC;AAAG,gBAAM,IAAI,MAAM,aAAa,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,QAAG;AAE1L,YAAIC,WAAU;AACd,YAAIC,SAAqE;AACzE,cAAM,cAAc,oBAAI,IAA6D;AACrF,yBAAiB,SAAS,kBAAkB,KAAK,QAAQ,GAAG;AAC1D,eAAK,kBAAkB,KAAK,IAAI;AAChC,cAAI,MAAM,SAAS,SAAS;AAAE,YAAAD,YAAW,MAAM;AAAS,iBAAK,qBAAqB,MAAM;AAAS,iBAAK,yBAAyB,MAAM,OAAO;AAAA,UAAG,WACtI,MAAM,SAAS,mBAAmB;AAAE,iBAAK,mBAAmB,aAAa,KAAK;AAAA,UAAG,WACjF,MAAM,SAAS,QAAQ;AAAE,YAAAC,SAAQ,MAAM;AAAA,UAAO;AAAA,QACzD;AACA,sBAAc,KAAK;AACnB,cAAMC,aAAY,KAAK,kBAAkB,WAAW;AACpD,eAAO,EAAE,SAASF,YAAW,MAAM,WAAAE,YAAW,OAAAD,OAAM;AAAA,MACtD;AAEA,YAAM,OAAgC;AAAA,QACpC,OAAO,KAAK;AAAA,QACZ,UAAU,QAAQ;AAAA,QAClB,OAAO,eAAe,KAAK,aAAa;AAAA,QACxC,YAAY,KAAK,OAAO;AAAA,QACxB,QAAQ;AAAA,QACR,gBAAgB,EAAE,eAAe,KAAK;AAAA,MACxC;AAGA,UAAI,KAAK,OAAO,UAAU;AACxB,YAAI,KAAK,OAAO,SAAS,UAAU,UAAU;AAC3C,eAAK,mBAAmB,KAAK,OAAO,SAAS;AAAA,QAC/C,WAAW,KAAK,OAAO,SAAS,UAAU,YAAY;AACpD,eAAK,WAAW,EAAE,MAAM,WAAW,eAAe,KAAK,OAAO,SAAS,QAAQ;AAAA,QACjF;AAAA,MACF;AAEA,UAAI,QAAQ,iBAAiB;AAC3B,cAAM,aAAqC,EAAE,KAAK,MAAM,QAAQ,MAAM,MAAM,MAAM;AAClF,YAAK,KAAK,OAAO,cAAyB,aAAa;AACrD,eAAK,WAAW,EAAE,MAAM,WAAW,eAAe,WAAW,QAAQ,eAAe,KAAK,KAAK;AAAA,QAChG,OAAO;AACL,eAAK,mBAAmB,QAAQ;AAAA,QAClC;AAAA,MACF;AAEA,YAAM,UAAkC,EAAE,gBAAgB,mBAAmB;AAC7E,UAAI,KAAK,aAAc,SAAQ,eAAe,IAAI,UAAU,KAAK,YAAY;AAE7E,YAAM,WAAW,MAAM;AAAA,QACrB,YAAY;AACV,gBAAM,MAAM,MAAM,MAAM,GAAG,KAAK,cAAc,qBAAqB;AAAA,YACjE,QAAQ;AAAA,YACR;AAAA,YACA,MAAM,KAAK,UAAU,IAAI;AAAA,YACzB,QAAQ;AAAA,UACV,CAAC;AACD,cAAI,CAAC,IAAI,IAAI;AACX,kBAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,SAAO;AAAE,4BAAcF,MAAK,mBAAmB,GAAG;AAAG,qBAAO;AAAA,YAAI,CAAC;AACrG,kBAAM,IAAI,MAAM,aAAa,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,UAClE;AACA,iBAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,UAAU;AAAA,UAAG,YAAY;AAAA,UACzB,eAAe,CAAC,QAAQ;AACtB,kBAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,gBAAI,oBAAoB,KAAK,GAAG,EAAG,QAAO;AAE1C,gBAAI,8BAA8B,KAAK,GAAG,EAAG,QAAO;AACpD,mBAAO,CAAC,QAAQ,GAAG;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAEA,UAAI,UAAU;AACd,YAAM,sBAAsB,oBAAI,IAA6D;AAC7F,UAAI,QAAqE;AAEzE,uBAAiB,SAAS,eAAe,UAAU,QAAQ,GAAG;AAC5D,aAAK,kBAAkB,KAAK,IAAI;AAEhC,gBAAQ,MAAM,MAAM;AAAA,UAClB,KAAK;AACH,uBAAW,MAAM;AACjB,iBAAK,qBAAqB,MAAM;AAChC,iBAAK,yBAAyB,MAAM,OAAO;AAC3C;AAAA,UAEF,KAAK;AACH,iBAAK,mBAAmB,qBAAqB,KAAK;AAClD;AAAA,UAEF,KAAK;AACH,oBAAQ,MAAM;AACd;AAAA,QACJ;AAAA,MACF;AAEA,YAAM,YAAY,KAAK,kBAAkB,mBAAmB;AAE5D,aAAO,EAAE,SAAS,WAAW,MAAM,WAAW,MAAM;AAAA,IACpD,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAAA;AAAA,EAGQ,mBACN,KACA,OACM;AAEN,UAAM,MAAM,MAAM,MAAM,OAAO,MAAM,KAAK;AAC1C,UAAM,WAAW,IAAI,IAAI,GAAG;AAC5B,QAAI,UAAU;AACZ,UAAI,MAAM,UAAW,UAAS,aAAa,MAAM;AAAA,IACnD,OAAO;AACL,UAAI,IAAI,KAAK,EAAE,IAAI,MAAM,MAAM,QAAQ,IAAI,IAAI,IAAI,MAAM,MAAM,QAAQ,IAAI,WAAW,MAAM,aAAa,GAAG,CAAC;AAAA,IAC/G;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,kBAAkB,KAA+E;AACvG,UAAM,MAAkB,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,IAAI,SAAO;AAAA,MACnD,IAAI,GAAG;AAAA,MAAI,MAAM;AAAA,MAAqB,UAAU,EAAE,MAAM,GAAG,MAAM,WAAW,GAAG,UAAU;AAAA,IAC3F,EAAE;AACF,WAAO,mBAAmB,GAAG;AAAA,EAC/B;AAAA,EAEQ,mBAAmB,YAAyC;AAClE,QAAI,UAAU,KAAK,SAAS,IAAI,UAAU;AAC1C,QAAI,CAAC,SAAS;AACZ,gBAAU,IAAI,oBAAoB,KAAK,cAAc,KAAK,OAAO,UAAU;AAC3E,WAAK,SAAS,IAAI,YAAY,OAAO;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAa,YAAmC;AACpD,UAAM,UAAU,KAAK,SAAS,IAAI,UAAU;AAC5C,QAAI,QAAS,SAAQ,MAAM,KAAK,YAAY;AAAA,QACvC,MAAK,SAAS,OAAO,UAAU;AACpC,YAAQA,MAAK,WAAW,UAAU,QAAQ;AAAA,EAC5C;AAAA,EAEA,MAAM,cAAc,QAAgC;AAClD,eAAW,MAAM,KAAK,iBAAiB,OAAO,EAAG,IAAG,MAAM,UAAU,MAAM;AAAA,EAC5E;AAAA,EAEA,UAAgB;AACd,eAAW,MAAM,KAAK,iBAAiB,OAAO,EAAG,IAAG,MAAM;AAC1D,SAAK,SAAS,MAAM;AACpB,SAAK,iBAAiB,MAAM;AAAA,EAC9B;AAAA,EAEA,IAAI,UAAmB;AAAE,WAAO;AAAA,EAAM;AAAA,EACtC,IAAI,iBAAyB;AAAE,WAAO,KAAK;AAAA,EAAiB;AAAA,EAC5D,IAAI,aAAqB;AAAE,WAAO,KAAK;AAAA,EAAa;AAAA,EACpD,mBAA+C;AAAE,WAAO,KAAK,SAAS,IAAI,KAAK,iBAAiB,KAAK;AAAA,EAAM;AAAA,EAC3G,IAAI,qBAA6B;AAAE,WAAO,KAAK;AAAA,EAAqB;AAAA,EAEpE,YAAsD;AACpD,WAAO,KAAK,qBAAqB,KAAK,wBAClC,EAAE,OAAO,KAAK,mBAAmB,QAAQ,KAAK,sBAAsB,IACpE;AAAA,EACN;AAAA;AAAA,EAGA,SAAS,OAAqB;AAC5B,SAAK,cAAc;AACnB,IAAC,KAAK,OAA6B,QAAQ;AAC3C,YAAQA,MAAK,0BAA0B,KAAK,EAAE;AAAA,EAChD;AAAA;AAAA,EAGA,eAAe,MAA8G;AAC3H,QAAI,KAAK,qBAAqB,MAAM;AAClC,YAAM,IAAI,MAAM,oFAA+E;AAAA,IACjG;AACA,SAAK,iBAAiB,KAAK;AAC3B,SAAK,eAAe,KAAK;AACzB,SAAK,cAAc,KAAK;AACxB,IAAC,KAAK,OAAiD,QAAQ,KAAK;AACpE,IAAC,KAAK,OAAkC,aAAa,KAAK;AAC1D,SAAK,SAAS,KAAK;AACnB,YAAQA,MAAK,sBAAsB,KAAK,KAAK,MAAM,KAAK,QAAQ,YAAY,KAAK,UAAU,GAAG;AAAA,EAChG;AAAA;AAAA,EAGA,WAAmB;AAAE,WAAO,KAAK;AAAA,EAAa;AAAA,EAC9C,IAAI,4BAAoC;AAAE,WAAO,KAAK;AAAA,EAAmB;AAAA,EACzE,IAAI,oBAA8B;AAAE,WAAO,CAAC;AAAA,EAAG;AAAA;AAAA,EAG/C,IAAI,kBAAiC;AAAE,WAAO,KAAK;AAAA,EAAkB;AAAA,EACrE,mBAAmB,IAAyB;AAAE,SAAK,qBAAqB;AAAA,EAAI;AAAA,EAC5E,yBAAyB,GAAwB;AAAE,SAAK,yBAAyB;AAAA,EAAG;AAAA,EAEpF,IAAI,iBAAgC;AAAE,WAAO,KAAK;AAAA,EAAiB;AAAA,EAElD,gBAAgB,OAAO,EAAE,oBAAoB;AAAA,EAE9D,MAAM,cAA6B;AACjC,QAAI,CAAC,KAAK,iBAAkB;AAC5B,UAAM,OAAO,KAAK,IAAI,KAAK,KAAK,mBAAmB,KAAK;AACxD,QAAI,OAAO,KAAK,eAAe;AAC7B,cAAQA,MAAK,oCAAoC,KAAK,MAAM,OAAO,GAAI,CAAC,yBAAoB;AAC5F,YAAM,KAAK,cAAc;AAAA,IAC3B;AAAA,EACF;AACF;",
|
|
6
|
-
"names": ["TAG", "TAG", "content", "usage", "toolCalls"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/components/dns-wakeup.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * dns-wakeup.ts \u2014 mDNS-disguised UDP wake-up for A2A callback (#425).\n *\n * Sender crafts a valid mDNS PTR query: AB-<token>._workstation._tcp.local\n * Token = (ts(4) + nonce(1)) XOR HMAC-SHA256(peer.token, peername)[:5]\n *\n * Receiver tries each known peer, XORs to recover ts, validates within 60s.\n * On valid wake-up \u2192 triggers A2A callback (outbound TCP).\n *\n * Looks like normal mDNS service discovery to endpoint protection.\n */\n\nimport { createSocket, type Socket } from \"node:dgram\";\nimport { createHmac, randomBytes } from \"node:crypto\";\nimport { logInfo, logWarn, logDebug } from \"./logger.js\";\nimport type { PeerConfig } from \"./peer-config.js\";\n\nconst TAG = \"dns-wakeup\";\nconst PREFIX = \"ab-\";\nconst SUFFIX = \"._workstation._tcp.local\";\nconst PATTERN = /^ab-([a-f0-9]{10})\\._workstation\\._tcp\\.local$/;\nconst MAX_AGE_S = 60;\nconst RATE_LIMIT_MS = 5000;\n\nconst lastWakeup = new Map<string, number>();\n\n/** Parse the query name from a raw DNS/mDNS packet (minimal parser). */\nfunction parseMdnsQueryName(buf: Buffer): string | null {\n if (buf.length < 12) return null;\n let offset = 12; // skip DNS header\n const labels: string[] = [];\n while (offset < buf.length) {\n const len = buf[offset]!;\n if (len === 0) break;\n if (len > 63) return null; // compressed \u2014 not expected in queries\n offset++;\n if (offset + len > buf.length) return null;\n labels.push(buf.subarray(offset, offset + len).toString(\"ascii\"));\n offset += len;\n }\n return labels.join(\".\").toLowerCase();\n}\n\n/** Build a minimal mDNS query packet for a PTR record. */\nfunction buildMdnsQuery(name: string): Buffer {\n const labels = name.split(\".\");\n // Header: ID=0, flags=0 (standard query), QDCOUNT=1\n const header = Buffer.from([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]);\n // Question section: labels + null + type PTR (12) + class IN (1)\n const parts: Buffer[] = [header];\n for (const label of labels) {\n parts.push(Buffer.from([label.length]));\n parts.push(Buffer.from(label, \"ascii\"));\n }\n parts.push(Buffer.from([0])); // root label\n parts.push(Buffer.from([0, 12, 0, 1])); // type PTR, class IN\n return Buffer.concat(parts);\n}\n\n/** Build an empty mDNS response (no answers \u2014 looks like \"not found\"). */\nfunction buildEmptyResponse(queryBuf: Buffer): Buffer {\n const resp = Buffer.from(queryBuf);\n // Set QR=1 (response), RCODE=0 in flags\n if (resp.length >= 4) {\n resp[2] = 0x84; // QR=1, AA=1\n resp[3] = 0x00; // RCODE=0\n }\n return resp;\n}\n\nexport function startDnsWakeup(\n port: number,\n config: PeerConfig,\n onWakeup: (peerName: string) => void,\n): Socket {\n const sock = createSocket(\"udp4\");\n\n sock.on(\"message\", (msg, rinfo) => {\n const name = parseMdnsQueryName(msg);\n if (!name || !PATTERN.test(name)) return; // early bail \u2014 not ours\n\n const token10 = name.match(PATTERN)![1]!;\n const tokenBuf = Buffer.from(token10, \"hex\"); // 5 bytes\n\n for (const [peerName, peer] of Object.entries(config.peers)) {\n const hmac = createHmac(\"sha256\", peer.token).update(peerName).digest();\n const decoded = Buffer.alloc(5);\n for (let i = 0; i < 5; i++) decoded[i] = tokenBuf[i]! ^ hmac[i]!;\n const ts = decoded.readUInt32BE(0);\n // decoded[4] = nonce \u2014 discarded\n\n if (Math.abs(Date.now() / 1000 - ts) <= MAX_AGE_S) {\n // Rate limit\n const now = Date.now();\n const last = lastWakeup.get(peerName) ?? 0;\n if (now - last < RATE_LIMIT_MS) {\n logDebug(TAG, `Rate-limited wake-up from ${peerName}`);\n return;\n }\n lastWakeup.set(peerName, now);\n\n // Send empty mDNS response\n sock.send(buildEmptyResponse(msg), rinfo.port, rinfo.address);\n\n logInfo(TAG, `Valid wake-up from ${peerName} \u2014 initiating callback`);\n onWakeup(peerName);\n return;\n }\n }\n });\n\n sock.on(\"error\", (err) => logWarn(TAG, `Socket error: ${err.message}`));\n sock.bind(port, () => logInfo(TAG, `Listening on UDP port ${port}`));\n return sock;\n}\n\n/** Send a wake-up signal to a peer (mDNS-disguised). */\nexport function sendWakeup(peerName: string, peerHost: string, udpPort: number, token: string): void {\n const ts = Math.floor(Date.now() / 1000);\n const nonce = randomBytes(1);\n const hmac = createHmac(\"sha256\", token).update(peerName).digest();\n\n const plain = Buffer.alloc(5);\n plain.writeUInt32BE(ts, 0);\n plain[4] = nonce[0]!;\n\n const xored = Buffer.alloc(5);\n for (let i = 0; i < 5; i++) xored[i] = plain[i]! ^ hmac[i]!;\n\n const queryName = `${PREFIX}${xored.toString(\"hex\")}${SUFFIX}`;\n const query = buildMdnsQuery(queryName);\n\n const sock = createSocket(\"udp4\");\n sock.send(query, udpPort, peerHost, () => sock.close());\n logDebug(TAG, `Sent wake-up to ${peerName} at ${peerHost}:${udpPort}`);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/boot/heartbeat-tier3.ts", "../src/components/self-healer.ts", "../src/boot/heartbeat-model-health.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * heartbeat-tier3.ts \u2014 Register Tier 3 heartbeat tasks.\n *\n * Called from phasePipelineDeps after transport+platforms+cronQueue are ready.\n * These tasks need transport, memory, cronQueue, or platform adapters.\n */\n\nimport { getEnv } from \"../components/env-schema.js\";\nimport { logAndSwallow } from \"../components/log-and-swallow.js\";\nimport { createSelfHealerTask } from \"../components/self-healer.js\";\nimport {\n createIdleCompactTask, createAgeCheckTask, createDbIntegrityTask,\n createKanbanDeliveryTask, createKanbanCleanupTask, createUserSessionExpiryTask, createMetricsTask,\n} from \"../components/heartbeat-tasks.js\";\nimport { checkCron, readPendingReminders, clearPendingReminders } from \"../components/tasks/task-checker.js\";\nimport { loadUsers } from \"../components/user-registry.js\";\nimport { logInfo, logWarn } from \"../components/logger.js\";\nimport { abtarsHome } from \"../paths.js\";\nimport { createCronCallback } from \"./phase-pipeline-deps.js\";\nimport { createModelHealthTask } from \"./heartbeat-model-health.js\";\nimport { readEnvWithDefault } from \"../components/env.js\";\nimport type { BootCtx } from \"./context.js\";\n\nconst TAG = \"heartbeat\";\n\nexport async function registerTier3Tasks(ctx: BootCtx): Promise<void> {\n const { heartbeat, transport, cronQueue, memory, memoryConfig, config, pipelineDeps, capabilities } = ctx;\n if (!heartbeat || !transport || !cronQueue || !pipelineDeps) return;\n\n const cronCallback = createCronCallback(ctx);\n\n heartbeat.registerTask({\n name: \"tasks\",\n execute: async () => {\n const dueTasks = checkCron();\n for (const entry of dueTasks) cronQueue.enqueue(entry, cronCallback);\n },\n });\n\n heartbeat.registerTask({\n name: \"reminder-injector\",\n execute: async () => {\n const reminders = readPendingReminders();\n if (reminders.length === 0) return;\n clearPendingReminders();\n for (const r of reminders) {\n logInfo(\"main\", `Injecting reminder for chat ${r.chatId}: \"${r.message}\"`);\n if (ctx.telegramAdapter) {\n ctx.telegramAdapter.injectMessage({\n platform: \"telegram\",\n channelId: String(r.chatId),\n userId: loadUsers().byPlatformId.get(\"telegram:\" + r.chatId)?.userId ?? \"master\",\n senderId: String(r.chatId),\n senderName: \"task\",\n text: `[Scheduled reminder] ${r.message}`,\n timestamp: Date.now(),\n threadId: r.threadId ? String(r.threadId) : undefined,\n isGroup: false,\n isVoice: false,\n });\n }\n }\n },\n });\n\n const SLEEP_HOUR = parseInt(readEnvWithDefault(\"BED_TIME\", \"2\", \"bedtime hour\").split(\":\")[0] ?? \"2\", 10);\n const SLEEP_MINUTE = parseInt(readEnvWithDefault(\"BED_TIME\", \"2\", \"bedtime hour\").split(\":\")[1] ?? \"0\", 10);\n\n if (getEnv().ctxIdleCompactMin > 0) {\n heartbeat.registerTask(createIdleCompactTask({\n transport, memory, memoryDir: memoryConfig.memoryDir,\n allowedUserIds: config.telegram.allowedUserIds,\n isSleepActive: ctx.isSleepActive,\n }));\n }\n\n heartbeat.registerTask(createAgeCheckTask({\n memory,\n bridgeLockPath: ctx.bridgeLockPath,\n sleepAuditDir: ctx.sleepAuditDir,\n sleepHour: SLEEP_HOUR,\n sleepMinute: SLEEP_MINUTE,\n isSleepActive: ctx.isSleepActive,\n // doctorPath removed \u2014 runFixes() called directly from heartbeat-tasks.ts\n startSleep: () => { ctx.sleepHandle?.spawn(); },\n checkHwSleep: () => { ctx.sleepHandle?.checkHwSleep(); },\n checkStaleSleep: () => { ctx.sleepHandle?.checkStale(); },\n cronBusy: () => cronQueue.currentJob !== null || cronQueue.pending > 0,\n }));\n\n heartbeat.registerTask(createDbIntegrityTask(memory));\n\n const masterChatId = [...config.telegram.allowedUserIds][0] ?? 0;\n heartbeat.registerTask(createKanbanDeliveryTask({\n sendSystemMessage: ctx.sendSystemMessage!,\n sendMessage: async (chatId, text) => {\n if (!ctx.telegramAdapter) return;\n await ctx.telegramAdapter.sendMessage(chatId, text);\n },\n sendDocument: async (chatId, filePath, caption) => {\n if (!ctx.telegramAdapter) return;\n await ctx.telegramAdapter.sendDocument(chatId, filePath, caption);\n },\n chatId: () => String(masterChatId),\n }));\n\n // Nerve-driven instant delivery\n import(\"../components/nerve.js\").then(({ nerve }) => {\n nerve.on(\"card:done\", async (cardId: number) => {\n try {\n const { kanbanPending, kanbanSetDelivering, kanbanMarkDelivered } = await import(\"../components/tasks/kanban-board.js\");\n const pending = kanbanPending();\n const card = pending.find((c: { id: number }) => c.id === cardId);\n if (!card) return;\n\n kanbanSetDelivering(card.id);\n const targetChat = card.chat_id || String(masterChatId);\n\n if (card.delivery_mode === \"silent\") {\n kanbanMarkDelivered(card.id);\n return;\n }\n\n if (card.delivery_mode === \"deliver\") {\n if (ctx.telegramAdapter) {\n if (card.result_path) await ctx.telegramAdapter.sendDocument(targetChat, card.result_path, card.title);\n }\n if (ctx.sendSystemMessage) {\n await ctx.sendSystemMessage(`[SYSTEM] Task \"${card.title}\" complete. File delivered: ${card.result_path ?? \"(no file)\"}`);\n }\n kanbanMarkDelivered(card.id);\n return;\n }\n\n // \"announce\" \u2014 inject into agent for natural delivery\n if (ctx.sendSystemMessage) {\n await ctx.sendSystemMessage(\n `[TASK COMPLETE] \"${card.title}\" done.\\nResult:\\n${card.result_summary ?? \"(no output)\"}\\n\\nDeliver this to the user naturally.`\n );\n }\n kanbanMarkDelivered(card.id);\n } catch (err) { logAndSwallow(TAG, \"nerve:card:done delivery\", err); }\n });\n\n nerve.on(\"channel:message\", async (_cardId: number, meta?: Record<string, unknown>) => {\n if (!meta || (meta.to as string)?.toUpperCase() !== \"MASTER\") return;\n if (!ctx.telegramAdapter) return;\n try {\n const from = meta.from as string ?? \"agent\";\n await ctx.telegramAdapter.sendMessage(String(masterChatId), `[${from}->MASTER] card:${_cardId}\\n${String(meta.message ?? \"\").slice(0, 200)}`);\n } catch (err) { logAndSwallow(TAG, \"nerve:channel:message TG notify\", err); }\n });\n }).catch(err => logAndSwallow(TAG, \"nerve import\", err));\n\n heartbeat.registerTask(createKanbanCleanupTask());\n\n import(\"../components/metrics-collector.js\").then(({ initMetrics }) => {\n initMetrics(abtarsHome());\n }).catch(() => {});\n heartbeat.registerTask(createMetricsTask(() => cronQueue.pending));\n\n heartbeat.registerTask(createUserSessionExpiryTask());\n\n // Reconciler\n import(\"../components/reconciler.js\").then(({ startReconciler }) => {\n startReconciler();\n }).catch(err => logAndSwallow(TAG, \"reconciler\", err));\n\n // Spin tick\n import(\"../components/spin.js\").then(({ spin }) => {\n heartbeat.registerTask({ name: \"spin-tick\", execute: () => spin.tick() });\n }).catch(err => logAndSwallow(TAG, \"spin-tick\", err));\n\n // Busy-unstick\n {\n const { spin: spinRef } = require(\"../components/spin.js\") as typeof import(\"../components/spin.js\");\n heartbeat.registerTask({ name: \"busy-unstick\", execute: async () => {\n const now = Date.now();\n for (const s of spinRef.listAllSessions()) {\n if (s.busy && s.lastActiveAt && now - s.lastActiveAt > 60_000) {\n if (transport && \"sendInterrupt\" in transport) {\n (transport as { sendInterrupt: (r?: string) => Promise<void> }).sendInterrupt(\"timeout\").catch(() => {});\n }\n s.busy = false;\n logWarn(TAG, `Force-cleared stuck busy on ${s.id} (>60s) \u2014 interrupted`);\n }\n }\n }});\n }\n\n // Gossip\n import(\"../components/peer-transport/gossip.js\").then(({ gossipBroadcast, setGossipInterval }) => {\n setGossipInterval(heartbeat.intervalMs);\n heartbeat.registerTask({ name: \"gossip-health\", execute: async () => { gossipBroadcast(); } });\n }).catch(err => logAndSwallow(TAG, \"gossip\", err));\n\n if (transport.healthCheck) {\n heartbeat.registerTask({ name: \"transport-health\", execute: () => transport.healthCheck!() });\n }\n\n // Self-healer\n let selfHealerTask: ReturnType<typeof createSelfHealerTask> | null = null;\n if (getEnv().selfhealEnabled) {\n selfHealerTask = createSelfHealerTask(() => ctx.telegramAdapter, config.telegram.allowedUserIds);\n heartbeat.registerTask(selfHealerTask);\n }\n ctx.selfHealerTask = selfHealerTask;\n pipelineDeps.selfHealerTask = selfHealerTask;\n\n // Capability tasks + commands\n const { registerCommand } = await import(\"../components/commands/index.js\");\n for (const [name, handler] of capabilities.commands) {\n registerCommand(name, handler);\n }\n for (const task of capabilities.heartbeatTasks) {\n heartbeat.registerTask(task);\n }\n\n // Model health\n const { task: modelHealthTask, runNow: runModelHealth } = createModelHealthTask(ctx);\n heartbeat.registerTask(modelHealthTask);\n queueMicrotask(() => { runModelHealth().catch(err => logAndSwallow(TAG, \"runModelHealth boot\", err)); });\n}\n", "/**\n * Self-healer heartbeat task \u2014 scans bridge log for ERROR lines (#954).\n *\n * Two-state dispatch:\n * 1. Known fault (pattern in sha-policy fixes) \u2192 wired command[], no LLM\n * 2. Unknown fault (no matching rule) \u2192 one-shot agent via Spin (if SELFHEAL_ENABLED)\n *\n * All gating via sha-tracker. No inline state.\n */\n\nimport { readFileSync, appendFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { spawn, execSync } from \"node:child_process\";\nimport { logInfo, logDebug } from \"./logger.js\";\nimport { getLogFile } from \"./logger.js\";\nimport { abtarsHome } from \"../paths.js\";\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { getEnv } from \"./env-schema.js\";\nimport { localISO } from \"../utils/local-time.js\";\nimport { loadFixes, shouldAttempt, recordResult } from \"./sha-tracker.js\";\nimport type { FixRule } from \"./sha-tracker.js\";\nimport type { HeartbeatTask } from \"../types/index.js\";\nimport type { TelegramAdapter } from \"../platforms/telegram/telegram-adapter.js\";\n\n/** Write SHA dispatch to sha-call.log (model reads this for recurrence detection). */\nfunction logShaCall(errorKey: string, errorLine: string): void {\n const logPath = join(abtarsHome(), \"logs\", \"sha-call.log\");\n const entry = JSON.stringify({ ts: localISO(), errorKey, errorLine: errorLine.slice(0, 300) });\n try { appendFileSync(logPath, entry + \"\\n\"); } catch {}\n}\n\n// Known-noise patterns are in sha-policy.json (seeded) \u2014 no hardcoded list.\n\nfunction logAutoFix(message: string): void {\n const dir = join(abtarsHome(), \"logs\");\n try { mkdirSync(dir, { recursive: true }); } catch (err) { logAndSwallow(\"self_healer\", \"op\", err); }\n const date = new Date().toISOString().slice(0, 10);\n appendFileSync(join(dir, `autofix-${date}.log`), `${localISO()} ${message}\\n`);\n}\n\nfunction notify(adapter: TelegramAdapter, chatId: string, msg: string): void {\n try { adapter.sendNotification(chatId, msg); } catch {}\n}\n\nexport function createSelfHealerTask(\n getTelegramAdapter: () => TelegramAdapter | null,\n allowedUserIds: Set<number>,\n): HeartbeatTask & { enabled: boolean } {\n let lastTs = localISO();\n let bridgeStartTs = \"\";\n let enabled = getEnv().selfhealEnabled;\n let agentRunning = false;\n const dryRun = process.env[\"SELFHEAL_DRY_RUN\"] === \"true\";\n\n const task: HeartbeatTask & { enabled: boolean } = {\n name: \"self-healer\",\n get enabled() { return enabled; },\n set enabled(v: boolean) { enabled = v; },\n execute: async () => {\n if (!enabled) return;\n const logFile = getLogFile();\n try {\n const content = readFileSync(logFile, \"utf-8\");\n const lines = content.split(\"\\n\");\n const fixes = loadFixes();\n\n if (!bridgeStartTs) {\n for (let i = lines.length - 1; i >= 0; i--) {\n if (lines[i]!.includes(\"BRIDGE START\")) { bridgeStartTs = lines[i]!.slice(0, 23); break; }\n }\n }\n\n const adapter = getTelegramAdapter();\n const chatId = String([...allowedUserIds][0] ?? \"\");\n if (!adapter || !chatId) return;\n\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i]!;\n if (line.length < 24 || !line.includes(\" ERROR \")) continue;\n const ts = line.slice(0, 23);\n if (ts <= lastTs) break;\n if (bridgeStartTs && ts < bridgeStartTs) continue;\n if (line.includes(\"TEST \")) continue;\n\n const match = line.match(/\\[([^\\]]+)\\] (.+)/);\n if (!match) continue;\n const stableMsg = match[2]!.slice(0, 80)\n .replace(/\\b[0-9a-f]{8,}\\b/gi, \"X\")\n .replace(/\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}[:\\d.]*/g, \"T\")\n .replace(/\\b\\d{4,}\\b/g, \"N\")\n .replace(/\\s+/g, \" \").trim();\n const errorKey = `${match[1]}:${stableMsg}`;\n\n // Try to match a wired fix rule\n const rule = fixes.find(f => line.includes(f.pattern));\n if (rule) {\n handleKnownFault(rule, errorKey, adapter, chatId, dryRun);\n continue;\n }\n\n // Unknown fault \u2014 agent path (one-shot)\n if (!agentRunning) {\n handleUnknownFault(line, errorKey, adapter, chatId, () => { agentRunning = false; });\n if (!agentRunning) agentRunning = true; // set after dispatch\n }\n }\n\n // Advance watermark\n if (lines.length > 1) {\n const lastLine = lines[lines.length - 2] ?? \"\";\n if (lastLine.length >= 23) lastTs = lastLine.slice(0, 23);\n }\n } catch (err) { logAndSwallow(\"self_healer\", \"op\", err); }\n },\n };\n return task;\n}\n\nfunction handleKnownFault(rule: FixRule, _errorKey: string, adapter: TelegramAdapter, chatId: string, dryRun: boolean): void {\n if (!shouldAttempt(\"autofix-known\", rule.pattern)) return;\n\n // Suppress: known noise, skip silently\n if (rule.action === \"suppress\") {\n logDebug(\"self-healer\", `Suppressed: \"${rule.pattern}\"`);\n return;\n }\n\n if (!rule.command?.length) return;\n\n if (dryRun) {\n logInfo(\"self-healer\", `[DRY-RUN] Would run: ${rule.command.join(\" \")}`);\n return;\n }\n\n logInfo(\"self-healer\", `Wired fix: ${rule.command.join(\" \")} (pattern: \"${rule.pattern}\")`);\n logAutoFix(`WIRED START: ${rule.pattern} \u2192 ${rule.command.join(\" \")}`);\n\n const child = spawn(rule.command[0]!, rule.command.slice(1), { stdio: \"ignore\" });\n child.on(\"exit\", (code) => {\n const ok = code === 0;\n recordResult(\"autofix-known\", rule.pattern, ok, ok ? undefined : `exit ${code}`);\n logAutoFix(`WIRED ${ok ? \"OK\" : \"FAIL\"}: ${rule.pattern} (exit ${code})`);\n\n if (!ok) {\n // Check if we hit maxRetries \u2014 notify user\n if (!shouldAttempt(\"autofix-known\", rule.pattern)) {\n notify(adapter, chatId, `\u26A0\uFE0F Wired fix failed 3x for \"${rule.pattern}\" \u2014 suppressed 24h. Manual intervention needed.`);\n }\n } else if (rule.verified === false) {\n // Unverified self-rule first success \u2014 notify\n notify(adapter, chatId, `\uD83D\uDD27 Self-fix ran: \"${rule.pattern}\" \u2192 ${(rule.command ?? []).join(\" \")} \u2713\\nRun /healing approve ${rule.pattern.slice(0, 20)} to silence.`);\n }\n });\n}\n\nfunction handleUnknownFault(errorLine: string, errorKey: string, adapter: TelegramAdapter, chatId: string, onDone: () => void): void {\n if (!shouldAttempt(\"autofix-unknown\", errorKey)) return;\n\n // Skip dispatch during darkwake (deploy restart) or night hours\n const hour = new Date().getHours();\n if (hour < 7) { logDebug(\"self-healer\", `Skipping SHA dispatch \u2014 night hours (${hour}:xx)`); return; }\n try {\n const lock = JSON.parse(readFileSync(join(abtarsHome(), \"bridge.lock\"), \"utf-8\"));\n if (lock.bootType === \"darkwake\") { logDebug(\"self-healer\", \"Skipping SHA dispatch \u2014 darkwake boot\"); return; }\n } catch { /* proceed if unreadable */ }\n\n logInfo(\"self-healer\", `Unknown fault \u2014 dispatching agent: ${errorKey.slice(0, 60)}`);\n logAutoFix(`AGENT START: ${errorKey}`);\n logShaCall(errorKey, errorLine);\n\n // Ensure source is available for SHA to investigate\n const srcDir = join(abtarsHome(), \"src/abtars\");\n if (!existsSync(srcDir)) {\n try {\n mkdirSync(join(abtarsHome(), \"src\"), { recursive: true });\n execSync(`git clone -b dev git@github.com:aksika/abtars.git \"${srcDir}\"`, { timeout: 60_000, stdio: \"ignore\" });\n } catch { /* proceed without source */ }\n }\n\n const prompt = `A runtime error occurred:\\n\"${errorLine.slice(0, 500)}\"\\n\\nBefore investigating, check ~/.abtars/logs/sha-call.log for prior entries matching this error pattern.\\nIf you find a PREVIOUS entry with a similar error pattern:\\n - This is a recurring fault you could not eliminate last time.\\n - Add a suppress rule to ~/.abtars/config/sha-policy-self.json (read existing file, append to fixes array):\\n {\"pattern\": \"<plain substring from the error line>\", \"action\": \"suppress\"}\\n Pattern is matched via substring (includes), NOT regex. Use a distinctive fragment.\\n - Report: \"Recurring unfixable fault \u2014 suppressed.\"\\n - Do NOT attempt a fix.\\n\\nOtherwise, diagnose and fix it. After fixing:\\n1. Report what you did (1 paragraph)\\n2. If this error is likely to recur and you found a deterministic fix, write a wired rule to ~/.abtars/config/sha-policy-self.json:\\n {\"pattern\": \"<substring>\", \"action\": \"run\", \"command\": [...], \"cooldownMin\": 30}\\n Pattern is matched via substring (includes), NOT regex.\\n If the error was a one-off or no reliable automated fix exists, skip this step.\\n\\nIf you cannot find the root cause in the source code, tell the user:\\n\"This may be fixed in a newer version. Try /update to get the latest.\"\nDo NOT attempt to fix code you don't understand.`;\n\n const timeout = setTimeout(() => { onDone(); }, 5 * 60_000);\n\n (async () => {\n try {\n const { spin } = await import(\"./spin.js\");\n const { result } = await spin.dispatchAwait({ type: \"H\", goal: prompt, title: `SHA: ${errorKey.slice(0, 20)}`, source: \"agent\" });\n recordResult(\"autofix-unknown\", errorKey, true);\n logAutoFix(`AGENT OK: ${errorKey} \u2192 ${result.slice(0, 200)}`);\n notify(adapter, chatId, `\uD83E\uDDE0 SHA agent fixed: ${errorKey.slice(0, 40)}\\n${result.slice(0, 300)}`);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n recordResult(\"autofix-unknown\", errorKey, false, msg);\n logAutoFix(`AGENT FAIL: ${errorKey} \u2192 ${msg}`);\n notify(adapter, chatId, `\u26A0\uFE0F SHA agent failed: ${errorKey.slice(0, 40)}\\n${msg.slice(0, 200)}`);\n } finally {\n clearTimeout(timeout);\n onDone();\n }\n })();\n}\n", "/**\n * heartbeat-model-health.ts \u2014 Model health check task.\n * Probes each configured model on first tick. Reports failures to Telegram.\n */\n\nimport { getEnv } from \"../components/env-schema.js\";\nimport { logInfo, logWarn } from \"../components/logger.js\";\nimport type { BootCtx } from \"./context.js\";\nimport type { HeartbeatTask } from \"../types/index.js\";\n\nexport function createModelHealthTask(ctx: BootCtx): { task: HeartbeatTask; runNow: () => Promise<void> } {\n let done = false;\n\n const execute = async (): Promise<void> => {\n if (done) return;\n done = true;\n const { loadTransport, resolveAgent, consumeRepairs } = await import(\"../components/transport-config.js\");\n const tc = loadTransport();\n if (!tc) return;\n\n const repairs = consumeRepairs();\n const warnings: string[] = [];\n if (repairs.length > 0) {\n for (const r of repairs) warnings.push(`\uD83D\uDD27 ${r.agent} auto-repaired: was ${r.oldProvider} \u2014 ${r.reason}`);\n }\n\n const prof = resolveAgent(\"professor\", tc);\n if (!prof) return;\n const profType = prof.provider.transport ?? \"api\";\n\n if (profType === \"api\") {\n const agents = [\"professor\", \"dreamy\", \"browsie\", \"coding\"] as const;\n const modelToAgents = new Map<string, string[]>();\n const modelToResolved = new Map<string, { endpoint: string; apiKey: string }>();\n for (const a of agents) {\n const r = resolveAgent(a, tc);\n if (!r) continue;\n if (!modelToAgents.has(r.model)) {\n modelToAgents.set(r.model, []);\n modelToResolved.set(r.model, { endpoint: r.provider.endpoint ?? \"http://localhost:11434/v1\", apiKey: getEnv().getApiKey(r.provider.apiKeyEnv ?? \"API_KEY\") ?? \"\" });\n }\n modelToAgents.get(r.model)!.push(a);\n }\n for (const [model, agentNames] of modelToAgents) {\n const { endpoint, apiKey } = modelToResolved.get(model)!;\n try {\n const res = await fetch(`${endpoint}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) },\n body: JSON.stringify({ model, messages: [{ role: \"user\", content: \"hi\" }], max_tokens: 1 }),\n signal: AbortSignal.timeout(30_000),\n });\n if (!res.ok) {\n warnings.push(`\u26A0\uFE0F ${model} \u2014 ${res.status} ${res.statusText} (affects ${agentNames.join(\", \")})`);\n logWarn(\"model-health\", `${model} failed: ${res.status} (${agentNames.join(\", \")})`);\n } else {\n logInfo(\"model-health\", `\u2713 ${agentNames[0]}=${model}`);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n warnings.push(`\u26A0\uFE0F ${model} \u2014 ${msg} (affects ${agentNames.join(\", \")})`);\n logWarn(\"model-health\", `${model} unreachable: ${msg} (${agentNames.join(\", \")})`);\n }\n }\n } else if (profType === \"acp\" || profType === \"tmux\") {\n const transport = ctx.transport;\n if (transport && \"isConnected\" in transport && typeof (transport as { isConnected?: () => boolean }).isConnected === \"function\") {\n const connected = (transport as { isConnected: () => boolean }).isConnected();\n if (connected) {\n logInfo(\"model-health\", `\u2713 ${profType} transport connected`);\n } else {\n warnings.push(`\u26A0\uFE0F ${profType} transport not connected`);\n logWarn(\"model-health\", `${profType} transport not connected`);\n }\n } else {\n logInfo(\"model-health\", `\u2713 ${profType} transport (no isConnected check available)`);\n }\n }\n\n if (warnings.length > 0) {\n const { sendNotification } = await import(\"../components/notification.js\");\n sendNotification(ctx, `\uD83C\uDFE5 Model health check:\\n${warnings.join(\"\\n\")}\\nSubagents will fall back to main model.`);\n }\n };\n\n return { task: { name: \"model-health\", execute }, runNow: execute };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|