agim-cli 1.2.45 → 1.2.49
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/CHANGELOG.md +340 -0
- package/README.md +40 -6
- package/README.zh-CN.md +40 -6
- package/dist/cli-ui/config-wizard.js +16 -2
- package/dist/cli-ui/config-wizard.js.map +1 -1
- package/dist/cli-ui/diag.d.ts +29 -0
- package/dist/cli-ui/diag.d.ts.map +1 -0
- package/dist/cli-ui/diag.js +135 -0
- package/dist/cli-ui/diag.js.map +1 -0
- package/dist/cli-ui/i18n.d.ts +38 -0
- package/dist/cli-ui/i18n.d.ts.map +1 -1
- package/dist/cli-ui/i18n.js +101 -0
- package/dist/cli-ui/i18n.js.map +1 -1
- package/dist/cli-ui/setup-llm.d.ts +30 -0
- package/dist/cli-ui/setup-llm.d.ts.map +1 -0
- package/dist/cli-ui/setup-llm.js +460 -0
- package/dist/cli-ui/setup-llm.js.map +1 -0
- package/dist/cli-ui/setup-mcp.d.ts +19 -0
- package/dist/cli-ui/setup-mcp.d.ts.map +1 -0
- package/dist/cli-ui/setup-mcp.js +308 -0
- package/dist/cli-ui/setup-mcp.js.map +1 -0
- package/dist/cli-ui/token-menu.js +2 -2
- package/dist/cli-ui/token-menu.js.map +1 -1
- package/dist/cli.js +121 -22
- package/dist/cli.js.map +1 -1
- package/dist/core/access-token.d.ts +16 -5
- package/dist/core/access-token.d.ts.map +1 -1
- package/dist/core/access-token.js +82 -13
- package/dist/core/access-token.js.map +1 -1
- package/dist/core/agent-cwd.d.ts.map +1 -1
- package/dist/core/agent-cwd.js +74 -0
- package/dist/core/agent-cwd.js.map +1 -1
- package/dist/core/approval-bus.d.ts +22 -0
- package/dist/core/approval-bus.d.ts.map +1 -1
- package/dist/core/approval-bus.js +93 -0
- package/dist/core/approval-bus.js.map +1 -1
- package/dist/core/ask-user-router.d.ts +24 -0
- package/dist/core/ask-user-router.d.ts.map +1 -0
- package/dist/core/ask-user-router.js +84 -0
- package/dist/core/ask-user-router.js.map +1 -0
- package/dist/core/ask-user-rpc.d.ts +80 -0
- package/dist/core/ask-user-rpc.d.ts.map +1 -0
- package/dist/core/ask-user-rpc.js +388 -0
- package/dist/core/ask-user-rpc.js.map +1 -0
- package/dist/core/audit-log.d.ts +1 -1
- package/dist/core/audit-log.d.ts.map +1 -1
- package/dist/core/audit-log.js.map +1 -1
- package/dist/core/commands/builtin.d.ts.map +1 -1
- package/dist/core/commands/builtin.js +21 -5
- package/dist/core/commands/builtin.js.map +1 -1
- package/dist/core/commands/goal.d.ts +3 -0
- package/dist/core/commands/goal.d.ts.map +1 -0
- package/dist/core/commands/goal.js +240 -0
- package/dist/core/commands/goal.js.map +1 -0
- package/dist/core/commands/heartbeat.d.ts +3 -0
- package/dist/core/commands/heartbeat.d.ts.map +1 -0
- package/dist/core/commands/heartbeat.js +219 -0
- package/dist/core/commands/heartbeat.js.map +1 -0
- package/dist/core/commands/router-compare.d.ts +3 -0
- package/dist/core/commands/router-compare.d.ts.map +1 -0
- package/dist/core/commands/router-compare.js +81 -0
- package/dist/core/commands/router-compare.js.map +1 -0
- package/dist/core/commands/router.d.ts.map +1 -1
- package/dist/core/commands/router.js +9 -1
- package/dist/core/commands/router.js.map +1 -1
- package/dist/core/commands/skill.d.ts +3 -0
- package/dist/core/commands/skill.d.ts.map +1 -0
- package/dist/core/commands/skill.js +91 -0
- package/dist/core/commands/skill.js.map +1 -0
- package/dist/core/config-schema.d.ts +28 -0
- package/dist/core/config-schema.d.ts.map +1 -1
- package/dist/core/config-schema.js +124 -0
- package/dist/core/config-schema.js.map +1 -1
- package/dist/core/goals.d.ts +81 -0
- package/dist/core/goals.d.ts.map +1 -0
- package/dist/core/goals.js +361 -0
- package/dist/core/goals.js.map +1 -0
- package/dist/core/heartbeat-store.d.ts +90 -0
- package/dist/core/heartbeat-store.d.ts.map +1 -0
- package/dist/core/heartbeat-store.js +302 -0
- package/dist/core/heartbeat-store.js.map +1 -0
- package/dist/core/heartbeat.d.ts +35 -0
- package/dist/core/heartbeat.d.ts.map +1 -0
- package/dist/core/heartbeat.js +332 -0
- package/dist/core/heartbeat.js.map +1 -0
- package/dist/core/intent-llm.d.ts +9 -0
- package/dist/core/intent-llm.d.ts.map +1 -1
- package/dist/core/intent-llm.js +77 -32
- package/dist/core/intent-llm.js.map +1 -1
- package/dist/core/llm/agent-loop.d.ts +112 -0
- package/dist/core/llm/agent-loop.d.ts.map +1 -0
- package/dist/core/llm/agent-loop.js +313 -0
- package/dist/core/llm/agent-loop.js.map +1 -0
- package/dist/core/llm/anthropic-provider.d.ts +53 -0
- package/dist/core/llm/anthropic-provider.d.ts.map +1 -0
- package/dist/core/llm/anthropic-provider.js +339 -0
- package/dist/core/llm/anthropic-provider.js.map +1 -0
- package/dist/core/llm/auto-compact.d.ts +35 -0
- package/dist/core/llm/auto-compact.d.ts.map +1 -0
- package/dist/core/llm/auto-compact.js +149 -0
- package/dist/core/llm/auto-compact.js.map +1 -0
- package/dist/core/llm/builtin-dispatcher.d.ts +21 -0
- package/dist/core/llm/builtin-dispatcher.d.ts.map +1 -0
- package/dist/core/llm/builtin-dispatcher.js +196 -0
- package/dist/core/llm/builtin-dispatcher.js.map +1 -0
- package/dist/core/llm/imhub-dispatcher.d.ts +27 -0
- package/dist/core/llm/imhub-dispatcher.d.ts.map +1 -0
- package/dist/core/llm/imhub-dispatcher.js +308 -0
- package/dist/core/llm/imhub-dispatcher.js.map +1 -0
- package/dist/core/llm/index.d.ts +11 -0
- package/dist/core/llm/index.d.ts.map +1 -0
- package/dist/core/llm/index.js +16 -0
- package/dist/core/llm/index.js.map +1 -0
- package/dist/core/llm/introspection.d.ts +73 -0
- package/dist/core/llm/introspection.d.ts.map +1 -0
- package/dist/core/llm/introspection.js +90 -0
- package/dist/core/llm/introspection.js.map +1 -0
- package/dist/core/llm/mcp-client.d.ts +80 -0
- package/dist/core/llm/mcp-client.d.ts.map +1 -0
- package/dist/core/llm/mcp-client.js +270 -0
- package/dist/core/llm/mcp-client.js.map +1 -0
- package/dist/core/llm/mcp-registry.d.ts +57 -0
- package/dist/core/llm/mcp-registry.d.ts.map +1 -0
- package/dist/core/llm/mcp-registry.js +155 -0
- package/dist/core/llm/mcp-registry.js.map +1 -0
- package/dist/core/llm/openai-compat-provider.d.ts +65 -0
- package/dist/core/llm/openai-compat-provider.d.ts.map +1 -0
- package/dist/core/llm/openai-compat-provider.js +451 -0
- package/dist/core/llm/openai-compat-provider.js.map +1 -0
- package/dist/core/llm/policy-approval-gate.d.ts +30 -0
- package/dist/core/llm/policy-approval-gate.d.ts.map +1 -0
- package/dist/core/llm/policy-approval-gate.js +86 -0
- package/dist/core/llm/policy-approval-gate.js.map +1 -0
- package/dist/core/llm/provider-base.d.ts +302 -0
- package/dist/core/llm/provider-base.d.ts.map +1 -0
- package/dist/core/llm/provider-base.js +222 -0
- package/dist/core/llm/provider-base.js.map +1 -0
- package/dist/core/llm/registry.d.ts +44 -0
- package/dist/core/llm/registry.d.ts.map +1 -0
- package/dist/core/llm/registry.js +160 -0
- package/dist/core/llm/registry.js.map +1 -0
- package/dist/core/llm/secrets.d.ts +46 -0
- package/dist/core/llm/secrets.d.ts.map +1 -0
- package/dist/core/llm/secrets.js +157 -0
- package/dist/core/llm/secrets.js.map +1 -0
- package/dist/core/llm/tool-dispatcher.d.ts +37 -0
- package/dist/core/llm/tool-dispatcher.d.ts.map +1 -0
- package/dist/core/llm/tool-dispatcher.js +85 -0
- package/dist/core/llm/tool-dispatcher.js.map +1 -0
- package/dist/core/memory-consolidate.d.ts.map +1 -1
- package/dist/core/memory-consolidate.js +38 -23
- package/dist/core/memory-consolidate.js.map +1 -1
- package/dist/core/memory-distill.d.ts.map +1 -1
- package/dist/core/memory-distill.js +51 -25
- package/dist/core/memory-distill.js.map +1 -1
- package/dist/core/memory-rpc.d.ts.map +1 -1
- package/dist/core/memory-rpc.js +6 -0
- package/dist/core/memory-rpc.js.map +1 -1
- package/dist/core/message-sink.d.ts.map +1 -1
- package/dist/core/message-sink.js +76 -0
- package/dist/core/message-sink.js.map +1 -1
- package/dist/core/notification-evaluator.d.ts +49 -0
- package/dist/core/notification-evaluator.d.ts.map +1 -0
- package/dist/core/notification-evaluator.js +232 -0
- package/dist/core/notification-evaluator.js.map +1 -0
- package/dist/core/onboarding.d.ts.map +1 -1
- package/dist/core/onboarding.js +10 -0
- package/dist/core/onboarding.js.map +1 -1
- package/dist/core/persona.d.ts +10 -0
- package/dist/core/persona.d.ts.map +1 -1
- package/dist/core/persona.js +28 -14
- package/dist/core/persona.js.map +1 -1
- package/dist/core/push-rpc.d.ts +8 -0
- package/dist/core/push-rpc.d.ts.map +1 -1
- package/dist/core/push-rpc.js +41 -1
- package/dist/core/push-rpc.js.map +1 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +11 -0
- package/dist/core/registry.js.map +1 -1
- package/dist/core/render-router.d.ts.map +1 -1
- package/dist/core/render-router.js +23 -6
- package/dist/core/render-router.js.map +1 -1
- package/dist/core/router-compare.d.ts +76 -0
- package/dist/core/router-compare.d.ts.map +1 -0
- package/dist/core/router-compare.js +253 -0
- package/dist/core/router-compare.js.map +1 -0
- package/dist/core/router.d.ts.map +1 -1
- package/dist/core/router.js +25 -1
- package/dist/core/router.js.map +1 -1
- package/dist/core/skills/builtin/agim-self/SKILL.md +81 -0
- package/dist/core/skills/loader.d.ts +120 -0
- package/dist/core/skills/loader.d.ts.map +1 -0
- package/dist/core/skills/loader.js +577 -0
- package/dist/core/skills/loader.js.map +1 -0
- package/dist/core/skills-rpc.d.ts +44 -0
- package/dist/core/skills-rpc.d.ts.map +1 -0
- package/dist/core/skills-rpc.js +71 -0
- package/dist/core/skills-rpc.js.map +1 -0
- package/dist/core/types.d.ts +35 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/util/format-age.d.ts +20 -0
- package/dist/core/util/format-age.d.ts.map +1 -0
- package/dist/core/util/format-age.js +86 -0
- package/dist/core/util/format-age.js.map +1 -0
- package/dist/plugins/agents/acp/acp-adapter.d.ts +3 -0
- package/dist/plugins/agents/acp/acp-adapter.d.ts.map +1 -1
- package/dist/plugins/agents/acp/acp-adapter.js +12 -0
- package/dist/plugins/agents/acp/acp-adapter.js.map +1 -1
- package/dist/plugins/agents/antigravity/index.d.ts +1 -0
- package/dist/plugins/agents/antigravity/index.d.ts.map +1 -1
- package/dist/plugins/agents/antigravity/index.js +1 -0
- package/dist/plugins/agents/antigravity/index.js.map +1 -1
- package/dist/plugins/agents/claude-code/index.d.ts +1 -0
- package/dist/plugins/agents/claude-code/index.d.ts.map +1 -1
- package/dist/plugins/agents/claude-code/index.js +1 -0
- package/dist/plugins/agents/claude-code/index.js.map +1 -1
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +22 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -1
- package/dist/plugins/agents/claude-code/mcp-approval-server.js +157 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
- package/dist/plugins/agents/codex/index.d.ts +1 -0
- package/dist/plugins/agents/codex/index.d.ts.map +1 -1
- package/dist/plugins/agents/codex/index.js +1 -0
- package/dist/plugins/agents/codex/index.js.map +1 -1
- package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts +43 -0
- package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts.map +1 -0
- package/dist/plugins/agents/cursor/ensure-mcp-config.js +99 -0
- package/dist/plugins/agents/cursor/ensure-mcp-config.js.map +1 -0
- package/dist/plugins/agents/cursor/index.d.ts +28 -0
- package/dist/plugins/agents/cursor/index.d.ts.map +1 -0
- package/dist/plugins/agents/cursor/index.js +290 -0
- package/dist/plugins/agents/cursor/index.js.map +1 -0
- package/dist/plugins/agents/native/index.d.ts +34 -0
- package/dist/plugins/agents/native/index.d.ts.map +1 -0
- package/dist/plugins/agents/native/index.js +598 -0
- package/dist/plugins/agents/native/index.js.map +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -1
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.d.ts +4 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.d.ts.map +1 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.js +26 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -1
- package/dist/web/agim-skills-api.d.ts +4 -0
- package/dist/web/agim-skills-api.d.ts.map +1 -0
- package/dist/web/agim-skills-api.js +150 -0
- package/dist/web/agim-skills-api.js.map +1 -0
- package/dist/web/background-tasks-api.d.ts +7 -0
- package/dist/web/background-tasks-api.d.ts.map +1 -0
- package/dist/web/background-tasks-api.js +225 -0
- package/dist/web/background-tasks-api.js.map +1 -0
- package/dist/web/llm-api.d.ts +8 -0
- package/dist/web/llm-api.d.ts.map +1 -0
- package/dist/web/llm-api.js +300 -0
- package/dist/web/llm-api.js.map +1 -0
- package/dist/web/mcp-api.d.ts +8 -0
- package/dist/web/mcp-api.d.ts.map +1 -0
- package/dist/web/mcp-api.js +205 -0
- package/dist/web/mcp-api.js.map +1 -0
- package/dist/web/public/assets/{a2a-Cdl8iY0e.js → a2a-06bnQicA.js} +3 -3
- package/dist/web/public/assets/{a2a-Cdl8iY0e.js.map → a2a-06bnQicA.js.map} +1 -1
- package/dist/web/public/assets/{activity-DXahuK1C.js → activity-Bhc6Esfy.js} +2 -2
- package/dist/web/public/assets/{activity-DXahuK1C.js.map → activity-Bhc6Esfy.js.map} +1 -1
- package/dist/web/public/assets/{admins-C8fJsuHC.js → admins-BVpnOw3o.js} +3 -3
- package/dist/web/public/assets/{admins-C8fJsuHC.js.map → admins-BVpnOw3o.js.map} +1 -1
- package/dist/web/public/assets/agents-Cn7D3UMz.js +7 -0
- package/dist/web/public/assets/agents-Cn7D3UMz.js.map +1 -0
- package/dist/web/public/assets/{approvals-CpyL90ef.js → approvals-BJiLyoLf.js} +3 -3
- package/dist/web/public/assets/{approvals-CpyL90ef.js.map → approvals-BJiLyoLf.js.map} +1 -1
- package/dist/web/public/assets/asks-C7gKbna1.js +7 -0
- package/dist/web/public/assets/asks-C7gKbna1.js.map +1 -0
- package/dist/web/public/assets/{audit-DDqpiC3z.js → audit-DgWZD8l5.js} +2 -2
- package/dist/web/public/assets/{audit-DDqpiC3z.js.map → audit-DgWZD8l5.js.map} +1 -1
- package/dist/web/public/assets/bell-pWZT2wlM.js +7 -0
- package/dist/web/public/assets/bell-pWZT2wlM.js.map +1 -0
- package/dist/web/public/assets/{bgjobs-CAFV-I4I.js → bgjobs-DkAJdzHf.js} +2 -2
- package/dist/web/public/assets/{bgjobs-CAFV-I4I.js.map → bgjobs-DkAJdzHf.js.map} +1 -1
- package/dist/web/public/assets/{brain-CJyZe3Oa.js → brain-B0mM-ro_.js} +2 -2
- package/dist/web/public/assets/{brain-CJyZe3Oa.js.map → brain-B0mM-ro_.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-DcLbQF2I.js → briefcase-CUQlj33_.js} +2 -2
- package/dist/web/public/assets/{briefcase-DcLbQF2I.js.map → briefcase-CUQlj33_.js.map} +1 -1
- package/dist/web/public/assets/{chevron-right-BhKELKvM.js → chevron-right-CJuDP_fx.js} +2 -2
- package/dist/web/public/assets/{chevron-right-BhKELKvM.js.map → chevron-right-CJuDP_fx.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-D1qST9RS.js → circle-check-CYse8LRx.js} +2 -2
- package/dist/web/public/assets/{circle-check-D1qST9RS.js.map → circle-check-CYse8LRx.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-EKe3o9y1.js → circle-check-big-9NpJLA1Z.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-EKe3o9y1.js.map → circle-check-big-9NpJLA1Z.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-DtePUX5x.js → circle-x-BxZ24SVG.js} +2 -2
- package/dist/web/public/assets/{circle-x-DtePUX5x.js.map → circle-x-BxZ24SVG.js.map} +1 -1
- package/dist/web/public/assets/{confirm-dialog-CCfCf6BG.js → confirm-dialog-CmHeZ7ei.js} +2 -2
- package/dist/web/public/assets/{confirm-dialog-CCfCf6BG.js.map → confirm-dialog-CmHeZ7ei.js.map} +1 -1
- package/dist/web/public/assets/{data-table-BRLUxacD.js → data-table-tu4BIahS.js} +5 -5
- package/dist/web/public/assets/{data-table-BRLUxacD.js.map → data-table-tu4BIahS.js.map} +1 -1
- package/dist/web/public/assets/{dialog-By4YA8bm.js → dialog-D8QAkLhI.js} +3 -3
- package/dist/web/public/assets/{dialog-By4YA8bm.js.map → dialog-D8QAkLhI.js.map} +1 -1
- package/dist/web/public/assets/{download-CiTB2sCh.js → download-DBS0ZPTh.js} +2 -2
- package/dist/web/public/assets/{download-CiTB2sCh.js.map → download-DBS0ZPTh.js.map} +1 -1
- package/dist/web/public/assets/{email-H-b2AExg.js → email-DgbAEEvZ.js} +3 -3
- package/dist/web/public/assets/{email-H-b2AExg.js.map → email-DgbAEEvZ.js.map} +1 -1
- package/dist/web/public/assets/{empty-state-DZJTUlvz.js → empty-state-B1S_EYNJ.js} +2 -2
- package/dist/web/public/assets/{empty-state-DZJTUlvz.js.map → empty-state-B1S_EYNJ.js.map} +1 -1
- package/dist/web/public/assets/{external-link-CfU6Rttn.js → external-link-Dkmwlv6p.js} +2 -2
- package/dist/web/public/assets/{external-link-CfU6Rttn.js.map → external-link-Dkmwlv6p.js.map} +1 -1
- package/dist/web/public/assets/{eye-BvWcd0pJ.js → eye-Ch0DLviZ.js} +4 -4
- package/dist/web/public/assets/{eye-BvWcd0pJ.js.map → eye-Ch0DLviZ.js.map} +1 -1
- package/dist/web/public/assets/{facts-BRDbQLSI.js → facts-C3YV1Mkp.js} +2 -2
- package/dist/web/public/assets/{facts-BRDbQLSI.js.map → facts-C3YV1Mkp.js.map} +1 -1
- package/dist/web/public/assets/goals-DEt5gGry.js +17 -0
- package/dist/web/public/assets/goals-DEt5gGry.js.map +1 -0
- package/dist/web/public/assets/{health-DJPFOiKw.js → health-DuB9uNiZ.js} +2 -2
- package/dist/web/public/assets/{health-DJPFOiKw.js.map → health-DuB9uNiZ.js.map} +1 -1
- package/dist/web/public/assets/heart-pulse-CD8xNAGs.js +7 -0
- package/dist/web/public/assets/heart-pulse-CD8xNAGs.js.map +1 -0
- package/dist/web/public/assets/heartbeat-DbR8VwmG.js +7 -0
- package/dist/web/public/assets/heartbeat-DbR8VwmG.js.map +1 -0
- package/dist/web/public/assets/hot-izk3vGQB.js +17 -0
- package/dist/web/public/assets/hot-izk3vGQB.js.map +1 -0
- package/dist/web/public/assets/index-B7QRVy9N.css +1 -0
- package/dist/web/public/assets/index-BY1vfCja.js +166 -0
- package/dist/web/public/assets/index-BY1vfCja.js.map +1 -0
- package/dist/web/public/assets/installed-BXB3-YIy.js +31 -0
- package/dist/web/public/assets/installed-BXB3-YIy.js.map +1 -0
- package/dist/web/public/assets/{jobs-DdWaBgOh.js → jobs-DkbM4mIQ.js} +2 -2
- package/dist/web/public/assets/{jobs-DdWaBgOh.js.map → jobs-DkbM4mIQ.js.map} +1 -1
- package/dist/web/public/assets/{layout-Dr12u0W_.js → layout-5ePj6Bek.js} +2 -2
- package/dist/web/public/assets/{layout-Dr12u0W_.js.map → layout-5ePj6Bek.js.map} +1 -1
- package/dist/web/public/assets/layout-B5Dzy_Zc.js +2 -0
- package/dist/web/public/assets/layout-B5Dzy_Zc.js.map +1 -0
- package/dist/web/public/assets/layout-BZpbNQFb.js +2 -0
- package/dist/web/public/assets/layout-BZpbNQFb.js.map +1 -0
- package/dist/web/public/assets/layout-DY9Xq34u.js +2 -0
- package/dist/web/public/assets/layout-DY9Xq34u.js.map +1 -0
- package/dist/web/public/assets/{layout-BybpkTy0.js → layout-DxzBaeTv.js} +2 -2
- package/dist/web/public/assets/{layout-BybpkTy0.js.map → layout-DxzBaeTv.js.map} +1 -1
- package/dist/web/public/assets/llm-Dg4W7eRM.js +7 -0
- package/dist/web/public/assets/llm-Dg4W7eRM.js.map +1 -0
- package/dist/web/public/assets/{loader-circle-BiR4Xs-3.js → loader-circle-pGNYdPoE.js} +2 -2
- package/dist/web/public/assets/{loader-circle-BiR4Xs-3.js.map → loader-circle-pGNYdPoE.js.map} +1 -1
- package/dist/web/public/assets/{map-pin-B8hea8yW.js → map-pin-D1UX9mg7.js} +2 -2
- package/dist/web/public/assets/{map-pin-B8hea8yW.js.map → map-pin-D1UX9mg7.js.map} +1 -1
- package/dist/web/public/assets/mcp-uoOzu4_J.js +7 -0
- package/dist/web/public/assets/mcp-uoOzu4_J.js.map +1 -0
- package/dist/web/public/assets/{memos-C0_I1Uzt.js → memos-CAWASHg5.js} +2 -2
- package/dist/web/public/assets/{memos-C0_I1Uzt.js.map → memos-CAWASHg5.js.map} +1 -1
- package/dist/web/public/assets/{messengers-DuS5_JlE.js → messengers-B1-mZms8.js} +3 -3
- package/dist/web/public/assets/{messengers-DuS5_JlE.js.map → messengers-B1-mZms8.js.map} +1 -1
- package/dist/web/public/assets/native-agent-UuVvvzsW.js +7 -0
- package/dist/web/public/assets/native-agent-UuVvvzsW.js.map +1 -0
- package/dist/web/public/assets/{network-CpkocMHV.js → network-DpjSgAwW.js} +2 -2
- package/dist/web/public/assets/{network-CpkocMHV.js.map → network-DpjSgAwW.js.map} +1 -1
- package/dist/web/public/assets/{outbox-mGqTV2Ex.js → outbox-DeAgiXkY.js} +3 -3
- package/dist/web/public/assets/{outbox-mGqTV2Ex.js.map → outbox-DeAgiXkY.js.map} +1 -1
- package/dist/web/public/assets/{pagination-BAYvy11u.js → pagination-5GD_he3L.js} +3 -3
- package/dist/web/public/assets/{pagination-BAYvy11u.js.map → pagination-5GD_he3L.js.map} +1 -1
- package/dist/web/public/assets/{persona-CM0TLPJa.js → persona-BhkDCmeB.js} +2 -2
- package/dist/web/public/assets/{persona-CM0TLPJa.js.map → persona-BhkDCmeB.js.map} +1 -1
- package/dist/web/public/assets/{play-DMgMpe7N.js → play-B7o6cJ8W.js} +2 -2
- package/dist/web/public/assets/{play-DMgMpe7N.js.map → play-B7o6cJ8W.js.map} +1 -1
- package/dist/web/public/assets/plus-C5d4C6Zp.js +7 -0
- package/dist/web/public/assets/plus-C5d4C6Zp.js.map +1 -0
- package/dist/web/public/assets/policy-Ct_sKm3Y.js +2 -0
- package/dist/web/public/assets/{policy-Ch-xirrA.js.map → policy-Ct_sKm3Y.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-D8mc4hxU.js → refresh-ccw-BlXMN3UX.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-D8mc4hxU.js.map → refresh-ccw-BlXMN3UX.js.map} +1 -1
- package/dist/web/public/assets/{reminders-Dbe7Rc4h.js → reminders-gb1Y0S3t.js} +4 -9
- package/dist/web/public/assets/reminders-gb1Y0S3t.js.map +1 -0
- package/dist/web/public/assets/{save-1aALBaZc.js → save-DAFuApnY.js} +2 -2
- package/dist/web/public/assets/{save-1aALBaZc.js.map → save-DAFuApnY.js.map} +1 -1
- package/dist/web/public/assets/{schedules-BBQ2wcnS.js → schedules-CtFumT2B.js} +3 -3
- package/dist/web/public/assets/{schedules-BBQ2wcnS.js.map → schedules-CtFumT2B.js.map} +1 -1
- package/dist/web/public/assets/{search-DDYjsJ7-.js → search-BWuZE0YD.js} +2 -2
- package/dist/web/public/assets/{search-DDYjsJ7-.js.map → search-BWuZE0YD.js.map} +1 -1
- package/dist/web/public/assets/{service-DMp11TKF.js → service-lah7RWEc.js} +3 -3
- package/dist/web/public/assets/{service-DMp11TKF.js.map → service-lah7RWEc.js.map} +1 -1
- package/dist/web/public/assets/{status-badge-Cvj81JKi.js → status-badge-BgmFa_8z.js} +2 -2
- package/dist/web/public/assets/{status-badge-Cvj81JKi.js.map → status-badge-BgmFa_8z.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-BC3Pf7OZ.js → subtasks-CgqrOGhl.js} +3 -3
- package/dist/web/public/assets/{subtasks-BC3Pf7OZ.js.map → subtasks-CgqrOGhl.js.map} +1 -1
- package/dist/web/public/assets/{table-B6nK6k3L.js → table-BhDzIBvB.js} +2 -2
- package/dist/web/public/assets/{table-B6nK6k3L.js.map → table-BhDzIBvB.js.map} +1 -1
- package/dist/web/public/assets/{topn-BwFh2jKv.js → topn-DXgTCdM_.js} +3 -3
- package/dist/web/public/assets/{topn-BwFh2jKv.js.map → topn-DXgTCdM_.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-CqpMjbu5.js → trash-2-i4F_Rzh3.js} +3 -3
- package/dist/web/public/assets/{trash-2-CqpMjbu5.js.map → trash-2-i4F_Rzh3.js.map} +1 -1
- package/dist/web/public/assets/use-background-tasks-Cq2D7JQJ.js +2 -0
- package/dist/web/public/assets/use-background-tasks-Cq2D7JQJ.js.map +1 -0
- package/dist/web/public/assets/use-llm-admin-BzOVXSjz.js +2 -0
- package/dist/web/public/assets/use-llm-admin-BzOVXSjz.js.map +1 -0
- package/dist/web/public/assets/{use-memory-jxZdt-RL.js → use-memory-B_RQWQyG.js} +2 -2
- package/dist/web/public/assets/{use-memory-jxZdt-RL.js.map → use-memory-B_RQWQyG.js.map} +1 -1
- package/dist/web/public/assets/{use-observability-9TDgLO9y.js → use-observability-CCTN-a71.js} +2 -2
- package/dist/web/public/assets/{use-observability-9TDgLO9y.js.map → use-observability-CCTN-a71.js.map} +1 -1
- package/dist/web/public/assets/{use-settings-DFB_c2pr.js → use-settings-D4EdDLiK.js} +2 -2
- package/dist/web/public/assets/{use-settings-DFB_c2pr.js.map → use-settings-D4EdDLiK.js.map} +1 -1
- package/dist/web/public/assets/{use-workspace-C-Eg6yWa.js → use-workspace-BhTEp_QH.js} +2 -2
- package/dist/web/public/assets/{use-workspace-C-Eg6yWa.js.map → use-workspace-BhTEp_QH.js.map} +1 -1
- package/dist/web/public/assets/useQuery-DmoWKLw3.js +2 -0
- package/dist/web/public/assets/{useQuery-rLmHxFp4.js.map → useQuery-DmoWKLw3.js.map} +1 -1
- package/dist/web/public/assets/{vector-D9UqmLi6.js → vector-By-cheMu.js} +2 -2
- package/dist/web/public/assets/{vector-D9UqmLi6.js.map → vector-By-cheMu.js.map} +1 -1
- package/dist/web/public/assets/{viewer-_OpObeWr.js → viewer-CJNrz2iw.js} +3 -3
- package/dist/web/public/assets/{viewer-_OpObeWr.js.map → viewer-CJNrz2iw.js.map} +1 -1
- package/dist/web/public/assets/{workspace-DSHRdspq.js → workspace-DvYlIAhu.js} +4 -4
- package/dist/web/public/assets/{workspace-DSHRdspq.js.map → workspace-DvYlIAhu.js.map} +1 -1
- package/dist/web/public/assets/{workspaces-CsBdhbXz.js → workspaces-2pn73O-K.js} +3 -3
- package/dist/web/public/assets/{workspaces-CsBdhbXz.js.map → workspaces-2pn73O-K.js.map} +1 -1
- package/dist/web/public/assets/{x-D1re-vBd.js → x-5Z_de5zo.js} +2 -2
- package/dist/web/public/assets/{x-D1re-vBd.js.map → x-5Z_de5zo.js.map} +1 -1
- package/dist/web/public/index.html +2 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +45 -0
- package/dist/web/server.js.map +1 -1
- package/package.json +2 -2
- package/dist/web/public/assets/agents-lrzFDGgX.js +0 -12
- package/dist/web/public/assets/agents-lrzFDGgX.js.map +0 -1
- package/dist/web/public/assets/hot-CFGHGkqL.js +0 -17
- package/dist/web/public/assets/hot-CFGHGkqL.js.map +0 -1
- package/dist/web/public/assets/index-C4hk1i67.js +0 -166
- package/dist/web/public/assets/index-C4hk1i67.js.map +0 -1
- package/dist/web/public/assets/index-Cvacw7Jg.css +0 -1
- package/dist/web/public/assets/installed-UONWfKHS.js +0 -7
- package/dist/web/public/assets/installed-UONWfKHS.js.map +0 -1
- package/dist/web/public/assets/layout-C8_IQRGM.js +0 -2
- package/dist/web/public/assets/layout-C8_IQRGM.js.map +0 -1
- package/dist/web/public/assets/layout-CxRHLqvi.js +0 -2
- package/dist/web/public/assets/layout-CxRHLqvi.js.map +0 -1
- package/dist/web/public/assets/layout-LC5zjw1h.js +0 -2
- package/dist/web/public/assets/layout-LC5zjw1h.js.map +0 -1
- package/dist/web/public/assets/policy-Ch-xirrA.js +0 -2
- package/dist/web/public/assets/reminders-Dbe7Rc4h.js.map +0 -1
- package/dist/web/public/assets/use-skills-OZKB5x-S.js +0 -2
- package/dist/web/public/assets/use-skills-OZKB5x-S.js.map +0 -1
- package/dist/web/public/assets/useQuery-rLmHxFp4.js +0 -2
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
// OpenAI-compatible chat completions provider.
|
|
2
|
+
//
|
|
3
|
+
// One adapter covers the entire OpenAI-compatible ecosystem: OpenAI,
|
|
4
|
+
// DeepSeek, Moonshot/Kimi, Qwen DashScope (compat mode), MiniMax,
|
|
5
|
+
// StepFun, VolcEngine, LongCat, Mistral La Plateforme, Groq, Together,
|
|
6
|
+
// SiliconFlow, OpenRouter, vLLM, LM Studio, Ollama's OpenAI-compat
|
|
7
|
+
// endpoint, and any custom gateway that exposes `/v1/chat/completions`.
|
|
8
|
+
//
|
|
9
|
+
// Stage 1 scope (intentionally narrow):
|
|
10
|
+
// - POST /v1/chat/completions with `messages` + `temperature` + `max_tokens`
|
|
11
|
+
// - Standard streaming via SSE (`stream: true`)
|
|
12
|
+
// - Single retry on 429 / 5xx transient errors
|
|
13
|
+
// - Usage extraction (prompt_tokens / completion_tokens / total_tokens)
|
|
14
|
+
//
|
|
15
|
+
// Out of scope for Stage 1 (lands in Stage 2):
|
|
16
|
+
// - structured outputs (json_schema)
|
|
17
|
+
// - response_format
|
|
18
|
+
//
|
|
19
|
+
// (Stage 2 added tool_calls + vision / image_url content parts; the
|
|
20
|
+
// remaining items are still pending.)
|
|
21
|
+
//
|
|
22
|
+
// Why no SDK: every OpenAI-compatible vendor diverges in subtle ways and
|
|
23
|
+
// the official `openai` SDK adds a 5MB+ dep tree for what is ultimately
|
|
24
|
+
// one POST. `fetch` keeps the code auditable and dependency-free.
|
|
25
|
+
import { LlmProvider, LlmProviderError, } from './provider-base.js';
|
|
26
|
+
import { statSync as fsStatSync, readFileSync as fsReadFileSync } from 'node:fs';
|
|
27
|
+
const DEFAULT_BASE_URL = 'https://api.openai.com/v1';
|
|
28
|
+
const DEFAULT_RETRY = 1;
|
|
29
|
+
/**
|
|
30
|
+
* Concrete provider for any OpenAI-compatible `/v1/chat/completions`
|
|
31
|
+
* endpoint. Single-shot chat is the only Stage-1 path we care about —
|
|
32
|
+
* the streaming method is wired up for Stage 2 / future "show thinking
|
|
33
|
+
* in web UI" features and is fully functional.
|
|
34
|
+
*/
|
|
35
|
+
export class OpenAICompatProvider extends LlmProvider {
|
|
36
|
+
baseUrl;
|
|
37
|
+
extraHeaders;
|
|
38
|
+
retryOnTransient;
|
|
39
|
+
vision;
|
|
40
|
+
constructor(cfg) {
|
|
41
|
+
super({
|
|
42
|
+
...cfg,
|
|
43
|
+
providerType: cfg.providerLabel || 'openai-compat',
|
|
44
|
+
});
|
|
45
|
+
this.baseUrl = (cfg.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
46
|
+
this.extraHeaders = cfg.extraHeaders || {};
|
|
47
|
+
this.retryOnTransient = Math.max(0, cfg.retryOnTransient ?? DEFAULT_RETRY);
|
|
48
|
+
if (typeof cfg.vision === 'boolean') {
|
|
49
|
+
this.vision = cfg.vision;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Heuristic: well-known vision-capable model families.
|
|
53
|
+
const m = (cfg.model || '').toLowerCase();
|
|
54
|
+
this.vision = /vision|gpt-4o|gpt-4\.1|qwen-vl|glm-4v|llava/.test(m);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
supportsVision() {
|
|
58
|
+
return this.vision;
|
|
59
|
+
}
|
|
60
|
+
async _callApi(messages, opts, signal) {
|
|
61
|
+
const body = this._buildBody(messages, opts, false);
|
|
62
|
+
const json = await this._postJson(body, signal);
|
|
63
|
+
const text = extractText(json);
|
|
64
|
+
const finishReason = mapFinishReason(json?.choices?.[0]?.finish_reason);
|
|
65
|
+
const usage = extractUsage(json);
|
|
66
|
+
const toolCalls = extractToolCalls(json);
|
|
67
|
+
const reasoningContent = extractReasoningContent(json);
|
|
68
|
+
return {
|
|
69
|
+
text,
|
|
70
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
71
|
+
reasoningContent,
|
|
72
|
+
usage,
|
|
73
|
+
finishReason,
|
|
74
|
+
modelUsed: typeof json?.model === 'string' ? json.model : opts.model,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async *_callApiStream(messages, opts, signal) {
|
|
78
|
+
const body = this._buildBody(messages, opts, true);
|
|
79
|
+
const url = `${this.baseUrl}/chat/completions`;
|
|
80
|
+
const resp = await this._fetchWithRetry(url, body, signal);
|
|
81
|
+
if (!resp.body) {
|
|
82
|
+
throw new LlmProviderError(this.name, 'streaming response had no body', { httpStatus: resp.status });
|
|
83
|
+
}
|
|
84
|
+
const reader = resp.body.getReader();
|
|
85
|
+
const decoder = new TextDecoder('utf-8');
|
|
86
|
+
let buffer = '';
|
|
87
|
+
let lastUsage;
|
|
88
|
+
let lastFinish;
|
|
89
|
+
try {
|
|
90
|
+
while (true) {
|
|
91
|
+
const { value, done } = await reader.read();
|
|
92
|
+
if (done)
|
|
93
|
+
break;
|
|
94
|
+
buffer += decoder.decode(value, { stream: true });
|
|
95
|
+
// SSE frames are separated by blank lines (`\n\n`); each frame
|
|
96
|
+
// contains one or more `data: <json>` lines.
|
|
97
|
+
for (;;) {
|
|
98
|
+
const sep = buffer.indexOf('\n\n');
|
|
99
|
+
if (sep === -1)
|
|
100
|
+
break;
|
|
101
|
+
const frame = buffer.slice(0, sep);
|
|
102
|
+
buffer = buffer.slice(sep + 2);
|
|
103
|
+
for (const line of frame.split('\n')) {
|
|
104
|
+
const trimmed = line.trim();
|
|
105
|
+
if (!trimmed.startsWith('data:'))
|
|
106
|
+
continue;
|
|
107
|
+
const payload = trimmed.slice(5).trim();
|
|
108
|
+
if (payload === '[DONE]') {
|
|
109
|
+
yield { textDelta: '', finishReason: lastFinish ?? 'stop', usage: lastUsage };
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
let parsed = null;
|
|
113
|
+
try {
|
|
114
|
+
parsed = JSON.parse(payload);
|
|
115
|
+
}
|
|
116
|
+
catch { /* ignore */ }
|
|
117
|
+
if (!parsed)
|
|
118
|
+
continue;
|
|
119
|
+
const delta = parsed.choices?.[0]?.delta?.content;
|
|
120
|
+
if (parsed.usage)
|
|
121
|
+
lastUsage = extractUsage(parsed);
|
|
122
|
+
if (parsed.choices?.[0]?.finish_reason) {
|
|
123
|
+
lastFinish = mapFinishReason(parsed.choices[0].finish_reason);
|
|
124
|
+
}
|
|
125
|
+
if (typeof delta === 'string' && delta.length > 0) {
|
|
126
|
+
yield { textDelta: delta };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Stream ended without `[DONE]` (some vendors do this) — surface
|
|
132
|
+
// the trailing state so callers still see a finalized chunk.
|
|
133
|
+
yield { textDelta: '', finishReason: lastFinish ?? 'stop', usage: lastUsage };
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
try {
|
|
137
|
+
reader.releaseLock();
|
|
138
|
+
}
|
|
139
|
+
catch { /* ignore */ }
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Compose the JSON body. Kept tiny on purpose — the messages array
|
|
144
|
+
* goes through as-is and the rest of the OpenAI surface (logprobs,
|
|
145
|
+
* top_p, stop, …) lands when callers ask for it via providerOptions.
|
|
146
|
+
*/
|
|
147
|
+
_buildBody(messages, opts, stream) {
|
|
148
|
+
const body = {
|
|
149
|
+
model: opts.model,
|
|
150
|
+
messages: messages.map((m) => serializeMessage(m, { vision: this.vision })),
|
|
151
|
+
temperature: opts.temperature,
|
|
152
|
+
max_tokens: opts.maxTokens,
|
|
153
|
+
};
|
|
154
|
+
if (stream)
|
|
155
|
+
body.stream = true;
|
|
156
|
+
if (opts.tools && opts.tools.length > 0) {
|
|
157
|
+
body.tools = opts.tools.map(serializeToolDef);
|
|
158
|
+
const tc = serializeToolChoice(opts.toolChoice);
|
|
159
|
+
if (tc !== undefined)
|
|
160
|
+
body.tool_choice = tc;
|
|
161
|
+
}
|
|
162
|
+
// providerOptions lets callers pass through e.g. {top_p: 0.9} or
|
|
163
|
+
// DeepSeek's {response_format: {type:'json_object'}} without
|
|
164
|
+
// requiring a release of this file every time a vendor adds a knob.
|
|
165
|
+
for (const [k, v] of Object.entries(opts.providerOptions)) {
|
|
166
|
+
if (v !== undefined)
|
|
167
|
+
body[k] = v;
|
|
168
|
+
}
|
|
169
|
+
return body;
|
|
170
|
+
}
|
|
171
|
+
async _postJson(body, signal) {
|
|
172
|
+
const url = `${this.baseUrl}/chat/completions`;
|
|
173
|
+
const resp = await this._fetchWithRetry(url, body, signal);
|
|
174
|
+
let json;
|
|
175
|
+
try {
|
|
176
|
+
json = await resp.json();
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
throw new LlmProviderError(this.name, 'failed to parse JSON response', {
|
|
180
|
+
httpStatus: resp.status,
|
|
181
|
+
cause: err,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return json;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* fetch + minimal retry. We backoff with a tiny fixed delay rather
|
|
188
|
+
* than honoring Retry-After because Stage 1 callers (distill /
|
|
189
|
+
* intent) have very short deadlines — long backoffs would force a
|
|
190
|
+
* fallback to CLI anyway, which is the whole point of "transient
|
|
191
|
+
* retry, then surrender".
|
|
192
|
+
*/
|
|
193
|
+
async _fetchWithRetry(url, body, signal) {
|
|
194
|
+
let lastErr;
|
|
195
|
+
let attempts = 0;
|
|
196
|
+
const maxAttempts = this.retryOnTransient + 1;
|
|
197
|
+
while (attempts < maxAttempts) {
|
|
198
|
+
attempts++;
|
|
199
|
+
try {
|
|
200
|
+
const headers = {
|
|
201
|
+
'Content-Type': 'application/json',
|
|
202
|
+
'User-Agent': 'agim-cli/llm-client',
|
|
203
|
+
...this.extraHeaders,
|
|
204
|
+
};
|
|
205
|
+
if (this.apiKey)
|
|
206
|
+
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
207
|
+
const resp = await fetch(url, {
|
|
208
|
+
method: 'POST',
|
|
209
|
+
headers,
|
|
210
|
+
body: JSON.stringify(body),
|
|
211
|
+
signal,
|
|
212
|
+
});
|
|
213
|
+
if (resp.ok)
|
|
214
|
+
return resp;
|
|
215
|
+
const transient = resp.status === 429 || resp.status === 408 || (resp.status >= 500 && resp.status < 600);
|
|
216
|
+
// Read body so we can surface a useful error message; vendor
|
|
217
|
+
// error envelopes vary too much to parse reliably here.
|
|
218
|
+
let bodyText = '';
|
|
219
|
+
try {
|
|
220
|
+
bodyText = (await resp.text()).slice(0, 500);
|
|
221
|
+
}
|
|
222
|
+
catch { /* ignore */ }
|
|
223
|
+
if (!transient || attempts >= maxAttempts) {
|
|
224
|
+
throw new LlmProviderError(this.name, `HTTP ${resp.status} from ${this.providerType}: ${bodyText || '(no body)'}`, { httpStatus: resp.status, transient });
|
|
225
|
+
}
|
|
226
|
+
// Transient and budget remaining — sleep and let the while loop
|
|
227
|
+
// tick to the next attempt. The retry budget is the only thing
|
|
228
|
+
// standing between us and an infinite loop.
|
|
229
|
+
await sleep(250 * attempts, signal);
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
// AbortError propagates immediately — callers wired timeouts on
|
|
233
|
+
// purpose and want to bail.
|
|
234
|
+
if (isAbortError(err))
|
|
235
|
+
throw err;
|
|
236
|
+
lastErr = err;
|
|
237
|
+
if (attempts < maxAttempts) {
|
|
238
|
+
await sleep(250 * attempts, signal);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (lastErr instanceof LlmProviderError)
|
|
243
|
+
throw lastErr;
|
|
244
|
+
throw new LlmProviderError(this.name, `transport error: ${lastErr?.message ?? String(lastErr)}`, { transient: true, cause: lastErr });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function extractReasoningContent(json) {
|
|
248
|
+
const r = json?.choices?.[0]?.message?.reasoning_content;
|
|
249
|
+
return typeof r === 'string' && r.length > 0 ? r : undefined;
|
|
250
|
+
}
|
|
251
|
+
function extractText(json) {
|
|
252
|
+
const c = json?.choices?.[0]?.message?.content;
|
|
253
|
+
if (typeof c === 'string')
|
|
254
|
+
return c;
|
|
255
|
+
return '';
|
|
256
|
+
}
|
|
257
|
+
function extractUsage(json) {
|
|
258
|
+
const u = json?.usage;
|
|
259
|
+
if (!u)
|
|
260
|
+
return {};
|
|
261
|
+
const result = {
|
|
262
|
+
promptTokens: typeof u.prompt_tokens === 'number' ? u.prompt_tokens : undefined,
|
|
263
|
+
completionTokens: typeof u.completion_tokens === 'number' ? u.completion_tokens : undefined,
|
|
264
|
+
totalTokens: typeof u.total_tokens === 'number' ? u.total_tokens : undefined,
|
|
265
|
+
};
|
|
266
|
+
const cost = typeof u.cost === 'number' ? u.cost
|
|
267
|
+
: typeof u.total_cost === 'number' ? u.total_cost
|
|
268
|
+
: undefined;
|
|
269
|
+
if (cost !== undefined)
|
|
270
|
+
result.costUsd = cost;
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
273
|
+
function mapFinishReason(raw) {
|
|
274
|
+
switch (raw) {
|
|
275
|
+
case 'stop': return 'stop';
|
|
276
|
+
case 'length': return 'length';
|
|
277
|
+
case 'content_filter': return 'content_filter';
|
|
278
|
+
case 'tool_calls': return 'tool_use'; // Stage 2 — agent loop iterates on this
|
|
279
|
+
case 'function_call': return 'tool_use';
|
|
280
|
+
case null:
|
|
281
|
+
case undefined:
|
|
282
|
+
case '': return 'unknown';
|
|
283
|
+
default: return 'unknown';
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function sleep(ms, signal) {
|
|
287
|
+
return new Promise((resolve, reject) => {
|
|
288
|
+
if (signal.aborted) {
|
|
289
|
+
reject(signal.reason ?? new Error('aborted'));
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const t = setTimeout(() => {
|
|
293
|
+
signal.removeEventListener('abort', onAbort);
|
|
294
|
+
resolve();
|
|
295
|
+
}, ms);
|
|
296
|
+
const onAbort = () => {
|
|
297
|
+
clearTimeout(t);
|
|
298
|
+
reject(signal.reason ?? new Error('aborted'));
|
|
299
|
+
};
|
|
300
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
function isAbortError(err) {
|
|
304
|
+
if (!err)
|
|
305
|
+
return false;
|
|
306
|
+
if (typeof err !== 'object')
|
|
307
|
+
return false;
|
|
308
|
+
const name = err.name;
|
|
309
|
+
return name === 'AbortError';
|
|
310
|
+
}
|
|
311
|
+
// ─── Stage 2 — tool-call serialization / deserialization ─────────────
|
|
312
|
+
function serializeMessage(m, opts) {
|
|
313
|
+
// OpenAI's wire-format expects either:
|
|
314
|
+
// - {role:'system'|'user', content}
|
|
315
|
+
// - {role:'assistant', content, tool_calls?: [...]}
|
|
316
|
+
// - {role:'tool', tool_call_id, content}
|
|
317
|
+
// We branch on role to put fields in the right shape, otherwise the
|
|
318
|
+
// API politely 400s with very unhelpful errors.
|
|
319
|
+
if (m.role === 'tool') {
|
|
320
|
+
return {
|
|
321
|
+
role: 'tool',
|
|
322
|
+
tool_call_id: m.toolCallId ?? '',
|
|
323
|
+
content: m.content,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
if (m.role === 'assistant' && m.toolCalls && m.toolCalls.length > 0) {
|
|
327
|
+
const out = {
|
|
328
|
+
role: 'assistant',
|
|
329
|
+
// content may be empty when the assistant emitted only tool_calls.
|
|
330
|
+
// OpenAI requires the key to be present (use null over '').
|
|
331
|
+
content: m.content || null,
|
|
332
|
+
tool_calls: m.toolCalls.map((tc) => ({
|
|
333
|
+
id: tc.id,
|
|
334
|
+
type: 'function',
|
|
335
|
+
function: {
|
|
336
|
+
name: tc.name,
|
|
337
|
+
arguments: tc.argumentsRaw ?? JSON.stringify(tc.arguments),
|
|
338
|
+
},
|
|
339
|
+
})),
|
|
340
|
+
};
|
|
341
|
+
if (m.reasoningContent)
|
|
342
|
+
out.reasoning_content = m.reasoningContent;
|
|
343
|
+
return out;
|
|
344
|
+
}
|
|
345
|
+
if (m.role === 'assistant' && m.reasoningContent) {
|
|
346
|
+
return { role: 'assistant', content: m.content || null, reasoning_content: m.reasoningContent };
|
|
347
|
+
}
|
|
348
|
+
// User / system path. Encode media as image_url content blocks when
|
|
349
|
+
// the provider declared vision support; otherwise drop the media
|
|
350
|
+
// (the text path already mentions the attachment by path so the
|
|
351
|
+
// model can still acknowledge it textually).
|
|
352
|
+
if (opts.vision && m.media && m.media.length > 0 && m.role === 'user') {
|
|
353
|
+
const blocks = [];
|
|
354
|
+
if (m.content)
|
|
355
|
+
blocks.push({ type: 'text', text: m.content });
|
|
356
|
+
for (const item of m.media) {
|
|
357
|
+
const dataUrl = mediaToDataUrl(item.path, item.mime);
|
|
358
|
+
if (dataUrl)
|
|
359
|
+
blocks.push({ type: 'image_url', image_url: { url: dataUrl } });
|
|
360
|
+
}
|
|
361
|
+
if (blocks.length > 0)
|
|
362
|
+
return { role: 'user', content: blocks };
|
|
363
|
+
}
|
|
364
|
+
return { role: m.role, content: m.content };
|
|
365
|
+
}
|
|
366
|
+
/** Read a local file and inline-base64 it as a data URL. Returns null
|
|
367
|
+
* on read failure so the caller can fall back to text-only. Capped at
|
|
368
|
+
* 20MB — most IM attachments are well under, and oversize files would
|
|
369
|
+
* blow past most providers' request-size limits anyway. */
|
|
370
|
+
function mediaToDataUrl(path, mimeHint) {
|
|
371
|
+
try {
|
|
372
|
+
const stat = fsStatSync(path);
|
|
373
|
+
if (stat.size > 20 * 1024 * 1024)
|
|
374
|
+
return null;
|
|
375
|
+
const buf = fsReadFileSync(path);
|
|
376
|
+
const mime = mimeHint || sniffMime(path);
|
|
377
|
+
return `data:${mime};base64,${buf.toString('base64')}`;
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function sniffMime(path) {
|
|
384
|
+
const lower = path.toLowerCase();
|
|
385
|
+
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
|
|
386
|
+
return 'image/jpeg';
|
|
387
|
+
if (lower.endsWith('.png'))
|
|
388
|
+
return 'image/png';
|
|
389
|
+
if (lower.endsWith('.webp'))
|
|
390
|
+
return 'image/webp';
|
|
391
|
+
if (lower.endsWith('.gif'))
|
|
392
|
+
return 'image/gif';
|
|
393
|
+
return 'application/octet-stream';
|
|
394
|
+
}
|
|
395
|
+
function serializeToolDef(t) {
|
|
396
|
+
return {
|
|
397
|
+
type: 'function',
|
|
398
|
+
function: {
|
|
399
|
+
name: t.name,
|
|
400
|
+
description: t.description,
|
|
401
|
+
parameters: t.parameters,
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function serializeToolChoice(choice) {
|
|
406
|
+
if (!choice)
|
|
407
|
+
return undefined;
|
|
408
|
+
if (choice === 'auto' || choice === 'required' || choice === 'none')
|
|
409
|
+
return choice;
|
|
410
|
+
if (typeof choice === 'object' && choice.type === 'tool') {
|
|
411
|
+
return { type: 'function', function: { name: choice.name } };
|
|
412
|
+
}
|
|
413
|
+
return undefined;
|
|
414
|
+
}
|
|
415
|
+
function extractToolCalls(json) {
|
|
416
|
+
const calls = json?.choices?.[0]?.message?.tool_calls;
|
|
417
|
+
if (!Array.isArray(calls) || calls.length === 0)
|
|
418
|
+
return [];
|
|
419
|
+
const out = [];
|
|
420
|
+
for (const c of calls) {
|
|
421
|
+
const id = typeof c?.id === 'string' ? c.id : '';
|
|
422
|
+
const name = typeof c?.function?.name === 'string' ? c.function.name : '';
|
|
423
|
+
const rawArgs = typeof c?.function?.arguments === 'string' ? c.function.arguments : '';
|
|
424
|
+
if (!id || !name)
|
|
425
|
+
continue;
|
|
426
|
+
let parsed = {};
|
|
427
|
+
let argumentsRaw;
|
|
428
|
+
if (rawArgs) {
|
|
429
|
+
try {
|
|
430
|
+
const obj = JSON.parse(rawArgs);
|
|
431
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
432
|
+
parsed = obj;
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
argumentsRaw = rawArgs;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
// Model emitted malformed JSON. Surface the raw text so tools
|
|
440
|
+
// can decide whether to error or to attempt a salvage.
|
|
441
|
+
argumentsRaw = rawArgs;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
const req = { id, name, arguments: parsed };
|
|
445
|
+
if (argumentsRaw !== undefined)
|
|
446
|
+
req.argumentsRaw = argumentsRaw;
|
|
447
|
+
out.push(req);
|
|
448
|
+
}
|
|
449
|
+
return out;
|
|
450
|
+
}
|
|
451
|
+
//# sourceMappingURL=openai-compat-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-compat-provider.js","sourceRoot":"","sources":["../../../src/core/llm/openai-compat-provider.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,EAAE;AACF,qEAAqE;AACrE,kEAAkE;AAClE,uEAAuE;AACvE,mEAAmE;AACnE,wEAAwE;AACxE,EAAE;AACF,wCAAwC;AACxC,+EAA+E;AAC/E,kDAAkD;AAClD,iDAAiD;AACjD,0EAA0E;AAC1E,EAAE;AACF,+CAA+C;AAC/C,uCAAuC;AACvC,sBAAsB;AACtB,EAAE;AACF,oEAAoE;AACpE,sCAAsC;AACtC,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,kEAAkE;AAElE,OAAO,EACL,WAAW,EACX,gBAAgB,GAWjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,YAAY,IAAI,cAAc,EAAE,MAAM,SAAS,CAAA;AAmChF,MAAM,gBAAgB,GAAG,2BAA2B,CAAA;AACpD,MAAM,aAAa,GAAG,CAAC,CAAA;AAEvB;;;;;GAKG;AACH,MAAM,OAAO,oBAAqB,SAAQ,WAAW;IAClC,OAAO,CAAQ;IACf,YAAY,CAAwB;IACpC,gBAAgB,CAAQ;IACxB,MAAM,CAAS;IAEhC,YAAY,GAA+B;QACzC,KAAK,CAAC;YACJ,GAAG,GAAG;YACN,YAAY,EAAE,GAAG,CAAC,aAAa,IAAI,eAAe;SACnD,CAAC,CAAA;QACF,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QACpE,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAA;QAC1C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,gBAAgB,IAAI,aAAa,CAAC,CAAA;QAC1E,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;YACzC,IAAI,CAAC,MAAM,GAAG,6CAA6C,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACrE,CAAC;IACH,CAAC;IAEQ,cAAc;QACrB,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAES,KAAK,CAAC,QAAQ,CACtB,QAAsB,EACtB,IAAuB,EACvB,MAAmB;QAEnB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;QACnD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAA;QACvE,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;QAChC,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;QACxC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;QACtD,OAAO;YACL,IAAI;YACJ,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACvD,gBAAgB;YAChB,KAAK;YACL,YAAY;YACZ,SAAS,EAAE,OAAO,IAAI,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK;SACrE,CAAA;IACH,CAAC;IAES,KAAK,CAAC,CAAC,cAAc,CAC7B,QAAsB,EACtB,IAAuB,EACvB,MAAmB;QAEnB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAClD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,mBAAmB,CAAA;QAC9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QAC1D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,gCAAgC,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QACtG,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAA;QACpC,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;QACxC,IAAI,MAAM,GAAG,EAAE,CAAA;QACf,IAAI,SAA+B,CAAA;QACnC,IAAI,UAAoC,CAAA;QACxC,IAAI,CAAC;YACH,OAAO,IAAI,EAAE,CAAC;gBACZ,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;gBAC3C,IAAI,IAAI;oBAAE,MAAK;gBACf,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;gBACjD,+DAA+D;gBAC/D,6CAA6C;gBAC7C,SAAS,CAAC;oBACR,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;oBAClC,IAAI,GAAG,KAAK,CAAC,CAAC;wBAAE,MAAK;oBACrB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;oBAClC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;oBAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;wBAC3B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;4BAAE,SAAQ;wBAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;wBACvC,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;4BACzB,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,EAAE,UAAU,IAAI,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;4BAC7E,OAAM;wBACR,CAAC;wBACD,IAAI,MAAM,GAA+B,IAAI,CAAA;wBAC7C,IAAI,CAAC;4BAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAwB,CAAA;wBAAC,CAAC;wBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;wBAClF,IAAI,CAAC,MAAM;4BAAE,SAAQ;wBACrB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAA;wBACjD,IAAI,MAAM,CAAC,KAAK;4BAAE,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;wBAClD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC;4BACvC,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;wBAC/D,CAAC;wBACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BAClD,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;wBAC5B,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YACD,iEAAiE;YACjE,6DAA6D;YAC7D,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,EAAE,UAAU,IAAI,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;QAC/E,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC;gBAAC,MAAM,CAAC,WAAW,EAAE,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,UAAU,CAChB,QAAsB,EACtB,IAAuB,EACvB,MAAe;QAEf,MAAM,IAAI,GAA4B;YACpC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3E,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,SAAS;SAC3B,CAAA;QACD,IAAI,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAC9B,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;YAC7C,MAAM,EAAE,GAAG,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAC/C,IAAI,EAAE,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,GAAG,EAAE,CAAA;QAC7C,CAAC;QACD,iEAAiE;QACjE,6DAA6D;QAC7D,oEAAoE;QACpE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,KAAK,SAAS;gBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAClC,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,IAAa,EAAE,MAAmB;QACxD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,mBAAmB,CAAA;QAC9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QAC1D,IAAI,IAA4B,CAAA;QAChC,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAA4B,CAAA;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,+BAA+B,EAAE;gBACrE,UAAU,EAAE,IAAI,CAAC,MAAM;gBACvB,KAAK,EAAE,GAAG;aACX,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,eAAe,CAAC,GAAW,EAAE,IAAa,EAAE,MAAmB;QAC3E,IAAI,OAAgB,CAAA;QACpB,IAAI,QAAQ,GAAG,CAAC,CAAA;QAChB,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAA;QAC7C,OAAO,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC9B,QAAQ,EAAE,CAAA;YACV,IAAI,CAAC;gBACH,MAAM,OAAO,GAA2B;oBACtC,cAAc,EAAE,kBAAkB;oBAClC,YAAY,EAAE,qBAAqB;oBACnC,GAAG,IAAI,CAAC,YAAY;iBACrB,CAAA;gBACD,IAAI,IAAI,CAAC,MAAM;oBAAE,OAAO,CAAC,aAAa,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAA;gBAChE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBAC5B,MAAM,EAAE,MAAM;oBACd,OAAO;oBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;oBAC1B,MAAM;iBACP,CAAC,CAAA;gBACF,IAAI,IAAI,CAAC,EAAE;oBAAE,OAAO,IAAI,CAAA;gBACxB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;gBACzG,6DAA6D;gBAC7D,wDAAwD;gBACxD,IAAI,QAAQ,GAAG,EAAE,CAAA;gBACjB,IAAI,CAAC;oBAAC,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;gBAC3E,IAAI,CAAC,SAAS,IAAI,QAAQ,IAAI,WAAW,EAAE,CAAC;oBAC1C,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAClC,QAAQ,IAAI,CAAC,MAAM,SAAS,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAI,WAAW,EAAE,EAC3E,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;gBAC3C,CAAC;gBACD,gEAAgE;gBAChE,+DAA+D;gBAC/D,4CAA4C;gBAC5C,MAAM,KAAK,CAAC,GAAG,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAA;YACrC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,gEAAgE;gBAChE,4BAA4B;gBAC5B,IAAI,YAAY,CAAC,GAAG,CAAC;oBAAE,MAAM,GAAG,CAAA;gBAChC,OAAO,GAAG,GAAG,CAAA;gBACb,IAAI,QAAQ,GAAG,WAAW,EAAE,CAAC;oBAC3B,MAAM,KAAK,CAAC,GAAG,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAA;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,OAAO,YAAY,gBAAgB;YAAE,MAAM,OAAO,CAAA;QACtD,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAClC,oBAAqB,OAAiB,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,EACpE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;IACxC,CAAC;CACF;AA8CD,SAAS,uBAAuB,CAAC,IAAmC;IAClE,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,CAAA;IACxD,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC9D,CAAC;AAED,SAAS,WAAW,CAAC,IAAmC;IACtD,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAA;IAC9C,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAA;IACnC,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,YAAY,CAAC,IAA4C;IAChE,MAAM,CAAC,GAAG,IAAI,EAAE,KAAK,CAAA;IACrB,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAA;IACjB,MAAM,MAAM,GAAa;QACvB,YAAY,EAAE,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QAC/E,gBAAgB,EAAE,OAAO,CAAC,CAAC,iBAAiB,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS;QAC3F,WAAW,EAAE,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;KAC7E,CAAA;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;QAC9C,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;YACjD,CAAC,CAAC,SAAS,CAAA;IACb,IAAI,IAAI,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;IAC7C,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,eAAe,CAAC,GAA8B;IACrD,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM,CAAC,CAAC,OAAO,MAAM,CAAA;QAC1B,KAAK,QAAQ,CAAC,CAAC,OAAO,QAAQ,CAAA;QAC9B,KAAK,gBAAgB,CAAC,CAAC,OAAO,gBAAgB,CAAA;QAC9C,KAAK,YAAY,CAAC,CAAC,OAAO,UAAU,CAAA,CAAG,wCAAwC;QAC/E,KAAK,eAAe,CAAC,CAAC,OAAO,UAAU,CAAA;QACvC,KAAK,IAAI,CAAC;QACV,KAAK,SAAS,CAAC;QACf,KAAK,EAAE,CAAC,CAAC,OAAO,SAAS,CAAA;QACzB,OAAO,CAAC,CAAC,OAAO,SAAS,CAAA;IAC3B,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU,EAAE,MAAmB;IAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;YAC7C,OAAM;QACR,CAAC;QACD,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE;YACxB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5C,OAAO,EAAE,CAAA;QACX,CAAC,EAAE,EAAE,CAAC,CAAA;QACN,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,YAAY,CAAC,CAAC,CAAC,CAAA;YACf,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;QAC/C,CAAC,CAAA;QACD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAA;IACtB,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACzC,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAA;IAC7C,OAAO,IAAI,KAAK,YAAY,CAAA;AAC9B,CAAC;AAED,wEAAwE;AAExE,SAAS,gBAAgB,CAAC,CAAa,EAAE,IAAyB;IAChE,uCAAuC;IACvC,sCAAsC;IACtC,sDAAsD;IACtD,2CAA2C;IAC3C,oEAAoE;IACpE,gDAAgD;IAChD,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,YAAY,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;YAChC,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAA;IACH,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpE,MAAM,GAAG,GAA4B;YACnC,IAAI,EAAE,WAAW;YACjB,mEAAmE;YACnE,4DAA4D;YAC5D,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI;YAC1B,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBACnC,EAAE,EAAE,EAAE,CAAC,EAAE;gBACT,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE;oBACR,IAAI,EAAE,EAAE,CAAC,IAAI;oBACb,SAAS,EAAE,EAAE,CAAC,YAAY,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC;iBAC3D;aACF,CAAC,CAAC;SACJ,CAAA;QACD,IAAI,CAAC,CAAC,gBAAgB;YAAE,GAAG,CAAC,iBAAiB,GAAG,CAAC,CAAC,gBAAgB,CAAA;QAClE,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACjD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC,gBAAgB,EAAE,CAAA;IACjG,CAAC;IACD,oEAAoE;IACpE,iEAAiE;IACjE,gEAAgE;IAChE,6CAA6C;IAC7C,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACtE,MAAM,MAAM,GAAmC,EAAE,CAAA;QACjD,IAAI,CAAC,CAAC,OAAO;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QAC7D,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YACpD,IAAI,OAAO;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QAC9E,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;IACjE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAA;AAC7C,CAAC;AAED;;;4DAG4D;AAC5D,SAAS,cAAc,CAAC,IAAY,EAAE,QAAiB;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QAC7B,IAAI,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;YAAE,OAAO,IAAI,CAAA;QAC7C,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;QAChC,MAAM,IAAI,GAAG,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,CAAA;QACxC,OAAO,QAAQ,IAAI,WAAW,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IAChC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,YAAY,CAAA;IAC1E,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,WAAW,CAAA;IAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,YAAY,CAAA;IAChD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,WAAW,CAAA;IAC9C,OAAO,0BAA0B,CAAA;AACnC,CAAC;AAED,SAAS,gBAAgB,CAAC,CAAU;IAClC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB;KACF,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,MAA8B;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAC7B,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,MAAM,CAAA;IAClF,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAA;IAC9D,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAmC;IAC3D,MAAM,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,CAAA;IACrD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAC1D,MAAM,GAAG,GAAsB,EAAE,CAAA;IACjC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAChD,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;QACzE,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,QAAQ,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAA;QACtF,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI;YAAE,SAAQ;QAC1B,IAAI,MAAM,GAA4B,EAAE,CAAA;QACxC,IAAI,YAAgC,CAAA;QACpC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAA;gBAC1C,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC1D,MAAM,GAAG,GAA8B,CAAA;gBACzC,CAAC;qBAAM,CAAC;oBACN,YAAY,GAAG,OAAO,CAAA;gBACxB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,8DAA8D;gBAC9D,uDAAuD;gBACvD,YAAY,GAAG,OAAO,CAAA;YACxB,CAAC;QACH,CAAC;QACD,MAAM,GAAG,GAAoB,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAA;QAC5D,IAAI,YAAY,KAAK,SAAS;YAAE,GAAG,CAAC,YAAY,GAAG,YAAY,CAAA;QAC/D,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACf,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ApprovalGate } from './agent-loop.js';
|
|
2
|
+
/**
|
|
3
|
+
* Approval mode. Defaults to 'allow-list' which is the safest sane
|
|
4
|
+
* default — operators must explicitly enumerate tools the agent may
|
|
5
|
+
* call without an external approver.
|
|
6
|
+
*/
|
|
7
|
+
export type ApprovalMode = 'allow-all' | 'read-only' | 'allow-list' | 'deny-all';
|
|
8
|
+
export interface PolicyApprovalGateConfig {
|
|
9
|
+
/** Selection rule. Default 'allow-list'. */
|
|
10
|
+
mode?: ApprovalMode;
|
|
11
|
+
/** Tools that are always allowed regardless of mode (except 'deny-all'
|
|
12
|
+
* where nothing passes). Names can be either built-in tool names
|
|
13
|
+
* (`native_echo`) or MCP namespaced names (`mcp_filesystem_read_file`). */
|
|
14
|
+
autoAllow?: string[];
|
|
15
|
+
/** Tools that are always denied regardless of mode (even in
|
|
16
|
+
* 'allow-all'). Use this as the operator's emergency brake. */
|
|
17
|
+
denyList?: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build an ApprovalGate based on the supplied policy. The returned gate
|
|
21
|
+
* is synchronous-fast (no IO) and always resolves — it never throws.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildPolicyApprovalGate(cfg?: PolicyApprovalGateConfig): ApprovalGate;
|
|
24
|
+
/**
|
|
25
|
+
* Describe a policy decision for logs / future IM "approval requested"
|
|
26
|
+
* preview cards. Returned as a one-liner; the gate itself doesn't log
|
|
27
|
+
* (logging belongs to the agent loop's `toolCalls` report).
|
|
28
|
+
*/
|
|
29
|
+
export declare function describePolicy(cfg: PolicyApprovalGateConfig): string;
|
|
30
|
+
//# sourceMappingURL=policy-approval-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-approval-gate.d.ts","sourceRoot":"","sources":["../../../src/core/llm/policy-approval-gate.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEnD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,CAAA;AAEhF,MAAM,WAAW,wBAAwB;IACvC,4CAA4C;IAC5C,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB;;gFAE4E;IAC5E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;oEACgE;IAChE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AA2BD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,wBAA6B,GAAG,YAAY,CAqBxF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,wBAAwB,GAAG,MAAM,CAKpE"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// policy-approval-gate — declarative approval gate for the native
|
|
2
|
+
// agent loop (Stage 2 sub-PR #4).
|
|
3
|
+
//
|
|
4
|
+
// Stage 2 sub-PR #4 ships a *policy-driven* gate rather than a full
|
|
5
|
+
// IM-interactive approval card. Why:
|
|
6
|
+
//
|
|
7
|
+
// - The existing approval-router pipeline is wired tightly to the
|
|
8
|
+
// MCP sidecar's Unix-socket bus protocol (one runId per CLI agent
|
|
9
|
+
// subprocess, decisions echoed back through that socket). Reusing
|
|
10
|
+
// it for native calls would require a substantial refactor of
|
|
11
|
+
// approval-bus to support arbitrary in-process awaiters.
|
|
12
|
+
// - For the native agent's initial cut, three operating modes cover
|
|
13
|
+
// the realistic ops surface:
|
|
14
|
+
// 1. 'allow-all' — fully autonomous (CI / monitoring runs).
|
|
15
|
+
// 2. 'read-only' — allow tools whose name suggests pure read
|
|
16
|
+
// (heuristic + explicit allow list).
|
|
17
|
+
// 3. 'allow-list' — explicit `autoAllow: string[]` from config;
|
|
18
|
+
// anything else is denied.
|
|
19
|
+
// This is enough to let operators run native safely while we design
|
|
20
|
+
// the cross-platform IM approval gate as a follow-up.
|
|
21
|
+
// - The agent loop ALWAYS calls `approve(call)`; passing our gate
|
|
22
|
+
// here doesn't preclude swapping for a richer gate later. Tests
|
|
23
|
+
// verify the contract.
|
|
24
|
+
/**
|
|
25
|
+
* Heuristic for the 'read-only' mode: tool names that historically
|
|
26
|
+
* mean "look but don't touch". Conservative on purpose — anything not
|
|
27
|
+
* on this list is treated as write-y and requires explicit allow-list
|
|
28
|
+
* approval. The list is shared by every backend (MCP tool naming
|
|
29
|
+
* conventions are loose enough that this works as a starting filter,
|
|
30
|
+
* and the explicit autoAllow always overrides it).
|
|
31
|
+
*/
|
|
32
|
+
const READ_ONLY_HINTS = [
|
|
33
|
+
'read', 'list', 'get', 'search', 'find', 'fetch', 'show', 'view',
|
|
34
|
+
'inspect', 'describe', 'status', 'echo', 'now', 'random_uuid',
|
|
35
|
+
];
|
|
36
|
+
function looksReadOnly(toolName) {
|
|
37
|
+
// Strip the mcp_{server}_ prefix so the verb appears at the start.
|
|
38
|
+
const stripped = toolName.replace(/^mcp_[A-Za-z0-9_]+?_/, '').toLowerCase();
|
|
39
|
+
for (const hint of READ_ONLY_HINTS) {
|
|
40
|
+
if (stripped.startsWith(hint) || stripped.endsWith(`_${hint}`) ||
|
|
41
|
+
stripped.includes(`_${hint}_`)) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build an ApprovalGate based on the supplied policy. The returned gate
|
|
49
|
+
* is synchronous-fast (no IO) and always resolves — it never throws.
|
|
50
|
+
*/
|
|
51
|
+
export function buildPolicyApprovalGate(cfg = {}) {
|
|
52
|
+
const mode = cfg.mode ?? 'allow-list';
|
|
53
|
+
const autoAllow = new Set(cfg.autoAllow ?? []);
|
|
54
|
+
const denyList = new Set(cfg.denyList ?? []);
|
|
55
|
+
return async (call) => {
|
|
56
|
+
if (denyList.has(call.name))
|
|
57
|
+
return 'deny';
|
|
58
|
+
if (autoAllow.has(call.name))
|
|
59
|
+
return 'allow';
|
|
60
|
+
switch (mode) {
|
|
61
|
+
case 'allow-all':
|
|
62
|
+
return 'allow';
|
|
63
|
+
case 'deny-all':
|
|
64
|
+
return 'deny';
|
|
65
|
+
case 'read-only':
|
|
66
|
+
return looksReadOnly(call.name) ? 'allow' : 'deny';
|
|
67
|
+
case 'allow-list':
|
|
68
|
+
// Outside the allow-list → deny. This is the default mode.
|
|
69
|
+
return 'deny';
|
|
70
|
+
default:
|
|
71
|
+
return 'deny';
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Describe a policy decision for logs / future IM "approval requested"
|
|
77
|
+
* preview cards. Returned as a one-liner; the gate itself doesn't log
|
|
78
|
+
* (logging belongs to the agent loop's `toolCalls` report).
|
|
79
|
+
*/
|
|
80
|
+
export function describePolicy(cfg) {
|
|
81
|
+
const mode = cfg.mode ?? 'allow-list';
|
|
82
|
+
const allowCount = cfg.autoAllow?.length ?? 0;
|
|
83
|
+
const denyCount = cfg.denyList?.length ?? 0;
|
|
84
|
+
return `mode=${mode}, autoAllow=${allowCount}, denyList=${denyCount}`;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=policy-approval-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-approval-gate.js","sourceRoot":"","sources":["../../../src/core/llm/policy-approval-gate.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,kCAAkC;AAClC,EAAE;AACF,oEAAoE;AACpE,qCAAqC;AACrC,EAAE;AACF,oEAAoE;AACpE,sEAAsE;AACtE,sEAAsE;AACtE,kEAAkE;AAClE,6DAA6D;AAC7D,sEAAsE;AACtE,iCAAiC;AACjC,sEAAsE;AACtE,uEAAuE;AACvE,gEAAgE;AAChE,yEAAyE;AACzE,sDAAsD;AACtD,wEAAwE;AACxE,0DAA0D;AAC1D,oEAAoE;AACpE,oEAAoE;AACpE,2BAA2B;AAwB3B;;;;;;;GAOG;AACH,MAAM,eAAe,GAAG;IACtB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM;IAChE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa;CAC9D,CAAA;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,mEAAmE;IACnE,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;IAC3E,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACnC,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;YAC1D,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAgC,EAAE;IACxE,MAAM,IAAI,GAAiB,GAAG,CAAC,IAAI,IAAI,YAAY,CAAA;IACnD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAA;IAC5C,OAAO,KAAK,EAAE,IAAqB,EAA6B,EAAE;QAChE,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,MAAM,CAAA;QAC1C,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAA;QAC5C,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,WAAW;gBACd,OAAO,OAAO,CAAA;YAChB,KAAK,UAAU;gBACb,OAAO,MAAM,CAAA;YACf,KAAK,WAAW;gBACd,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAA;YACpD,KAAK,YAAY;gBACf,2DAA2D;gBAC3D,OAAO,MAAM,CAAA;YACf;gBACE,OAAO,MAAM,CAAA;QACjB,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAA6B;IAC1D,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,YAAY,CAAA;IACrC,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,CAAA;IAC7C,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAA;IAC3C,OAAO,QAAQ,IAAI,eAAe,UAAU,cAAc,SAAS,EAAE,CAAA;AACvE,CAAC"}
|