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,332 @@
|
|
|
1
|
+
// heartbeat — periodic proactive wake-up loop (P0 #1).
|
|
2
|
+
//
|
|
3
|
+
// For each enabled binding (one per IM thread; see heartbeat-store), the
|
|
4
|
+
// scheduler runs a three-phase tick:
|
|
5
|
+
//
|
|
6
|
+
// 1. DECIDE — ask the cheap LLM (role 'cheap', via tryIntrospect)
|
|
7
|
+
// whether the binding body has any action to do *right
|
|
8
|
+
// now*. Returns {run, summary} JSON; on parse/LLM
|
|
9
|
+
// failure we fail OPEN (always execute) so the loop
|
|
10
|
+
// doesn't silently go dark just because the LLM is
|
|
11
|
+
// misconfigured.
|
|
12
|
+
//
|
|
13
|
+
// 2. EXECUTE — when DECIDE said run, hand the body + the LLM's
|
|
14
|
+
// rephrased summary to the user's IM CLI agent
|
|
15
|
+
// (Claude Code / Codex / OpenCode) via the existing
|
|
16
|
+
// agent-helper layer. The agent does the actual work
|
|
17
|
+
// (look up a price, summarise an inbox, …) and returns
|
|
18
|
+
// free-form text.
|
|
19
|
+
//
|
|
20
|
+
// 3. EVALUATE — push the agent's text through the
|
|
21
|
+
// notification-evaluator gate (source='heartbeat',
|
|
22
|
+
// default-gated). Routine / empty output gets
|
|
23
|
+
// silently dropped + audit-logged; actionable info
|
|
24
|
+
// reaches the user via the sink.
|
|
25
|
+
//
|
|
26
|
+
// Each tick's outcome is stamped onto the binding row so /heartbeat
|
|
27
|
+
// show can render "last status: delivered 5 min ago" or "last status:
|
|
28
|
+
// skipped — nothing to do". Failures never throw out of tickOnce(); a
|
|
29
|
+
// stuck agent or LLM problem must not crash the daemon.
|
|
30
|
+
import { logger as rootLogger } from './logger.js';
|
|
31
|
+
import { sink } from './message-sink.js';
|
|
32
|
+
import { callHelperAgent } from './agent-helper.js';
|
|
33
|
+
import { tryIntrospect } from './llm/index.js';
|
|
34
|
+
import { evaluateNotification } from './notification-evaluator.js';
|
|
35
|
+
import { listDueBindings, recordTick, } from './heartbeat-store.js';
|
|
36
|
+
const log = rootLogger.child({ component: 'heartbeat' });
|
|
37
|
+
/** Default 60s — short enough that a 5-min binding fires within ~1
|
|
38
|
+
* scheduler tick of due; long enough that the SQLite scan + Promise
|
|
39
|
+
* fan-out doesn't show up on /api/metrics CPU. */
|
|
40
|
+
const DEFAULT_TICK_INTERVAL_MS = 60_000;
|
|
41
|
+
/** When `IMHUB_HEARTBEAT_ENABLED` is unset we still **load** the store
|
|
42
|
+
* (so /heartbeat bind / show works for setup) but DON'T start the
|
|
43
|
+
* scheduler. That matches the project's "opt-in everywhere" policy
|
|
44
|
+
* for things that spend LLM budget on the user's behalf. */
|
|
45
|
+
function isSchedulerEnabled() {
|
|
46
|
+
const raw = (process.env.IMHUB_HEARTBEAT_ENABLED || '').toLowerCase();
|
|
47
|
+
return raw === 'on' || raw === '1' || raw === 'true';
|
|
48
|
+
}
|
|
49
|
+
function tickIntervalMs() {
|
|
50
|
+
const raw = process.env.IMHUB_HEARTBEAT_TICK_INTERVAL_MS;
|
|
51
|
+
if (raw) {
|
|
52
|
+
const n = parseInt(raw, 10);
|
|
53
|
+
if (Number.isFinite(n) && n >= 5_000 && n <= 600_000)
|
|
54
|
+
return n;
|
|
55
|
+
}
|
|
56
|
+
return DEFAULT_TICK_INTERVAL_MS;
|
|
57
|
+
}
|
|
58
|
+
function buildDecidePrompt(body) {
|
|
59
|
+
return [
|
|
60
|
+
'你是一个 heartbeat 调度器。下面是用户登记的"想让我定期帮他盯着"的事项清单。',
|
|
61
|
+
'现在请判断**此刻**有没有需要执行的事项;如果有,把它简短改写成一段后台 agent 能直接照做的任务描述。',
|
|
62
|
+
'',
|
|
63
|
+
'严格输出 JSON,**无 markdown 围栏 / 解释 / 多余字段**:',
|
|
64
|
+
'',
|
|
65
|
+
'{"run": true|false, "summary": "<≤200字中英文混合的任务描述;run=false 时填空字符串>"}',
|
|
66
|
+
'',
|
|
67
|
+
'判断规则:',
|
|
68
|
+
'- 时间敏感的事项(每天 8 点 / 收盘前 / 周一上午)只在窗口内 run=true',
|
|
69
|
+
'- 持续型监控("盯着 600519 涨停")→ 每次 tick 都 run=true',
|
|
70
|
+
'- 完全不到时间 / 已经过期 / 无内容 → run=false,summary=""',
|
|
71
|
+
'- 拿不准时倾向 run=true(防漏)',
|
|
72
|
+
'',
|
|
73
|
+
'事项清单:',
|
|
74
|
+
'"""',
|
|
75
|
+
body,
|
|
76
|
+
'"""',
|
|
77
|
+
'',
|
|
78
|
+
'现在输出 JSON:',
|
|
79
|
+
].join('\n');
|
|
80
|
+
}
|
|
81
|
+
function parseDecide(raw) {
|
|
82
|
+
let s = raw.trim();
|
|
83
|
+
const fence = s.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
84
|
+
if (fence)
|
|
85
|
+
s = fence[1].trim();
|
|
86
|
+
const start = s.indexOf('{');
|
|
87
|
+
const end = s.lastIndexOf('}');
|
|
88
|
+
if (start < 0 || end < 0 || end <= start)
|
|
89
|
+
return null;
|
|
90
|
+
s = s.slice(start, end + 1);
|
|
91
|
+
let obj;
|
|
92
|
+
try {
|
|
93
|
+
obj = JSON.parse(s);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
if (!obj || typeof obj !== 'object')
|
|
99
|
+
return null;
|
|
100
|
+
const o = obj;
|
|
101
|
+
if (typeof o.run !== 'boolean')
|
|
102
|
+
return null;
|
|
103
|
+
const summary = typeof o.summary === 'string' ? o.summary : '';
|
|
104
|
+
return { run: o.run, summary: summary.slice(0, 400) };
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The decide phase. Returns either a verdict from the LLM or a synthetic
|
|
108
|
+
* fail-open verdict that runs the binding (because skipping silently
|
|
109
|
+
* would erode trust in heartbeats more than running unnecessarily).
|
|
110
|
+
*/
|
|
111
|
+
async function decideRun(row) {
|
|
112
|
+
const result = await tryIntrospect({
|
|
113
|
+
role: 'cheap',
|
|
114
|
+
prompt: buildDecidePrompt(row.body),
|
|
115
|
+
timeoutMs: 10_000,
|
|
116
|
+
temperature: 0,
|
|
117
|
+
});
|
|
118
|
+
if (!result) {
|
|
119
|
+
return {
|
|
120
|
+
verdict: { run: true, summary: row.body.slice(0, 400) },
|
|
121
|
+
via: 'fail-open-no-backend',
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const parsed = parseDecide(result.text);
|
|
125
|
+
if (!parsed) {
|
|
126
|
+
log.warn({
|
|
127
|
+
event: 'heartbeat.decide.unparseable',
|
|
128
|
+
id: row.id, backend: result.backendName,
|
|
129
|
+
preview: result.text.slice(0, 200),
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
verdict: { run: true, summary: row.body.slice(0, 400) },
|
|
133
|
+
via: 'fail-open-parse-error',
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return { verdict: parsed, via: 'llm' };
|
|
137
|
+
}
|
|
138
|
+
// ---------------------------------------------------------------------
|
|
139
|
+
// Execute phase
|
|
140
|
+
// ---------------------------------------------------------------------
|
|
141
|
+
function buildExecutePrompt(row, decideSummary) {
|
|
142
|
+
return [
|
|
143
|
+
'You are running a periodic heartbeat task for the user. Be terse, factual, and OUTPUT ONLY the user-facing result text (no preamble, no "OK, here\'s what I found", no markdown fences around the whole answer).',
|
|
144
|
+
'',
|
|
145
|
+
'If after investigation there is genuinely no new information to share, reply EXACTLY:',
|
|
146
|
+
' NO_UPDATE',
|
|
147
|
+
'(the supervisor will silently drop NO_UPDATE before notifying the user.)',
|
|
148
|
+
'',
|
|
149
|
+
'Otherwise reply with the actionable update only, ≤ 800 chars.',
|
|
150
|
+
'',
|
|
151
|
+
`## Heartbeat charter (last set by the user)\n${row.body}`,
|
|
152
|
+
'',
|
|
153
|
+
`## Concrete task for THIS tick\n${decideSummary || row.body.slice(0, 400)}`,
|
|
154
|
+
].join('\n');
|
|
155
|
+
}
|
|
156
|
+
const NO_UPDATE_SENTINELS = new Set([
|
|
157
|
+
'no_update',
|
|
158
|
+
'NO_UPDATE',
|
|
159
|
+
'no update',
|
|
160
|
+
'NO UPDATE',
|
|
161
|
+
]);
|
|
162
|
+
/**
|
|
163
|
+
* Run the user's CLI agent on the decided task. Returns null when no
|
|
164
|
+
* agent could be picked or the helper call failed; runForBinding will
|
|
165
|
+
* record this as 'no-agent' or 'failed' accordingly.
|
|
166
|
+
*/
|
|
167
|
+
async function executeTask(row, decideSummary) {
|
|
168
|
+
const composed = buildExecutePrompt(row, decideSummary);
|
|
169
|
+
const out = await callHelperAgent({
|
|
170
|
+
platform: row.platform,
|
|
171
|
+
channelId: row.channelId,
|
|
172
|
+
threadId: row.threadId,
|
|
173
|
+
systemPrompt: 'You execute heartbeat tasks. Output only the result body.',
|
|
174
|
+
userPrompt: composed,
|
|
175
|
+
timeoutMs: 60_000,
|
|
176
|
+
maxOutputChars: 2_000,
|
|
177
|
+
});
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Single binding tick. ALL exceptions caught + logged + stamped onto
|
|
182
|
+
* the row; never throws. Returns the result so the slash command's
|
|
183
|
+
* `/heartbeat run-now` can show it back to the user synchronously.
|
|
184
|
+
*/
|
|
185
|
+
export async function runForBinding(row) {
|
|
186
|
+
if (!row.enabled) {
|
|
187
|
+
return { status: 'skipped', reason: 'binding disabled' };
|
|
188
|
+
}
|
|
189
|
+
// ── DECIDE ────────────────────────────────────────────────────────
|
|
190
|
+
const decide = await decideRun(row);
|
|
191
|
+
if (!decide.verdict.run) {
|
|
192
|
+
const reason = `decide=skip (via ${decide.via})`;
|
|
193
|
+
recordTick({ id: row.id, status: 'skipped', reason });
|
|
194
|
+
log.info({ event: 'heartbeat.skipped', id: row.id, via: decide.via });
|
|
195
|
+
return { status: 'skipped', reason };
|
|
196
|
+
}
|
|
197
|
+
// ── EXECUTE ───────────────────────────────────────────────────────
|
|
198
|
+
let agentOut = null;
|
|
199
|
+
try {
|
|
200
|
+
agentOut = await executeTask(row, decide.verdict.summary);
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
204
|
+
log.warn({ event: 'heartbeat.execute_failed', id: row.id, err: msg });
|
|
205
|
+
recordTick({ id: row.id, status: 'failed', reason: `execute: ${msg}` });
|
|
206
|
+
return { status: 'failed', reason: msg };
|
|
207
|
+
}
|
|
208
|
+
if (agentOut === null) {
|
|
209
|
+
const reason = 'no agent available or helper returned null';
|
|
210
|
+
recordTick({ id: row.id, status: 'no-agent', reason });
|
|
211
|
+
log.info({ event: 'heartbeat.no_agent', id: row.id });
|
|
212
|
+
return { status: 'no-agent', reason };
|
|
213
|
+
}
|
|
214
|
+
const trimmedOut = agentOut.trim();
|
|
215
|
+
if (trimmedOut === '' || NO_UPDATE_SENTINELS.has(trimmedOut)) {
|
|
216
|
+
const reason = 'agent returned NO_UPDATE / empty';
|
|
217
|
+
recordTick({ id: row.id, status: 'skipped', reason });
|
|
218
|
+
log.info({ event: 'heartbeat.no_update', id: row.id });
|
|
219
|
+
return { status: 'skipped', reason, rawAgentOutput: trimmedOut };
|
|
220
|
+
}
|
|
221
|
+
// ── EVALUATE ──────────────────────────────────────────────────────
|
|
222
|
+
const verdict = await evaluateNotification({
|
|
223
|
+
source: 'heartbeat',
|
|
224
|
+
text: trimmedOut,
|
|
225
|
+
targetThread: `${row.platform}:${row.channelId}:${row.threadId}`,
|
|
226
|
+
caller: { platform: row.platform, userId: row.userId, agent: 'heartbeat' },
|
|
227
|
+
});
|
|
228
|
+
if (!verdict.shouldDeliver) {
|
|
229
|
+
const reason = `evaluator suppressed: ${verdict.reason} (via ${verdict.via})`;
|
|
230
|
+
recordTick({ id: row.id, status: 'suppressed', reason });
|
|
231
|
+
return {
|
|
232
|
+
status: 'suppressed',
|
|
233
|
+
reason,
|
|
234
|
+
rawAgentOutput: trimmedOut,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
// ── DELIVER ───────────────────────────────────────────────────────
|
|
238
|
+
try {
|
|
239
|
+
await sink.deliver({
|
|
240
|
+
platform: row.platform,
|
|
241
|
+
channelId: row.channelId,
|
|
242
|
+
threadId: row.threadId,
|
|
243
|
+
payload: trimmedOut,
|
|
244
|
+
kind: 'text',
|
|
245
|
+
priority: 'normal',
|
|
246
|
+
source: 'system',
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
251
|
+
log.warn({ event: 'heartbeat.deliver_failed', id: row.id, err: msg });
|
|
252
|
+
recordTick({ id: row.id, status: 'failed', reason: `deliver: ${msg}` });
|
|
253
|
+
return { status: 'failed', reason: msg };
|
|
254
|
+
}
|
|
255
|
+
const reason = `delivered via ${decide.via}`;
|
|
256
|
+
recordTick({
|
|
257
|
+
id: row.id,
|
|
258
|
+
status: 'delivered',
|
|
259
|
+
reason,
|
|
260
|
+
deliveredText: trimmedOut,
|
|
261
|
+
});
|
|
262
|
+
log.info({
|
|
263
|
+
event: 'heartbeat.delivered',
|
|
264
|
+
id: row.id,
|
|
265
|
+
bytes: trimmedOut.length,
|
|
266
|
+
});
|
|
267
|
+
return { status: 'delivered', reason, deliveredText: trimmedOut, rawAgentOutput: trimmedOut };
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* One scheduler pass. Picks up to 50 due bindings and runs them
|
|
271
|
+
* sequentially; concurrent ticks on the same scheduler are intentional
|
|
272
|
+
* (avoids stampedes on the user's agent, keeps memory bounded). Returns
|
|
273
|
+
* a summary so tests can assert on it.
|
|
274
|
+
*/
|
|
275
|
+
export async function tickOnce() {
|
|
276
|
+
const due = listDueBindings();
|
|
277
|
+
const results = {};
|
|
278
|
+
for (const row of due) {
|
|
279
|
+
let r;
|
|
280
|
+
try {
|
|
281
|
+
r = await runForBinding(row);
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
285
|
+
log.error({ event: 'heartbeat.run_unhandled', id: row.id, err: msg });
|
|
286
|
+
recordTick({ id: row.id, status: 'failed', reason: `unhandled: ${msg}` });
|
|
287
|
+
r = { status: 'failed', reason: msg };
|
|
288
|
+
}
|
|
289
|
+
results[r.status] = (results[r.status] ?? 0) + 1;
|
|
290
|
+
}
|
|
291
|
+
if (due.length > 0) {
|
|
292
|
+
log.info({ event: 'heartbeat.tick.done', scanned: due.length, results });
|
|
293
|
+
}
|
|
294
|
+
return { scanned: due.length, results };
|
|
295
|
+
}
|
|
296
|
+
// ---------------------------------------------------------------------
|
|
297
|
+
// Scheduler lifecycle (called from cli.ts at boot)
|
|
298
|
+
// ---------------------------------------------------------------------
|
|
299
|
+
let timer = null;
|
|
300
|
+
export function startHeartbeatScheduler() {
|
|
301
|
+
if (timer)
|
|
302
|
+
return;
|
|
303
|
+
if (!isSchedulerEnabled()) {
|
|
304
|
+
log.info({ event: 'heartbeat.scheduler.disabled' }, 'IMHUB_HEARTBEAT_ENABLED unset; /heartbeat bind/show still works but no automatic ticks');
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
const period = tickIntervalMs();
|
|
308
|
+
log.info({ event: 'heartbeat.scheduler.start', periodMs: period });
|
|
309
|
+
timer = setInterval(() => {
|
|
310
|
+
void tickOnce().catch((err) => {
|
|
311
|
+
log.warn({ event: 'heartbeat.tick.unhandled', err: String(err) });
|
|
312
|
+
});
|
|
313
|
+
}, period);
|
|
314
|
+
if (typeof timer === 'object' && timer && 'unref' in timer) {
|
|
315
|
+
timer.unref();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
export function stopHeartbeatScheduler() {
|
|
319
|
+
if (timer) {
|
|
320
|
+
clearInterval(timer);
|
|
321
|
+
timer = null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/** Reflect current scheduler state for /heartbeat status output. */
|
|
325
|
+
export function schedulerInfo() {
|
|
326
|
+
return {
|
|
327
|
+
enabled: isSchedulerEnabled(),
|
|
328
|
+
running: timer !== null,
|
|
329
|
+
periodMs: tickIntervalMs(),
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/core/heartbeat.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,15 @@ export declare function configureLLMJudge(cfg: LLMJudgeConfig | null): void;
|
|
|
11
11
|
/** Read the judge configuration. Used by classifyIntent to know whether
|
|
12
12
|
* to attempt a fallback at all. */
|
|
13
13
|
export declare function getLLMJudge(): LLMJudgeConfig | null;
|
|
14
|
+
/**
|
|
15
|
+
* True when intent fallback can run — either via the legacy CLI judge
|
|
16
|
+
* (`IM_HUB_LLM_JUDGE_AGENT` env / configureLLMJudge) OR via a native
|
|
17
|
+
* 'cheap' LLM backend from D+ Stage 1. Router uses this to gate the
|
|
18
|
+
* fallback path; previously it could only gate on `getLLMJudge()`,
|
|
19
|
+
* which forced operators to set IM_HUB_LLM_JUDGE_AGENT even when they
|
|
20
|
+
* only had a native backend wired.
|
|
21
|
+
*/
|
|
22
|
+
export declare function hasIntentFallback(): boolean;
|
|
14
23
|
/**
|
|
15
24
|
* Ask the judge agent which candidate to use. Returns null on any
|
|
16
25
|
* failure path (timeout, judge unavailable, malformed response) so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-llm.d.ts","sourceRoot":"","sources":["../../src/core/intent-llm.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"intent-llm.d.ts","sourceRoot":"","sources":["../../src/core/intent-llm.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAuD9C,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAA;IACjB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAID,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAGlE;AAED;oCACoC;AACpC,wBAAgB,WAAW,IAAI,cAAc,GAAG,IAAI,CAEnD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAgDD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAAE,EACpB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,YAAY,GAAG,SAAS,GACvD,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAqFnD;AAED,wEAAwE;AACxE,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,IAAI,MAAM,CAAsB"}
|
package/dist/core/intent-llm.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// 10-minute window so repeated chat-room banter doesn't burn budget.
|
|
11
11
|
import { createHash } from 'node:crypto';
|
|
12
12
|
import { logger as rootLogger } from './logger.js';
|
|
13
|
+
import { getProvider, tryIntrospect } from './llm/index.js';
|
|
13
14
|
const log = rootLogger.child({ component: 'intent-llm' });
|
|
14
15
|
const CACHE_TTL_MS = 10 * 60 * 1000;
|
|
15
16
|
const CACHE_MAX_ENTRIES = 1000; // LRU upper bound prevents unbounded growth
|
|
@@ -66,6 +67,19 @@ export function configureLLMJudge(cfg) {
|
|
|
66
67
|
export function getLLMJudge() {
|
|
67
68
|
return config;
|
|
68
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* True when intent fallback can run — either via the legacy CLI judge
|
|
72
|
+
* (`IM_HUB_LLM_JUDGE_AGENT` env / configureLLMJudge) OR via a native
|
|
73
|
+
* 'cheap' LLM backend from D+ Stage 1. Router uses this to gate the
|
|
74
|
+
* fallback path; previously it could only gate on `getLLMJudge()`,
|
|
75
|
+
* which forced operators to set IM_HUB_LLM_JUDGE_AGENT even when they
|
|
76
|
+
* only had a native backend wired.
|
|
77
|
+
*/
|
|
78
|
+
export function hasIntentFallback() {
|
|
79
|
+
if (config !== null)
|
|
80
|
+
return true;
|
|
81
|
+
return getProvider('cheap') !== null;
|
|
82
|
+
}
|
|
69
83
|
/** Probe env on first import so common deployments get auto-config. */
|
|
70
84
|
function autoFromEnv() {
|
|
71
85
|
const name = process.env.IM_HUB_LLM_JUDGE_AGENT;
|
|
@@ -114,7 +128,11 @@ function buildPrompt(text, candidates) {
|
|
|
114
128
|
* the caller can keep its rule-based decision.
|
|
115
129
|
*/
|
|
116
130
|
export async function classifyWithLLM(text, candidates, resolveAgent) {
|
|
117
|
-
|
|
131
|
+
// Enter as long as some fallback (legacy CLI judge OR native backend)
|
|
132
|
+
// is available. Pre-D+ behaviour required `config != null`; we now
|
|
133
|
+
// also accept a native-only setup.
|
|
134
|
+
const nativeProvider = getProvider('cheap');
|
|
135
|
+
if (!config && !nativeProvider)
|
|
118
136
|
return null;
|
|
119
137
|
if (candidates.length === 0)
|
|
120
138
|
return null;
|
|
@@ -123,43 +141,70 @@ export async function classifyWithLLM(text, candidates, resolveAgent) {
|
|
|
123
141
|
if (cached) {
|
|
124
142
|
return { agent: cached.agent, reason: `${cached.reason} (cached)` };
|
|
125
143
|
}
|
|
126
|
-
const
|
|
127
|
-
if (!judge) {
|
|
128
|
-
log.warn({ judge: config.agentName }, 'LLM judge agent not registered');
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
const timeoutMs = config.timeoutMs ?? RESPONSE_TIMEOUT_MS;
|
|
144
|
+
const timeoutMs = config?.timeoutMs ?? RESPONSE_TIMEOUT_MS;
|
|
132
145
|
const prompt = buildPrompt(text, candidates);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (!
|
|
152
|
-
log.warn({
|
|
146
|
+
let raw = '';
|
|
147
|
+
let viaNative = false;
|
|
148
|
+
// D+ Stage 1: prefer the 'cheap' native LLM backend. Fast (~200ms),
|
|
149
|
+
// dollar-cheap, no CLI spawn. Falls through to the configured CLI
|
|
150
|
+
// judge on no-backend OR failure so historical behaviour is intact.
|
|
151
|
+
if (nativeProvider) {
|
|
152
|
+
const nativeResult = await tryIntrospect({
|
|
153
|
+
role: 'cheap',
|
|
154
|
+
prompt,
|
|
155
|
+
timeoutMs,
|
|
156
|
+
temperature: 0,
|
|
157
|
+
});
|
|
158
|
+
if (nativeResult && nativeResult.text.trim().length > 0) {
|
|
159
|
+
raw = nativeResult.text;
|
|
160
|
+
viaNative = true;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (!viaNative) {
|
|
164
|
+
if (!config) {
|
|
165
|
+
log.warn({ event: 'intent-llm.native_failed_no_cli_fallback' }, 'native LLM judge failed and no CLI judge configured — skipping fallback');
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const judge = resolveAgent(config.agentName);
|
|
169
|
+
if (!judge) {
|
|
170
|
+
log.warn({ judge: config.agentName }, 'LLM judge agent not registered');
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
let acc = '';
|
|
175
|
+
const generator = judge.sendPrompt(`llm-judge`, prompt, []);
|
|
176
|
+
const collect = (async () => {
|
|
177
|
+
for await (const chunk of generator) {
|
|
178
|
+
acc += chunk;
|
|
179
|
+
if (acc.length > 4096)
|
|
180
|
+
break; // guard runaway output
|
|
181
|
+
}
|
|
182
|
+
})();
|
|
183
|
+
const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error('LLM judge timed out')), timeoutMs));
|
|
184
|
+
await Promise.race([collect, timeout]);
|
|
185
|
+
raw = acc;
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, 'LLM judge call failed');
|
|
153
189
|
return null;
|
|
154
190
|
}
|
|
155
|
-
const decision = { agent: match, reason: `LLM judge picked ${match}` };
|
|
156
|
-
cache.set(key, { ...decision, ts: Date.now() });
|
|
157
|
-
return decision;
|
|
158
191
|
}
|
|
159
|
-
|
|
160
|
-
|
|
192
|
+
// Parse: take the first line, lowercase, strip punctuation, match
|
|
193
|
+
// against candidates case-insensitively.
|
|
194
|
+
const firstLine = raw.split('\n').map((s) => s.trim()).filter(Boolean)[0] || '';
|
|
195
|
+
const cleaned = firstLine.toLowerCase().replace(/[^a-z0-9_-]/g, '');
|
|
196
|
+
const match = candidates.find((c) => c.toLowerCase() === cleaned)
|
|
197
|
+
?? candidates.find((c) => cleaned.includes(c.toLowerCase()));
|
|
198
|
+
if (!match) {
|
|
199
|
+
log.warn({ raw: firstLine, candidates, viaNative }, 'LLM judge produced unrecognized output');
|
|
161
200
|
return null;
|
|
162
201
|
}
|
|
202
|
+
const decision = {
|
|
203
|
+
agent: match,
|
|
204
|
+
reason: viaNative ? `LLM judge (native) picked ${match}` : `LLM judge picked ${match}`,
|
|
205
|
+
};
|
|
206
|
+
cache.set(key, { ...decision, ts: Date.now() });
|
|
207
|
+
return decision;
|
|
163
208
|
}
|
|
164
209
|
/** Test-only: clear cache so memoization doesn't leak between cases. */
|
|
165
210
|
export function _clearLLMCache() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-llm.js","sourceRoot":"","sources":["../../src/core/intent-llm.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,qEAAqE;AACrE,uEAAuE;AACvE,oEAAoE;AACpE,iEAAiE;AACjE,qBAAqB;AACrB,EAAE;AACF,uEAAuE;AACvE,qEAAqE;AAErE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"intent-llm.js","sourceRoot":"","sources":["../../src/core/intent-llm.ts"],"names":[],"mappings":"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"}
|