@symerian/symi 2.6.0 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agents-Bi50kp6u.js → agents-DQIz-_on.js} +4 -4
- package/dist/{agents.config-Duce7lam.js → agents.config-CIJRaVWl.js} +1 -1
- package/dist/{agents.config-BcTeP94V.js → agents.config-D8WPDf-m.js} +1 -1
- package/dist/{audio-preflight-DHTaS5U1.js → audio-preflight-BVaaZWkg.js} +4 -4
- package/dist/{audio-preflight-C40mKAp7.js → audio-preflight-CPBOQV4I.js} +4 -4
- package/dist/{auth-choice-BFIBR4l9.js → auth-choice-BqFbNDuP.js} +1 -1
- package/dist/{auth-choice-Dyq-0MNq.js → auth-choice-DTDyJL1r.js} +1 -1
- package/dist/{banner-D50f_0qf.js → banner-DYDCxnDL.js} +1 -1
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +6 -6
- package/dist/bundled/session-memory/handler.js +6 -6
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-options-BvBcjqyk.js → channel-options-CvHSm_Kx.js} +1 -1
- package/dist/{channel-options-BFqaanEt.js → channel-options-vBCJhJB7.js} +1 -1
- package/dist/{channel-web-BQtFg4IP.js → channel-web-CM2LyWZW.js} +1 -1
- package/dist/{channels-cli-BYFQdWnL.js → channels-cli-D5H3Wcho.js} +4 -4
- package/dist/{channels-cli-BuTH-iVi.js → channels-cli-DzOjNNFn.js} +4 -4
- package/dist/{chrome-DYZwl5Gv.js → chrome-D2SKJnR7.js} +5 -5
- package/dist/{chrome-CDJYxX5a.js → chrome-DkaXoP36.js} +5 -5
- package/dist/{cli-r2L-UK6y.js → cli-8hqssnRJ.js} +1 -1
- package/dist/{cli-eOBlVLcC.js → cli-DNZwCDRe.js} +1 -1
- package/dist/{command-registry-D-pwcAIW.js → command-registry-CHtN2HeK.js} +9 -9
- package/dist/{completion-cli-DMO2OGTm.js → completion-cli-C8y_J5KC.js} +1 -1
- package/dist/{completion-cli-DIx7KyOG.js → completion-cli-Cov6N3BO.js} +2 -2
- package/dist/{config-cli-BsDxqYDU.js → config-cli-B2REEd2l.js} +1 -1
- package/dist/{config-cli-seaVWVru.js → config-cli-BwO0xAbV.js} +1 -1
- package/dist/{configure-BmPwuHXL.js → configure-BWSYSi2-.js} +3 -3
- package/dist/{configure-CqbKA0_V.js → configure-C6yNe33U.js} +3 -3
- package/dist/{deliver-BH0l3UKW.js → deliver-C-37cZUe.js} +1 -1
- package/dist/{deliver-dODxSv3b.js → deliver-C46-vyqg.js} +1 -1
- package/dist/{doctor-completion-DMjs7-Qa.js → doctor-completion-BKKzstt6.js} +1 -1
- package/dist/{doctor-completion-C2IV3lKi.js → doctor-completion-D7CDLFLg.js} +1 -1
- package/dist/entry.js +1 -1
- package/dist/extensionAPI.js +6 -6
- package/dist/{gateway-cli-C-J_s559.js → gateway-cli-BhFM4Bkm.js} +9 -9
- package/dist/{gateway-cli-BanaeKQ_.js → gateway-cli-Datohp3m.js} +9 -9
- package/dist/{glass-ui-ws-DK7x3Tz7.js → glass-ui-ws-BzqfD_wX.js} +7 -7
- package/dist/{glass-ui-ws-DUzp9m0D.js → glass-ui-ws-D9yvYULL.js} +7 -7
- package/dist/{health-DK6rAOhC.js → health-BjwDRAdd.js} +1 -1
- package/dist/{health-BpHgCv-u.js → health-C5XJPwpt.js} +1 -1
- package/dist/{hooks-cli-Cin_3tFg.js → hooks-cli-CafMq9Vr.js} +2 -2
- package/dist/{hooks-cli-D-75G_66.js → hooks-cli-U12oVyLH.js} +2 -2
- package/dist/{image-CXu8W39c.js → image-CuzFLQWC.js} +1 -1
- package/dist/{image-CHzdaNJ4.js → image-DcpMiprB.js} +1 -1
- package/dist/index.js +6 -6
- package/dist/llm-slug-generator.js +6 -6
- package/dist/{models-CeKIXf5B.js → models-Bo4iHJy-.js} +2 -2
- package/dist/{models-cli-2NcPKR9A.js → models-cli-6aNi3eN9.js} +2 -2
- package/dist/{models-cli-DN4AVlpI.js → models-cli-B5vh-XK8.js} +3 -3
- package/dist/{onboard-BcxDiUl_.js → onboard-Bm-pmstf.js} +2 -2
- package/dist/{onboard-channels-HPxu77wp.js → onboard-channels-BRd1cXye.js} +1 -1
- package/dist/{onboard-channels-DS6s341R.js → onboard-channels-CUl5U8kV.js} +1 -1
- package/dist/{onboard-BukRqcRH.js → onboard-f-GJ26Ix.js} +2 -2
- package/dist/{onboarding-B8uz24jt.js → onboarding-CvBDWlBJ.js} +3 -3
- package/dist/{onboarding-DI-o_sax.js → onboarding-DIVKvosg.js} +3 -3
- package/dist/{onboarding.finalize-CfE_AEto.js → onboarding.finalize-DJX6mSLa.js} +6 -6
- package/dist/{onboarding.finalize-Bn2e61yb.js → onboarding.finalize-WSac-JKd.js} +5 -5
- package/dist/{pi-embedded-B5qBa69e.js → pi-embedded-BmbbC1Sb.js} +133 -27
- package/dist/{pi-embedded-helpers-lgx_U5KS.js → pi-embedded-helpers-B8kqLWns.js} +4 -4
- package/dist/{pi-embedded-helpers-pubKo8HQ.js → pi-embedded-helpers-CfqDGQ9J.js} +4 -4
- package/dist/{plugin-registry-NIUxULTk.js → plugin-registry-2zUJMasm.js} +1 -1
- package/dist/{plugin-registry-cj99EI0k.js → plugin-registry-5yf-hu_W.js} +1 -1
- package/dist/plugin-sdk/{accounts-BtaOa4z_.js → accounts-BToL3HlP.js} +1 -1
- package/dist/plugin-sdk/{accounts-Ddm33hQm.js → accounts-D9zGZU5t.js} +3 -3
- package/dist/plugin-sdk/{accounts-s-AdhXVR.js → accounts-Dtszw3Zn.js} +1 -1
- package/dist/plugin-sdk/{active-listener-BXYeALs0.js → active-listener-bEk__wbB.js} +1 -1
- package/dist/plugin-sdk/{agent-scope-CYYpcO9W.js → agent-scope-C3gMMKCU.js} +2 -2
- package/dist/plugin-sdk/agents/model-token-filter.d.ts +10 -0
- package/dist/plugin-sdk/agents/pi-tools.validate-wrapper.d.ts +23 -0
- package/dist/plugin-sdk/agents/pi-tools.validate.d.ts +26 -0
- package/dist/plugin-sdk/agents/tool-loop-detection.d.ts +3 -1
- package/dist/plugin-sdk/{api-key-rotation-D_sMvI5W.js → api-key-rotation-CVBMpnPc.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-VpItkiy3.js → audio-preflight-DoQQKlxa.js} +24 -24
- package/dist/plugin-sdk/{bindings-C7hRtgYW.js → bindings-BbwoUGPx.js} +2 -2
- package/dist/plugin-sdk/{channel-activity-DoC1xtDu.js → channel-activity-Ji7f0gqq.js} +1 -1
- package/dist/plugin-sdk/{channel-web-CSd16cDi.js → channel-web-DPyyTvFo.js} +22 -22
- package/dist/plugin-sdk/{chrome-B7RdxmJ0.js → chrome-C7c_0I5M.js} +3 -3
- package/dist/plugin-sdk/{chunk-Dw2XBYXv.js → chunk-jvk9axTQ.js} +1 -1
- package/dist/plugin-sdk/{command-format-GKSevep4.js → command-format-DSdvQ_M5.js} +1 -1
- package/dist/plugin-sdk/{commands-registry-COIaslGl.js → commands-registry-CQFbmUMs.js} +4 -4
- package/dist/plugin-sdk/config/model-profiles.d.ts +2 -0
- package/dist/plugin-sdk/{config-KlTNfkFF.js → config-DDkdiUOR.js} +9 -9
- package/dist/plugin-sdk/{deliver-BZ99UKQq.js → deliver-BZ6iNLl7.js} +10 -10
- package/dist/plugin-sdk/{diagnostic-05pm5Rxi.js → diagnostic-mFf4i4G9.js} +1 -1
- package/dist/plugin-sdk/{image-CLOPx7yW.js → image-BOYy0Ump.js} +4 -4
- package/dist/plugin-sdk/{image-ops-BlQR__MN.js → image-ops-Bnp6LXEx.js} +1 -1
- package/dist/plugin-sdk/index.js +53 -53
- package/dist/plugin-sdk/infra/diagnostic-events.d.ts +1 -1
- package/dist/plugin-sdk/{ir-BJ6BHE5b.js → ir-Fb3qpcis.js} +4 -4
- package/dist/plugin-sdk/{local-roots-BHLNSI8U.js → local-roots-Ckk1QfzI.js} +3 -3
- package/dist/plugin-sdk/logging/diagnostic-session-state.d.ts +2 -0
- package/dist/plugin-sdk/logging/diagnostic.d.ts +1 -1
- package/dist/plugin-sdk/{login-DQMXuxOk.js → login-Bh3DZPam.js} +7 -7
- package/dist/plugin-sdk/{login-qr-BjVZSoCi.js → login-qr-DbR7odSr.js} +9 -9
- package/dist/plugin-sdk/{manager-CBSBFuFz.js → manager-DckktAQ3.js} +8 -8
- package/dist/plugin-sdk/{manifest-registry-CPnHl_K3.js → manifest-registry-B3ugY9-f.js} +1 -1
- package/dist/plugin-sdk/{markdown-tables-BoYFajMu.js → markdown-tables-Dfaqilz6.js} +1 -1
- package/dist/plugin-sdk/{message-channel-COTAJzHd.js → message-channel-BdI5Ra9S.js} +1 -1
- package/dist/plugin-sdk/{model-selection-CsbEfrS0.js → model-selection-OpU8HN50.js} +4 -4
- package/dist/plugin-sdk/{outbound-attachment-CnslKL38.js → outbound-attachment-DnVQfTG2.js} +2 -2
- package/dist/plugin-sdk/{outbound-B0e8KdaR.js → outbound-rF6G8Xpr.js} +7 -7
- package/dist/plugin-sdk/{pi-auth-json-qWi7ZIYV.js → pi-auth-json-CJk8t14T.js} +5 -5
- package/dist/plugin-sdk/{pi-embedded-helpers-CW630epe.js → pi-embedded-helpers-BveUP4hk.js} +17 -17
- package/dist/plugin-sdk/{plugins-BNByVCIH.js → plugins-BbAvhC25.js} +4 -4
- package/dist/plugin-sdk/{pw-ai-CnbPIPY9.js → pw-ai-DjGUsee-.js} +8 -8
- package/dist/plugin-sdk/{qmd-manager-CH0XbIHf.js → qmd-manager-mjKcdwVr.js} +4 -4
- package/dist/plugin-sdk/{registry-D0xTnUWt.js → registry--_pGht6S.js} +2 -2
- package/dist/plugin-sdk/{replies-LLcQL3w6.js → replies-fI39rPGa.js} +3 -3
- package/dist/plugin-sdk/{reply-CkqSfQZN.js → reply-QAcAd9ev.js} +193 -87
- package/dist/plugin-sdk/{reply-prefix-uxfMZW4p.js → reply-prefix-BHuV5t70.js} +1 -1
- package/dist/plugin-sdk/{resolve-outbound-target-BiyAyTWz.js → resolve-outbound-target-BkCUbYGV.js} +2 -2
- package/dist/plugin-sdk/{resolve-route-B3CCBumQ.js → resolve-route-D3JH_D2N.js} +3 -3
- package/dist/plugin-sdk/{retry-CwQ_iIj8.js → retry-ilSJqnz9.js} +1 -1
- package/dist/plugin-sdk/{runner-CGBT7tgF.js → runner-BVqnEfNe.js} +9 -9
- package/dist/plugin-sdk/{send-C5h_YxNb.js → send-BHbXh8Ly.js} +7 -7
- package/dist/plugin-sdk/{send-pYqe432l.js → send-BMfJIhCk.js} +6 -6
- package/dist/plugin-sdk/{send-B2CEnVLL.js → send-BtANzsAo.js} +6 -6
- package/dist/plugin-sdk/{send-CjOBB3Vo.js → send-Bxdu6ZZy.js} +10 -10
- package/dist/plugin-sdk/{send-CRsR8-vO.js → send-D6LMZJ_h.js} +10 -10
- package/dist/plugin-sdk/{session-BsOrxiMj.js → session-kI0tzViQ.js} +4 -4
- package/dist/plugin-sdk/{skill-commands-ff_01_r3.js → skill-commands-DCNXVERE.js} +5 -5
- package/dist/plugin-sdk/{skills-_yTP47Cd.js → skills-B1GeRYlu.js} +7 -7
- package/dist/plugin-sdk/{sqlite-CxAR5ttJ.js → sqlite-Cq_7Cg4E.js} +1 -1
- package/dist/plugin-sdk/{store-BdrNabcU.js → store-Do3t33-c.js} +2 -2
- package/dist/plugin-sdk/{subsystem-B2uDN3TV.js → subsystem-Coz2AgU8.js} +1 -1
- package/dist/plugin-sdk/{tables-DNwXwNFa.js → tables-DR0NmBeH.js} +1 -1
- package/dist/plugin-sdk/{target-errors-Paro1BjP.js → target-errors-B7YyMnIi.js} +2 -2
- package/dist/plugin-sdk/{thinking-CXqf7WTe.js → thinking-DCNUIAHY.js} +5 -5
- package/dist/plugin-sdk/{tokens-bC3UVmVH.js → tokens-CWMflosr.js} +1 -1
- package/dist/plugin-sdk/{tool-images-HJ2sfZDV.js → tool-images-D7Lno-TE.js} +2 -2
- package/dist/plugin-sdk/{tool-loop-detection-BVA6fax-.js → tool-loop-detection-DU5sTIKg.js} +55 -5
- package/dist/plugin-sdk/web-DaTTL9M0.js +65 -0
- package/dist/plugin-sdk/{whatsapp-actions-DfseosPO.js → whatsapp-actions-CcBzDuL-.js} +21 -21
- package/dist/{plugins-cli-CcjxxESJ.js → plugins-cli-D4eRESV2.js} +2 -2
- package/dist/{plugins-cli-D8hhTHZD.js → plugins-cli-DksVl33N.js} +2 -2
- package/dist/{program-D09h71pS.js → program-BjORH7Cc.js} +7 -7
- package/dist/{program-context-CLJSWBZr.js → program-context-DaNGrTOm.js} +17 -17
- package/dist/{prompt-select-styled-zRUqu0c8.js → prompt-select-styled-QaS2zul_.js} +4 -4
- package/dist/{prompt-select-styled-DQqZEGoo.js → prompt-select-styled-YOj4xigd.js} +4 -4
- package/dist/{provider-auth-helpers-16r2WHNe.js → provider-auth-helpers-BAGT_RXV.js} +1 -1
- package/dist/{provider-auth-helpers-LzJ2WQIc.js → provider-auth-helpers-DCEbm2hz.js} +1 -1
- package/dist/{push-apns-B5xZKIxK.js → push-apns-BECodU1i.js} +1 -1
- package/dist/{push-apns-DJddAK3u.js → push-apns-Bek3ANJa.js} +1 -1
- package/dist/{pw-ai-De-KR9_s.js → pw-ai-1htA-NnS.js} +1 -1
- package/dist/{pw-ai-B5asscAD.js → pw-ai-m0mj2KWK.js} +1 -1
- package/dist/{register.agent-D7NKuUkY.js → register.agent-B34lxx7F.js} +5 -5
- package/dist/{register.agent-CP_sigRh.js → register.agent-DJHQo-Iq.js} +6 -6
- package/dist/{register.configure-BEsGd0PR.js → register.configure-BdhhIzb0.js} +6 -6
- package/dist/{register.configure-BjRLNatb.js → register.configure-DC_-t5kj.js} +6 -6
- package/dist/{register.maintenance-DD6TNFtV.js → register.maintenance-CITur3O_.js} +8 -8
- package/dist/{register.maintenance-CN6KUuX7.js → register.maintenance-cs-A4kHF.js} +7 -7
- package/dist/{register.message-DEUcNly1.js → register.message--RhtnEYn.js} +2 -2
- package/dist/{register.message-DMVC_Sqm.js → register.message-PIaHm2pZ.js} +2 -2
- package/dist/{register.onboard-CP6RP90V.js → register.onboard-CTJQoDcK.js} +4 -4
- package/dist/{register.onboard-J1pgV7lz.js → register.onboard-DucZgrF7.js} +4 -4
- package/dist/{register.setup-Dhc3jKpK.js → register.setup-2ZiUN7ui.js} +4 -4
- package/dist/{register.setup-BeHpW3xI.js → register.setup-DD4Rgkt9.js} +4 -4
- package/dist/{register.status-health-sessions-b-lWNsTM.js → register.status-health-sessions-BqD7L8XL.js} +3 -3
- package/dist/{register.status-health-sessions-DDkC0aoW.js → register.status-health-sessions-sLgA92t7.js} +3 -3
- package/dist/{register.subclis-BJqiT8Q2.js → register.subclis-B2dGWFur.js} +9 -9
- package/dist/{reply-D40cmAci.js → reply-DYnTEYoa.js} +119 -13
- package/dist/{run-main-BruREeZ6.js → run-main-DWmu2b6D.js} +14 -14
- package/dist/{runner-DUBExAb5.js → runner-BcQ0sF9T.js} +1 -1
- package/dist/{runner-WAG0M5s9.js → runner-CU9l0uJh.js} +1 -1
- package/dist/{server-methods-K-0MHs8x.js → server-methods-C8EWZt2g.js} +7 -7
- package/dist/{server-methods-Cyw_WS3A.js → server-methods-vDGoM3xL.js} +7 -7
- package/dist/{server-node-events-89R9Ryky.js → server-node-events-CKi12bol.js} +2 -2
- package/dist/{server-node-events-RA8RurtC.js → server-node-events-DFwGbkcO.js} +2 -2
- package/dist/{status-DHJLMwQN.js → status--iNVOTMO.js} +2 -2
- package/dist/{status-CtNKWuzg.js → status-B1_iHrOg.js} +2 -2
- package/dist/{status-BSMEjz4q.js → status-BQcdARV4.js} +1 -1
- package/dist/{status-Kv_hsY8N.js → status-DiX0DAtH.js} +1 -1
- package/dist/{subagent-registry-Cb5e_x99.js → subagent-registry-CXrOOgPW.js} +119 -13
- package/dist/{tool-loop-detection-BgbtzUGc.js → tool-loop-detection-C7TCF2V2.js} +53 -3
- package/dist/{tool-loop-detection-BU3fbtCd.js → tool-loop-detection-D7qjFnRh.js} +53 -3
- package/dist/{tool-loop-detection-B6j1r-Wk.js → tool-loop-detection-DPVtQOfM.js} +53 -3
- package/dist/{tool-loop-detection-D0kUzUGu.js → tool-loop-detection-DR_rrIA1.js} +53 -3
- package/dist/{unified-runner-CkJLTsTK.js → unified-runner-CulJZMxc.js} +133 -27
- package/dist/{update-cli-Bl66LJZ4.js → update-cli-560gprSp.js} +7 -7
- package/dist/{update-cli-CrRBoiVU.js → update-cli-D1pLX3eo.js} +8 -8
- package/dist/{update-runner-DxpSPK-f.js → update-runner-BQxFFCGc.js} +1 -1
- package/dist/{update-runner-FgrqoxvV.js → update-runner-CLKHrONW.js} +1 -1
- package/dist/{web-Czp0JS6-.js → web-Bqrgp43v.js} +1 -1
- package/dist/{web-D99WHLTL.js → web-D4qJ9XKP.js} +6 -6
- package/dist/{web-BYRKX5Ln.js → web-Dr5cOn-1.js} +2 -2
- package/dist/{web-RePh7lRy.js → web-hHX9a9YO.js} +6 -6
- package/package.json +1 -1
- package/dist/plugin-sdk/web-DdTTil50.js +0 -65
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { u as resolveGatewayPort } from "./paths-Cqn-zk3M.js";
|
|
2
2
|
import { B as theme, k as info, z as isRich } from "./utils-B-0b9bGM.js";
|
|
3
|
-
import { B as summarizeRestartSentinel, Jt as sha256HexPrefix, _t as formatUsageReportLines, a as buildChannelSummary, gt as loadProviderUsageSummary, h as listAgentsForGateway, m as classifySessionKey, o as buildChannelAccountSnapshot, pr as lookupContextTokens, s as formatChannelAllowFrom, wr as peekSystemEvents, x as resolveSessionModelRef, z as readRestartSentinel } from "./reply-
|
|
3
|
+
import { B as summarizeRestartSentinel, Jt as sha256HexPrefix, _t as formatUsageReportLines, a as buildChannelSummary, gt as loadProviderUsageSummary, h as listAgentsForGateway, m as classifySessionKey, o as buildChannelAccountSnapshot, pr as lookupContextTokens, s as formatChannelAllowFrom, wr as peekSystemEvents, x as resolveSessionModelRef, z as readRestartSentinel } from "./reply-DYnTEYoa.js";
|
|
4
4
|
import { S as parseAgentSessionKey } from "./session-key-DCt45XZa.js";
|
|
5
5
|
import { t as resolveSymiPackageRoot } from "./symi-root-CrGJbkzf.js";
|
|
6
6
|
import { n as runExec } from "./exec-CWkblSrI.js";
|
|
@@ -28,7 +28,7 @@ import { t as formatRuntimeStatusWithDetails } from "./runtime-status-CR9445g5.j
|
|
|
28
28
|
import { t as readLastGatewayErrorLine } from "./diagnostics-BAMlsVVX.js";
|
|
29
29
|
import { t as renderTable } from "./table-BTgkRafz.js";
|
|
30
30
|
import { a as resolveGatewayProbeAuth$1, c as probeGateway, t as runSecurityAudit } from "./audit-CrITRV6w.js";
|
|
31
|
-
import { a as resolveHeartbeatSummaryForAgent, t as formatHealthChannelLines } from "./health-
|
|
31
|
+
import { a as resolveHeartbeatSummaryForAgent, t as formatHealthChannelLines } from "./health-BjwDRAdd.js";
|
|
32
32
|
import { g as resolveUpdateChannelDisplay, i as formatGitInstallLabel, m as normalizeUpdateChannel, t as checkUpdateStatus } from "./update-check-CtckACbb.js";
|
|
33
33
|
import { t as resolveNodeService } from "./node-service-Cxz4e-Qd.js";
|
|
34
34
|
import { n as redactSecrets, t as formatGatewayAuthUsed } from "./format-yQZNwAF2.js";
|
|
@@ -9,7 +9,7 @@ import { c as resolveAgentWorkspaceDir } from "./agent-scope-D-jRCY0d.js";
|
|
|
9
9
|
import { t as buildWorkspaceSkillStatus } from "./skills-status-DKXJ-tbi.js";
|
|
10
10
|
import { H as VERSION, i as loadConfig, o as readConfigFileSnapshot } from "./config-DHBLS1Hl.js";
|
|
11
11
|
import { n as callGateway, t as buildGatewayConnectionDetails } from "./call-BcE47FtD.js";
|
|
12
|
-
import { En as peekSystemEvents, St as summarizeRestartSentinel, cn as buildChannelAccountSnapshot, in as formatUsageReportLines, ln as formatChannelAllowFrom, nt as sha256HexPrefix, rn as loadProviderUsageSummary, sn as buildChannelSummary, xt as readRestartSentinel } from "./subagent-registry-
|
|
12
|
+
import { En as peekSystemEvents, St as summarizeRestartSentinel, cn as buildChannelAccountSnapshot, in as formatUsageReportLines, ln as formatChannelAllowFrom, nt as sha256HexPrefix, rn as loadProviderUsageSummary, sn as buildChannelSummary, xt as readRestartSentinel } from "./subagent-registry-CXrOOgPW.js";
|
|
13
13
|
import { F as resolveMainSessionKey, j as resolveFreshSessionTotalTokens, o as loadSessionStore } from "./sessions-CJXnZVjR.js";
|
|
14
14
|
import { n as listChannelPlugins } from "./plugins-CwSlLxM8.js";
|
|
15
15
|
import { o as getTailnetHostname, s as readTailscaleStatusJson } from "./tailscale-CbbvYNVw.js";
|
|
@@ -29,7 +29,7 @@ import { t as formatRuntimeStatusWithDetails } from "./runtime-status-hFVEC3wO.j
|
|
|
29
29
|
import { t as readLastGatewayErrorLine } from "./diagnostics-CS1ov_hH.js";
|
|
30
30
|
import { t as renderTable } from "./table-D01d2GuY.js";
|
|
31
31
|
import { a as resolveGatewayProbeAuth$1, c as probeGateway, t as runSecurityAudit } from "./audit-Byo5jCLN.js";
|
|
32
|
-
import { o as resolveHeartbeatSummaryForAgent, t as formatHealthChannelLines } from "./health-
|
|
32
|
+
import { o as resolveHeartbeatSummaryForAgent, t as formatHealthChannelLines } from "./health-C5XJPwpt.js";
|
|
33
33
|
import { g as resolveUpdateChannelDisplay, i as formatGitInstallLabel, m as normalizeUpdateChannel, t as checkUpdateStatus } from "./update-check-ZdimP1aU.js";
|
|
34
34
|
import { t as resolveNodeService } from "./node-service-fcZExd22.js";
|
|
35
35
|
import { n as redactSecrets, t as formatGatewayAuthUsed } from "./format-DVLB9DNB.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { o as createSubsystemLogger } from "./entry.js";
|
|
2
2
|
import { D as resolveDefaultAgentWorkspaceDir, c as resolveAgentWorkspaceDir, l as resolveDefaultAgentId } from "./agent-scope-D-jRCY0d.js";
|
|
3
3
|
import { i as loadConfig } from "./config-DHBLS1Hl.js";
|
|
4
|
-
import { m as loadSymiPlugins, p as createPluginLoaderLogger } from "./subagent-registry-
|
|
4
|
+
import { m as loadSymiPlugins, p as createPluginLoaderLogger } from "./subagent-registry-CXrOOgPW.js";
|
|
5
5
|
|
|
6
6
|
//#region src/plugins/status.ts
|
|
7
7
|
const log = createSubsystemLogger("plugins");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { dt as createPluginLoaderLogger, ft as loadSymiPlugins } from "./reply-
|
|
1
|
+
import { dt as createPluginLoaderLogger, ft as loadSymiPlugins } from "./reply-DYnTEYoa.js";
|
|
2
2
|
import { t as createSubsystemLogger } from "./subsystem-D9vIQve0.js";
|
|
3
3
|
import { D as resolveDefaultAgentWorkspaceDir, c as resolveAgentWorkspaceDir, l as resolveDefaultAgentId } from "./agent-scope-CgUHAtCo.js";
|
|
4
4
|
import { i as loadConfig } from "./config-CHwyw6l5.js";
|
|
@@ -32327,7 +32327,8 @@ const BUILTIN_PROFILES = [
|
|
|
32327
32327
|
"<end_of_turn>"
|
|
32328
32328
|
],
|
|
32329
32329
|
suppressMonologue: true,
|
|
32330
|
-
hasStructuredThinking: false
|
|
32330
|
+
hasStructuredThinking: false,
|
|
32331
|
+
validateToolArgs: true
|
|
32331
32332
|
},
|
|
32332
32333
|
promptAdditions: [
|
|
32333
32334
|
"CRITICAL OUTPUT RULES:",
|
|
@@ -32337,7 +32338,8 @@ const BUILTIN_PROFILES = [
|
|
|
32337
32338
|
"- Do not write verification checklists, self-assessments, or numbered assessment lists after your answer.",
|
|
32338
32339
|
"- Do not write 'Verification:', 'Requirements:', 'Status Check:', or 'Everything is correct'.",
|
|
32339
32340
|
"- If you need to verify your work, do so before writing your response, not after.",
|
|
32340
|
-
"- Send brief progress updates on long tasks so the user knows you are active."
|
|
32341
|
+
"- Send brief progress updates on long tasks so the user knows you are active.",
|
|
32342
|
+
"- When calling tools, provide arguments as clean values only. Never include <|, |>, or XML-like tags in tool argument values. For exec/bash commands, provide only valid shell syntax."
|
|
32341
32343
|
],
|
|
32342
32344
|
ui: {
|
|
32343
32345
|
badge: "Local",
|
|
@@ -32361,7 +32363,8 @@ const BUILTIN_PROFILES = [
|
|
|
32361
32363
|
filters: {
|
|
32362
32364
|
stripPatterns: [],
|
|
32363
32365
|
suppressMonologue: false,
|
|
32364
|
-
hasStructuredThinking: true
|
|
32366
|
+
hasStructuredThinking: true,
|
|
32367
|
+
validateToolArgs: false
|
|
32365
32368
|
},
|
|
32366
32369
|
promptAdditions: [],
|
|
32367
32370
|
ui: {
|
|
@@ -32395,7 +32398,8 @@ const BUILTIN_PROFILES = [
|
|
|
32395
32398
|
"^\\s*<bos>\\s*"
|
|
32396
32399
|
],
|
|
32397
32400
|
suppressMonologue: true,
|
|
32398
|
-
hasStructuredThinking: false
|
|
32401
|
+
hasStructuredThinking: false,
|
|
32402
|
+
validateToolArgs: true
|
|
32399
32403
|
},
|
|
32400
32404
|
promptAdditions: [
|
|
32401
32405
|
"CRITICAL OUTPUT RULES:",
|
|
@@ -32406,7 +32410,8 @@ const BUILTIN_PROFILES = [
|
|
|
32406
32410
|
"- Do not write 'Verification:', 'Requirements:', 'Status Check:', or 'Everything is correct'.",
|
|
32407
32411
|
"- If you need to verify your work, do so before writing your response, not after.",
|
|
32408
32412
|
"- Keep planning and reasoning internal. Only speak when you have a result or need user input.",
|
|
32409
|
-
"- When working on multi-step tasks, send a brief one-line status update so the user knows you are active."
|
|
32413
|
+
"- When working on multi-step tasks, send a brief one-line status update so the user knows you are active.",
|
|
32414
|
+
"- When calling tools, provide arguments as clean values only. Never include <|, |>, or XML-like tags in tool argument values. For exec/bash commands, provide only valid shell syntax."
|
|
32410
32415
|
],
|
|
32411
32416
|
ui: {
|
|
32412
32417
|
badge: "CoreWeave",
|
|
@@ -32434,7 +32439,8 @@ const FALLBACK_PROFILE = {
|
|
|
32434
32439
|
filters: {
|
|
32435
32440
|
stripPatterns: [],
|
|
32436
32441
|
suppressMonologue: false,
|
|
32437
|
-
hasStructuredThinking: false
|
|
32442
|
+
hasStructuredThinking: false,
|
|
32443
|
+
validateToolArgs: false
|
|
32438
32444
|
},
|
|
32439
32445
|
promptAdditions: [],
|
|
32440
32446
|
ui: {
|
|
@@ -32861,6 +32867,19 @@ function stripModelTokensAggressive(text, modelId) {
|
|
|
32861
32867
|
}
|
|
32862
32868
|
return result;
|
|
32863
32869
|
}
|
|
32870
|
+
/**
|
|
32871
|
+
* Clean residual fragments left after aggressive token stripping.
|
|
32872
|
+
* After `<|` and `|>` are removed, orphaned `<`, `"`, `|` can remain
|
|
32873
|
+
* at string boundaries (e.g., `<<|"|uname -a` → `<"uname -a`).
|
|
32874
|
+
*
|
|
32875
|
+
* Conservative: only trims leading junk before what looks like a command,
|
|
32876
|
+
* and trailing junk. Does NOT touch content in the middle of the string.
|
|
32877
|
+
* Preserves heredoc syntax (`<<EOF`, `<<"EOF"`) via negative lookahead.
|
|
32878
|
+
*/
|
|
32879
|
+
function cleanResidualTokenFragments(text) {
|
|
32880
|
+
if (!text) return text;
|
|
32881
|
+
return text.replace(/^[<"|]+(?!<[A-Z_])(?=[a-zA-Z0-9/~$.(])/gm, "").replace(/[<"|]+$/gm, "").trim();
|
|
32882
|
+
}
|
|
32864
32883
|
|
|
32865
32884
|
//#endregion
|
|
32866
32885
|
//#region src/agents/output-normalizer.ts
|
|
@@ -32946,10 +32965,14 @@ function detectRepetition(text, minBlock) {
|
|
|
32946
32965
|
const searchStart = sampleStart + minBlock;
|
|
32947
32966
|
return text.indexOf(sample, searchStart) >= 0;
|
|
32948
32967
|
}
|
|
32968
|
+
function sanitizeStringValue(value, modelId) {
|
|
32969
|
+
const stripped = stripModelTokensAggressive(value, modelId);
|
|
32970
|
+
return isGemmaModel$1(modelId) ? cleanResidualTokenFragments(stripped) : stripped;
|
|
32971
|
+
}
|
|
32949
32972
|
function sanitizeArgs(args, modelId) {
|
|
32950
32973
|
const result = {};
|
|
32951
|
-
for (const [key, value] of Object.entries(args)) if (typeof value === "string") result[key] =
|
|
32952
|
-
else if (Array.isArray(value)) result[key] = value.map((item) => typeof item === "string" ?
|
|
32974
|
+
for (const [key, value] of Object.entries(args)) if (typeof value === "string") result[key] = sanitizeStringValue(value, modelId);
|
|
32975
|
+
else if (Array.isArray(value)) result[key] = value.map((item) => typeof item === "string" ? sanitizeStringValue(item, modelId) : item && typeof item === "object" ? sanitizeArgs(item, modelId) : item);
|
|
32953
32976
|
else if (value && typeof value === "object") result[key] = sanitizeArgs(value, modelId);
|
|
32954
32977
|
else result[key] = value;
|
|
32955
32978
|
return result;
|
|
@@ -35243,7 +35266,7 @@ async function recordLoopOutcome(args) {
|
|
|
35243
35266
|
if (!args.ctx?.sessionKey) return;
|
|
35244
35267
|
try {
|
|
35245
35268
|
const { getDiagnosticSessionState } = await import("./diagnostic-session-state-CIjIGxEE.js").then((n) => n.n);
|
|
35246
|
-
const { recordToolCallOutcome } = await import("./tool-loop-detection-
|
|
35269
|
+
const { recordToolCallOutcome } = await import("./tool-loop-detection-D7qjFnRh.js");
|
|
35247
35270
|
recordToolCallOutcome(getDiagnosticSessionState({
|
|
35248
35271
|
sessionKey: args.ctx.sessionKey,
|
|
35249
35272
|
sessionId: args.ctx?.agentId
|
|
@@ -35265,7 +35288,7 @@ async function runBeforeToolCallHook(args) {
|
|
|
35265
35288
|
if (args.ctx?.sessionKey) {
|
|
35266
35289
|
const { getDiagnosticSessionState } = await import("./diagnostic-session-state-CIjIGxEE.js").then((n) => n.n);
|
|
35267
35290
|
const { logToolLoopAction } = await import("./diagnostic-Ci8Xsc_Y.js").then((n) => n.n);
|
|
35268
|
-
const { detectToolCallLoop, recordToolCall } = await import("./tool-loop-detection-
|
|
35291
|
+
const { detectToolCallLoop, recordToolCall } = await import("./tool-loop-detection-D7qjFnRh.js");
|
|
35269
35292
|
const sessionState = getDiagnosticSessionState({
|
|
35270
35293
|
sessionKey: args.ctx.sessionKey,
|
|
35271
35294
|
sessionId: args.ctx?.agentId
|
|
@@ -35536,6 +35559,88 @@ function toClientToolDefinitions(tools, onClientToolCall, hookContext) {
|
|
|
35536
35559
|
});
|
|
35537
35560
|
}
|
|
35538
35561
|
|
|
35562
|
+
//#endregion
|
|
35563
|
+
//#region src/agents/pi-tools.validate.ts
|
|
35564
|
+
/**
|
|
35565
|
+
* Tool argument validation — validates that exec/bash commands contain
|
|
35566
|
+
* valid shell syntax after model token sanitization.
|
|
35567
|
+
*
|
|
35568
|
+
* Gated on ModelProfile.filters.validateToolArgs — only active for
|
|
35569
|
+
* models known to leak control tokens into structured output (Gemma, Ollama).
|
|
35570
|
+
*
|
|
35571
|
+
* @module
|
|
35572
|
+
*/
|
|
35573
|
+
/**
|
|
35574
|
+
* Validate that a command string contains extractable valid shell syntax.
|
|
35575
|
+
* Returns the cleaned command if valid, or an error reason if not.
|
|
35576
|
+
*
|
|
35577
|
+
* Does NOT attempt to parse the full shell grammar — just checks for
|
|
35578
|
+
* obvious corruption (residual control tokens, empty commands).
|
|
35579
|
+
* Preserves heredocs, redirects, pipes, and other legitimate shell syntax.
|
|
35580
|
+
*/
|
|
35581
|
+
function validateShellCommand(command) {
|
|
35582
|
+
if (!command || !command.trim()) return {
|
|
35583
|
+
valid: false,
|
|
35584
|
+
cleaned: "",
|
|
35585
|
+
reason: "empty command"
|
|
35586
|
+
};
|
|
35587
|
+
let cleaned = cleanResidualTokenFragments(command);
|
|
35588
|
+
if (/(?:^|[^<])<\|/.test(cleaned) || /\|>/.test(cleaned)) {
|
|
35589
|
+
cleaned = cleaned.replace(/<\|[^|>]*(?:\|>)?/g, "").trim();
|
|
35590
|
+
cleaned = cleanResidualTokenFragments(cleaned);
|
|
35591
|
+
}
|
|
35592
|
+
if (!cleaned || !cleaned.trim()) return {
|
|
35593
|
+
valid: false,
|
|
35594
|
+
cleaned: "",
|
|
35595
|
+
reason: "command is empty after removing control tokens"
|
|
35596
|
+
};
|
|
35597
|
+
if (!/[a-zA-Z0-9_/.~-]/.test(cleaned)) return {
|
|
35598
|
+
valid: false,
|
|
35599
|
+
cleaned,
|
|
35600
|
+
reason: "no recognizable shell command found"
|
|
35601
|
+
};
|
|
35602
|
+
return {
|
|
35603
|
+
valid: true,
|
|
35604
|
+
cleaned: cleaned.trim()
|
|
35605
|
+
};
|
|
35606
|
+
}
|
|
35607
|
+
|
|
35608
|
+
//#endregion
|
|
35609
|
+
//#region src/agents/pi-tools.validate-wrapper.ts
|
|
35610
|
+
const EXEC_TOOL_NAMES = new Set(["exec", "bash"]);
|
|
35611
|
+
/**
|
|
35612
|
+
* Wrap tools with argument validation. Only exec/bash tools are validated.
|
|
35613
|
+
* Other tools pass through unchanged.
|
|
35614
|
+
*
|
|
35615
|
+
* Call this AFTER tools are created and the model profile is resolved.
|
|
35616
|
+
*/
|
|
35617
|
+
function wrapToolsWithArgValidation(tools, profile) {
|
|
35618
|
+
if (!profile.filters?.validateToolArgs) return tools;
|
|
35619
|
+
return tools.map((tool) => wrapToolWithArgValidation(tool));
|
|
35620
|
+
}
|
|
35621
|
+
/**
|
|
35622
|
+
* Wrap a single tool with argument validation for exec/bash commands.
|
|
35623
|
+
*/
|
|
35624
|
+
function wrapToolWithArgValidation(tool) {
|
|
35625
|
+
const toolName = (tool.name ?? "").toLowerCase().trim();
|
|
35626
|
+
if (!EXEC_TOOL_NAMES.has(toolName)) return tool;
|
|
35627
|
+
const originalExecute = tool.execute;
|
|
35628
|
+
return {
|
|
35629
|
+
...tool,
|
|
35630
|
+
execute(toolCallId, params, ...rest) {
|
|
35631
|
+
const command = params.command ?? params.cmd;
|
|
35632
|
+
if (typeof command !== "string") return originalExecute.call(tool, toolCallId, params, ...rest);
|
|
35633
|
+
const result = validateShellCommand(command);
|
|
35634
|
+
if (!result.valid) return Promise.resolve({ output: `Error: ${result.reason}. The command appears to contain model control tokens. Please provide a clean shell command without any <|, |>, or XML-like tags. Only valid shell syntax is accepted.` });
|
|
35635
|
+
if (result.cleaned !== command) return originalExecute.call(tool, toolCallId, {
|
|
35636
|
+
...params,
|
|
35637
|
+
command: result.cleaned
|
|
35638
|
+
}, ...rest);
|
|
35639
|
+
return originalExecute.call(tool, toolCallId, params, ...rest);
|
|
35640
|
+
}
|
|
35641
|
+
};
|
|
35642
|
+
}
|
|
35643
|
+
|
|
35539
35644
|
//#endregion
|
|
35540
35645
|
//#region src/agents/plan-mode.ts
|
|
35541
35646
|
/**
|
|
@@ -39488,10 +39593,11 @@ async function runEmbeddedAttempt(params) {
|
|
|
39488
39593
|
await resourceLoader.reload();
|
|
39489
39594
|
}
|
|
39490
39595
|
const hookRunner = getGlobalHookRunner();
|
|
39491
|
-
const { builtInTools, customTools } = splitSdkTools({
|
|
39596
|
+
const { builtInTools: rawBuiltInTools, customTools } = splitSdkTools({
|
|
39492
39597
|
tools,
|
|
39493
39598
|
sandboxEnabled: !!sandbox?.enabled
|
|
39494
39599
|
});
|
|
39600
|
+
const builtInTools = wrapToolsWithArgValidation(rawBuiltInTools, modelProfile);
|
|
39495
39601
|
let clientToolCallDetected = null;
|
|
39496
39602
|
const clientToolLoopDetection = resolveToolLoopDetectionConfig({
|
|
39497
39603
|
cfg: params.config,
|
|
@@ -52836,7 +52942,7 @@ function isVoiceChannelType(type) {
|
|
|
52836
52942
|
function createDefaultDeps() {
|
|
52837
52943
|
return {
|
|
52838
52944
|
sendMessageWhatsApp: async (...args) => {
|
|
52839
|
-
const { sendMessageWhatsApp } = await import("./web-
|
|
52945
|
+
const { sendMessageWhatsApp } = await import("./web-Bqrgp43v.js");
|
|
52840
52946
|
return await sendMessageWhatsApp(...args);
|
|
52841
52947
|
},
|
|
52842
52948
|
sendMessageTelegram: async (...args) => {
|
|
@@ -68150,7 +68256,7 @@ function loadWebLoginQr() {
|
|
|
68150
68256
|
return webLoginQrPromise;
|
|
68151
68257
|
}
|
|
68152
68258
|
function loadWebChannel() {
|
|
68153
|
-
webChannelPromise ??= import("./web-
|
|
68259
|
+
webChannelPromise ??= import("./web-Bqrgp43v.js");
|
|
68154
68260
|
return webChannelPromise;
|
|
68155
68261
|
}
|
|
68156
68262
|
function loadWhatsAppActions() {
|
|
@@ -9,6 +9,8 @@ const TOOL_CALL_HISTORY_SIZE = 30;
|
|
|
9
9
|
const WARNING_THRESHOLD = 10;
|
|
10
10
|
const CRITICAL_THRESHOLD = 20;
|
|
11
11
|
const GLOBAL_CIRCUIT_BREAKER_THRESHOLD = 30;
|
|
12
|
+
const CONSECUTIVE_FAILURE_WARNING_THRESHOLD = 3;
|
|
13
|
+
const CONSECUTIVE_FAILURE_CRITICAL_THRESHOLD = 5;
|
|
12
14
|
const DEFAULT_LOOP_DETECTION_CONFIG = {
|
|
13
15
|
enabled: false,
|
|
14
16
|
historySize: TOOL_CALL_HISTORY_SIZE,
|
|
@@ -18,8 +20,11 @@ const DEFAULT_LOOP_DETECTION_CONFIG = {
|
|
|
18
20
|
detectors: {
|
|
19
21
|
genericRepeat: true,
|
|
20
22
|
knownPollNoProgress: true,
|
|
21
|
-
pingPong: true
|
|
22
|
-
|
|
23
|
+
pingPong: true,
|
|
24
|
+
consecutiveFailure: true
|
|
25
|
+
},
|
|
26
|
+
consecutiveFailureWarningThreshold: CONSECUTIVE_FAILURE_WARNING_THRESHOLD,
|
|
27
|
+
consecutiveFailureCriticalThreshold: CONSECUTIVE_FAILURE_CRITICAL_THRESHOLD
|
|
23
28
|
};
|
|
24
29
|
function asPositiveInt(value, fallback) {
|
|
25
30
|
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) return fallback;
|
|
@@ -37,10 +42,13 @@ function resolveLoopDetectionConfig(config) {
|
|
|
37
42
|
warningThreshold,
|
|
38
43
|
criticalThreshold,
|
|
39
44
|
globalCircuitBreakerThreshold,
|
|
45
|
+
consecutiveFailureWarningThreshold: asPositiveInt(config?.consecutiveFailureWarningThreshold, DEFAULT_LOOP_DETECTION_CONFIG.consecutiveFailureWarningThreshold),
|
|
46
|
+
consecutiveFailureCriticalThreshold: asPositiveInt(config?.consecutiveFailureCriticalThreshold, DEFAULT_LOOP_DETECTION_CONFIG.consecutiveFailureCriticalThreshold),
|
|
40
47
|
detectors: {
|
|
41
48
|
genericRepeat: config?.detectors?.genericRepeat ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.genericRepeat,
|
|
42
49
|
knownPollNoProgress: config?.detectors?.knownPollNoProgress ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.knownPollNoProgress,
|
|
43
|
-
pingPong: config?.detectors?.pingPong ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.pingPong
|
|
50
|
+
pingPong: config?.detectors?.pingPong ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.pingPong,
|
|
51
|
+
consecutiveFailure: (config?.detectors)?.consecutiveFailure ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.consecutiveFailure
|
|
44
52
|
}
|
|
45
53
|
};
|
|
46
54
|
}
|
|
@@ -218,6 +226,22 @@ function canonicalPairKey(signatureA, signatureB) {
|
|
|
218
226
|
return [signatureA, signatureB].toSorted().join("|");
|
|
219
227
|
}
|
|
220
228
|
/**
|
|
229
|
+
* Count consecutive error results for a specific tool, walking backward from
|
|
230
|
+
* the most recent call. A success or a call to a different tool resets the streak.
|
|
231
|
+
* Only counts entries that have been resolved (have a resultHash or isError flag).
|
|
232
|
+
*/
|
|
233
|
+
function getConsecutiveFailureStreak(history, toolName) {
|
|
234
|
+
let count = 0;
|
|
235
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
236
|
+
const entry = history[i];
|
|
237
|
+
if (entry.toolName !== toolName) break;
|
|
238
|
+
if (entry.resultHash === void 0 && entry.isError === void 0) break;
|
|
239
|
+
if (!entry.isError) break;
|
|
240
|
+
count++;
|
|
241
|
+
}
|
|
242
|
+
return count;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
221
245
|
* Detect if an agent is stuck in a repetitive tool call loop.
|
|
222
246
|
* Checks if the same tool+params combination has been called excessively.
|
|
223
247
|
*/
|
|
@@ -230,6 +254,31 @@ function detectToolCallLoop(state, toolName, params, config) {
|
|
|
230
254
|
const noProgressStreak = noProgress.count;
|
|
231
255
|
const knownPollTool = isKnownPollToolCall(toolName, params);
|
|
232
256
|
const pingPong = getPingPongStreak(history, currentHash);
|
|
257
|
+
if (resolvedConfig.detectors.consecutiveFailure) {
|
|
258
|
+
const failureStreak = getConsecutiveFailureStreak(history, toolName);
|
|
259
|
+
if (failureStreak >= resolvedConfig.consecutiveFailureCriticalThreshold) {
|
|
260
|
+
log.error(`Consecutive failure circuit breaker: ${toolName} failed ${failureStreak} times in a row`);
|
|
261
|
+
return {
|
|
262
|
+
stuck: true,
|
|
263
|
+
level: "critical",
|
|
264
|
+
detector: "consecutive_failure",
|
|
265
|
+
count: failureStreak,
|
|
266
|
+
message: `CRITICAL: ${toolName} has failed ${failureStreak} consecutive times. Stop calling this tool. Explain to the user what you were trying to do and why it failed.`,
|
|
267
|
+
warningKey: `consecutive-failure:${toolName}`
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
if (failureStreak >= resolvedConfig.consecutiveFailureWarningThreshold) {
|
|
271
|
+
log.warn(`Consecutive failure warning: ${toolName} failed ${failureStreak} times in a row`);
|
|
272
|
+
return {
|
|
273
|
+
stuck: true,
|
|
274
|
+
level: "warning",
|
|
275
|
+
detector: "consecutive_failure",
|
|
276
|
+
count: failureStreak,
|
|
277
|
+
message: `WARNING: You have failed to call ${toolName} ${failureStreak} times consecutively. Stop retrying and explain to the user what you were trying to do. The tool arguments may contain invalid syntax from model control tokens.`,
|
|
278
|
+
warningKey: `consecutive-failure:${toolName}`
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
233
282
|
if (noProgressStreak >= resolvedConfig.globalCircuitBreakerThreshold) {
|
|
234
283
|
log.error(`Global circuit breaker triggered: ${toolName} repeated ${noProgressStreak} times with no progress`);
|
|
235
284
|
return {
|
|
@@ -334,6 +383,7 @@ function recordToolCallOutcome(state, params) {
|
|
|
334
383
|
if (call.toolName !== params.toolName || call.argsHash !== argsHash) continue;
|
|
335
384
|
if (call.resultHash !== void 0) continue;
|
|
336
385
|
call.resultHash = resultHash;
|
|
386
|
+
call.isError = params.error !== void 0;
|
|
337
387
|
matched = true;
|
|
338
388
|
break;
|
|
339
389
|
}
|
|
@@ -7,6 +7,8 @@ const TOOL_CALL_HISTORY_SIZE = 30;
|
|
|
7
7
|
const WARNING_THRESHOLD = 10;
|
|
8
8
|
const CRITICAL_THRESHOLD = 20;
|
|
9
9
|
const GLOBAL_CIRCUIT_BREAKER_THRESHOLD = 30;
|
|
10
|
+
const CONSECUTIVE_FAILURE_WARNING_THRESHOLD = 3;
|
|
11
|
+
const CONSECUTIVE_FAILURE_CRITICAL_THRESHOLD = 5;
|
|
10
12
|
const DEFAULT_LOOP_DETECTION_CONFIG = {
|
|
11
13
|
enabled: false,
|
|
12
14
|
historySize: TOOL_CALL_HISTORY_SIZE,
|
|
@@ -16,8 +18,11 @@ const DEFAULT_LOOP_DETECTION_CONFIG = {
|
|
|
16
18
|
detectors: {
|
|
17
19
|
genericRepeat: true,
|
|
18
20
|
knownPollNoProgress: true,
|
|
19
|
-
pingPong: true
|
|
20
|
-
|
|
21
|
+
pingPong: true,
|
|
22
|
+
consecutiveFailure: true
|
|
23
|
+
},
|
|
24
|
+
consecutiveFailureWarningThreshold: CONSECUTIVE_FAILURE_WARNING_THRESHOLD,
|
|
25
|
+
consecutiveFailureCriticalThreshold: CONSECUTIVE_FAILURE_CRITICAL_THRESHOLD
|
|
21
26
|
};
|
|
22
27
|
function asPositiveInt(value, fallback) {
|
|
23
28
|
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) return fallback;
|
|
@@ -35,10 +40,13 @@ function resolveLoopDetectionConfig(config) {
|
|
|
35
40
|
warningThreshold,
|
|
36
41
|
criticalThreshold,
|
|
37
42
|
globalCircuitBreakerThreshold,
|
|
43
|
+
consecutiveFailureWarningThreshold: asPositiveInt(config?.consecutiveFailureWarningThreshold, DEFAULT_LOOP_DETECTION_CONFIG.consecutiveFailureWarningThreshold),
|
|
44
|
+
consecutiveFailureCriticalThreshold: asPositiveInt(config?.consecutiveFailureCriticalThreshold, DEFAULT_LOOP_DETECTION_CONFIG.consecutiveFailureCriticalThreshold),
|
|
38
45
|
detectors: {
|
|
39
46
|
genericRepeat: config?.detectors?.genericRepeat ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.genericRepeat,
|
|
40
47
|
knownPollNoProgress: config?.detectors?.knownPollNoProgress ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.knownPollNoProgress,
|
|
41
|
-
pingPong: config?.detectors?.pingPong ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.pingPong
|
|
48
|
+
pingPong: config?.detectors?.pingPong ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.pingPong,
|
|
49
|
+
consecutiveFailure: (config?.detectors)?.consecutiveFailure ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.consecutiveFailure
|
|
42
50
|
}
|
|
43
51
|
};
|
|
44
52
|
}
|
|
@@ -216,6 +224,22 @@ function canonicalPairKey(signatureA, signatureB) {
|
|
|
216
224
|
return [signatureA, signatureB].toSorted().join("|");
|
|
217
225
|
}
|
|
218
226
|
/**
|
|
227
|
+
* Count consecutive error results for a specific tool, walking backward from
|
|
228
|
+
* the most recent call. A success or a call to a different tool resets the streak.
|
|
229
|
+
* Only counts entries that have been resolved (have a resultHash or isError flag).
|
|
230
|
+
*/
|
|
231
|
+
function getConsecutiveFailureStreak(history, toolName) {
|
|
232
|
+
let count = 0;
|
|
233
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
234
|
+
const entry = history[i];
|
|
235
|
+
if (entry.toolName !== toolName) break;
|
|
236
|
+
if (entry.resultHash === void 0 && entry.isError === void 0) break;
|
|
237
|
+
if (!entry.isError) break;
|
|
238
|
+
count++;
|
|
239
|
+
}
|
|
240
|
+
return count;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
219
243
|
* Detect if an agent is stuck in a repetitive tool call loop.
|
|
220
244
|
* Checks if the same tool+params combination has been called excessively.
|
|
221
245
|
*/
|
|
@@ -228,6 +252,31 @@ function detectToolCallLoop(state, toolName, params, config) {
|
|
|
228
252
|
const noProgressStreak = noProgress.count;
|
|
229
253
|
const knownPollTool = isKnownPollToolCall(toolName, params);
|
|
230
254
|
const pingPong = getPingPongStreak(history, currentHash);
|
|
255
|
+
if (resolvedConfig.detectors.consecutiveFailure) {
|
|
256
|
+
const failureStreak = getConsecutiveFailureStreak(history, toolName);
|
|
257
|
+
if (failureStreak >= resolvedConfig.consecutiveFailureCriticalThreshold) {
|
|
258
|
+
log.error(`Consecutive failure circuit breaker: ${toolName} failed ${failureStreak} times in a row`);
|
|
259
|
+
return {
|
|
260
|
+
stuck: true,
|
|
261
|
+
level: "critical",
|
|
262
|
+
detector: "consecutive_failure",
|
|
263
|
+
count: failureStreak,
|
|
264
|
+
message: `CRITICAL: ${toolName} has failed ${failureStreak} consecutive times. Stop calling this tool. Explain to the user what you were trying to do and why it failed.`,
|
|
265
|
+
warningKey: `consecutive-failure:${toolName}`
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (failureStreak >= resolvedConfig.consecutiveFailureWarningThreshold) {
|
|
269
|
+
log.warn(`Consecutive failure warning: ${toolName} failed ${failureStreak} times in a row`);
|
|
270
|
+
return {
|
|
271
|
+
stuck: true,
|
|
272
|
+
level: "warning",
|
|
273
|
+
detector: "consecutive_failure",
|
|
274
|
+
count: failureStreak,
|
|
275
|
+
message: `WARNING: You have failed to call ${toolName} ${failureStreak} times consecutively. Stop retrying and explain to the user what you were trying to do. The tool arguments may contain invalid syntax from model control tokens.`,
|
|
276
|
+
warningKey: `consecutive-failure:${toolName}`
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
231
280
|
if (noProgressStreak >= resolvedConfig.globalCircuitBreakerThreshold) {
|
|
232
281
|
log.error(`Global circuit breaker triggered: ${toolName} repeated ${noProgressStreak} times with no progress`);
|
|
233
282
|
return {
|
|
@@ -332,6 +381,7 @@ function recordToolCallOutcome(state, params) {
|
|
|
332
381
|
if (call.toolName !== params.toolName || call.argsHash !== argsHash) continue;
|
|
333
382
|
if (call.resultHash !== void 0) continue;
|
|
334
383
|
call.resultHash = resultHash;
|
|
384
|
+
call.isError = params.error !== void 0;
|
|
335
385
|
matched = true;
|
|
336
386
|
break;
|
|
337
387
|
}
|
|
@@ -10,6 +10,8 @@ const TOOL_CALL_HISTORY_SIZE = 30;
|
|
|
10
10
|
const WARNING_THRESHOLD = 10;
|
|
11
11
|
const CRITICAL_THRESHOLD = 20;
|
|
12
12
|
const GLOBAL_CIRCUIT_BREAKER_THRESHOLD = 30;
|
|
13
|
+
const CONSECUTIVE_FAILURE_WARNING_THRESHOLD = 3;
|
|
14
|
+
const CONSECUTIVE_FAILURE_CRITICAL_THRESHOLD = 5;
|
|
13
15
|
const DEFAULT_LOOP_DETECTION_CONFIG = {
|
|
14
16
|
enabled: false,
|
|
15
17
|
historySize: TOOL_CALL_HISTORY_SIZE,
|
|
@@ -19,8 +21,11 @@ const DEFAULT_LOOP_DETECTION_CONFIG = {
|
|
|
19
21
|
detectors: {
|
|
20
22
|
genericRepeat: true,
|
|
21
23
|
knownPollNoProgress: true,
|
|
22
|
-
pingPong: true
|
|
23
|
-
|
|
24
|
+
pingPong: true,
|
|
25
|
+
consecutiveFailure: true
|
|
26
|
+
},
|
|
27
|
+
consecutiveFailureWarningThreshold: CONSECUTIVE_FAILURE_WARNING_THRESHOLD,
|
|
28
|
+
consecutiveFailureCriticalThreshold: CONSECUTIVE_FAILURE_CRITICAL_THRESHOLD
|
|
24
29
|
};
|
|
25
30
|
function asPositiveInt(value, fallback) {
|
|
26
31
|
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) return fallback;
|
|
@@ -38,10 +43,13 @@ function resolveLoopDetectionConfig(config) {
|
|
|
38
43
|
warningThreshold,
|
|
39
44
|
criticalThreshold,
|
|
40
45
|
globalCircuitBreakerThreshold,
|
|
46
|
+
consecutiveFailureWarningThreshold: asPositiveInt(config?.consecutiveFailureWarningThreshold, DEFAULT_LOOP_DETECTION_CONFIG.consecutiveFailureWarningThreshold),
|
|
47
|
+
consecutiveFailureCriticalThreshold: asPositiveInt(config?.consecutiveFailureCriticalThreshold, DEFAULT_LOOP_DETECTION_CONFIG.consecutiveFailureCriticalThreshold),
|
|
41
48
|
detectors: {
|
|
42
49
|
genericRepeat: config?.detectors?.genericRepeat ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.genericRepeat,
|
|
43
50
|
knownPollNoProgress: config?.detectors?.knownPollNoProgress ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.knownPollNoProgress,
|
|
44
|
-
pingPong: config?.detectors?.pingPong ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.pingPong
|
|
51
|
+
pingPong: config?.detectors?.pingPong ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.pingPong,
|
|
52
|
+
consecutiveFailure: (config?.detectors)?.consecutiveFailure ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.consecutiveFailure
|
|
45
53
|
}
|
|
46
54
|
};
|
|
47
55
|
}
|
|
@@ -219,6 +227,22 @@ function canonicalPairKey(signatureA, signatureB) {
|
|
|
219
227
|
return [signatureA, signatureB].toSorted().join("|");
|
|
220
228
|
}
|
|
221
229
|
/**
|
|
230
|
+
* Count consecutive error results for a specific tool, walking backward from
|
|
231
|
+
* the most recent call. A success or a call to a different tool resets the streak.
|
|
232
|
+
* Only counts entries that have been resolved (have a resultHash or isError flag).
|
|
233
|
+
*/
|
|
234
|
+
function getConsecutiveFailureStreak(history, toolName) {
|
|
235
|
+
let count = 0;
|
|
236
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
237
|
+
const entry = history[i];
|
|
238
|
+
if (entry.toolName !== toolName) break;
|
|
239
|
+
if (entry.resultHash === void 0 && entry.isError === void 0) break;
|
|
240
|
+
if (!entry.isError) break;
|
|
241
|
+
count++;
|
|
242
|
+
}
|
|
243
|
+
return count;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
222
246
|
* Detect if an agent is stuck in a repetitive tool call loop.
|
|
223
247
|
* Checks if the same tool+params combination has been called excessively.
|
|
224
248
|
*/
|
|
@@ -231,6 +255,31 @@ function detectToolCallLoop(state, toolName, params, config) {
|
|
|
231
255
|
const noProgressStreak = noProgress.count;
|
|
232
256
|
const knownPollTool = isKnownPollToolCall(toolName, params);
|
|
233
257
|
const pingPong = getPingPongStreak(history, currentHash);
|
|
258
|
+
if (resolvedConfig.detectors.consecutiveFailure) {
|
|
259
|
+
const failureStreak = getConsecutiveFailureStreak(history, toolName);
|
|
260
|
+
if (failureStreak >= resolvedConfig.consecutiveFailureCriticalThreshold) {
|
|
261
|
+
log.error(`Consecutive failure circuit breaker: ${toolName} failed ${failureStreak} times in a row`);
|
|
262
|
+
return {
|
|
263
|
+
stuck: true,
|
|
264
|
+
level: "critical",
|
|
265
|
+
detector: "consecutive_failure",
|
|
266
|
+
count: failureStreak,
|
|
267
|
+
message: `CRITICAL: ${toolName} has failed ${failureStreak} consecutive times. Stop calling this tool. Explain to the user what you were trying to do and why it failed.`,
|
|
268
|
+
warningKey: `consecutive-failure:${toolName}`
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
if (failureStreak >= resolvedConfig.consecutiveFailureWarningThreshold) {
|
|
272
|
+
log.warn(`Consecutive failure warning: ${toolName} failed ${failureStreak} times in a row`);
|
|
273
|
+
return {
|
|
274
|
+
stuck: true,
|
|
275
|
+
level: "warning",
|
|
276
|
+
detector: "consecutive_failure",
|
|
277
|
+
count: failureStreak,
|
|
278
|
+
message: `WARNING: You have failed to call ${toolName} ${failureStreak} times consecutively. Stop retrying and explain to the user what you were trying to do. The tool arguments may contain invalid syntax from model control tokens.`,
|
|
279
|
+
warningKey: `consecutive-failure:${toolName}`
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
234
283
|
if (noProgressStreak >= resolvedConfig.globalCircuitBreakerThreshold) {
|
|
235
284
|
log.error(`Global circuit breaker triggered: ${toolName} repeated ${noProgressStreak} times with no progress`);
|
|
236
285
|
return {
|
|
@@ -335,6 +384,7 @@ function recordToolCallOutcome(state, params) {
|
|
|
335
384
|
if (call.toolName !== params.toolName || call.argsHash !== argsHash) continue;
|
|
336
385
|
if (call.resultHash !== void 0) continue;
|
|
337
386
|
call.resultHash = resultHash;
|
|
387
|
+
call.isError = params.error !== void 0;
|
|
338
388
|
matched = true;
|
|
339
389
|
break;
|
|
340
390
|
}
|