agim-cli 1.4.9 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +437 -402
- package/README.md +43 -7
- package/README.zh-CN.md +42 -7
- package/bin/agim_rpc.py +12 -12
- package/dist/cli-ui/cmd-handlers.d.ts +25 -4
- package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
- package/dist/cli-ui/cmd-handlers.js +315 -59
- package/dist/cli-ui/cmd-handlers.js.map +1 -1
- package/dist/cli-ui/config-wizard.d.ts +13 -1
- package/dist/cli-ui/config-wizard.d.ts.map +1 -1
- package/dist/cli-ui/config-wizard.js +120 -48
- package/dist/cli-ui/config-wizard.js.map +1 -1
- package/dist/cli-ui/doctor.d.ts +15 -0
- package/dist/cli-ui/doctor.d.ts.map +1 -0
- package/dist/cli-ui/doctor.js +151 -0
- package/dist/cli-ui/doctor.js.map +1 -0
- package/dist/cli-ui/entry-menu.d.ts +6 -0
- package/dist/cli-ui/entry-menu.d.ts.map +1 -1
- package/dist/cli-ui/entry-menu.js +67 -30
- package/dist/cli-ui/entry-menu.js.map +1 -1
- package/dist/cli-ui/env-file.d.ts +4 -4
- package/dist/cli-ui/env-file.js +13 -13
- package/dist/cli-ui/env-file.js.map +1 -1
- package/dist/cli-ui/i18n.d.ts +17 -8
- package/dist/cli-ui/i18n.d.ts.map +1 -1
- package/dist/cli-ui/i18n.js +39 -21
- package/dist/cli-ui/i18n.js.map +1 -1
- package/dist/cli-ui/lang-picker.js +1 -1
- package/dist/cli-ui/lang-picker.js.map +1 -1
- package/dist/cli-ui/paths.d.ts.map +1 -1
- package/dist/cli-ui/paths.js +2 -4
- package/dist/cli-ui/paths.js.map +1 -1
- package/dist/cli-ui/quickstart.d.ts +3 -0
- package/dist/cli-ui/quickstart.d.ts.map +1 -0
- package/dist/cli-ui/quickstart.js +108 -0
- package/dist/cli-ui/quickstart.js.map +1 -0
- package/dist/cli-ui/readiness.d.ts +10 -0
- package/dist/cli-ui/readiness.d.ts.map +1 -0
- package/dist/cli-ui/readiness.js +75 -0
- package/dist/cli-ui/readiness.js.map +1 -0
- package/dist/cli-ui/service.d.ts +30 -7
- package/dist/cli-ui/service.d.ts.map +1 -1
- package/dist/cli-ui/service.js +171 -77
- package/dist/cli-ui/service.js.map +1 -1
- package/dist/cli-ui/tui/app.js +2 -2
- package/dist/cli-ui/tui/app.js.map +1 -1
- package/dist/cli-ui/tui/index.js +6 -6
- package/dist/cli-ui/tui/index.js.map +1 -1
- package/dist/cli-ui/tui/mouse-stdin.js +1 -1
- package/dist/cli-ui/tui/mouse-stdin.js.map +1 -1
- package/dist/cli-ui/tui/stream-reveal.d.ts +2 -2
- package/dist/cli-ui/tui/stream-reveal.d.ts.map +1 -1
- package/dist/cli-ui/tui/stream-reveal.js +4 -4
- package/dist/cli-ui/tui/stream-reveal.js.map +1 -1
- package/dist/cli.js +118 -436
- package/dist/cli.js.map +1 -1
- package/dist/core/a2a-notify.js +5 -5
- package/dist/core/a2a-notify.js.map +1 -1
- package/dist/core/a2a.d.ts +2 -2
- package/dist/core/a2a.d.ts.map +1 -1
- package/dist/core/a2a.js +12 -12
- package/dist/core/a2a.js.map +1 -1
- package/dist/core/access-token.d.ts +1 -1
- package/dist/core/access-token.js +7 -7
- package/dist/core/access-token.js.map +1 -1
- package/dist/core/acp-server.d.ts.map +1 -1
- package/dist/core/acp-server.js +21 -7
- package/dist/core/acp-server.js.map +1 -1
- package/dist/core/admin-allowlist.js +5 -5
- package/dist/core/admin-allowlist.js.map +1 -1
- package/dist/core/agent-base.d.ts +1 -1
- package/dist/core/agent-base.js +3 -3
- package/dist/core/agent-base.js.map +1 -1
- package/dist/core/agent-cwd.d.ts +13 -6
- package/dist/core/agent-cwd.d.ts.map +1 -1
- package/dist/core/agent-cwd.js +72 -23
- package/dist/core/agent-cwd.js.map +1 -1
- package/dist/core/agim-paths.d.ts +1 -4
- package/dist/core/agim-paths.d.ts.map +1 -1
- package/dist/core/agim-paths.js +18 -35
- package/dist/core/agim-paths.js.map +1 -1
- package/dist/core/approval-bus.d.ts +4 -4
- package/dist/core/approval-bus.d.ts.map +1 -1
- package/dist/core/approval-bus.js +14 -14
- package/dist/core/approval-bus.js.map +1 -1
- package/dist/core/approval-router.js +2 -2
- package/dist/core/artifacts.js +3 -3
- package/dist/core/artifacts.js.map +1 -1
- package/dist/core/ask-user-rpc.js +1 -1
- package/dist/core/ask-user-rpc.js.map +1 -1
- package/dist/core/audit-log.js +2 -2
- package/dist/core/audit-log.js.map +1 -1
- package/dist/core/bgjob-reader.d.ts +1 -1
- package/dist/core/bgjob-reader.js +4 -4
- package/dist/core/bgjob-reader.js.map +1 -1
- package/dist/core/commands/approval.js +2 -2
- package/dist/core/commands/approval.js.map +1 -1
- package/dist/core/commands/builtin.d.ts.map +1 -1
- package/dist/core/commands/builtin.js +12 -2
- package/dist/core/commands/builtin.js.map +1 -1
- package/dist/core/commands/heartbeat.js +2 -2
- package/dist/core/commands/heartbeat.js.map +1 -1
- package/dist/core/commands/memo.js +1 -1
- package/dist/core/commands/memo.js.map +1 -1
- package/dist/core/commands/model.d.ts.map +1 -1
- package/dist/core/commands/model.js +32 -3
- package/dist/core/commands/model.js.map +1 -1
- package/dist/core/commands/plan.js +3 -3
- package/dist/core/commands/plan.js.map +1 -1
- package/dist/core/commands/router-compare.js +3 -3
- package/dist/core/commands/router-compare.js.map +1 -1
- package/dist/core/commands/service.d.ts.map +1 -1
- package/dist/core/commands/service.js +1 -3
- package/dist/core/commands/service.js.map +1 -1
- package/dist/core/commands/sessions.js +4 -4
- package/dist/core/commands/sessions.js.map +1 -1
- package/dist/core/commands/skill.js +1 -1
- package/dist/core/commands/skill.js.map +1 -1
- package/dist/core/commands/stats.js +1 -1
- package/dist/core/commands/stats.js.map +1 -1
- package/dist/core/commands/web.js +5 -5
- package/dist/core/commands/web.js.map +1 -1
- package/dist/core/config-schema.js +1 -1
- package/dist/core/coord-systems.d.ts +1 -1
- package/dist/core/coord-systems.js +4 -4
- package/dist/core/coord-systems.js.map +1 -1
- package/dist/core/event-bus.d.ts +5 -5
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +3 -3
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/feature-flags.d.ts +2 -2
- package/dist/core/feature-flags.js +4 -4
- package/dist/core/feature-flags.js.map +1 -1
- package/dist/core/goal-rpc.js +2 -2
- package/dist/core/goal-rpc.js.map +1 -1
- package/dist/core/goals.d.ts +1 -1
- package/dist/core/goals.js +3 -3
- package/dist/core/goals.js.map +1 -1
- package/dist/core/heartbeat-store.d.ts +1 -1
- package/dist/core/heartbeat-store.d.ts.map +1 -1
- package/dist/core/heartbeat-store.js +3 -3
- package/dist/core/heartbeat-store.js.map +1 -1
- package/dist/core/heartbeat.js +4 -4
- package/dist/core/heartbeat.js.map +1 -1
- package/dist/core/intent-llm.d.ts +2 -2
- package/dist/core/intent-llm.js +5 -5
- package/dist/core/intent-llm.js.map +1 -1
- package/dist/core/job-board.d.ts +5 -5
- package/dist/core/job-board.d.ts.map +1 -1
- package/dist/core/job-board.js +17 -17
- package/dist/core/job-board.js.map +1 -1
- package/dist/core/llm/agent-loop.d.ts +3 -3
- package/dist/core/llm/agent-loop.js +14 -14
- package/dist/core/llm/agent-loop.js.map +1 -1
- package/dist/core/llm/{imhub-dispatcher.d.ts → agim-dispatcher.d.ts} +4 -4
- package/dist/core/llm/agim-dispatcher.d.ts.map +1 -0
- package/dist/core/llm/{imhub-dispatcher.js → agim-dispatcher.js} +43 -43
- package/dist/core/llm/agim-dispatcher.js.map +1 -0
- package/dist/core/llm/agim-rpc-server.js +17 -17
- package/dist/core/llm/agim-rpc-server.js.map +1 -1
- package/dist/core/llm/anthropic-provider.js +2 -1
- package/dist/core/llm/anthropic-provider.js.map +1 -1
- package/dist/core/llm/auto-compact.d.ts +3 -3
- package/dist/core/llm/auto-compact.d.ts.map +1 -1
- package/dist/core/llm/auto-compact.js +5 -5
- package/dist/core/llm/auto-compact.js.map +1 -1
- package/dist/core/llm/builtin-dispatcher.js +3 -3
- package/dist/core/llm/builtin-dispatcher.js.map +1 -1
- package/dist/core/llm/exec-dispatcher.d.ts +2 -2
- package/dist/core/llm/exec-dispatcher.d.ts.map +1 -1
- package/dist/core/llm/exec-dispatcher.js +20 -22
- package/dist/core/llm/exec-dispatcher.js.map +1 -1
- package/dist/core/llm/fs-dispatcher.js +8 -8
- package/dist/core/llm/fs-dispatcher.js.map +1 -1
- package/dist/core/llm/goal-critic.js +4 -4
- package/dist/core/llm/goal-critic.js.map +1 -1
- package/dist/core/llm/hallucination-detector.js +2 -2
- package/dist/core/llm/hallucination-detector.js.map +1 -1
- package/dist/core/llm/mcp-client.d.ts +1 -1
- package/dist/core/llm/mcp-client.js +3 -3
- package/dist/core/llm/mcp-client.js.map +1 -1
- package/dist/core/llm/mcp-registry.js +3 -3
- package/dist/core/llm/mcp-registry.js.map +1 -1
- package/dist/core/llm/openai-compat-provider.d.ts +1 -1
- package/dist/core/llm/openai-compat-provider.js +5 -4
- package/dist/core/llm/openai-compat-provider.js.map +1 -1
- package/dist/core/llm/provider-base.d.ts +5 -5
- package/dist/core/llm/provider-base.d.ts.map +1 -1
- package/dist/core/llm/provider-base.js +1 -1
- package/dist/core/llm/provider-base.js.map +1 -1
- package/dist/core/llm/secrets.d.ts +2 -2
- package/dist/core/llm/secrets.d.ts.map +1 -1
- package/dist/core/llm/tool-dispatcher.d.ts +1 -1
- package/dist/core/llm/web-dispatcher.d.ts +1 -1
- package/dist/core/llm/web-dispatcher.js +15 -15
- package/dist/core/llm/web-dispatcher.js.map +1 -1
- package/dist/core/logger.d.ts +1 -1
- package/dist/core/logger.js +3 -3
- package/dist/core/logger.js.map +1 -1
- package/dist/core/memo-rpc.js +3 -3
- package/dist/core/memo-rpc.js.map +1 -1
- package/dist/core/memory-consolidate.js +4 -4
- package/dist/core/memory-consolidate.js.map +1 -1
- package/dist/core/memory-distill.js +4 -4
- package/dist/core/memory-distill.js.map +1 -1
- package/dist/core/memory-distiller.js +9 -9
- package/dist/core/memory-distiller.js.map +1 -1
- package/dist/core/memory-vector.js +9 -9
- package/dist/core/memory-vector.js.map +1 -1
- package/dist/core/memory.js +2 -2
- package/dist/core/memory.js.map +1 -1
- package/dist/core/memos.js +6 -6
- package/dist/core/memos.js.map +1 -1
- package/dist/core/message-sink.js +13 -13
- package/dist/core/message-sink.js.map +1 -1
- package/dist/core/notification-evaluator.d.ts +2 -2
- package/dist/core/notification-evaluator.js +4 -4
- package/dist/core/notification-evaluator.js.map +1 -1
- package/dist/core/onboarding.js +3 -3
- package/dist/core/onboarding.js.map +1 -1
- package/dist/core/outbox.js +2 -2
- package/dist/core/outbox.js.map +1 -1
- package/dist/core/persona.d.ts +1 -1
- package/dist/core/persona.d.ts.map +1 -1
- package/dist/core/persona.js +2 -2
- package/dist/core/persona.js.map +1 -1
- package/dist/core/plan-history.js +1 -1
- package/dist/core/plan-history.js.map +1 -1
- package/dist/core/plan-intent.js +5 -5
- package/dist/core/plan-intent.js.map +1 -1
- package/dist/core/plan-mode-state.d.ts +1 -1
- package/dist/core/plan-mode-state.js +4 -4
- package/dist/core/plan-mode-state.js.map +1 -1
- package/dist/core/push-rpc.d.ts +1 -1
- package/dist/core/push-rpc.js +6 -6
- package/dist/core/push-rpc.js.map +1 -1
- package/dist/core/registry.d.ts +4 -4
- package/dist/core/registry.js +10 -10
- package/dist/core/registry.js.map +1 -1
- package/dist/core/reminders.js +1 -1
- package/dist/core/reminders.js.map +1 -1
- package/dist/core/restart-flow.d.ts.map +1 -1
- package/dist/core/restart-flow.js +5 -7
- package/dist/core/restart-flow.js.map +1 -1
- package/dist/core/router.d.ts +1 -1
- package/dist/core/router.js +5 -5
- package/dist/core/router.js.map +1 -1
- package/dist/core/schedule.d.ts +2 -2
- package/dist/core/schedule.js +4 -4
- package/dist/core/schedule.js.map +1 -1
- package/dist/core/self-protect.js +3 -3
- package/dist/core/self-protect.js.map +1 -1
- package/dist/core/sender-allowlist.js +7 -7
- package/dist/core/sender-allowlist.js.map +1 -1
- package/dist/core/sensitive-paths.d.ts.map +1 -1
- package/dist/core/sensitive-paths.js +1 -2
- package/dist/core/sensitive-paths.js.map +1 -1
- package/dist/core/session.js +2 -2
- package/dist/core/session.js.map +1 -1
- package/dist/core/skills/builtin/ECC_NOTICE.md +1 -1
- package/dist/core/skills/builtin/agim-memory/SKILL.md +1 -1
- package/dist/core/skills/builtin/agim-reminders/SKILL.md +2 -2
- package/dist/core/skills/builtin/agim-self/SKILL.md +9 -9
- package/dist/core/skills/builtin/agim-skill-discovery/SKILL.md +5 -5
- package/dist/core/skills/builtin/image-generation/SKILL.md +2 -2
- package/dist/core/skills/builtin/long-goal/SKILL.md +7 -7
- package/dist/core/skills/builtin/my/SKILL.md +2 -2
- package/dist/core/skills/builtin/skill-creator/SKILL.md +2 -2
- package/dist/core/skills/loader.d.ts +4 -4
- package/dist/core/skills/loader.js +22 -22
- package/dist/core/skills/loader.js.map +1 -1
- package/dist/core/skills-rpc.js +1 -1
- package/dist/core/skills-rpc.js.map +1 -1
- package/dist/core/transcribe.js +13 -13
- package/dist/core/transcribe.js.map +1 -1
- package/dist/core/tunnel.js +1 -1
- package/dist/core/tunnel.js.map +1 -1
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/user-coord-prefs.js +1 -1
- package/dist/core/user-coord-prefs.js.map +1 -1
- package/dist/core/viewer-config.d.ts +8 -8
- package/dist/core/viewer-config.js +17 -17
- package/dist/core/viewer-config.js.map +1 -1
- package/dist/core/viewer-local.js +4 -4
- package/dist/core/viewer-local.js.map +1 -1
- package/dist/core/viewer-remote.js +1 -1
- package/dist/core/viewer-remote.js.map +1 -1
- package/dist/plugins/agents/acp/url-guard.d.ts +1 -1
- package/dist/plugins/agents/acp/url-guard.js +2 -2
- package/dist/plugins/agents/acp/url-guard.js.map +1 -1
- package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts +6 -6
- package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts.map +1 -1
- package/dist/plugins/agents/antigravity/ensure-mcp-config.js +12 -12
- package/dist/plugins/agents/antigravity/ensure-mcp-config.js.map +1 -1
- package/dist/plugins/agents/antigravity/index.js +10 -10
- package/dist/plugins/agents/antigravity/index.js.map +1 -1
- package/dist/plugins/agents/claude-code/index.d.ts +2 -2
- package/dist/plugins/agents/claude-code/index.js +16 -16
- package/dist/plugins/agents/claude-code/index.js.map +1 -1
- package/dist/plugins/agents/claude-code/mcp-approval-server.js +13 -13
- package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
- package/dist/plugins/agents/codex/build-mcp-cli-args.d.ts +4 -4
- package/dist/plugins/agents/codex/build-mcp-cli-args.js +14 -14
- package/dist/plugins/agents/codex/build-mcp-cli-args.js.map +1 -1
- package/dist/plugins/agents/codex/index.d.ts +3 -3
- package/dist/plugins/agents/codex/index.js +14 -14
- package/dist/plugins/agents/codex/index.js.map +1 -1
- package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts +5 -5
- package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts.map +1 -1
- package/dist/plugins/agents/cursor/ensure-mcp-config.js +11 -11
- package/dist/plugins/agents/cursor/ensure-mcp-config.js.map +1 -1
- package/dist/plugins/agents/cursor/index.d.ts +1 -1
- package/dist/plugins/agents/cursor/index.js +12 -12
- package/dist/plugins/agents/cursor/index.js.map +1 -1
- package/dist/plugins/agents/native/index.d.ts +1 -0
- package/dist/plugins/agents/native/index.d.ts.map +1 -1
- package/dist/plugins/agents/native/index.js +28 -14
- package/dist/plugins/agents/native/index.js.map +1 -1
- package/dist/plugins/agents/native/tool-registry.d.ts +3 -3
- package/dist/plugins/agents/native/tool-registry.d.ts.map +1 -1
- package/dist/plugins/agents/native/tool-registry.js +5 -5
- package/dist/plugins/agents/native/tool-registry.js.map +1 -1
- package/dist/plugins/agents/opencode/ensure-mcp-config.d.ts +1 -1
- package/dist/plugins/agents/opencode/ensure-mcp-config.js +9 -9
- package/dist/plugins/agents/opencode/ensure-mcp-config.js.map +1 -1
- package/dist/plugins/agents/opencode/index.js +3 -3
- package/dist/plugins/agents/opencode/index.js.map +1 -1
- package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +4 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -1
- package/dist/plugins/agents/opencode/opencode-http-adapter.js +16 -12
- package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -1
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +2 -2
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -1
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +7 -5
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -1
- package/dist/plugins/agents/opencode/serve-manager.d.ts +1 -1
- package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -1
- package/dist/plugins/agents/opencode/serve-manager.js +10 -10
- package/dist/plugins/agents/opencode/serve-manager.js.map +1 -1
- package/dist/plugins/agents/pi-native/factory.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/factory.js +29 -13
- package/dist/plugins/agents/pi-native/factory.js.map +1 -1
- package/dist/plugins/agents/pi-native/index.d.ts +14 -3
- package/dist/plugins/agents/pi-native/index.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/index.js +58 -4
- package/dist/plugins/agents/pi-native/index.js.map +1 -1
- package/dist/plugins/agents/pi-native/provider-resolver.d.ts +2 -0
- package/dist/plugins/agents/pi-native/provider-resolver.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/provider-resolver.js +9 -1
- package/dist/plugins/agents/pi-native/provider-resolver.js.map +1 -1
- package/dist/plugins/agents/pi-native/tool-bridge.js +1 -1
- package/dist/plugins/agents/pi-native/tool-bridge.js.map +1 -1
- package/dist/plugins/agents/pi-native/tools.js +4 -4
- package/dist/plugins/agents/pi-native/tools.js.map +1 -1
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.d.ts +1 -1
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js +2 -2
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js.map +1 -1
- package/dist/plugins/messengers/email/email-adapter.js +15 -15
- package/dist/plugins/messengers/email/email-adapter.js.map +1 -1
- package/dist/plugins/messengers/telegram/media-download.d.ts +1 -1
- package/dist/plugins/messengers/telegram/media-download.js +4 -4
- package/dist/plugins/messengers/telegram/media-download.js.map +1 -1
- package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +1 -1
- package/dist/plugins/messengers/telegram/telegram-adapter.js +3 -3
- package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -1
- package/dist/plugins/messengers/wechat/context-store.js +1 -1
- package/dist/plugins/messengers/wechat/context-store.js.map +1 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.js +1 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -1
- package/dist/plugins/messengers/wechat/ilink-client.js +1 -1
- package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -1
- package/dist/plugins/messengers/wechat/media-download.js +1 -1
- package/dist/plugins/messengers/wechat/media-download.js.map +1 -1
- package/dist/scripts/migrate-gcj02-to-wgs84.js +1 -1
- package/dist/scripts/migrate-gcj02-to-wgs84.js.map +1 -1
- package/dist/web/public/assets/a2a-CTsDMefo.js +7 -0
- package/dist/web/public/assets/a2a-CTsDMefo.js.map +1 -0
- package/dist/web/public/assets/{activity-BnlFGipw.js → activity-ul8Os7Pz.js} +2 -2
- package/dist/web/public/assets/{activity-BnlFGipw.js.map → activity-ul8Os7Pz.js.map} +1 -1
- package/dist/web/public/assets/{admins-CH84Rw1d.js → admins-ByMAuquy.js} +3 -3
- package/dist/web/public/assets/{admins-CH84Rw1d.js.map → admins-ByMAuquy.js.map} +1 -1
- package/dist/web/public/assets/agents-Ds1zyxBj.js +2 -0
- package/dist/web/public/assets/agents-Ds1zyxBj.js.map +1 -0
- package/dist/web/public/assets/{approvals-DnzjbDR6.js → approvals-DOWlWI7Z.js} +3 -3
- package/dist/web/public/assets/{approvals-DnzjbDR6.js.map → approvals-DOWlWI7Z.js.map} +1 -1
- package/dist/web/public/assets/{arrow-down-DxlRHrs8.js → arrow-down-7i0xwCI2.js} +2 -2
- package/dist/web/public/assets/{arrow-down-DxlRHrs8.js.map → arrow-down-7i0xwCI2.js.map} +1 -1
- package/dist/web/public/assets/arrow-right-A889Wof8.js +7 -0
- package/dist/web/public/assets/arrow-right-A889Wof8.js.map +1 -0
- package/dist/web/public/assets/{arrow-up-CAiQ2jy-.js → arrow-up-Dm0U4-6U.js} +2 -2
- package/dist/web/public/assets/{arrow-up-CAiQ2jy-.js.map → arrow-up-Dm0U4-6U.js.map} +1 -1
- package/dist/web/public/assets/{asks-DyUQopay.js → asks-DGuBsrJ7.js} +3 -3
- package/dist/web/public/assets/{asks-DyUQopay.js.map → asks-DGuBsrJ7.js.map} +1 -1
- package/dist/web/public/assets/{audit-BVHTMS82.js → audit-BRXsplJ2.js} +2 -2
- package/dist/web/public/assets/{audit-BVHTMS82.js.map → audit-BRXsplJ2.js.map} +1 -1
- package/dist/web/public/assets/{bell-D7iS7ctN.js → bell-B-UdeJsp.js} +2 -2
- package/dist/web/public/assets/{bell-D7iS7ctN.js.map → bell-B-UdeJsp.js.map} +1 -1
- package/dist/web/public/assets/bgjobs-CcRiffyJ.js +2 -0
- package/dist/web/public/assets/bgjobs-CcRiffyJ.js.map +1 -0
- package/dist/web/public/assets/book-open-CSCq5cjL.js +7 -0
- package/dist/web/public/assets/book-open-CSCq5cjL.js.map +1 -0
- package/dist/web/public/assets/{brain-CCF25Egu.js → brain-Dl4DF5kX.js} +2 -2
- package/dist/web/public/assets/{brain-CCF25Egu.js.map → brain-Dl4DF5kX.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-BMLMD8nM.js → briefcase-CeKUkFSq.js} +2 -2
- package/dist/web/public/assets/{briefcase-BMLMD8nM.js.map → briefcase-CeKUkFSq.js.map} +1 -1
- package/dist/web/public/assets/chat-rLJMdJBk.js +12 -0
- package/dist/web/public/assets/chat-rLJMdJBk.js.map +1 -0
- package/dist/web/public/assets/{chevron-left-BDO3vw8G.js → chevron-left-01fAFVpo.js} +2 -2
- package/dist/web/public/assets/{chevron-left-BDO3vw8G.js.map → chevron-left-01fAFVpo.js.map} +1 -1
- package/dist/web/public/assets/{chevron-right-5ZUC2opg.js → chevron-right-CFRb-SM_.js} +3 -3
- package/dist/web/public/assets/{chevron-right-5ZUC2opg.js.map → chevron-right-CFRb-SM_.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-DHAHqUlS.js → circle-check-big-DBg2BD6o.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-DHAHqUlS.js.map → circle-check-big-DBg2BD6o.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-7VaoZ7dY.js → circle-x-CqFMzO-x.js} +2 -2
- package/dist/web/public/assets/{circle-x-7VaoZ7dY.js.map → circle-x-CqFMzO-x.js.map} +1 -1
- package/dist/web/public/assets/clipboard-list-lnqdk2_J.js +7 -0
- package/dist/web/public/assets/clipboard-list-lnqdk2_J.js.map +1 -0
- package/dist/web/public/assets/{clock-ZPVXnd6V.js → clock-4hd1joQe.js} +3 -3
- package/dist/web/public/assets/{clock-ZPVXnd6V.js.map → clock-4hd1joQe.js.map} +1 -1
- package/dist/web/public/assets/confirm-dialog-BDb0NLny.js +2 -0
- package/dist/web/public/assets/{confirm-dialog-CgpJL9oN.js.map → confirm-dialog-BDb0NLny.js.map} +1 -1
- package/dist/web/public/assets/{copy-BaZl52tH.js → copy-CD4A7VD8.js} +3 -3
- package/dist/web/public/assets/{copy-BaZl52tH.js.map → copy-CD4A7VD8.js.map} +1 -1
- package/dist/web/public/assets/dashboard-CG3WiG7h.js +2 -0
- package/dist/web/public/assets/dashboard-CG3WiG7h.js.map +1 -0
- package/dist/web/public/assets/{data-table-BLYG79TX.js → data-table-BkUshOZz.js} +2 -2
- package/dist/web/public/assets/{data-table-BLYG79TX.js.map → data-table-BkUshOZz.js.map} +1 -1
- package/dist/web/public/assets/database-lQzk64rV.js +7 -0
- package/dist/web/public/assets/database-lQzk64rV.js.map +1 -0
- package/dist/web/public/assets/distill-CPurVW3v.js +7 -0
- package/dist/web/public/assets/distill-CPurVW3v.js.map +1 -0
- package/dist/web/public/assets/{download-bzCepctg.js → download-CVZnHcwj.js} +2 -2
- package/dist/web/public/assets/{download-bzCepctg.js.map → download-CVZnHcwj.js.map} +1 -1
- package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js +7 -0
- package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js.map +1 -0
- package/dist/web/public/assets/email-YlI4MWLp.js +7 -0
- package/dist/web/public/assets/email-YlI4MWLp.js.map +1 -0
- package/dist/web/public/assets/{empty-state-96qpPTNg.js → empty-state-CuiqdZiB.js} +2 -2
- package/dist/web/public/assets/{empty-state-96qpPTNg.js.map → empty-state-CuiqdZiB.js.map} +1 -1
- package/dist/web/public/assets/{external-link-J4nIlCem.js → external-link-1WPpVvdu.js} +2 -2
- package/dist/web/public/assets/{external-link-J4nIlCem.js.map → external-link-1WPpVvdu.js.map} +1 -1
- package/dist/web/public/assets/{eye-BvsBLK42.js → eye-BfPyNFzk.js} +2 -2
- package/dist/web/public/assets/{eye-BvsBLK42.js.map → eye-BfPyNFzk.js.map} +1 -1
- package/dist/web/public/assets/{facts-DMucDXYd.js → facts-xT_24pH8.js} +2 -2
- package/dist/web/public/assets/{facts-DMucDXYd.js.map → facts-xT_24pH8.js.map} +1 -1
- package/dist/web/public/assets/file-text-BxfdLM0-.js +7 -0
- package/dist/web/public/assets/file-text-BxfdLM0-.js.map +1 -0
- package/dist/web/public/assets/{goals-B9ETHgL0.js → goals-C8ZQfbhj.js} +3 -3
- package/dist/web/public/assets/{goals-B9ETHgL0.js.map → goals-C8ZQfbhj.js.map} +1 -1
- package/dist/web/public/assets/health-A2StNEfn.js +2 -0
- package/dist/web/public/assets/{health-DLzZ7KHc.js.map → health-A2StNEfn.js.map} +1 -1
- package/dist/web/public/assets/{heart-pulse-CVEeD2sz.js → heart-pulse-DXlE9oic.js} +2 -2
- package/dist/web/public/assets/{heart-pulse-CVEeD2sz.js.map → heart-pulse-DXlE9oic.js.map} +1 -1
- package/dist/web/public/assets/{heartbeat-B1BEBHge.js → heartbeat-ClO5gJrj.js} +3 -3
- package/dist/web/public/assets/{heartbeat-B1BEBHge.js.map → heartbeat-ClO5gJrj.js.map} +1 -1
- package/dist/web/public/assets/hot-bfTA-V_z.js +7 -0
- package/dist/web/public/assets/{hot-Yc7iad0D.js.map → hot-bfTA-V_z.js.map} +1 -1
- package/dist/web/public/assets/index-Bi2qWb-u.css +1 -0
- package/dist/web/public/assets/index-DCfdN5R7.js +244 -0
- package/dist/web/public/assets/index-DCfdN5R7.js.map +1 -0
- package/dist/web/public/assets/{injection-Ca-9gbo0.js → injection-omvCR6-p.js} +2 -2
- package/dist/web/public/assets/{injection-Ca-9gbo0.js.map → injection-omvCR6-p.js.map} +1 -1
- package/dist/web/public/assets/{installed-Zz34apdi.js → installed-DL6r3ktm.js} +4 -9
- package/dist/web/public/assets/installed-DL6r3ktm.js.map +1 -0
- package/dist/web/public/assets/jobs-Biy5lYd4.js +2 -0
- package/dist/web/public/assets/jobs-Biy5lYd4.js.map +1 -0
- package/dist/web/public/assets/layout-BLm6NJ3V.js +2 -0
- package/dist/web/public/assets/layout-BLm6NJ3V.js.map +1 -0
- package/dist/web/public/assets/layout-BTKafRVZ.js +2 -0
- package/dist/web/public/assets/layout-BTKafRVZ.js.map +1 -0
- package/dist/web/public/assets/layout-Bm-2s2fp.js +2 -0
- package/dist/web/public/assets/layout-Bm-2s2fp.js.map +1 -0
- package/dist/web/public/assets/layout-DsZ8eR4i.js +2 -0
- package/dist/web/public/assets/layout-DsZ8eR4i.js.map +1 -0
- package/dist/web/public/assets/{layout-CtDc2i7w.js → layout-sxvovjEH.js} +2 -2
- package/dist/web/public/assets/{layout-CtDc2i7w.js.map → layout-sxvovjEH.js.map} +1 -1
- package/dist/web/public/assets/llm-JjZDbBvJ.js +37 -0
- package/dist/web/public/assets/llm-JjZDbBvJ.js.map +1 -0
- package/dist/web/public/assets/loader-circle-DDdmcH0k.js +7 -0
- package/dist/web/public/assets/{loader-circle-D8L1w9c1.js.map → loader-circle-DDdmcH0k.js.map} +1 -1
- package/dist/web/public/assets/{map-pin--GMunU9n.js → map-pin-C_jAxukI.js} +2 -2
- package/dist/web/public/assets/{map-pin--GMunU9n.js.map → map-pin-C_jAxukI.js.map} +1 -1
- package/dist/web/public/assets/{mcp-DhnXhO9B.js → mcp-vKajK1F8.js} +3 -3
- package/dist/web/public/assets/{mcp-DhnXhO9B.js.map → mcp-vKajK1F8.js.map} +1 -1
- package/dist/web/public/assets/memos-DAt4k3DO.js +7 -0
- package/dist/web/public/assets/memos-DAt4k3DO.js.map +1 -0
- package/dist/web/public/assets/messengers-GYVTFlAj.js +2 -0
- package/dist/web/public/assets/messengers-GYVTFlAj.js.map +1 -0
- package/dist/web/public/assets/{mobile-CUZ359rQ.js → mobile-VUyTo40E.js} +3 -3
- package/dist/web/public/assets/{mobile-CUZ359rQ.js.map → mobile-VUyTo40E.js.map} +1 -1
- package/dist/web/public/assets/{network-BBdRdrH_.js → network-BUeWK3bs.js} +2 -2
- package/dist/web/public/assets/{network-BBdRdrH_.js.map → network-BUeWK3bs.js.map} +1 -1
- package/dist/web/public/assets/outbox-CEE0rwN3.js +2 -0
- package/dist/web/public/assets/outbox-CEE0rwN3.js.map +1 -0
- package/dist/web/public/assets/overview-BSOZ5gTD.js +12 -0
- package/dist/web/public/assets/overview-BSOZ5gTD.js.map +1 -0
- package/dist/web/public/assets/overview-COop5K2Y.js +12 -0
- package/dist/web/public/assets/overview-COop5K2Y.js.map +1 -0
- package/dist/web/public/assets/overview-DeH5ud6d.js +2 -0
- package/dist/web/public/assets/overview-DeH5ud6d.js.map +1 -0
- package/dist/web/public/assets/{pagination-DcsgDXXM.js → pagination-BBicLzXP.js} +3 -3
- package/dist/web/public/assets/{pagination-DcsgDXXM.js.map → pagination-BBicLzXP.js.map} +1 -1
- package/dist/web/public/assets/persona-CElXQZ4p.js +2 -0
- package/dist/web/public/assets/{persona-ig2ac4mY.js.map → persona-CElXQZ4p.js.map} +1 -1
- package/dist/web/public/assets/{plans-Bzbk8eUr.js → plans-Bo5LlLeH.js} +3 -8
- package/dist/web/public/assets/plans-Bo5LlLeH.js.map +1 -0
- package/dist/web/public/assets/{play-Di1jqulh.js → play-DX5wp4WH.js} +2 -2
- package/dist/web/public/assets/{play-Di1jqulh.js.map → play-DX5wp4WH.js.map} +1 -1
- package/dist/web/public/assets/{plus-C2zyJ1mF.js → plus-DH4J_YhN.js} +2 -2
- package/dist/web/public/assets/{plus-C2zyJ1mF.js.map → plus-DH4J_YhN.js.map} +1 -1
- package/dist/web/public/assets/policy-BrgOuDt_.js +2 -0
- package/dist/web/public/assets/policy-BrgOuDt_.js.map +1 -0
- package/dist/web/public/assets/{qr-code-C-ACsKv_.js → qr-code-YrEuhMPC.js} +2 -2
- package/dist/web/public/assets/{qr-code-C-ACsKv_.js.map → qr-code-YrEuhMPC.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-7HdadG5V.js → refresh-ccw-DlAd-eTQ.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-7HdadG5V.js.map → refresh-ccw-DlAd-eTQ.js.map} +1 -1
- package/dist/web/public/assets/{reminders-BDeiVYTC.js → reminders-DBEE0zXG.js} +3 -3
- package/dist/web/public/assets/{reminders-BDeiVYTC.js.map → reminders-DBEE0zXG.js.map} +1 -1
- package/dist/web/public/assets/{save-BYFmz9gD.js → save-BDOtZrfp.js} +2 -2
- package/dist/web/public/assets/{save-BYFmz9gD.js.map → save-BDOtZrfp.js.map} +1 -1
- package/dist/web/public/assets/schedules-DAyhVI8-.js +2 -0
- package/dist/web/public/assets/schedules-DAyhVI8-.js.map +1 -0
- package/dist/web/public/assets/search-55mtgHrB.js +17 -0
- package/dist/web/public/assets/search-55mtgHrB.js.map +1 -0
- package/dist/web/public/assets/{search-DxkvV-8p.js → search-CAICU3aU.js} +2 -2
- package/dist/web/public/assets/{search-DxkvV-8p.js.map → search-CAICU3aU.js.map} +1 -1
- package/dist/web/public/assets/security-CbP4QgVp.js +2 -0
- package/dist/web/public/assets/security-CbP4QgVp.js.map +1 -0
- package/dist/web/public/assets/server-Dg4e8pvm.js +7 -0
- package/dist/web/public/assets/server-Dg4e8pvm.js.map +1 -0
- package/dist/web/public/assets/service-gWZa3sup.js +7 -0
- package/dist/web/public/assets/service-gWZa3sup.js.map +1 -0
- package/dist/web/public/assets/{shield-alert-DXGk9Rak.js → shield-alert-DOKK9EnJ.js} +2 -2
- package/dist/web/public/assets/{shield-alert-DXGk9Rak.js.map → shield-alert-DOKK9EnJ.js.map} +1 -1
- package/dist/web/public/assets/sparkles-G0QIs9nP.js +7 -0
- package/dist/web/public/assets/sparkles-G0QIs9nP.js.map +1 -0
- package/dist/web/public/assets/start-D-abhl3q.js +2 -0
- package/dist/web/public/assets/start-D-abhl3q.js.map +1 -0
- package/dist/web/public/assets/{status-badge-D0nbFSom.js → status-badge-CyLdpsXq.js} +2 -2
- package/dist/web/public/assets/{status-badge-D0nbFSom.js.map → status-badge-CyLdpsXq.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-DFiAXvDp.js → subtasks-BnEjSGUR.js} +3 -3
- package/dist/web/public/assets/{subtasks-DFiAXvDp.js.map → subtasks-BnEjSGUR.js.map} +1 -1
- package/dist/web/public/assets/{table-_WsrnZ_T.js → table-sCMZBe_Z.js} +2 -2
- package/dist/web/public/assets/{table-_WsrnZ_T.js.map → table-sCMZBe_Z.js.map} +1 -1
- package/dist/web/public/assets/terminal-_pXeEjXG.js +7 -0
- package/dist/web/public/assets/terminal-_pXeEjXG.js.map +1 -0
- package/dist/web/public/assets/{topn-C2PHE4tX.js → topn-D1B-gS1M.js} +3 -3
- package/dist/web/public/assets/{topn-C2PHE4tX.js.map → topn-D1B-gS1M.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-1Km439fW.js → trash-2-D2x2UPuZ.js} +2 -2
- package/dist/web/public/assets/{trash-2-1Km439fW.js.map → trash-2-D2x2UPuZ.js.map} +1 -1
- package/dist/web/public/assets/use-a2a-C98e2Via.js +2 -0
- package/dist/web/public/assets/use-a2a-C98e2Via.js.map +1 -0
- package/dist/web/public/assets/{use-agim-skills-COSqZrdH.js → use-agim-skills-BbuJP3NT.js} +2 -2
- package/dist/web/public/assets/{use-agim-skills-COSqZrdH.js.map → use-agim-skills-BbuJP3NT.js.map} +1 -1
- package/dist/web/public/assets/use-background-tasks-CwFmOokw.js +2 -0
- package/dist/web/public/assets/{use-background-tasks-wCL7jn68.js.map → use-background-tasks-CwFmOokw.js.map} +1 -1
- package/dist/web/public/assets/use-jobs-BJjeJ5lh.js +2 -0
- package/dist/web/public/assets/use-jobs-BJjeJ5lh.js.map +1 -0
- package/dist/web/public/assets/use-memory-CXDwKCco.js +2 -0
- package/dist/web/public/assets/{use-memory-B9oRyQC8.js.map → use-memory-CXDwKCco.js.map} +1 -1
- package/dist/web/public/assets/use-observability-CY5ZUPrC.js +2 -0
- package/dist/web/public/assets/{use-observability-DGkN80qa.js.map → use-observability-CY5ZUPrC.js.map} +1 -1
- package/dist/web/public/assets/use-outbox-DT_XWB_7.js +7 -0
- package/dist/web/public/assets/use-outbox-DT_XWB_7.js.map +1 -0
- package/dist/web/public/assets/use-schedules-D4W8fMwo.js +7 -0
- package/dist/web/public/assets/use-schedules-D4W8fMwo.js.map +1 -0
- package/dist/web/public/assets/use-settings-DGIjmUX0.js +2 -0
- package/dist/web/public/assets/use-settings-DGIjmUX0.js.map +1 -0
- package/dist/web/public/assets/use-skills-D2bMM580.js +7 -0
- package/dist/web/public/assets/use-skills-D2bMM580.js.map +1 -0
- package/dist/web/public/assets/use-vector-BYOFwjU0.js +2 -0
- package/dist/web/public/assets/use-vector-BYOFwjU0.js.map +1 -0
- package/dist/web/public/assets/use-workspace-CuytyHwb.js +2 -0
- package/dist/web/public/assets/{use-workspace-BDXP5XO1.js.map → use-workspace-CuytyHwb.js.map} +1 -1
- package/dist/web/public/assets/vector-CL8ezpSR.js +2 -0
- package/dist/web/public/assets/vector-CL8ezpSR.js.map +1 -0
- package/dist/web/public/assets/viewer-CD0iEfPU.js +7 -0
- package/dist/web/public/assets/viewer-CD0iEfPU.js.map +1 -0
- package/dist/web/public/assets/workspace-BA1_hso3.js +17 -0
- package/dist/web/public/assets/workspace-BA1_hso3.js.map +1 -0
- package/dist/web/public/assets/workspaces-DyGLJUgB.js +7 -0
- package/dist/web/public/assets/workspaces-DyGLJUgB.js.map +1 -0
- package/dist/web/public/index.html +2 -2
- package/dist/web/public/loc.html +1 -1
- package/dist/web/public/login.html +2 -2
- package/dist/web/server.d.ts +2 -5
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +256 -122
- package/dist/web/server.js.map +1 -1
- package/package.json +2 -3
- package/dist/core/llm/imhub-dispatcher.d.ts.map +0 -1
- package/dist/core/llm/imhub-dispatcher.js.map +0 -1
- package/dist/web/public/assets/a2a-CZxwvgvh.js +0 -7
- package/dist/web/public/assets/a2a-CZxwvgvh.js.map +0 -1
- package/dist/web/public/assets/agents-CFB4Uj6b.js +0 -7
- package/dist/web/public/assets/agents-CFB4Uj6b.js.map +0 -1
- package/dist/web/public/assets/bgjobs-BYCQhd_1.js +0 -7
- package/dist/web/public/assets/bgjobs-BYCQhd_1.js.map +0 -1
- package/dist/web/public/assets/chat-DPkKy5y_.js +0 -17
- package/dist/web/public/assets/chat-DPkKy5y_.js.map +0 -1
- package/dist/web/public/assets/circle-check-COhM5JsK.js +0 -7
- package/dist/web/public/assets/circle-check-COhM5JsK.js.map +0 -1
- package/dist/web/public/assets/confirm-dialog-CgpJL9oN.js +0 -2
- package/dist/web/public/assets/distill-D9p8O8Jf.js +0 -7
- package/dist/web/public/assets/distill-D9p8O8Jf.js.map +0 -1
- package/dist/web/public/assets/email-Douv-rZ5.js +0 -7
- package/dist/web/public/assets/email-Douv-rZ5.js.map +0 -1
- package/dist/web/public/assets/health-DLzZ7KHc.js +0 -2
- package/dist/web/public/assets/hot-Yc7iad0D.js +0 -12
- package/dist/web/public/assets/index-DY2Zglku.js +0 -209
- package/dist/web/public/assets/index-DY2Zglku.js.map +0 -1
- package/dist/web/public/assets/index-DknVjPYB.css +0 -1
- package/dist/web/public/assets/installed-Zz34apdi.js.map +0 -1
- package/dist/web/public/assets/jobs-CtVRpl0r.js +0 -2
- package/dist/web/public/assets/jobs-CtVRpl0r.js.map +0 -1
- package/dist/web/public/assets/layout-BTCLgkgN.js +0 -2
- package/dist/web/public/assets/layout-BTCLgkgN.js.map +0 -1
- package/dist/web/public/assets/layout-Cxch59sI.js +0 -2
- package/dist/web/public/assets/layout-Cxch59sI.js.map +0 -1
- package/dist/web/public/assets/layout-DnANw2Q2.js +0 -2
- package/dist/web/public/assets/layout-DnANw2Q2.js.map +0 -1
- package/dist/web/public/assets/layout-yIZG87fq.js +0 -2
- package/dist/web/public/assets/layout-yIZG87fq.js.map +0 -1
- package/dist/web/public/assets/llm-CMMa85Ig.js +0 -27
- package/dist/web/public/assets/llm-CMMa85Ig.js.map +0 -1
- package/dist/web/public/assets/loader-circle-D8L1w9c1.js +0 -7
- package/dist/web/public/assets/memos-DQZc7llR.js +0 -12
- package/dist/web/public/assets/memos-DQZc7llR.js.map +0 -1
- package/dist/web/public/assets/messengers-DwSmauLs.js +0 -2
- package/dist/web/public/assets/messengers-DwSmauLs.js.map +0 -1
- package/dist/web/public/assets/outbox-CmN0U35l.js +0 -7
- package/dist/web/public/assets/outbox-CmN0U35l.js.map +0 -1
- package/dist/web/public/assets/persona-ig2ac4mY.js +0 -2
- package/dist/web/public/assets/plans-Bzbk8eUr.js.map +0 -1
- package/dist/web/public/assets/policy-yD1c2Pcn.js +0 -2
- package/dist/web/public/assets/policy-yD1c2Pcn.js.map +0 -1
- package/dist/web/public/assets/schedules-BddzBrxI.js +0 -7
- package/dist/web/public/assets/schedules-BddzBrxI.js.map +0 -1
- package/dist/web/public/assets/search-B8PlbtLg.js +0 -17
- package/dist/web/public/assets/search-B8PlbtLg.js.map +0 -1
- package/dist/web/public/assets/security-DpOGp3nS.js +0 -2
- package/dist/web/public/assets/security-DpOGp3nS.js.map +0 -1
- package/dist/web/public/assets/service-BsY8CaNG.js +0 -7
- package/dist/web/public/assets/service-BsY8CaNG.js.map +0 -1
- package/dist/web/public/assets/use-background-tasks-wCL7jn68.js +0 -2
- package/dist/web/public/assets/use-memory-B9oRyQC8.js +0 -2
- package/dist/web/public/assets/use-observability-DGkN80qa.js +0 -2
- package/dist/web/public/assets/use-settings-Co-iafXD.js +0 -2
- package/dist/web/public/assets/use-settings-Co-iafXD.js.map +0 -1
- package/dist/web/public/assets/use-workspace-BDXP5XO1.js +0 -2
- package/dist/web/public/assets/vector-BfIEx8xX.js +0 -2
- package/dist/web/public/assets/vector-BfIEx8xX.js.map +0 -1
- package/dist/web/public/assets/viewer-BPMZkT05.js +0 -12
- package/dist/web/public/assets/viewer-BPMZkT05.js.map +0 -1
- package/dist/web/public/assets/workspace-BbCchiHE.js +0 -17
- package/dist/web/public/assets/workspace-BbCchiHE.js.map +0 -1
- package/dist/web/public/assets/workspaces-5HE7pjdA.js +0 -7
- package/dist/web/public/assets/workspaces-5HE7pjdA.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,41 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.5.1] - 2026-07-02
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added a first-run Web dashboard path with clear next actions for Web chat, Agim Agent API setup, and IM connection.
|
|
12
|
+
- Added `agim go`, `agim web`, service recovery hints, local doctor checks, and safer background-start diagnostics for new users.
|
|
13
|
+
- Added Web settings overviews for Start, Memory, Tasks, agim Skills, Workspace, Service recovery, Security posture, and Agim Agent API setup.
|
|
14
|
+
- Added native Agim Agent `/models` and `/model` support, including backend switching by name or list index.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Made Agim Agent API setup progressive: quick setup is shown first; multi-API management, role bindings, and runtime knobs now live behind Advanced settings.
|
|
19
|
+
- Simplified IM, workspace, memory, tasks, and settings navigation so advanced features remain available without overwhelming first-time users.
|
|
20
|
+
- Improved security settings visual hierarchy with explicit surfaces for status, controls, diagnostics, and warning items.
|
|
21
|
+
- Native/OpenAI-compatible model probes now omit `temperature` unless explicitly configured, avoiding providers that reject deprecated temperature parameters.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Fixed Web service log handling when the log file has not been created yet.
|
|
26
|
+
- Ensured workspace-created memory files are linked into the Agent workspace so Agim Agent can consume them.
|
|
27
|
+
- Fixed undefined Web theme utility classes that made some settings blocks visually blend into the page background.
|
|
28
|
+
|
|
29
|
+
## [1.5.0] - 2026-06-29
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- Public runtime surfaces now consistently use Agim naming: `agim`, `AGIM_*`, `mcp__agim__*`, `X-Agim-Token`, `~/.agim`, `~/.agim-workspaces`, and `agim.service`.
|
|
34
|
+
- Removed retired command, env, path, MCP, HTTP header, and systemd aliases from code, docs, tests, and release notes.
|
|
35
|
+
- Decoupled opencode from normal startup: Agim now registers the opencode MCP sidecar lazily only when an opencode adapter is actually used.
|
|
36
|
+
- Headless production startup now defaults to `claude-code` when no default agent is configured.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- Non-Linux Agim process detection now validates argv shape via `ps` instead of substring matching, avoiding false positives from shell commands that merely contain `agim start`.
|
|
41
|
+
|
|
7
42
|
## [1.3.10] - 2026-06-23
|
|
8
43
|
|
|
9
44
|
### Added
|
|
@@ -49,7 +84,7 @@ All notable changes to this project will be documented in this file.
|
|
|
49
84
|
|
|
50
85
|
### Added(自 1.3.0 累积)
|
|
51
86
|
|
|
52
|
-
- `
|
|
87
|
+
- `mcp__agim__ask_user` 扩展为结构化决策模式:单选/多选/自定义输入(`selectionMode`、`minSelections`、`maxSelections`、`allowCustomInput`、`customInputLabel`;结果含 `selectionMode`、`indexes`、`labels`、`customText`,旧字段兼容)。
|
|
53
88
|
- TUI 统一决策交互面板(审批 + `ask_user`:键盘单选 / 多选 Space 勾选 / 自定义输入);会话管理 `/new` `/sessions`;`/agent` 名称补全;token/cost 状态栏;工具调用审批桥。
|
|
54
89
|
|
|
55
90
|
### Documentation
|
|
@@ -65,17 +100,17 @@ All notable changes to this project will be documented in this file.
|
|
|
65
100
|
|
|
66
101
|
- **pi-native 成为默认 native 引擎**(1.2.155):in-process 循环换成 pi 的
|
|
67
102
|
`AgentHarness` + durable JSONL session(崩溃可恢复);legacy 降级为逃生通道
|
|
68
|
-
(`
|
|
103
|
+
(`AGIM_NATIVE_ENGINE=legacy`)。含 approval 门 / plan-mode / max-iter /
|
|
69
104
|
stuck-loop 护栏 / 真实身份 system prompt。
|
|
70
105
|
- **上下文压缩 + provider 韧性**(1.2.156):每轮按 token 阈值 `harness.compact()`;
|
|
71
|
-
provider 重试/退避/超时 + prompt 缓存,全 `
|
|
72
|
-
- **A2A 子输出压缩**(1.2.157):子代理回传超 `
|
|
106
|
+
provider 重试/退避/超时 + prompt 缓存,全 `AGIM_NATIVE_*` 可覆盖。
|
|
107
|
+
- **A2A 子输出压缩**(1.2.157):子代理回传超 `AGIM_A2A_MAX_RESULT_CHARS`(默认
|
|
73
108
|
8000)即截断,全文溢出到 `_agim-output/`,父按需 read。
|
|
74
109
|
- **TUI 体验**(1.2.158):`/agent` 名称补全 + 底部 token/cost 实时状态栏。
|
|
75
110
|
- **模型成本/窗口元数据**(1.2.159):复用 pi-ai MODELS 目录,`LlmProvider`
|
|
76
111
|
在 API 不回成本时按目录回填真实 $(覆盖所有 legacy provider)。
|
|
77
112
|
- **auth 重构 + 手机端**(1.2.160):web-token-only admin 注册表(IM admin 在
|
|
78
|
-
Settings → Admins 管理,取消 bootstrap token / `
|
|
113
|
+
Settings → Admins 管理,取消 bootstrap token / `AGIM_ADMIN_USERS` 运行时依赖);
|
|
79
114
|
手机版聊天 UX + run 活动时间线;native 配置弹窗 + role-optional 后端兜底。
|
|
80
115
|
|
|
81
116
|
详见各 1.2.15x 段。
|
|
@@ -83,13 +118,13 @@ All notable changes to this project will be documented in this file.
|
|
|
83
118
|
## Native engine (pi-native) overview
|
|
84
119
|
|
|
85
120
|
> Consolidated from historical pi-native migration notes.
|
|
86
|
-
> Default native engine since `1.2.155`; legacy escape hatch: `
|
|
121
|
+
> Default native engine since `1.2.155`; legacy escape hatch: `AGIM_NATIVE_ENGINE=legacy`.
|
|
87
122
|
|
|
88
123
|
### Shipped (1.2.155 → 1.2.159)
|
|
89
124
|
|
|
90
125
|
- **1.2.155**: switched native engine to pi-native (`AgentHarness` + durable JSONL session), added tool bridge, resolver, approval integration, runaway/stuck-loop guards.
|
|
91
|
-
- **1.2.156**: added pre-turn compaction (`
|
|
92
|
-
- **1.2.157**: added A2A result compression (`
|
|
126
|
+
- **1.2.156**: added pre-turn compaction (`AGIM_NATIVE_COMPACTION`), provider retry/cache tuning (`AGIM_NATIVE_*`).
|
|
127
|
+
- **1.2.157**: added A2A result compression (`AGIM_A2A_MAX_RESULT_CHARS`) with overflow to artifact files.
|
|
93
128
|
- **1.2.158**: improved TUI interaction (`/agent` completion + token/cost status visibility).
|
|
94
129
|
- **1.2.159**: added model catalog-based usage enrichment for cost/window metadata backfill.
|
|
95
130
|
|
|
@@ -254,7 +289,7 @@ workspace 排在 ECC picks 之前。运营者亲装 > 框架预选 > ECC remaind
|
|
|
254
289
|
运营者可以覆盖自动生成的 skill 块。文件存在且非空时,**全文替换** auto block
|
|
255
290
|
(路由头 + always-on body 保留)。三个 helper:
|
|
256
291
|
`readInjectionOverride / writeInjectionOverride / deleteInjectionOverride`。
|
|
257
|
-
环境变量 `
|
|
292
|
+
环境变量 `AGIM_SKILLS_INJECTION_OVERRIDE_PATH` 可改路径(测试用)。
|
|
258
293
|
|
|
259
294
|
#### Admin API + SPA 页
|
|
260
295
|
|
|
@@ -268,8 +303,8 @@ workspace 排在 ECC picks 之前。运营者亲装 > 框架预选 > ECC remaind
|
|
|
268
303
|
|
|
269
304
|
#### 新增 env knob
|
|
270
305
|
|
|
271
|
-
- `
|
|
272
|
-
- `
|
|
306
|
+
- `AGIM_SKILLS_ECC_PICKS=name1,name2,...` 覆盖默认 20 picks(推荐池)
|
|
307
|
+
- `AGIM_SKILLS_INJECT_ECC_REMAINDER=on|off|name-list`:
|
|
273
308
|
- `on`(默认):cluster 模式
|
|
274
309
|
- `off`:完全抑制 ECC remainder 块(省 token)
|
|
275
310
|
- 逗号分隔白名单:只保留指定 skill
|
|
@@ -343,7 +378,7 @@ LLM 看不到 description → 无法 route。
|
|
|
343
378
|
/ code-tour / coding-standards / content-engine / context-budget / continuous-learning-v2
|
|
344
379
|
/ cost-aware-llm-pipeline / prompt-optimizer / security-review / tdd-workflow / verification-loop
|
|
345
380
|
|
|
346
|
-
## ECC remainder (read full description via
|
|
381
|
+
## ECC remainder (read full description via mcp__agim__read_skill) (210)
|
|
347
382
|
- django-* (5): django-celery · django-patterns · django-security · django-tdd · django-verification
|
|
348
383
|
- kotlin-* (5): kotlin-coroutines-flows · kotlin-exposed-patterns · kotlin-ktor-patterns
|
|
349
384
|
· kotlin-patterns · kotlin-testing
|
|
@@ -414,7 +449,7 @@ v1.2.148 的 bulk-import 脚本对 YAML 折叠语法(`description: >-\n text.
|
|
|
414
449
|
| 3 | 工作区运营者 skill(业务域)+ ECC 余下 210 |
|
|
415
450
|
|
|
416
451
|
4 + 8 + 20 = 32 正好填满;bucket 3 全部靠 description match + 显式
|
|
417
|
-
`
|
|
452
|
+
`mcp__agim__read_skill('name')` 触发,不强占系统提示门面。
|
|
418
453
|
|
|
419
454
|
#### ECC 精选清单(20 个)
|
|
420
455
|
|
|
@@ -493,7 +528,7 @@ verification 循环、cost-aware LLM 流水线等。MIT 许可,license 文件
|
|
|
493
528
|
|
|
494
529
|
#### env switch
|
|
495
530
|
|
|
496
|
-
- `
|
|
531
|
+
- `AGIM_INCLUDE_ECC_SKILLS=off` (或 `0`/`false`/`no`/`disable`)→ loader 跳过
|
|
497
532
|
所有 `origin: ECC` 的 skill。默认 ON,保留新装 agim 用户的开箱即用体验。
|
|
498
533
|
- 仅过滤 ECC pack;用户自己写 SKILL.md 时若复用 `origin: ECC` 字段是允许的
|
|
499
534
|
(但显式标记 ECC pack 的 description `[ECC]` 前缀已写死,不影响 user skill)。
|
|
@@ -517,7 +552,7 @@ verification 循环、cost-aware LLM 流水线等。MIT 许可,license 文件
|
|
|
517
552
|
(部分含 scripts/references/templates 子目录),description 行加 `[ECC]` 前缀
|
|
518
553
|
- 新增 `src/core/skills/builtin/ECC_LICENSE` —— MIT, © Affaan Mustafa
|
|
519
554
|
- 新增 `src/core/skills/builtin/ECC_NOTICE.md` —— 归属说明 + 排除清单
|
|
520
|
-
- `src/core/skills/loader.ts` —— `parseSkill` 加
|
|
555
|
+
- `src/core/skills/loader.ts` —— `parseSkill` 加 AGIM_INCLUDE_ECC_SKILLS 过滤
|
|
521
556
|
- `src/core/skills/loader.test.ts` —— 新增 1 case 覆盖 env switch(默认 ON / off /
|
|
522
557
|
unrecognized 三态)
|
|
523
558
|
|
|
@@ -530,7 +565,7 @@ verification 循环、cost-aware LLM 流水线等。MIT 许可,license 文件
|
|
|
530
565
|
#### 注意事项(agim user 视角)
|
|
531
566
|
|
|
532
567
|
- system prompt 仍只列前 32 个 skill(`MAX_INJECTED_SKILLS=32`),不会爆 context
|
|
533
|
-
- 其余 200+ 个仍可通过 `
|
|
568
|
+
- 其余 200+ 个仍可通过 `mcp__agim__read_skill('name')` 主动调
|
|
534
569
|
- 同名 workspace skill 会 shadow builtin(用户自定义优先)
|
|
535
570
|
|
|
536
571
|
## [1.2.147] - 2026-06-12
|
|
@@ -548,7 +583,7 @@ prompt,命中模式就走复盘卡)。
|
|
|
548
583
|
push 一段 `[agim framework rule — tool-call discipline]` 块。**默认所有 agim 安装
|
|
549
584
|
生效**,不依赖用户写 AGENTS.md。
|
|
550
585
|
- 段内 5 条硬规则(禁演练、必须真调、不确定走 todo、追问时坦白、副作用工具一次发完整)。
|
|
551
|
-
- env `
|
|
586
|
+
- env `AGIM_NATIVE_TOOL_DISCIPLINE`,默认 `on`;`off`/`0`/`false`/`no`/`disable`
|
|
552
587
|
关掉(escape hatch,给 prompt 调优实验用)。
|
|
553
588
|
|
|
554
589
|
### Added (native harness — hallucinated tool-call detector)
|
|
@@ -574,7 +609,7 @@ prompt,命中模式就走复盘卡)。
|
|
|
574
609
|
|
|
575
610
|
#### Env
|
|
576
611
|
|
|
577
|
-
- `
|
|
612
|
+
- `AGIM_NATIVE_HALLUCINATION_DETECT` 默认 `on`;`off`/`0`/`false`/`no`/`disable` 关掉
|
|
578
613
|
(误判 cost 仅是多一张复盘卡,关掉 cost 是放过 silent lies,所以默认开)。
|
|
579
614
|
|
|
580
615
|
#### Tests
|
|
@@ -588,11 +623,11 @@ prompt,命中模式就走复盘卡)。
|
|
|
588
623
|
|
|
589
624
|
#### 未做(留续作)
|
|
590
625
|
|
|
591
|
-
- 自动 retry(`
|
|
626
|
+
- 自动 retry(`AGIM_NATIVE_HALLUCINATION_AUTO_RETRY=1` 强制注入纠正 prompt 再跑一轮)
|
|
592
627
|
- web outbox crash-safe delivery(web reply 在 client 重连时丢失)
|
|
593
628
|
- viewer DELETE 加 audit_event
|
|
594
|
-
- `docs/security-hardening.md` §1 env 速查表补 `
|
|
595
|
-
与 `
|
|
629
|
+
- `docs/security-hardening.md` §1 env 速查表补 `AGIM_NATIVE_WEB_ALLOW_PRIVATE`
|
|
630
|
+
与 `AGIM_NATIVE_WEB_SSRF_WHITELIST` 两项
|
|
596
631
|
|
|
597
632
|
## [1.2.145] - 2026-06-12
|
|
598
633
|
|
|
@@ -601,9 +636,9 @@ prompt,命中模式就走复盘卡)。
|
|
|
601
636
|
### Security (CR 修复)
|
|
602
637
|
|
|
603
638
|
- **viewer 越权删除(H1, #90)**:`DELETE /api/viewer/:id` 之前漏了 `requireAdmin` 且 handler 忽略请求上下文,任意已认证 token(含 `role=user` 移动 QR token)可凭 paste id(经 IM `/v/<uuid>` 链接外泄)删除任意 paste。已补 `requireAdmin`。
|
|
604
|
-
- **notify_url SSRF(H2, #92)**:定时任务 webhook 之前只做词法校验(只看 host 串)。新增 `assertWebhookHostPublic()`,在 fetch 前 DNS 解析 + 拒私网/回环/link-local,堵住"主机名解析进内网 / DNS-rebinding"。新 env `
|
|
639
|
+
- **notify_url SSRF(H2, #92)**:定时任务 webhook 之前只做词法校验(只看 host 串)。新增 `assertWebhookHostPublic()`,在 fetch 前 DNS 解析 + 拒私网/回环/link-local,堵住"主机名解析进内网 / DNS-rebinding"。新 env `AGIM_ALLOW_PRIVATE_WEBHOOKS=1` 放行内网调试。
|
|
605
640
|
- **sensitive-paths 绕过(#83)**:denylist 可被 `/proc/<pid>/{root,cwd}/...`(root 是指向进程 `/` 的 symlink)与工作区 symlink 绕过。`canonical()` 现做 best-effort `realpath`,对字面 + 解析后路径双重匹配,并直拒 `/proc` 间接寻址。
|
|
606
|
-
- **工作区信任门(T6, #89)**:新 env `
|
|
641
|
+
- **工作区信任门(T6, #89)**:新 env `AGIM_NATIVE_TRUST_WORKSPACE=off` → native 一次性跳过工作区发现的 `AGENTS.md`/`AGENTS.local.md` 注入(多租户 / A2A 防 prompt 投毒)。显式 `AGIM_NATIVE_AGENT_ROLE_FILE` 不受门控。
|
|
607
642
|
|
|
608
643
|
### Fixed (运行时可靠性,CR + #83)
|
|
609
644
|
|
|
@@ -619,7 +654,7 @@ prompt,命中模式就走复盘卡)。
|
|
|
619
654
|
- **IM 入站非阻塞(M3, #93)**:Feishu / DingTalk 之前在 SDK 回调内 `await` 整轮 agent,阻塞接收循环(一个慢会话拖死其他线程入站)。改 fire-and-forget;钉钉 **先 ack 再派发**(避免超 60s 重投 + handler 挂起时消息被 dedup 丢弃)。
|
|
620
655
|
- **native 上下文预算(T1/T3, #85)**:`readOperatorRole` 按 mtime/size memoize(每轮省一次磁盘读 + 注入扫描);system-prompt skills 列表封顶 `MAX_INJECTED_SKILLS`(之前未封顶且与 router 注入重复)。
|
|
621
656
|
- **native 单一工具注册表(T2, #86)**:`tools[]` / `combineDispatchers` / 静态 `parallelSafeTools` 三份并行清单合一为 `tool-registry.ts` 的 `assembleNativeTools()`;并发判定改 **逐调用** classifier(`agent-loop` 新增 `parallelSafeClassifier`,fail-closed);外部 MCP 分区按名排序保证 prompt-cache 稳定。
|
|
622
|
-
- **native 指令分层(T4, #88, local-wins)**:操作员角色从单 `AGENTS.md` → `<cwd>/AGENTS.md`(project)+ `<cwd>/AGENTS.local.md`(local,最后拼接=胜出)。`
|
|
657
|
+
- **native 指令分层(T4, #88, local-wins)**:操作员角色从单 `AGENTS.md` → `<cwd>/AGENTS.md`(project)+ `<cwd>/AGENTS.local.md`(local,最后拼接=胜出)。`AGIM_NATIVE_AGENT_ROLE_FILE` 仍可 pin 单文件。
|
|
623
658
|
- **验证子代理 SOP(T5, #89)**:native system prompt 增加"产出实质结果后用全新子代理独立校验 + 自包含 brief + 先综合再委派"指导(纯 prompt,无运行时分支)。
|
|
624
659
|
- **native 审计 traceId 关联(M5, #94)**:native 之前自造 `native-<sid>-<ts>` traceId,审计行无法关联入站消息。`AgentSendOpts.traceId` 由 router 透传、native 优先采用;进程内 A2A 子调用链接 `${parent}/a2a-${id}`(ADR-0002 修复)。
|
|
625
660
|
|
|
@@ -632,7 +667,7 @@ prompt,命中模式就走复盘卡)。
|
|
|
632
667
|
|
|
633
668
|
- A2A `call_agent('native')` 进程内快路径绕过 `callAgentByName`,不写 inline job / `intent:'a2a'` 审计行(本轮仅补 trace 链接)。
|
|
634
669
|
- `isAgentEnabled('native')` 恒 true,无视 `config.agents` 禁用开关。
|
|
635
|
-
- ACP 侧 SSRF 仅覆盖 Web test/discover API(该面默认被 `
|
|
670
|
+
- ACP 侧 SSRF 仅覆盖 Web test/discover API(该面默认被 `AGIM_ENABLE_REMOTE_AGENT` 关闭)。
|
|
636
671
|
|
|
637
672
|
## [1.2.144] - 2026-06-05
|
|
638
673
|
|
|
@@ -649,7 +684,7 @@ prompt,命中模式就走复盘卡)。
|
|
|
649
684
|
|
|
650
685
|
**修复**:新增 `isTrustedLoopbackPeer()` 三层检查:
|
|
651
686
|
1. `isLoopbackPeer(req)`(原有)
|
|
652
|
-
2. `
|
|
687
|
+
2. `AGIM_TRUST_LOOPBACK !== off`(新增 env kill switch)
|
|
653
688
|
3. **`!hasForwardedPeerHeaders(req)`** — 任一 `Forwarded` / `X-Forwarded-*`
|
|
654
689
|
/ `X-Real-IP` / `CF-Connecting-IP` header 出现 → 视为反代后流量,
|
|
655
690
|
走正常 token 路径
|
|
@@ -806,7 +841,7 @@ adapter.test.ts 已覆盖 commandName 通路。
|
|
|
806
841
|
正常收尾。请按三节给阶段性报告——已经做到/没做到/下一步建议。"
|
|
807
842
|
- **失败描述要求人话**:不能写 "`native_web_fetch` ×8 failed",要写
|
|
808
843
|
"新浪财经页面抓不到(疑似反爬)"。系统消息里 ban 掉 `native_xxx`
|
|
809
|
-
和 `
|
|
844
|
+
和 `mcp__agim__xxx` 字面字符串。
|
|
810
845
|
- **下一步软约束**:1-3 个具体可执行建议("继续 / 换数据源 / 缩小范
|
|
811
846
|
围 / 终止"),让模型自然挑词,不强制 a/b/c 选项格式。
|
|
812
847
|
- **off_track 模式**:critic 给的 reason / redirect 注入到 prompt 的
|
|
@@ -821,7 +856,7 @@ adapter.test.ts 已覆盖 commandName 通路。
|
|
|
821
856
|
- 把 `result.toolCalls.slice(-20)` 分成 success / failed 两组分别喂
|
|
822
857
|
——成功的截 300 字预览,失败的截 200 字(错误一般短)
|
|
823
858
|
- 返回的 `costUsd` 累加到 turn 总 cost,audit row 跟着算对
|
|
824
|
-
- env `
|
|
859
|
+
- env `AGIM_NATIVE_STAGE_REPORT=off` 全局禁用,回退到老的纯技术
|
|
825
860
|
recap,调试用
|
|
826
861
|
|
|
827
862
|
#### 兼容性
|
|
@@ -843,7 +878,7 @@ adapter.test.ts 已覆盖 commandName 通路。
|
|
|
843
878
|
- off_track reason 注入到 user prompt
|
|
844
879
|
- provider 返回空 → null(caller 走老 recap)
|
|
845
880
|
- provider 抛错 → null(不外抛)
|
|
846
|
-
- `
|
|
881
|
+
- `AGIM_NATIVE_STAGE_REPORT=off` → 不调 provider,直接 null
|
|
847
882
|
|
|
848
883
|
### 文件
|
|
849
884
|
|
|
@@ -1000,16 +1035,16 @@ delegate 就绕过了。
|
|
|
1000
1035
|
——所有 adapter 都已经认识 AgentSendOpts.planMode(claude-code 翻
|
|
1001
1036
|
`--permission-mode plan`,opencode 走 `--agent plan`,native 进
|
|
1002
1037
|
policy gate 拦写工具)
|
|
1003
|
-
- `
|
|
1038
|
+
- `AgimDispatcherCtx` 加 `callerPlanMode?: boolean`
|
|
1004
1039
|
- native/index.ts 通过 `effectivePlanModeOn(planThreadKey)` 求值后
|
|
1005
|
-
注入
|
|
1040
|
+
注入 agimCtx
|
|
1006
1041
|
- 派发 call_agent 时(in-process self-spawn 和正式 A2A 两条路)都
|
|
1007
1042
|
把这个标志透传出去
|
|
1008
1043
|
|
|
1009
1044
|
**P1a — 子代理返回值整段塞回父上下文**(context bloat)
|
|
1010
1045
|
|
|
1011
1046
|
call_agent 返回的文本默认整段进父对话历史,链 2-3 个就把 native 的
|
|
1012
|
-
context 撑爆了。新增 `
|
|
1047
|
+
context 撑爆了。新增 `AGIM_NATIVE_CALL_AGENT_OUTPUT_MAX_CHARS`
|
|
1013
1048
|
(默认 8000):
|
|
1014
1049
|
|
|
1015
1050
|
- 超过阈值 → 70/30 截首尾 + 中间放截断标记
|
|
@@ -1041,9 +1076,9 @@ claude-code 子代理调起来时偶发 5xx / socket reset,整次 call_agent
|
|
|
1041
1076
|
### 文件
|
|
1042
1077
|
|
|
1043
1078
|
- `src/core/a2a.ts` — `CallAgentOpts.planMode` + 透传到 sendPrompt
|
|
1044
|
-
- `src/core/llm/
|
|
1079
|
+
- `src/core/llm/agim-dispatcher.ts` — `callerPlanMode` + output cap +
|
|
1045
1080
|
retry + history-aware cap_exceeded
|
|
1046
|
-
- `src/plugins/agents/native/index.ts` —
|
|
1081
|
+
- `src/plugins/agents/native/index.ts` — agimCtx 注入 callerPlanMode +
|
|
1047
1082
|
system prompt 加 "when to delegate" 段落
|
|
1048
1083
|
|
|
1049
1084
|
### 不在范围
|
|
@@ -1066,8 +1101,8 @@ v1.2.123 的 graceful-degradation 只处理"有 partial 文本"的场景,零
|
|
|
1066
1101
|
#### 实现
|
|
1067
1102
|
在 `agent-loop.ts` streamThenBuffer 调用点加重试逻辑:
|
|
1068
1103
|
- **触发**:抛错 + isAbort(err)=false + isTransientStreamError(err)=true
|
|
1069
|
-
- **退避**:固定 1s(
|
|
1070
|
-
- **次数**:默认 1 次(
|
|
1104
|
+
- **退避**:固定 1s(AGIM_NATIVE_FIRSTTOKEN_RETRY_DELAY_MS 可调,cap 10s)
|
|
1105
|
+
- **次数**:默认 1 次(AGIM_NATIVE_FIRSTTOKEN_RETRY_MAX 可调,cap 3)
|
|
1071
1106
|
- **退出**:成功立刻退;超 cap 抛最后一次的错
|
|
1072
1107
|
|
|
1073
1108
|
#### 模式识别
|
|
@@ -1136,7 +1171,7 @@ v1.2.123 的 graceful-degradation 只处理"有 partial 文本"的场景,零
|
|
|
1136
1171
|
Before calling any generic tool (web_fetch / web_search / native_exec /
|
|
1137
1172
|
shell-style commands), you MUST scan the skill list below. If any entry's
|
|
1138
1173
|
description matches the user's intent — even loosely — you MUST call
|
|
1139
|
-
|
|
1174
|
+
mcp__agim__read_skill('<name>') first to load that skill's body. Skill
|
|
1140
1175
|
bodies contain dedicated tools, endpoints, or queries that produce
|
|
1141
1176
|
higher-quality, structured results than free-text web pages for the
|
|
1142
1177
|
same intent. Falling back to the generic tool is only valid when:
|
|
@@ -1168,7 +1203,7 @@ prompt 和 dispatcher 里写两次。Prompt 约束是软约束,硬约束应留
|
|
|
1168
1203
|
|
|
1169
1204
|
两项实战反馈一起打:
|
|
1170
1205
|
|
|
1171
|
-
#### 1. `
|
|
1206
|
+
#### 1. `AGIM_NATIVE_AGENT_MAX_ITER` 默认 20 → 50
|
|
1172
1207
|
真实使用观察:CR / 多步重构等任务常需 28-35 次迭代,20 把它们切掉。
|
|
1173
1208
|
50 给充足缓冲;30 分钟 IM 硬超时仍是更早的天花板(按 20-30s / iter
|
|
1174
1209
|
算,撞天花板大约 60-80 次),v1.2.122 语义死循环检测也会在 50 之前
|
|
@@ -1178,8 +1213,8 @@ agent` 调到 100。
|
|
|
1178
1213
|
#### 2. 移除 `先看看` 关键词
|
|
1179
1214
|
v1.2.135 P3 的默认 phrase 列表里有「先看看」,但 CR 指出这条过宽 ——
|
|
1180
1215
|
「先看看这个文件」明显是要读文件,不是 plan-only 意图。如果开启了
|
|
1181
|
-
`
|
|
1182
|
-
列表删除;操作员真需要可通过 `
|
|
1216
|
+
`AGIM_PLAN_INTENT_AUTO`,会把常规读操作误判进 plan 模式。从默认
|
|
1217
|
+
列表删除;操作员真需要可通过 `AGIM_PLAN_INTENT_PHRASES` 自行加
|
|
1183
1218
|
回(v1.2.135 的覆盖机制)。
|
|
1184
1219
|
|
|
1185
1220
|
### 文件
|
|
@@ -1200,7 +1235,7 @@ v1.2.135 P3 的默认 phrase 列表里有「先看看」,但 CR 指出这条
|
|
|
1200
1235
|
- `detectPlanIntent(text)` —— 子串匹配 + 大小写不敏感 + 中英文 26 个内置短语
|
|
1201
1236
|
- 中文:"先想想 / 先规划 / 先讨论 / 不要直接做 / 只规划 / 先别动手" 等
|
|
1202
1237
|
- 英文:"plan only / don't act yet / let's plan / research first / dry run only" 等
|
|
1203
|
-
- `
|
|
1238
|
+
- `AGIM_PLAN_INTENT_PHRASES` env 可整体覆盖(逗号分隔),不是合并;
|
|
1204
1239
|
让操作员能收紧或放宽匹配范围而不改代码
|
|
1205
1240
|
- `shouldAutoEnterPlanMode(prompt)` —— 综合判断:master switch on + 命中
|
|
1206
1241
|
→ 返回命中的短语;否则 null
|
|
@@ -1209,7 +1244,7 @@ v1.2.135 P3 的默认 phrase 列表里有「先看看」,但 CR 指出这条
|
|
|
1209
1244
|
`router.ts:callAgentWithHistory` 在确定 `effectivePlanMode` 后立刻做一次
|
|
1210
1245
|
启发式检查:
|
|
1211
1246
|
```
|
|
1212
|
-
if (planMode OFF +
|
|
1247
|
+
if (planMode OFF + AGIM_PLAN_INTENT_AUTO=on + intent matched) {
|
|
1213
1248
|
effectivePlanMode = true
|
|
1214
1249
|
log({ event: 'plan-intent.auto-enter', matchedPhrase })
|
|
1215
1250
|
}
|
|
@@ -1218,7 +1253,7 @@ if (planMode OFF + IMHUB_PLAN_INTENT_AUTO=on + intent matched) {
|
|
|
1218
1253
|
下一条消息不带这些关键词时自动回到 normal —— 这就是"临时"的语义。
|
|
1219
1254
|
|
|
1220
1255
|
#### 关键设计决策
|
|
1221
|
-
- **默认 OFF**:opt-in,env `
|
|
1256
|
+
- **默认 OFF**:opt-in,env `AGIM_PLAN_INTENT_AUTO=on` 才启用
|
|
1222
1257
|
- **绝不自动退出**:一旦进了 plan mode,要么用户 `/plan off`,要么模型
|
|
1223
1258
|
调 `native_exit_plan_mode`(v1.2.131 的握手)
|
|
1224
1259
|
- **错检 vs 漏检**:错检(用户想动手→被卡到 plan)代价远高于漏检(不
|
|
@@ -1228,8 +1263,8 @@ if (planMode OFF + IMHUB_PLAN_INTENT_AUTO=on + intent matched) {
|
|
|
1228
1263
|
|
|
1229
1264
|
#### 后台 UI
|
|
1230
1265
|
`/settings/native-agent` 早停+复盘卡内新增两项:
|
|
1231
|
-
- `Plan-intent auto-enter` bool toggle → `
|
|
1232
|
-
- `Plan-intent phrase list (optional override)` text → `
|
|
1266
|
+
- `Plan-intent auto-enter` bool toggle → `AGIM_PLAN_INTENT_AUTO`
|
|
1267
|
+
- `Plan-intent phrase list (optional override)` text → `AGIM_PLAN_INTENT_PHRASES`
|
|
1233
1268
|
(开关关闭时输入框 disabled)
|
|
1234
1269
|
|
|
1235
1270
|
env 白名单 (`ENV_EDITABLE_KEYS`) 同步扩展两个键。
|
|
@@ -1425,13 +1460,13 @@ P1 推到 v1.2.133。
|
|
|
1425
1460
|
- 拒绝场景下模型会自动迭代再次调用 `native_exit_plan_mode`
|
|
1426
1461
|
|
|
1427
1462
|
#### 新增 plan_history 审计表
|
|
1428
|
-
- `~/.agim/plan-history.db`(路径可由 `
|
|
1463
|
+
- `~/.agim/plan-history.db`(路径可由 `AGIM_PLAN_HISTORY_DB` 覆盖)
|
|
1429
1464
|
- 每次握手写一条不可变记录:thread_key / plan_md / outcome (approved|rejected|edited|expired)
|
|
1430
1465
|
/ detail / pending_ms / resolved_at
|
|
1431
1466
|
- 为后续 v1.2.133 的 `/tasks/plans` admin 列表查询打底(本版不做 UI)
|
|
1432
1467
|
|
|
1433
1468
|
#### system prompt 改造
|
|
1434
|
-
plan mode banner 之前结尾写"操作员清掉
|
|
1469
|
+
plan mode banner 之前结尾写"操作员清掉 AGIM_NATIVE_PLAN_MODE 你才能动手"。
|
|
1435
1470
|
现在改为:
|
|
1436
1471
|
|
|
1437
1472
|
> Exit handshake (v1.2.131): when the plan is ready, call
|
|
@@ -1601,26 +1636,26 @@ v1.2.126 把搜索 provider + 4 个运行上限接进 web admin,本版把 v1.2
|
|
|
1601
1636
|
#### 新增 4 张卡
|
|
1602
1637
|
|
|
1603
1638
|
**A. A2A 子 Agent 派生**
|
|
1604
|
-
- `
|
|
1605
|
-
- `
|
|
1606
|
-
- `
|
|
1607
|
-
- `
|
|
1639
|
+
- `AGIM_A2A_MAX_DEPTH` — 子 Agent 递归深度(默认 1,v1.2.119)
|
|
1640
|
+
- `AGIM_A2A_TIMEOUT_DEFAULT_MS` — 默认超时(默认 30 分钟)
|
|
1641
|
+
- `AGIM_NATIVE_CALL_AGENT_IN_PROCESS` — native→native 同进程 spawn 开关(默认开,v1.2.121)
|
|
1642
|
+
- `AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN` — 单轮 call_agent 调用上限(默认 2)
|
|
1608
1643
|
|
|
1609
1644
|
**B. 早停 + 复盘**
|
|
1610
|
-
- `
|
|
1611
|
-
- `
|
|
1612
|
-
- `
|
|
1613
|
-
- `
|
|
1645
|
+
- `AGIM_NATIVE_SEMANTIC_STUCK_LOOP` — 语义死循环检测开关(默认开,v1.2.122)
|
|
1646
|
+
- `AGIM_NATIVE_CRITIC` — Goal Critic 复盘开关(默认关)
|
|
1647
|
+
- `AGIM_NATIVE_CRITIC_ROLE` — Critic LLM role override(可选)
|
|
1648
|
+
- `AGIM_NATIVE_PLAN_MODE` — PlanMode 默认状态(不影响 /plan per-thread)
|
|
1614
1649
|
|
|
1615
1650
|
**C. Auto-compact**(v1.2.125 完成的 4 滑块)
|
|
1616
|
-
- `
|
|
1617
|
-
- `
|
|
1618
|
-
- `
|
|
1619
|
-
- `
|
|
1651
|
+
- `AGIM_NATIVE_COMPACT_TRIGGER_CHARS` — 触发阈值(默认 60000)
|
|
1652
|
+
- `AGIM_NATIVE_COMPACT_KEEP_TURNS` — tail 保留 user/assistant 对数(默认 6)
|
|
1653
|
+
- `AGIM_NATIVE_COMPACT_KEEP_FIRST` — head 保留前 N 条 user 消息(默认 1)
|
|
1654
|
+
- `AGIM_NATIVE_COMPACT_SUMMARY_CHARS` — 摘要字符上限(默认 1500)
|
|
1620
1655
|
|
|
1621
1656
|
**D. 流式 + 迭代**
|
|
1622
|
-
- `
|
|
1623
|
-
- `
|
|
1657
|
+
- `AGIM_NATIVE_STREAM_PARTIAL` — 流式增量回写(默认开,v1.2.112/123)
|
|
1658
|
+
- `AGIM_NATIVE_AGENT_MAX_ITER` — 工具循环上限(默认 20,clamp [1,100])
|
|
1624
1659
|
|
|
1625
1660
|
#### 默认值对齐
|
|
1626
1661
|
所有 boolean 类型的默认开关都按 source 行为镜像(v1.2.119/121/122 的 enable-by-default
|
|
@@ -1644,7 +1679,7 @@ v1.2.126 把搜索 provider + 4 个运行上限接进 web admin,本版把 v1.2
|
|
|
1644
1679
|
#### 安全
|
|
1645
1680
|
- 全部走 `requireAdmin()` + `ENV_EDITABLE_KEYS` 白名单
|
|
1646
1681
|
- 不动 SSRF / FS / bwrap 沙箱键(这些已经在 `/settings/security` 与 `/settings/policy`)
|
|
1647
|
-
- 不动 `
|
|
1682
|
+
- 不动 `AGIM_NATIVE_AGENT_ROLE_FILE`(绝对路径敏感,留 env file 配置)
|
|
1648
1683
|
|
|
1649
1684
|
### 文件
|
|
1650
1685
|
- 新增 `test/unit/admin-env-allowed-keys.test.ts` (~95 lines)
|
|
@@ -1663,7 +1698,7 @@ v1.2.126 把搜索 provider + 4 个运行上限接进 web admin,本版把 v1.2
|
|
|
1663
1698
|
#### 新增 `/settings/search` 页面
|
|
1664
1699
|
- 列出 6 个已注册 web_search provider:tavily / brave / serper / exa / duckduckgo / metaso
|
|
1665
1700
|
- 每行包含:
|
|
1666
|
-
- **启用复选框** + **上移/下移按钮** → 编辑 `
|
|
1701
|
+
- **启用复选框** + **上移/下移按钮** → 编辑 `AGIM_WEB_SEARCH_PROVIDERS` CSV 链
|
|
1667
1702
|
- **API key 输入框**(密文输入;已配置时占位符为"已保存(隐藏)",可清空)
|
|
1668
1703
|
- **状态徽章**:configured / missing key / no key needed
|
|
1669
1704
|
- **测试按钮**:一次性发"agim ping"探针,返回 `{ ok, latencyMs, hits }`
|
|
@@ -1671,10 +1706,10 @@ v1.2.126 把搜索 provider + 4 个运行上限接进 web admin,本版把 v1.2
|
|
|
1671
1706
|
|
|
1672
1707
|
#### `/settings/native-agent` 页面新增 Runtime caps 卡片
|
|
1673
1708
|
覆盖 v1.2.118-119 的 4 个运行上限:
|
|
1674
|
-
- `
|
|
1675
|
-
- `
|
|
1676
|
-
- `
|
|
1677
|
-
- `
|
|
1709
|
+
- `AGIM_NATIVE_TOOL_RESULT_MAX_CHARS` — 单次工具返回字符上限
|
|
1710
|
+
- `AGIM_NATIVE_TOOL_TIMEOUT_MS` — 单次工具超时
|
|
1711
|
+
- `AGIM_NATIVE_BLANK_RETRY_MAX` — 空响应重试次数
|
|
1712
|
+
- `AGIM_NATIVE_LENGTH_RECOVERY_MAX` — finishReason=length 续写次数
|
|
1678
1713
|
|
|
1679
1714
|
留空则用默认值;编辑后 Save,下一次调用立即生效。
|
|
1680
1715
|
|
|
@@ -1684,7 +1719,7 @@ v1.2.126 把搜索 provider + 4 个运行上限接进 web admin,本版把 v1.2
|
|
|
1684
1719
|
- `server.ts` 新增两个端点:
|
|
1685
1720
|
- `GET /api/search/providers` — 列出 6 个 provider + 当前 chain
|
|
1686
1721
|
- `POST /api/search/test` — 单次探针,10 秒硬超时
|
|
1687
|
-
- `ENV_EDITABLE_KEYS` 扩展:新增 5 个 `*_API_KEY` + 4 个 `
|
|
1722
|
+
- `ENV_EDITABLE_KEYS` 扩展:新增 5 个 `*_API_KEY` + 4 个 `AGIM_NATIVE_*` 上限键
|
|
1688
1723
|
- `SECRET_KEYS` 扩展:5 个 search API key 全部加入掩码白名单
|
|
1689
1724
|
|
|
1690
1725
|
#### 热生效保证
|
|
@@ -1723,7 +1758,7 @@ v1.2.126 把搜索 provider + 4 个运行上限接进 web admin,本版把 v1.2
|
|
|
1723
1758
|
用户最初要做什么"
|
|
1724
1759
|
|
|
1725
1760
|
#### v1.2.125 修法
|
|
1726
|
-
- 新选项 `keepFirst`(env `
|
|
1761
|
+
- 新选项 `keepFirst`(env `AGIM_NATIVE_COMPACT_KEEP_FIRST`,默认 **1**):
|
|
1727
1762
|
保留前 N 个 user 消息**连同**它们的 assistant 回复 + tool 链 verbatim
|
|
1728
1763
|
- 新 helper `pickHeadEndIndex(messages, N)`:往前走到第 N 个 user,再吃完它之后
|
|
1729
1764
|
所有非-user 消息(assistant + tool),保证 head 是个完整的回合,不会留 orphan
|
|
@@ -1802,8 +1837,8 @@ native agent 现在有一把 in-process 的 plan-tracker 工具:
|
|
|
1802
1837
|
|
|
1803
1838
|
- `src/core/llm/todo-dispatcher.ts`(新 ~165 行)
|
|
1804
1839
|
- `src/plugins/agents/native/index.ts`:import + 加入 dispatcher chain
|
|
1805
|
-
(在
|
|
1806
|
-
加 Plan tracking 段落;planThreadKey 计算上移到
|
|
1840
|
+
(在 agim 之前);defaultBuiltins 加 `native_todo_write`;buildSystemPrompt
|
|
1841
|
+
加 Plan tracking 段落;planThreadKey 计算上移到 agimCtx 之前
|
|
1807
1842
|
- `test/unit/todo-dispatcher.test.ts`(新 / 12 case):write / 渲染 / per-thread
|
|
1808
1843
|
隔离 / 验证 / unknown 工具回退
|
|
1809
1844
|
|
|
@@ -1880,7 +1915,7 @@ tool name 不同所以不 fire,agent 会一直耗到 max_iter。
|
|
|
1880
1915
|
- ≥2 个不同 tool name 才触发,避免与 strict `isStuckLoop` 重叠
|
|
1881
1916
|
- 触发后走 `finishReason='stuck_loop'` 早停(与现有 stuck_loop 路径一致)
|
|
1882
1917
|
- 新 log event `agent-loop.semantic_stuck_loop_detected` 便于排查
|
|
1883
|
-
- `
|
|
1918
|
+
- `AGIM_NATIVE_SEMANTIC_STUCK_LOOP=off` 是 kill switch
|
|
1884
1919
|
|
|
1885
1920
|
### Affected paths
|
|
1886
1921
|
|
|
@@ -1914,8 +1949,8 @@ tool name 不同所以不 fire,agent 会一直耗到 max_iter。
|
|
|
1914
1949
|
本版加入 in-process fast path:
|
|
1915
1950
|
- 当 target=='native' → 跳过 subprocess,直接在同 JS 堆里 `nativeAgentAdapter.sendPrompt()`
|
|
1916
1951
|
- 共享 cwd / MCP fleet / 同一 LLM 后端,但开**全新 session id** 避免污染父对话
|
|
1917
|
-
- 仍按 `
|
|
1918
|
-
- `
|
|
1952
|
+
- 仍按 `AGIM_A2A_MAX_DEPTH`(默认 1)做深度检查 + 走 callerDepth+1 入子层
|
|
1953
|
+
- `AGIM_NATIVE_CALL_AGENT_IN_PROCESS=off` 是 kill switch(强制走 subprocess 老路)
|
|
1919
1954
|
- 子层若再 call_agent 会被 depth 拦下,避免无限递归
|
|
1920
1955
|
- 完整 trace 链:parent traceId → `a2a-{call.id}` → child native loop 内每个 tool
|
|
1921
1956
|
|
|
@@ -1925,18 +1960,18 @@ tool name 不同所以不 fire,agent 会一直耗到 max_iter。
|
|
|
1925
1960
|
- **Serper** (`SERPER_API_KEY`):Google SERP 中继,cheap
|
|
1926
1961
|
- **Exa** (`EXA_API_KEY`):语义/向量搜索,适合"找类似页"
|
|
1927
1962
|
- 新默认链:`tavily,brave,serper,exa,duckduckgo,metaso`
|
|
1928
|
-
- 缺 key 仍然静默跳过,env override `
|
|
1963
|
+
- 缺 key 仍然静默跳过,env override `AGIM_WEB_SEARCH_PROVIDERS` 不变
|
|
1929
1964
|
|
|
1930
1965
|
### Affected paths
|
|
1931
1966
|
|
|
1932
1967
|
- `src/core/llm/web-dispatcher.ts`:新增 `searchBrave/parseBraveResults` /
|
|
1933
1968
|
`searchSerper/parseSerperResults` / `searchExa/parseExaResults` + 注册到
|
|
1934
1969
|
`PROVIDERS`;默认 chain 更新;工具描述更新
|
|
1935
|
-
- `src/core/llm/
|
|
1970
|
+
- `src/core/llm/agim-dispatcher.ts`:`isInProcessSpawnDisabled` helper +
|
|
1936
1971
|
call_agent 分支检测 `agentName === 'native'` → in-process fast path
|
|
1937
1972
|
- `test/unit/web-search-providers.test.ts`:新增 3 个 parse 测试 + 1 个默认
|
|
1938
1973
|
chain 顺序测试 + 1 个三 provider 同时启用测试
|
|
1939
|
-
- `src/core/llm/
|
|
1974
|
+
- `src/core/llm/agim-dispatcher.test.ts`:新增 4 个 case(depth 拒绝 / A2A
|
|
1940
1975
|
disabled / 非 native 不走 in-process / kill switch 强制 subprocess)
|
|
1941
1976
|
|
|
1942
1977
|
### Test status
|
|
@@ -1960,11 +1995,11 @@ tool name 不同所以不 fire,agent 会一直耗到 max_iter。
|
|
|
1960
1995
|
|
|
1961
1996
|
- 新增 `src/core/plan-mode-state.ts`:sqlite 表 `native_plan_mode(thread_key PK,
|
|
1962
1997
|
enabled, updated_at)`,per-thread 持久化覆盖;DB 默认 `~/.agim/plan-mode.db`,
|
|
1963
|
-
env `
|
|
1998
|
+
env `AGIM_PLAN_MODE_DB` 可指定路径
|
|
1964
1999
|
- 三态优先级 `effectivePlanModeOn(threadKey)`:
|
|
1965
2000
|
1. per-thread = **true** → on(即使 env=off)
|
|
1966
2001
|
2. per-thread = **false** → off(即使 env=on——一个线程可单独 opt-out)
|
|
1967
|
-
3. per-thread = null(未设置)→ 回退到 env `
|
|
2002
|
+
3. per-thread = null(未设置)→ 回退到 env `AGIM_NATIVE_PLAN_MODE`
|
|
1968
2003
|
- `/plan on|off` 现在**同时**写 sessionManager.planMode(claude-code / codex /
|
|
1969
2004
|
opencode 用)和 plan-mode-state.db(native 用),native 加入 PLAN_CAPABLE_AGENTS
|
|
1970
2005
|
集合,提示文案里移除"native 不读 planMode"的警告
|
|
@@ -2008,16 +2043,16 @@ tool name 不同所以不 fire,agent 会一直耗到 max_iter。
|
|
|
2008
2043
|
- `src/core/a2a.ts:A2A_MAX_DEPTH_DEFAULT` 从 3 改为 1,对齐 OpenAI Codex CLI 的
|
|
2009
2044
|
`agents.max_depth=1` 默认。理由:链式委派(A 调 B 调 C …)几乎都是 LLM 失策,
|
|
2010
2045
|
外层应该用自己的工具收尾,而不是再委派。**Breaking-ish**:依赖 max_depth=3 的
|
|
2011
|
-
环境 `export
|
|
2012
|
-
- 配套:`callerDepth` 传播链路(
|
|
2046
|
+
环境 `export AGIM_A2A_MAX_DEPTH=3` 恢复。
|
|
2047
|
+
- 配套:`callerDepth` 传播链路(agim-dispatcher → callAgentByName → 检查 ceil)
|
|
2013
2048
|
本来就在,所以这一项**主要是默认值收紧**,逻辑没大动
|
|
2014
2049
|
|
|
2015
|
-
#### Item 5 — PlanMode(`
|
|
2050
|
+
#### Item 5 — PlanMode(`AGIM_NATIVE_PLAN_MODE=1`)
|
|
2016
2051
|
- 对齐 opencode plan-mode UX:env-toggled hard-deny `native_write_file` +
|
|
2017
2052
|
`native_exec`。读工具(Read/Grep/Glob/web_fetch/web_search)保持可用,agent
|
|
2018
2053
|
只能产出**只读规划**
|
|
2019
2054
|
- 实现:`resolvePolicy()` 在 PlanMode on 时把上述写工具追加到 denyList(与用户的
|
|
2020
|
-
`
|
|
2055
|
+
`AGIM_NATIVE_AGENT_DENYLIST` 合并去重)
|
|
2021
2056
|
- 加上系统 prompt 顶部的 `⚠ Plan mode is ACTIVE` 横幅,明确告诉模型现在不能落地,
|
|
2022
2057
|
让它产出 plan 后停手而不是反复试探被 deny
|
|
2023
2058
|
|
|
@@ -2028,7 +2063,7 @@ tool name 不同所以不 fire,agent 会一直耗到 max_iter。
|
|
|
2028
2063
|
final answer`",最多重试 2 次
|
|
2029
2064
|
- 与 length-recovery 互不冲突:`finishReason=length` 优先走截断续写,因为它有
|
|
2030
2065
|
partial text;blank-retry 处理的是真正"啥也没说"的失态
|
|
2031
|
-
- `
|
|
2066
|
+
- `AGIM_NATIVE_BLANK_RETRY_MAX` 控制,默认 2,最大 5,0=禁用
|
|
2032
2067
|
|
|
2033
2068
|
### Affected paths
|
|
2034
2069
|
|
|
@@ -2039,7 +2074,7 @@ tool name 不同所以不 fire,agent 会一直耗到 max_iter。
|
|
|
2039
2074
|
`resolvePolicy` 加 PlanMode 合并;`buildSystemPrompt` 加 PlanMode 横幅;export
|
|
2040
2075
|
这三个供测试
|
|
2041
2076
|
- `src/plugins/agents/native/native.test.ts`:在 clearAll 中显式
|
|
2042
|
-
`
|
|
2077
|
+
`AGIM_NATIVE_BLANK_RETRY_MAX=0` 让 legacy adapter 测试不受 blank-retry 影响
|
|
2043
2078
|
- `test/unit/agent-loop-blank-retry.test.ts`(新,5 case):one-shot recover /
|
|
2044
2079
|
cap=2 / cap=0 disable / tool_calls 不触发 / length 优先
|
|
2045
2080
|
- `src/plugins/agents/native/plan-mode.test.ts`(新,14 case):env 解析各形态 +
|
|
@@ -2071,20 +2106,20 @@ sst/opencode / Cursor / Continue.dev),按 ROI 排序产出 12 项改进路
|
|
|
2071
2106
|
- 新增 `SearchProvider` 接口(`name` / `available()` / `search()`)
|
|
2072
2107
|
- 内置 3 个 provider:**Tavily**(新增;行业默认 agent 搜索,`TAVILY_API_KEY`) /
|
|
2073
2108
|
DuckDuckGo(无 key) / Metaso(`METASO_API_KEY`)
|
|
2074
|
-
- 通过 `
|
|
2109
|
+
- 通过 `AGIM_WEB_SEARCH_PROVIDERS` 环境变量定义有序链
|
|
2075
2110
|
(默认 `tavily,duckduckgo,metaso`),首个返回 ≥1 结果的胜出
|
|
2076
2111
|
- 缺 key 的 provider **静默跳过**(不刷日志);未知 provider 名 warn 一次后跳过
|
|
2077
2112
|
- 添加 Tavily provider 后只需 `export TAVILY_API_KEY=tvly-...` 即可启用
|
|
2078
2113
|
|
|
2079
2114
|
#### Item 2 — per-tool-result 字节上限
|
|
2080
2115
|
- `src/core/llm/agent-loop.ts` 在 dispatch 包装层加 `truncateToolResult()`:
|
|
2081
|
-
- 默认 32 KB 上限(`
|
|
2116
|
+
- 默认 32 KB 上限(`AGIM_NATIVE_TOOL_RESULT_MAX_CHARS`),0 = 禁用
|
|
2082
2117
|
- 超限文本带明确截断标记返回模型:`…[native_grep output truncated: 5000000 of 5032768 chars omitted]`
|
|
2083
2118
|
- 防止一条 grep / curl 把 context 喂爆,比 auto-compact 触发更早更安全
|
|
2084
2119
|
|
|
2085
2120
|
#### Item 3 — per-tool 钟摆超时
|
|
2086
2121
|
- `ToolDef` 新增 `timeoutMs?: number` 字段;新 `dispatchWithTimeout()` helper:
|
|
2087
|
-
- 默认 60 秒(`
|
|
2122
|
+
- 默认 60 秒(`AGIM_NATIVE_TOOL_TIMEOUT_MS`),0 = 关闭该工具的超时(如 `long_task`)
|
|
2088
2123
|
- 超时后**返回结构化 timeout 工具结果**(不是抛异常),模型看到 tool-level 失败
|
|
2089
2124
|
- 同步 abort 子调用的 signal,防 wedge
|
|
2090
2125
|
|
|
@@ -2124,7 +2159,7 @@ sst/opencode / Cursor / Continue.dev),按 ROI 排序产出 12 项改进路
|
|
|
2124
2159
|
任何 partial tool_calls(避免 obot 文档化的"$0.91 烧在 6 次连续 length retry
|
|
2125
2160
|
执行截断 JSON 上"灾难),注入合成 user 消息:`Your previous response was cut
|
|
2126
2161
|
off … Continue from exactly where you left off — do not repeat any content`
|
|
2127
|
-
- **per-turn 计数器 cap=3**:与 HKUDS/nanobot 一致;env `
|
|
2162
|
+
- **per-turn 计数器 cap=3**:与 HKUDS/nanobot 一致;env `AGIM_NATIVE_LENGTH_
|
|
2128
2163
|
RECOVERY_MAX` 可调(0 = 完全关闭走老逻辑,最大 10)
|
|
2129
2164
|
- **partial text 累积返回**:新增 `lengthRecoveryPrefix` 串,所有终止路径
|
|
2130
2165
|
(aborted / error / stuck_loop / off_track / max_iterations / 早 terminate)
|
|
@@ -2315,8 +2350,8 @@ sst/opencode / Cursor / Continue.dev),按 ROI 排序产出 12 项改进路
|
|
|
2315
2350
|
- `AgentLoopInput` 新增两字段:`streamPartialText?: boolean`(caller 显式
|
|
2316
2351
|
opt-in;默认 false 保持 v1.2.111 行为不变)+ `onPartialText?: (delta,
|
|
2317
2352
|
totalSoFar) => void`(流式回调,将来可挂 IM 端 SSE 推送)。
|
|
2318
|
-
- **native 默认开启**:`
|
|
2319
|
-
全局 `
|
|
2353
|
+
- **native 默认开启**:`AGIM_NATIVE_STREAM_PARTIAL`(默认 'on';'off' 关闭)+
|
|
2354
|
+
全局 `AGIM_AGENT_LOOP_STREAM`(默认 'on';'off' 强制 buffer)双重 kill
|
|
2320
2355
|
switch,万一某 vendor 流式不稳可立即降级。
|
|
2321
2356
|
|
|
2322
2357
|
### Tests
|
|
@@ -2340,7 +2375,7 @@ v1.2.112(③)。下一步是真实使用观察 + 长尾红测试修复。
|
|
|
2340
2375
|
- **每个工具调用单独落 audit 行 + traceId 跨 A2A 贯通。** 之前 agent-loop 只在
|
|
2341
2376
|
iteration 层落一行 (`intent='native.agent.iter'`),单工具调用只在内存里;事后
|
|
2342
2377
|
无法在 audit 表按 traceId 拼出"一个 turn 里跑了哪些工具/sub-agent / 在哪一步
|
|
2343
|
-
失败"。同时
|
|
2378
|
+
失败"。同时 agim-dispatcher 调 A2A 时自造 `native-a2a-${Date.now()}`,把 turn
|
|
2344
2379
|
的 traceId 链断了。本版:
|
|
2345
2380
|
- agent-loop 在 slot 提交时调用新的 `writeToolCallAudit(audit, report)`,每个
|
|
2346
2381
|
tool call 一行 `intent='tool.<name>'`,traceId = 父 traceId,agent = 父
|
|
@@ -2348,7 +2383,7 @@ v1.2.112(③)。下一步是真实使用观察 + 长尾红测试修复。
|
|
|
2348
2383
|
`success = !isError`。deny / schema-validation 失败 / 真正派发都会落行。
|
|
2349
2384
|
- `ToolDispatcher` 类型新增可选第三参 `ctx?: ToolDispatcherContext { traceId? }`。
|
|
2350
2385
|
agent-loop 调 dispatch 时把 `input.audit?.traceId` 透传;`combineDispatchers`
|
|
2351
|
-
转发;
|
|
2386
|
+
转发;agim-dispatcher A2A 路径读 ctx.traceId 构造 `${parent}/a2a-${call.id}`
|
|
2352
2387
|
作为子 trace(无父则回退老格式,向后兼容)。其他 dispatcher 因为参数可选
|
|
2353
2388
|
完全不感知,0 改动。
|
|
2354
2389
|
- `queryInvocations` 新增 `traceId` / `tracePrefix` 过滤参数,按 trace 反查
|
|
@@ -2378,7 +2413,7 @@ v1.2.112(③)。下一步是真实使用观察 + 长尾红测试修复。
|
|
|
2378
2413
|
`required`/`enum`/`additionalProperties:false`/对象一层嵌套/数组 `items`。复杂
|
|
2379
2414
|
schema($ref/oneOf/format/数值约束)静默通过——失败开 footgun 比假阳性危险。
|
|
2380
2415
|
对 agim 现有 tool 的扁平 object schema 足够。
|
|
2381
|
-
- **Env 关阀**:`
|
|
2416
|
+
- **Env 关阀**:`AGIM_TOOL_SCHEMA_VALIDATE=off` 关闭校验,回退到 v1.2.109 行为,
|
|
2382
2417
|
万一某 vendor schema 触发误报有快速逃生路径。
|
|
2383
2418
|
|
|
2384
2419
|
### Tests
|
|
@@ -2407,7 +2442,7 @@ v1.2.112(③)。下一步是真实使用观察 + 长尾红测试修复。
|
|
|
2407
2442
|
- **native 内置声明的 parallel-safe 集合**(`NATIVE_PARALLEL_SAFE_TOOLS`):
|
|
2408
2443
|
`native_echo` / `native_now` / `native_random_uuid` / `native_read_file` /
|
|
2409
2444
|
`native_list_dir` / `native_glob` / `native_grep` / `native_web_fetch` /
|
|
2410
|
-
`native_web_search` / `
|
|
2445
|
+
`native_web_search` / `mcp__agim__{read_skill,list_skills,search_memos,
|
|
2411
2446
|
memory_list,memory_query}`。`native_exec` / `native_write_file` / 任何写类
|
|
2412
2447
|
memo / `push_message` / `ask_user` / `call_agent` / `long_task` /
|
|
2413
2448
|
`complete_goal` / 其他 MCP 均不在内(保持串行 + barrier)。
|
|
@@ -2427,7 +2462,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2427
2462
|
DeepSeek / Moonshot 等 OpenAI-compat 提供方返回 429 时把服务器要求的几秒等待
|
|
2428
2463
|
完全无视,250ms 后再撞墙、跳到 fallback provider,吃 cold-start + 模型语义切换。
|
|
2429
2464
|
现在默认 4 次尝试(base 250ms、cap 30s、jitter ±20%),`Retry-After` 作为硬下限
|
|
2430
|
-
(秒/HTTP-date 两种 RFC 7231 格式都支持)。`
|
|
2465
|
+
(秒/HTTP-date 两种 RFC 7231 格式都支持)。`AGIM_LLM_RETRY_MAX` 覆盖默认(clamp
|
|
2431
2466
|
[0,10])。导出 `parseRetryAfter` / `computeBackoffMs` 两个纯函数 + 13 个回归测试。
|
|
2432
2467
|
- **stuck-loop 早停升级为 `(name, argsKey, errorType)` 三元组。** v1.2.95 用的是
|
|
2433
2468
|
`(name, isError, preview[0..200])`:模型只要让结果文本带个时间戳/换行/计数器就
|
|
@@ -2439,7 +2474,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2439
2474
|
成功重置)。** v1.2.96 的 cachedTools 永不刷新——上游 MCP server 加新工具/改
|
|
2440
2475
|
schema 必须重启 agim 才看得见;重连冷却也是固定 5s,永远 broken 的 server 被
|
|
2441
2476
|
5s 一次永久敲。现在:`McpClient.cachedTools` 带 `fetchedAt`,
|
|
2442
|
-
`
|
|
2477
|
+
`AGIM_MCP_TOOLS_TTL_MS` 控制 TTL(0=不缓存),新增 `refresh()` 主动清缓存;
|
|
2443
2478
|
`mcp-registry.tryReconnect` 按 `state.reconnectFailures` 指数翻倍冷却,成功
|
|
2444
2479
|
立即 reset 为 0。导出 `computeReconnectCooldownMs` + 8 个回归测试。
|
|
2445
2480
|
|
|
@@ -2468,7 +2503,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2468
2503
|
`bunfig.toml` preload (stray `bun test <file>`, wrong cwd, a different
|
|
2469
2504
|
runner) leaves `AGIM_HOME` pointed at the real `~/.agim`, so
|
|
2470
2505
|
`admin-bootstrap.test.ts`'s `promoteAdmin('telegram','123')` →
|
|
2471
|
-
`updateEnvFile()` overwrites the operator's real `
|
|
2506
|
+
`updateEnvFile()` overwrites the operator's real `AGIM_ADMIN_USERS`,
|
|
2472
2507
|
locking them out of every admin command. The preload sandbox was the
|
|
2473
2508
|
only guard and is a single point of failure. Fix: a second,
|
|
2474
2509
|
preload-independent guard — `assertEnvWriteAllowed()` in
|
|
@@ -2550,7 +2585,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2550
2585
|
- **`/long_task` and `/complete_goal` slash commands.** Field observation
|
|
2551
2586
|
(the goal-critic recap card already hints at them, and users tried them
|
|
2552
2587
|
after off-track verdicts): both names existed only as MCP tools
|
|
2553
|
-
(`
|
|
2588
|
+
(`mcp__agim__long_task` / `mcp__agim__complete_goal`), so a human
|
|
2554
2589
|
typing `/long_task ship v1.2` in chat got back "Unknown command".
|
|
2555
2590
|
Added parser branches in `router.ts`:
|
|
2556
2591
|
- `/long_task <title>` → equivalent to `/goal set <title>`
|
|
@@ -2591,7 +2626,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2591
2626
|
### Fixed
|
|
2592
2627
|
|
|
2593
2628
|
- **bwrap sandbox: `/bin/sh` ENOENT, every `native_exec` failed.**
|
|
2594
|
-
Field report: with `
|
|
2629
|
+
Field report: with `AGIM_EXEC_SANDBOX=bwrap`, every command
|
|
2595
2630
|
the model tried to run came back as `ENOENT`. Root cause:
|
|
2596
2631
|
`buildBwrapInvocation` used `/bin/sh` as the shell, but on
|
|
2597
2632
|
usrmerge systems (modern Debian / Ubuntu / Fedora — most
|
|
@@ -2629,7 +2664,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2629
2664
|
story** (CR finding A2). v1.2.98 docs said the critic was off
|
|
2630
2665
|
by default for daily-driver turns; the code actually defaulted
|
|
2631
2666
|
on whenever the per-turn prompt was non-empty (which is
|
|
2632
|
-
always). `
|
|
2667
|
+
always). `AGIM_NATIVE_CRITIC` is now a three-valued knob:
|
|
2633
2668
|
- `off` (or `0` / `false`) — hard kill switch, never fire.
|
|
2634
2669
|
- `always` (or `on` / `1` / `true`) — fire whenever an
|
|
2635
2670
|
anchor exists; previous v1.2.98 default behaviour.
|
|
@@ -2668,7 +2703,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2668
2703
|
native renders a redirect recap citing the critic's reason
|
|
2669
2704
|
+ suggested new direction.
|
|
2670
2705
|
|
|
2671
|
-
Cost gate: disabled if `
|
|
2706
|
+
Cost gate: disabled if `AGIM_NATIVE_CRITIC=off`, if no
|
|
2672
2707
|
`cheap` role provider is configured, or if neither prompt nor
|
|
2673
2708
|
active goal is available as an anchor. Trigger only after 5+
|
|
2674
2709
|
tool calls so day-to-day short turns pay nothing. Diagnostic
|
|
@@ -2699,16 +2734,16 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2699
2734
|
- `core/llm/agim-rpc-server.ts` — Unix-socket HTTP server on
|
|
2700
2735
|
`AGIM_HOME/rpc.sock` (mode 0600, never bound to a TCP port).
|
|
2701
2736
|
Per-process token registry. Tool whitelist hard-coded to
|
|
2702
|
-
five read/write-safe
|
|
2737
|
+
five read/write-safe agim MCP tools: `search_memos`,
|
|
2703
2738
|
`save_memo`, `read_skill`, `list_skills`, `push_message`.
|
|
2704
|
-
Operators can extend via `
|
|
2705
|
-
Token TTL 24 h, configurable via `
|
|
2739
|
+
Operators can extend via `AGIM_RPC_ALLOWED_TOOLS`.
|
|
2740
|
+
Token TTL 24 h, configurable via `AGIM_RPC_TOKEN_TTL_MS`.
|
|
2706
2741
|
- `bin/agim_rpc.py` — stdlib-only Python sidecar shipped in
|
|
2707
2742
|
the npm package. `from agim_rpc import client; rpc =
|
|
2708
2743
|
client()` reads env + validates, then `rpc.search_memos(...)`
|
|
2709
2744
|
/ `rpc.push_message(...)` are typed wrappers.
|
|
2710
2745
|
- `exec-dispatcher`: every spawn under a known `rpcCtx` gets
|
|
2711
|
-
`
|
|
2746
|
+
`AGIM_RPC_SOCKET` + `AGIM_RPC_TOKEN` injected as env (not
|
|
2712
2747
|
argv — keeps the token out of `ps`). Token is bound to the
|
|
2713
2748
|
spawning thread; the worker can only drive its OWN IM
|
|
2714
2749
|
thread's tool surface, never anyone else's.
|
|
@@ -2746,7 +2781,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2746
2781
|
flagged `!isConnected()` before the call, or (b) `callTool`
|
|
2747
2782
|
itself throws — and runs `close() → connect() → retry once`.
|
|
2748
2783
|
Per-server cooldown (default 5 s, configurable via
|
|
2749
|
-
`
|
|
2784
|
+
`AGIM_MCP_RECONNECT_COOLDOWN_MS`) prevents hammering a
|
|
2750
2785
|
persistently-broken server. Diagnostic events:
|
|
2751
2786
|
`mcp-registry.reconnect_throttled / reconnected /
|
|
2752
2787
|
reconnect_failed / tool_call_threw`.
|
|
@@ -2757,7 +2792,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2757
2792
|
substantive turn for facts worth outliving the chat (personal
|
|
2758
2793
|
preferences, holdings / portfolio codes, recurring people /
|
|
2759
2794
|
places, stable identifiers, explicit "记一下" instructions) and
|
|
2760
|
-
call `
|
|
2795
|
+
call `mcp__agim__save_memo` itself without waiting for the
|
|
2761
2796
|
user to ask. Also tells it what NOT to save (one-off
|
|
2762
2797
|
questions, transient debug state) and to use small atomic
|
|
2763
2798
|
memos rather than one large one. Cost is just prompt bytes;
|
|
@@ -2840,7 +2875,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2840
2875
|
`bgjob status / tail` for follow-ups and explicitly forbids
|
|
2841
2876
|
`nohup … &` (those die with the parent shell).
|
|
2842
2877
|
- **bwrap sandbox carve-out for the bgjob wrapper.** When
|
|
2843
|
-
`
|
|
2878
|
+
`AGIM_EXEC_SANDBOX=bwrap`, bwrap's pid / cgroup namespace
|
|
2844
2879
|
used to tear down bgjob's `setsid`-detached worker the
|
|
2845
2880
|
moment `bgjob start` returned — so the model saw success
|
|
2846
2881
|
while the worker died a second later. `isBgjobInvocation`
|
|
@@ -2858,9 +2893,9 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2858
2893
|
|
|
2859
2894
|
### Fixed
|
|
2860
2895
|
|
|
2861
|
-
- **`
|
|
2896
|
+
- **`AGIM_NATIVE_AGENT_MAX_ITER` was dead documentation.** The
|
|
2862
2897
|
max-iterations banner had been telling operators to "raise
|
|
2863
|
-
|
|
2898
|
+
AGIM_NATIVE_AGENT_MAX_ITER" since v1.2.48, but no code path
|
|
2864
2899
|
ever read the env var — the agent loop quietly used the
|
|
2865
2900
|
hard-coded default of 20 regardless. `resolveMaxIterations()`
|
|
2866
2901
|
now reads the env (clamped to [1, 100]) and passes it to
|
|
@@ -2874,7 +2909,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2874
2909
|
last step's output, name the cause ("model wanted to keep going
|
|
2875
2910
|
but hit the safety cap at iteration N"), and offer three
|
|
2876
2911
|
continuation paths — reply 继续 to push forward, split the task
|
|
2877
|
-
into smaller pieces, or raise `
|
|
2912
|
+
into smaller pieces, or raise `AGIM_NATIVE_AGENT_MAX_ITER` to
|
|
2878
2913
|
2× current (capped at 100). Diagnostic
|
|
2879
2914
|
`native.turn.max_iterations` log added so the audit trail
|
|
2880
2915
|
records iterations / cap / last tool name.
|
|
@@ -2931,7 +2966,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
2931
2966
|
turn, and notes picture-count in the dispatched text so the
|
|
2932
2967
|
user knows to re-send images standalone for multimodal
|
|
2933
2968
|
parsing.
|
|
2934
|
-
- **`
|
|
2969
|
+
- **`mcp__agim__ask_user` typed replies were silently dropped.**
|
|
2935
2970
|
`ask-user-router.tryHandleAskReply` was defined and documented
|
|
2936
2971
|
to be called from `cli.ts` onMessage, but no caller existed —
|
|
2937
2972
|
the function was dead code. Result: when an agent invoked
|
|
@@ -3002,11 +3037,11 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3002
3037
|
- **Long-task: active goal exempts the wall-clock timeout.** Inspired
|
|
3003
3038
|
by nanobot's "an objective in flight is not a turn", agent-loop +
|
|
3004
3039
|
A2A now consult `hasActiveGoal(platform, channelId, threadId)` and
|
|
3005
|
-
multiply the base timeout by `
|
|
3040
|
+
multiply the base timeout by `AGIM_GOAL_ACTIVE_TIMEOUT_MULTIPLIER`
|
|
3006
3041
|
(default `3`, hard-capped at 6 h). The native 30-minute SIGTERM no
|
|
3007
3042
|
longer kills a "research-an-entire-day" objective mid-flight; once
|
|
3008
3043
|
the goal is `complete_goal`'d, the next turn's timeout falls back
|
|
3009
|
-
to the normal base. Opt-out: `
|
|
3044
|
+
to the normal base. Opt-out: `AGIM_GOAL_ACTIVE_TIMEOUT_MULTIPLIER=1`.
|
|
3010
3045
|
- **Event-bus emission for goal state changes.** New `GoalEvent` type
|
|
3011
3046
|
in `event-bus.ts` (`phase: created | status | progress`). `goal-rpc`
|
|
3012
3047
|
publishes on `long_task` (created + auto-paused prior), on
|
|
@@ -3199,7 +3234,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3199
3234
|
command; works regardless of input state. Up / Down + Enter to
|
|
3200
3235
|
pick, Esc to dismiss.
|
|
3201
3236
|
- **Completion bell**. After each agent reply ends successfully, write
|
|
3202
|
-
`\x07` to stdout. Disable with `
|
|
3237
|
+
`\x07` to stdout. Disable with `AGIM_TUI_NO_BELL=1`.
|
|
3203
3238
|
- **Markdown rendering** for assistant replies. New `Markdown` Ink
|
|
3204
3239
|
component walks `marked`'s lexer tokens to emit native Ink boxes:
|
|
3205
3240
|
headings (depth-coloured), paragraphs, bold / italic / strikethrough,
|
|
@@ -3264,7 +3299,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3264
3299
|
- `tsconfig.json`: `"jsx": "react-jsx"` for tsx files.
|
|
3265
3300
|
- Root logger is set to `silent` for the TUI session (and restored
|
|
3266
3301
|
on exit) so pino-pretty doesn't write to fd 1 and scramble Ink's
|
|
3267
|
-
diff renderer. `
|
|
3302
|
+
diff renderer. `AGIM_TUI_VERBOSE=1` keeps logs flowing (helpful
|
|
3268
3303
|
when stuck — pair with `2>tui.log`).
|
|
3269
3304
|
|
|
3270
3305
|
## [1.2.75] - 2026-05-26
|
|
@@ -3329,7 +3364,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3329
3364
|
|
|
3330
3365
|
### Removed
|
|
3331
3366
|
|
|
3332
|
-
- **Legacy v1 web admin: gone for good.** The `
|
|
3367
|
+
- **Legacy v1 web admin: gone for good.** The `AGIM_WEB_V2` env gate
|
|
3333
3368
|
is removed; v2 SPA is the only web admin path now. Multiple
|
|
3334
3369
|
operators kept hitting "white screen / wrong page" because the
|
|
3335
3370
|
default env (`unset`) was being misread on some installs, and the
|
|
@@ -3342,7 +3377,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3342
3377
|
- `src/web/public/_app.js` (248 lines — shared v1 theme / i18n /
|
|
3343
3378
|
auth-aware fetch; replaced by the v2 SPA's bundle)
|
|
3344
3379
|
- **Removed routes** in `web/server.ts`:
|
|
3345
|
-
- The `process.env.
|
|
3380
|
+
- The `process.env.AGIM_WEB_V2 !== '0'` env gate is gone — SPA
|
|
3346
3381
|
fallback is now unconditional for GET requests.
|
|
3347
3382
|
- The legacy `/settings` / `/tasks` / `/reminders` / `/memos`
|
|
3348
3383
|
direct-HTML routing block deleted.
|
|
@@ -3351,13 +3386,13 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3351
3386
|
- **No back-out hatch.** Operators who were on v1 (last shipped
|
|
3352
3387
|
default-ON 1.2.20 → flipped default-v2 1.2.21, knob preserved until
|
|
3353
3388
|
1.2.71) flipped over automatically when they upgraded. Anyone who
|
|
3354
|
-
still set `
|
|
3389
|
+
still set `AGIM_WEB_V2=0` in `~/.agim/env` can safely delete the
|
|
3355
3390
|
line — the value is ignored.
|
|
3356
3391
|
|
|
3357
3392
|
### Notes
|
|
3358
3393
|
|
|
3359
|
-
- `
|
|
3360
|
-
`
|
|
3394
|
+
- `AGIM_ENABLE_GLOBAL_IM` / `AGIM_ENABLE_REMOTE_AGENT` /
|
|
3395
|
+
`AGIM_PLATFORM_BLACKLIST` etc. are unaffected — those gate IM
|
|
3361
3396
|
platform visibility inside the SPA, not the SPA itself.
|
|
3362
3397
|
- `/loc` / `/loc.html` SSR pages and `/login.html` stay (they're not
|
|
3363
3398
|
part of the SPA).
|
|
@@ -3366,12 +3401,12 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3366
3401
|
|
|
3367
3402
|
### Fixed
|
|
3368
3403
|
|
|
3369
|
-
- **
|
|
3404
|
+
- **AGIM_PLATFORM_BLACKLIST: SPA PlatformCards now hidden.**
|
|
3370
3405
|
v1.2.69 added 3-layer blacklist enforcement (registry refusal at
|
|
3371
3406
|
boot, CLI wizard filter, web GET `/api/config` field stripping)
|
|
3372
3407
|
but left the SPA `messengers.tsx` page hardcoding 5 `PlatformCard`
|
|
3373
3408
|
components that ignored the blacklist. Operators who set
|
|
3374
|
-
`
|
|
3409
|
+
`AGIM_PLATFORM_BLACKLIST=feishu,discord` still saw the Feishu /
|
|
3375
3410
|
Discord cards in /settings/messengers (with the fields blank,
|
|
3376
3411
|
since the backend correctly returned `null` for those slots).
|
|
3377
3412
|
- **Backend** (`web/server.ts:1574`): `/api/config` now returns
|
|
@@ -3444,14 +3479,14 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3444
3479
|
### Notes
|
|
3445
3480
|
|
|
3446
3481
|
- CR-5 (exec-dispatcher dangerous-pattern regex bypass) and CR-6
|
|
3447
|
-
(`
|
|
3482
|
+
(`AGIM_NATIVE_EXEC_SANDBOX` defaults off) deferred to the next
|
|
3448
3483
|
batch alongside CR-2 (DNS-aware SSRF resolver).
|
|
3449
3484
|
|
|
3450
3485
|
## [1.2.69] - 2026-05-26
|
|
3451
3486
|
|
|
3452
3487
|
### Added
|
|
3453
3488
|
|
|
3454
|
-
- **`
|
|
3489
|
+
- **`AGIM_PLATFORM_BLACKLIST` env** — comma-separated list of IM
|
|
3455
3490
|
platform ids that the bot will REFUSE to enable. Default empty
|
|
3456
3491
|
(no blocks; backward compatible). Three-layer enforcement:
|
|
3457
3492
|
1. **Registry** (`core/registry.ts`): `registry.registerMessenger`
|
|
@@ -3462,7 +3497,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3462
3497
|
2. **CLI wizard** (`core/onboarding.ts`): blacklisted platforms
|
|
3463
3498
|
vanish from `getAvailableMessengers()` so the wizard never
|
|
3464
3499
|
prompts for them. Layered on top of the existing
|
|
3465
|
-
`
|
|
3500
|
+
`AGIM_ENABLE_GLOBAL_IM` filter.
|
|
3466
3501
|
3. **Web admin** (`/api/messengers` GET): per-platform credential
|
|
3467
3502
|
blocks (`telegram` / `discord` / `feishu` / `dingtalk` /
|
|
3468
3503
|
`wechat`) are omitted from the response when their id (or
|
|
@@ -3484,7 +3519,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3484
3519
|
- New section at the bottom: input field for the blacklist CSV
|
|
3485
3520
|
+ live preview of "currently in force" entries.
|
|
3486
3521
|
- `ENV_EDITABLE_KEYS` in `web/server.ts` extended with
|
|
3487
|
-
`
|
|
3522
|
+
`AGIM_PLATFORM_BLACKLIST`.
|
|
3488
3523
|
- `/api/security/diagnostics` returns `platformBlacklist: string[]`.
|
|
3489
3524
|
|
|
3490
3525
|
### Internal
|
|
@@ -3516,7 +3551,7 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3516
3551
|
1. **Runtime diagnostics** (read-only badges): running-as-root,
|
|
3517
3552
|
env-file permissions (0600 / lax), bubblewrap availability,
|
|
3518
3553
|
sender allowlist configured, admin allowlist configured.
|
|
3519
|
-
2. **Sender allowlist** — `
|
|
3554
|
+
2. **Sender allowlist** — `AGIM_ALLOWED_USERS` editor.
|
|
3520
3555
|
3. **Native exec tool** — sandbox backend (none / bwrap, disabled
|
|
3521
3556
|
when bwrap missing), sandbox-net, timeout, max output.
|
|
3522
3557
|
4. **Native web tools** — allow-all-private toggle, SSRF CIDR
|
|
@@ -3531,12 +3566,12 @@ compat)、完成顺序 ≠ 原始顺序时 history 仍按原始顺序、serial
|
|
|
3531
3566
|
### Changed
|
|
3532
3567
|
|
|
3533
3568
|
- `ENV_EDITABLE_KEYS` in `web/server.ts` extended with the 11 new
|
|
3534
|
-
v1.2.58–v1.2.66 security knobs (`
|
|
3535
|
-
`
|
|
3536
|
-
`
|
|
3537
|
-
`
|
|
3538
|
-
`
|
|
3539
|
-
`
|
|
3569
|
+
v1.2.58–v1.2.66 security knobs (`AGIM_ALLOWED_USERS`,
|
|
3570
|
+
`AGIM_NATIVE_FS_RESTRICT`, `AGIM_NATIVE_FS_TIMEOUT_MS`,
|
|
3571
|
+
`AGIM_NATIVE_WEB_ALLOW_PRIVATE`, `AGIM_NATIVE_WEB_SSRF_WHITELIST`,
|
|
3572
|
+
`AGIM_NATIVE_WEB_TIMEOUT_MS`, `AGIM_EXEC_SANDBOX`,
|
|
3573
|
+
`AGIM_EXEC_SANDBOX_NET`, `AGIM_EXEC_TIMEOUT_MS`,
|
|
3574
|
+
`AGIM_EXEC_MAX_OUTPUT`, `AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN`).
|
|
3540
3575
|
All editable + persistable via the existing `/api/env` PUT path.
|
|
3541
3576
|
- Settings sidebar: new "Security" tab between "Policy" and
|
|
3542
3577
|
"Workspaces". i18n keys `tabs.security` + `security.*` added to
|
|
@@ -3563,7 +3598,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3563
3598
|
- **Command-embedded SSRF scan** — `native_exec` now regex-extracts
|
|
3564
3599
|
every `http(s)://…` token in the command string and refuses if any
|
|
3565
3600
|
resolves through `checkUrlSafety` as private/internal. Honours
|
|
3566
|
-
the shared `
|
|
3601
|
+
the shared `AGIM_NATIVE_WEB_SSRF_WHITELIST`. Closes the
|
|
3567
3602
|
curl/wget-to-IMDS bypass.
|
|
3568
3603
|
- **SSRF redirect re-check** (`web-dispatcher.ts`) — `native_web_fetch`
|
|
3569
3604
|
no longer uses `redirect: 'follow'`. Now does `redirect: 'manual'`
|
|
@@ -3574,16 +3609,16 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3574
3609
|
- **100.64.0.0/10 carrier-grade NAT** added to default block list
|
|
3575
3610
|
(matches nanobot). Cloud providers + some ISPs use this for
|
|
3576
3611
|
internal hosts.
|
|
3577
|
-
- **CIDR whitelist** — new `
|
|
3612
|
+
- **CIDR whitelist** — new `AGIM_NATIVE_WEB_SSRF_WHITELIST=<csv>`
|
|
3578
3613
|
env (e.g. `100.64.0.0/10,10.20.0.0/16`) opens specific ranges for
|
|
3579
3614
|
legitimate Tailscale / VPN / internal-API use cases without
|
|
3580
|
-
binary-flipping `
|
|
3615
|
+
binary-flipping `AGIM_NATIVE_WEB_ALLOW_PRIVATE=1`. IPv4 only;
|
|
3581
3616
|
invalid entries dropped.
|
|
3582
3617
|
|
|
3583
3618
|
#### Sandbox
|
|
3584
3619
|
|
|
3585
|
-
- **bwrap tmpfs-mask** — when `
|
|
3586
|
-
now `--tmpfs $HOME/.agim` + `$HOME/.
|
|
3620
|
+
- **bwrap tmpfs-mask** — when `AGIM_EXEC_SANDBOX=bwrap`, the sandbox
|
|
3621
|
+
now `--tmpfs $HOME/.agim` + `$HOME/.agim` + the cwd's parent
|
|
3587
3622
|
directory, then bind-mounts the actual workspace back over the
|
|
3588
3623
|
masked parent. Even if the agent bypasses `sensitive-paths.ts` at
|
|
3589
3624
|
the tool-arg layer, an exec'd shell will see an empty
|
|
@@ -3595,8 +3630,8 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3595
3630
|
- **Sender allowlist** (new `core/sender-allowlist.ts`) — controls
|
|
3596
3631
|
WHO can talk to the bot (distinct from admin allowlist for
|
|
3597
3632
|
`/restart`).
|
|
3598
|
-
- `
|
|
3599
|
-
`
|
|
3633
|
+
- `AGIM_ALLOWED_USERS=platform:userId,…` — same syntax as
|
|
3634
|
+
`AGIM_ADMIN_USERS`. Set to `*` to explicitly mark "everyone
|
|
3600
3635
|
allowed" + suppress the boot warning.
|
|
3601
3636
|
- **Default is OPEN** when unset (no breaking change to existing
|
|
3602
3637
|
deployments). cli.ts emits a one-shot
|
|
@@ -3624,7 +3659,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3624
3659
|
### Changed
|
|
3625
3660
|
|
|
3626
3661
|
- **`long-goal` skill body** — replaced the stale "Future tools
|
|
3627
|
-
(deferred to v1.2.58)" section with the real `
|
|
3662
|
+
(deferred to v1.2.58)" section with the real `mcp__agim__long_task`
|
|
3628
3663
|
/ `complete_goal` usage instructions. Now matches v1.2.63 reality.
|
|
3629
3664
|
- **`agim-self` skill body** — added the 12 tools shipped in
|
|
3630
3665
|
v1.2.58–v1.2.63 that were missing: `long_task` / `complete_goal`
|
|
@@ -3644,7 +3679,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3644
3679
|
generator.
|
|
3645
3680
|
- **`agim-skill-discovery` skill** — teaches the agent how to answer
|
|
3646
3681
|
"what skills do I have / install X / search for Y" by referring to
|
|
3647
|
-
the system-prompt list, calling `
|
|
3682
|
+
the system-prompt list, calling `mcp__agim__read_skill` for
|
|
3648
3683
|
details, and pointing the operator at skillhub.cn + web admin's
|
|
3649
3684
|
Skills page. Documents the multi-root install layout +
|
|
3650
3685
|
restart-to-pick-up semantics.
|
|
@@ -3663,7 +3698,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3663
3698
|
- **`buildSkillsSummary` fallback** — if a skill somehow still ends
|
|
3664
3699
|
up with empty description after parsing, the summary line now
|
|
3665
3700
|
substitutes `(no description in SKILL.md — read body via
|
|
3666
|
-
|
|
3701
|
+
mcp__agim__read_skill)` instead of leaving the slot blank.
|
|
3667
3702
|
|
|
3668
3703
|
## [1.2.64] - 2026-05-26
|
|
3669
3704
|
|
|
@@ -3687,7 +3722,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3687
3722
|
|
|
3688
3723
|
### Added
|
|
3689
3724
|
|
|
3690
|
-
- **`
|
|
3725
|
+
- **`mcp__agim__long_task` / `mcp__agim__complete_goal` MCP tools** —
|
|
3691
3726
|
wraps `goals.ts` so every agim agent can self-register a sustained
|
|
3692
3727
|
multi-turn objective (previously only the `/goal set` slash command
|
|
3693
3728
|
let the user do this manually).
|
|
@@ -3699,7 +3734,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3699
3734
|
`completed` (default) or `cancelled`. `recap` becomes the final
|
|
3700
3735
|
progress note.
|
|
3701
3736
|
- **All agents** see these tools — registered in both
|
|
3702
|
-
`
|
|
3737
|
+
`agim-dispatcher.ts` (native side) and
|
|
3703
3738
|
`mcp-approval-server.ts` (claude-code / cursor / antigravity MCP
|
|
3704
3739
|
sidecar) with the new `goal` wire envelope handled by
|
|
3705
3740
|
`approval-bus.ts:handleGoal`. RunContext-resolved identity (no
|
|
@@ -3721,16 +3756,16 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3721
3756
|
|
|
3722
3757
|
- **`native_exec(command, timeout_ms?, cwd?)`** — shell execution
|
|
3723
3758
|
tool in `src/core/llm/exec-dispatcher.ts`. Default timeout 60s
|
|
3724
|
-
(hard cap 600s via `
|
|
3725
|
-
capped at 32KB (override via `
|
|
3759
|
+
(hard cap 600s via `AGIM_EXEC_TIMEOUT_MS`), per-stream output
|
|
3760
|
+
capped at 32KB (override via `AGIM_EXEC_MAX_OUTPUT`). Returns
|
|
3726
3761
|
JSON `{ exit_code, signal, timed_out, stdout, stderr,
|
|
3727
3762
|
stdout_truncated, stderr_truncated }`. SIGTERM at timeout with a
|
|
3728
3763
|
3s grace before SIGKILL.
|
|
3729
|
-
- **Optional bubblewrap sandbox** when `
|
|
3764
|
+
- **Optional bubblewrap sandbox** when `AGIM_EXEC_SANDBOX=bwrap`
|
|
3730
3765
|
(Linux + `/usr/bin/bwrap` required). Read-only binds the host's
|
|
3731
3766
|
`/usr`, `/lib`, `/lib64`, `/etc/ssl`, `/etc/resolv.conf`; rw-binds
|
|
3732
3767
|
the agent's cwd; tmpfs `/tmp`; isolated proc/dev. Net stays on by
|
|
3733
|
-
default; set `
|
|
3768
|
+
default; set `AGIM_EXEC_SANDBOX_NET=off` to add `--unshare-net`
|
|
3734
3769
|
for fully offline execution.
|
|
3735
3770
|
- `native_exec` is **NOT** in the default autoAllow — each invocation
|
|
3736
3771
|
routes through the v1.2.60 IM approval card. Same-fingerprint
|
|
@@ -3753,7 +3788,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3753
3788
|
protocols, RFC1918 (10/8, 172.16-31/12, 192.168/16), loopback
|
|
3754
3789
|
(127/8, ::1, localhost), link-local (169.254/16, fe80::/10), and
|
|
3755
3790
|
IPv6 ULA (fc00::/7). Operators who genuinely need private targets
|
|
3756
|
-
set `
|
|
3791
|
+
set `AGIM_NATIVE_WEB_ALLOW_PRIVATE=1`.
|
|
3757
3792
|
- Both tools added to native's default autoAllow — they're read-only
|
|
3758
3793
|
and the SSRF block stays in force regardless.
|
|
3759
3794
|
|
|
@@ -3781,7 +3816,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3781
3816
|
notifier (CI / smoke-test path), native silently falls back to the
|
|
3782
3817
|
legacy silent-deny so tests don't hang.
|
|
3783
3818
|
- **autoAllow lookup happens BEFORE mode resolution**, so adding a tool
|
|
3784
|
-
to `
|
|
3819
|
+
to `AGIM_NATIVE_AGENT_AUTOALLOW` always shortcuts the user-prompt
|
|
3785
3820
|
path regardless of mode.
|
|
3786
3821
|
|
|
3787
3822
|
## [1.2.59] - 2026-05-25
|
|
@@ -3789,14 +3824,14 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3789
3824
|
### Fixed
|
|
3790
3825
|
|
|
3791
3826
|
- **Native runaway delegation loop** — under deepseek-v4 the native agent
|
|
3792
|
-
would chain `
|
|
3827
|
+
would chain `mcp__agim__call_agent('claude-code', …)` repeatedly
|
|
3793
3828
|
inside a single turn (observed: 8 chained delegations across 11
|
|
3794
3829
|
minutes on one wechat thread before the user had to `/abort`). The
|
|
3795
3830
|
model picked call_agent over its own native fs tools even after
|
|
3796
3831
|
v1.2.58 added them. Three changes close it:
|
|
3797
|
-
- **Per-turn cap** in `
|
|
3832
|
+
- **Per-turn cap** in `agim-dispatcher.ts`: refuses further
|
|
3798
3833
|
`call_agent` after 2 delegations per turn (override with
|
|
3799
|
-
`
|
|
3834
|
+
`AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN`, set 0 to disable). Refusal
|
|
3800
3835
|
message tells the model exactly which native tools to try instead,
|
|
3801
3836
|
so it self-corrects on the next iteration.
|
|
3802
3837
|
- **System-prompt HARD RULE** in `native/index.ts`: for read-file /
|
|
@@ -3818,7 +3853,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3818
3853
|
### Deferred
|
|
3819
3854
|
|
|
3820
3855
|
- `native_exec` (one-shot shell), `native_web_fetch`, `native_web_search`
|
|
3821
|
-
(duckduckgo → metaso fallback), `
|
|
3856
|
+
(duckduckgo → metaso fallback), `mcp__agim__long_task` /
|
|
3822
3857
|
`complete_goal`, and the bwrap sandbox path all move to v1.2.60.
|
|
3823
3858
|
Scope split: v1.2.59 is a focused hotfix for the user-visible
|
|
3824
3859
|
delegation loop; v1.2.60 returns to the bigger tool batch.
|
|
@@ -3839,20 +3874,20 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3839
3874
|
available; falls back to fs walk with a minimatch-style matcher
|
|
3840
3875
|
- `native_grep(pattern, path?, glob?, output_mode?, max_matches?,
|
|
3841
3876
|
case_insensitive?)` — ripgrep wrapper (rg required for now)
|
|
3842
|
-
- **Workspace restriction** — default-on via `
|
|
3877
|
+
- **Workspace restriction** — default-on via `AGIM_NATIVE_FS_RESTRICT`
|
|
3843
3878
|
(`'0'` disables). When on, every fs tool's path must resolve under
|
|
3844
3879
|
the per-thread native cwd subtree (typically
|
|
3845
3880
|
`~/.agim-workspaces/native/<thread>/`). Sensitive-path denylist
|
|
3846
3881
|
(`sensitive-paths.ts`) applies even when restriction is off.
|
|
3847
3882
|
- **Per-tool wall-clock** — every fs tool races against
|
|
3848
|
-
`
|
|
3883
|
+
`AGIM_NATIVE_FS_TIMEOUT_MS` (default 60_000). Prevents a slow
|
|
3849
3884
|
remote-mounted file from hanging the whole agent loop.
|
|
3850
3885
|
- **Default auto-allow** for the 4 read-only fs tools
|
|
3851
3886
|
(`native_read_file` / `native_list_dir` / `native_glob` /
|
|
3852
3887
|
`native_grep`) so native doesn't pop an IM card for every file
|
|
3853
3888
|
inspection. `native_write_file` stays approval-gated by default —
|
|
3854
3889
|
operators who trust native can add it via
|
|
3855
|
-
`
|
|
3890
|
+
`AGIM_NATIVE_AGENT_AUTOALLOW`.
|
|
3856
3891
|
|
|
3857
3892
|
### Deferred
|
|
3858
3893
|
|
|
@@ -3870,7 +3905,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3870
3905
|
packages — they teach the agent procedural knowledge and trigger
|
|
3871
3906
|
phrases without adding code. Available to every agim agent that
|
|
3872
3907
|
reads `agim skills available` (native injects into prompt; CLI
|
|
3873
|
-
agents load via `
|
|
3908
|
+
agents load via `mcp__agim__read_skill`):
|
|
3874
3909
|
- `weather` — wttr.in + Open-Meteo, no API key
|
|
3875
3910
|
- `summarize` — URL / article / YouTube / PDF summarisation flow
|
|
3876
3911
|
- `github` — `gh` CLI patterns (PR, issue, CI runs, gh api)
|
|
@@ -3881,7 +3916,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3881
3916
|
progress logging, and acceptance-criteria rules (adapted from
|
|
3882
3917
|
nanobot but mapped onto agim's existing goals.ts)
|
|
3883
3918
|
- `agim-reminders` — replaces nanobot's `cron`; teaches the
|
|
3884
|
-
`
|
|
3919
|
+
`mcp__agim__create_reminder` family with concrete examples
|
|
3885
3920
|
- `agim-memory` — replaces nanobot's `memory`; teaches the
|
|
3886
3921
|
`memory_*` + `*_memo` tools and the 5W1H taxonomy
|
|
3887
3922
|
|
|
@@ -3914,7 +3949,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3914
3949
|
v1.2.55 read the operator's real `~/.agim/env` on the dev/CI
|
|
3915
3950
|
host, breaking 7 tests that expected an empty allowlist after
|
|
3916
3951
|
`setEnv(undefined)`. Added a test opt-out: setting
|
|
3917
|
-
`
|
|
3952
|
+
`AGIM_ENV_FILE_PATH=''` disables the file read entirely (the
|
|
3918
3953
|
two admin test files now do this at module load).
|
|
3919
3954
|
|
|
3920
3955
|
## [1.2.55] - 2026-05-25
|
|
@@ -3927,7 +3962,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3927
3962
|
vanished from the web/IM admin list. Root cause: systemd's
|
|
3928
3963
|
`EnvironmentFile=` parser is stricter than agim's `readEnvFile` (it
|
|
3929
3964
|
silently drops lines containing certain characters), so the
|
|
3930
|
-
`
|
|
3965
|
+
`AGIM_ADMIN_USERS=…,…` line could land in `~/.agim/env` correctly
|
|
3931
3966
|
but be partially or fully ignored when systemd handed env to the new
|
|
3932
3967
|
process. `admin-allowlist.getEntries()` now ALSO reads
|
|
3933
3968
|
`~/.agim/env` directly with agim's own parser and merges entries
|
|
@@ -3946,10 +3981,10 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3946
3981
|
|
|
3947
3982
|
### Fixed
|
|
3948
3983
|
|
|
3949
|
-
- Web settings → Viewer: saving **「禁用社区默认」** (`
|
|
3984
|
+
- Web settings → Viewer: saving **「禁用社区默认」** (`AGIM_VIEWER_NO_DEFAULT_REMOTE`)
|
|
3950
3985
|
failed with「请求里的 key 均不可编辑」because the env whitelist omitted that
|
|
3951
3986
|
key. It is now editable via `PUT /api/env`.
|
|
3952
|
-
- Long-message viewer master switch (`
|
|
3987
|
+
- Long-message viewer master switch (`AGIM_VIEWER_ENABLED=0`) now hard-blocks
|
|
3953
3988
|
all viewer routing (truncate/link + remote paste + A2A artifact snapshots).
|
|
3954
3989
|
Previously only `decideRender` gated on enabled; A2A snapshots could still
|
|
3955
3990
|
upload when remote mode resolved.
|
|
@@ -3963,7 +3998,7 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
3963
3998
|
- `/models` under cursor returned "未能获取 cursor 的模型列表" on
|
|
3964
3999
|
systemd-launched agim because the spawned `cursor-agent` couldn't be
|
|
3965
4000
|
found on the stripped PATH. ModelDriver's listModels now uses the
|
|
3966
|
-
same bin-resolution as the cursor adapter (env `
|
|
4001
|
+
same bin-resolution as the cursor adapter (env `AGIM_CURSOR_BIN`
|
|
3967
4002
|
→ PATH → `~/.local/bin/cursor-agent` → `/usr/local/bin/...` →
|
|
3968
4003
|
`/opt/cursor/bin/...`), cached for the process lifetime.
|
|
3969
4004
|
- Tightened ANSI strip regex from `\[[0-9;]*m` (where the leading `\[`
|
|
@@ -4028,9 +4063,9 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
4028
4063
|
full `/cc cursor <prompt>` form).
|
|
4029
4064
|
- **Plan mode**: `/cs plan` or `--plan` flag yields cursor's plan mode
|
|
4030
4065
|
(read-only / clarifying questions). `--mode ask` similarly.
|
|
4031
|
-
- **MCP
|
|
4066
|
+
- **MCP agim bridge** — `~/.cursor/mcp.json` gets an `agim` entry on
|
|
4032
4067
|
first cursor turn, pointing at the same approval-bus sidecar
|
|
4033
|
-
claude-code uses. All `
|
|
4068
|
+
claude-code uses. All `mcp__agim__*` tool calls inside a cursor run
|
|
4034
4069
|
hop through agim's existing approval-bus + audit pipeline — no
|
|
4035
4070
|
bypass of agim policy.
|
|
4036
4071
|
- **Auth inheritance** — defaults to the machine's existing cursor
|
|
@@ -4050,11 +4085,11 @@ Nanobot-inspired defense-in-depth pass. 9 hardening items across
|
|
|
4050
4085
|
### Migration
|
|
4051
4086
|
|
|
4052
4087
|
- Existing cursor installs (with `cursor-agent login` already done) are
|
|
4053
|
-
picked up automatically. Set `
|
|
4088
|
+
picked up automatically. Set `AGIM_CURSOR_BIN=/path/to/cursor-agent`
|
|
4054
4089
|
to override binary resolution.
|
|
4055
4090
|
- `~/.cursor/mcp.json` is read-modify-written on first cursor turn;
|
|
4056
4091
|
pre-existing `mcpServers` entries are preserved.
|
|
4057
|
-
- The bin probe order is `
|
|
4092
|
+
- The bin probe order is `AGIM_CURSOR_BIN` env → PATH lookup →
|
|
4058
4093
|
`~/.local/bin/cursor-agent` → `/usr/local/bin/cursor-agent` →
|
|
4059
4094
|
`/opt/cursor/bin/cursor-agent`.
|
|
4060
4095
|
|
|
@@ -4076,19 +4111,19 @@ multi-hop research turn.
|
|
|
4076
4111
|
`[operator role definition]`. Edit the seed at
|
|
4077
4112
|
`~/.agim-workspaces/native/AGENTS.md` to change persona / tone /
|
|
4078
4113
|
house rules; no restart required. Env override
|
|
4079
|
-
`
|
|
4114
|
+
`AGIM_NATIVE_AGENT_ROLE_FILE=...` for non-default locations.
|
|
4080
4115
|
Prompt-injection guard runs over the content + audit-logs hits.
|
|
4081
|
-
- **Skills multi-root scan** — `
|
|
4116
|
+
- **Skills multi-root scan** — `AGIM_SKILLS_MODE=auto` (default)
|
|
4082
4117
|
merges `~/.agim/skills/` (write target) with `~/.claude/skills/`,
|
|
4083
4118
|
`~/.config/opencode/skills/`, and `~/.codex/skills/` so a fresh
|
|
4084
4119
|
install sees every skill the user already has from CLI agents.
|
|
4085
4120
|
Workspace skills shadow same-named entries from inherited roots.
|
|
4086
|
-
Modes: `auto | agim-only | custom` + `
|
|
4087
|
-
/ `
|
|
4121
|
+
Modes: `auto | agim-only | custom` + `AGIM_SKILLS_ROOTS=...`
|
|
4122
|
+
/ `AGIM_SKILLS_EXTRA_ROOTS=...`.
|
|
4088
4123
|
- **Auto-compact long histories** — when a native turn's accumulated
|
|
4089
|
-
history crosses `
|
|
4124
|
+
history crosses `AGIM_NATIVE_COMPACT_TRIGGER_CHARS` (default
|
|
4090
4125
|
60_000), a cheap LLM call summarises the older slice and the loop
|
|
4091
|
-
keeps only the last `
|
|
4126
|
+
keeps only the last `AGIM_NATIVE_COMPACT_KEEP_TURNS` (default 6)
|
|
4092
4127
|
user/assistant pairs verbatim. Tool round-trips kept intact (the
|
|
4093
4128
|
fix that landed in CR — never start the tail on `role:'tool'`).
|
|
4094
4129
|
- **Provider fallback chain** — native walks the configured role
|
|
@@ -4101,25 +4136,25 @@ multi-hop research turn.
|
|
|
4101
4136
|
content blocks when the provider's `vision: true` (or its model
|
|
4102
4137
|
name matches a known vision family). Anthropic provider remains
|
|
4103
4138
|
text-only for now. Hard cap 20MB per image. Path-safety:
|
|
4104
|
-
attachments must resolve under `
|
|
4139
|
+
attachments must resolve under `AGIM_MEDIA_ROOT`.
|
|
4105
4140
|
- **Tool-call heartbeat** — tool dispatches that take longer than
|
|
4106
|
-
`
|
|
4141
|
+
`AGIM_NATIVE_HEARTBEAT_MS` (default 6000) push a "🔧 调用工具 X
|
|
4107
4142
|
中…" so users know the bot is still working.
|
|
4108
4143
|
- **Turn-level heartbeat** — every
|
|
4109
|
-
`
|
|
4144
|
+
`AGIM_NATIVE_TURN_HEARTBEAT_MS` (default 180_000 = 3 min) since
|
|
4110
4145
|
turn start, push "⏳ 还在处理(已 Nm)…". Survives long
|
|
4111
4146
|
multi-hop research turns where individual tool calls finish but the
|
|
4112
4147
|
outer LLM is reasoning.
|
|
4113
4148
|
- **Cross-channel operator alert** — when outbox delivery fails ≥3
|
|
4114
4149
|
times on any thread, push a "⚠️ outbox 告警" to
|
|
4115
|
-
`
|
|
4150
|
+
`AGIM_OPERATOR_ALERT_PLATFORM` / `AGIM_OPERATOR_ALERT_THREAD_ID`
|
|
4116
4151
|
(throttled per dead-thread, 10-min cooldown). Self-loop protection.
|
|
4117
4152
|
- **agim built-in MCP tools default-allowed** — the 9
|
|
4118
|
-
`
|
|
4153
|
+
`mcp__agim__*` tools (read_skill / list_skills / save_memo /
|
|
4119
4154
|
search_memos / update_memo / delete_memo / push_message /
|
|
4120
4155
|
ask_user / call_agent) are now in native's default allow-list,
|
|
4121
4156
|
matching what claude-code already saw via the MCP sidecar. Override
|
|
4122
|
-
via `
|
|
4157
|
+
via `AGIM_NATIVE_AGENT_DENYLIST=...`.
|
|
4123
4158
|
- **Per-agent native workspace** — `resolveAgentCwd('native', opts)`
|
|
4124
4159
|
pins IM turns to `~/.agim-workspaces/native/` (was `/` under
|
|
4125
4160
|
systemd). AGENTS.md seeded with role-definition cues.
|
|
@@ -4138,7 +4173,7 @@ multi-hop research turn.
|
|
|
4138
4173
|
— native now passes `timeoutMs: 28 * 60 * 1000` to `runAgentLoop`,
|
|
4139
4174
|
matching the IM 30-min hard ceiling. Multi-hop `call_agent` chains
|
|
4140
4175
|
used to abort mid-flight on the 6th minute. Override via
|
|
4141
|
-
`
|
|
4176
|
+
`AGIM_NATIVE_AGENT_TIMEOUT_MS`.
|
|
4142
4177
|
- **wechat-ilink dead-session auto-recovery** — `sendMessage` returning
|
|
4143
4178
|
`-2` (`INVALID_PARAMS`) now invalidates the cached + persisted
|
|
4144
4179
|
context-token for that user, so the next inbound message refreshes
|
|
@@ -4165,12 +4200,12 @@ multi-hop research turn.
|
|
|
4165
4200
|
- Operators who customised `~/.agim-workspaces/native/AGENTS.md` keep
|
|
4166
4201
|
their file unchanged (`ensureAgentWorkspace` never overwrites).
|
|
4167
4202
|
- Default skill mode is `auto` — agim now reads `~/.claude/skills/`
|
|
4168
|
-
etc. Set `
|
|
4169
|
-
- The 9 `
|
|
4170
|
-
default policy. Set `
|
|
4203
|
+
etc. Set `AGIM_SKILLS_MODE=agim-only` to opt out of inheritance.
|
|
4204
|
+
- The 9 `mcp__agim__*` tools are auto-allowed under native's
|
|
4205
|
+
default policy. Set `AGIM_NATIVE_AGENT_DENYLIST=mcp__agim__call_agent,...`
|
|
4171
4206
|
to block individual ones.
|
|
4172
4207
|
- Auto-compact will make one cheap-role LLM call per compaction.
|
|
4173
|
-
Disable with `
|
|
4208
|
+
Disable with `AGIM_NATIVE_COMPACT_TRIGGER_CHARS=0`.
|
|
4174
4209
|
|
|
4175
4210
|
## [1.3.0] - 2026-05-23
|
|
4176
4211
|
|
|
@@ -4233,20 +4268,20 @@ for the architectural stance + anti-patterns.
|
|
|
4233
4268
|
- **agim Skills engine (Stage 3 + P0 #3)** — discover `SKILL.md`
|
|
4234
4269
|
files in `~/.agim/skills/` + bundled `<dist>/skills/builtin/`; 3-tier
|
|
4235
4270
|
progressive disclosure (name+desc auto-injected; body via
|
|
4236
|
-
`
|
|
4271
|
+
`mcp__agim__read_skill`; scripts/refs via normal file read);
|
|
4237
4272
|
`/skill list|show|refresh` + `/settings/agim-skills` web editor. See
|
|
4238
4273
|
[`docs/skills.md`](docs/skills.md). PR #68 + #76.
|
|
4239
4274
|
- **Inline row-age annotations on memory facts (P0 #4)** — every fact
|
|
4240
4275
|
/ persona row gets a `(2d ago)` style annotation in the injected
|
|
4241
4276
|
context so the agent has temporal context for free. `format-age.ts`
|
|
4242
4277
|
utility + `persona-age.test.ts`. PR #69.
|
|
4243
|
-
- **`
|
|
4278
|
+
- **`mcp__agim__ask_user` structured choice (P0 #5)** — agent presents
|
|
4244
4279
|
N choices (2-9) with optional timeout; user replies via button or
|
|
4245
4280
|
text; result returns deterministically as a typed choice index +
|
|
4246
4281
|
free-text. `/tasks/asks` pending-queue admin. See
|
|
4247
4282
|
[`docs/ask-user.md`](docs/ask-user.md). PR #67.
|
|
4248
4283
|
- **Notification evaluator for agent-initiated push (P0 #9)** —
|
|
4249
|
-
`
|
|
4284
|
+
`mcp__agim__push_message` and `POST /api/notify` go through an
|
|
4250
4285
|
LLM-graded "should we deliver this?" filter before hitting the IM
|
|
4251
4286
|
thread. Per-thread rate limit; verdict logged to audit. PR #60.
|
|
4252
4287
|
|
|
@@ -4375,12 +4410,12 @@ for the architectural stance + anti-patterns.
|
|
|
4375
4410
|
|
|
4376
4411
|
### R15 — new
|
|
4377
4412
|
|
|
4378
|
-
- **CLI 向导 "Web 后台 — 监听地址 + 端口" 段** — bind (`
|
|
4413
|
+
- **CLI 向导 "Web 后台 — 监听地址 + 端口" 段** — bind (`AGIM_WEB_BIND`
|
|
4379
4414
|
写到 `~/.agim/env`) + port (`webPort` 写到 `config.json`). 选
|
|
4380
4415
|
`0.0.0.0` 强制 yesNo 二次确认 "你前面有 TLS 反代吗"; port `< 1024`
|
|
4381
4416
|
拒绝。PR #56.
|
|
4382
4417
|
- **ACP port gate 闭合** — `GET /api/config` 现透传 `acpPort` 但只在
|
|
4383
|
-
`
|
|
4418
|
+
`AGIM_ENABLE_REMOTE_AGENT=1` 时; `PUT /api/config` 在 gate 关时丢
|
|
4384
4419
|
incoming.acpPort; Web `/settings/service` Ports 卡的 ACP 输入框
|
|
4385
4420
|
按 `features.remoteAgent` gate (之前一直显示). PR #56.
|
|
4386
4421
|
|
|
@@ -4469,21 +4504,21 @@ for the architectural stance + anti-patterns.
|
|
|
4469
4504
|
`memory_list` 输出对 5W1H 走 `sanitizeForInjection`;
|
|
4470
4505
|
`ensureAgentWorkspace` 启动期扫 AGENTS.md/CLAUDE.md, 11 英文 + 4
|
|
4471
4506
|
中文 prompt-injection 模式命中 → warn + audit. PR #48.
|
|
4472
|
-
- **G4 `
|
|
4507
|
+
- **G4 `AGIM_ACP_BIND` env + non-loopback audit** — ACP 服务监听
|
|
4473
4508
|
地址可配; 改非回环时启动 warn + 持久 audit-event. PR #48.
|
|
4474
|
-
- **G5 advisories** — `
|
|
4475
|
-
小时 reminder; 按 IP WS 限流 (`
|
|
4476
|
-
`
|
|
4477
|
-
warn + audit; 非回环 Web bind 未设 `
|
|
4509
|
+
- **G5 advisories** — `AGIM_TIMEOUT_DEFAULT=allow` 启动横幅 + 每
|
|
4510
|
+
小时 reminder; 按 IP WS 限流 (`AGIM_WS_MAX_PER_IP=20` +
|
|
4511
|
+
`AGIM_WS_MAX_NEW_PER_IP_PER_MIN=30`); `?token=` URL 回退首次使用
|
|
4512
|
+
warn + audit; 非回环 Web bind 未设 `AGIM_WEB_TLS_ACK` 启动横幅.
|
|
4478
4513
|
PR #48.
|
|
4479
4514
|
|
|
4480
4515
|
### R12 — 6 enterprise privacy hardening items + visibility gates
|
|
4481
4516
|
|
|
4482
4517
|
- **① 用户消息日志脱敏** — `sanitizeUserText()` 默认
|
|
4483
|
-
`{len, prefix(6), sha256(12)}`, `
|
|
4518
|
+
`{len, prefix(6), sha256(12)}`, `AGIM_LOG_USER_TEXT=1` 显式启用
|
|
4484
4519
|
原文 (120 字符 cap). PR #48.
|
|
4485
|
-
- **② Memory / Persona / Paste TTL** — `
|
|
4486
|
-
DAYS=90`/`
|
|
4520
|
+
- **② Memory / Persona / Paste TTL** — `AGIM_MEMORY_FACT_RETENTION_
|
|
4521
|
+
DAYS=90`/`AGIM_PERSONA_RETENTION_DAYS=180`/`AGIM_PASTE_RETENTION_
|
|
4487
4522
|
DAYS=30`. facts 按 last_referenced_at (LRU 友好), 0 = 永久. PR #48.
|
|
4488
4523
|
- **③ `agim uninstall` 三模式** — 保留 / 清凭据保留历史 / 完全销毁
|
|
4489
4524
|
(typed "DELETE" + shred + rm -rf). PR #48.
|
|
@@ -4492,10 +4527,10 @@ for the architectural stance + anti-patterns.
|
|
|
4492
4527
|
- **⑤ `audit_events` 持久审计表** — 10 类事件 (approval / admin /
|
|
4493
4528
|
config / env / token / workspace) 持久 180 天, details JSON 只放
|
|
4494
4529
|
字段名 / 长度 / 哈希前缀. `GET /api/audit/events` 暴露. PR #48.
|
|
4495
|
-
- **⑥ `
|
|
4530
|
+
- **⑥ `AGIM_SKILLHUB_ENABLED` 出网开关** — `=0` 关 skillhub
|
|
4496
4531
|
对外 fetch (气隙部署). PR #48.
|
|
4497
|
-
- **Compliance visibility gates** — `
|
|
4498
|
-
Discord+Telegram, `
|
|
4532
|
+
- **Compliance visibility gates** — `AGIM_ENABLE_GLOBAL_IM` 控
|
|
4533
|
+
Discord+Telegram, `AGIM_ENABLE_REMOTE_AGENT` 控 ACP. 默认全关,
|
|
4499
4534
|
三层都 gate (CLI 向导 / Web 设置 / 运行时). PR #48.
|
|
4500
4535
|
|
|
4501
4536
|
### Build
|
|
@@ -4511,12 +4546,12 @@ for the architectural stance + anti-patterns.
|
|
|
4511
4546
|
- **Fresh install white-screens on the web console.** `index.html`
|
|
4512
4547
|
shipped in `dist/web/public/` is the v2 SPA shell since M1 / R10,
|
|
4513
4548
|
but the static-asset router that serves `/assets/<chunk>.js` was
|
|
4514
|
-
gated behind `
|
|
4549
|
+
gated behind `AGIM_WEB_V2=1`. New installs without that env var
|
|
4515
4550
|
set received the SPA HTML (which references `/assets/index-…js`)
|
|
4516
4551
|
but every chunk request fell through to the catch-all 404 — the
|
|
4517
4552
|
browser parsed the shell, failed every module import, and stuck
|
|
4518
4553
|
on a white screen with no obvious error short of devtools.
|
|
4519
|
-
- Default flipped to ON. Set `
|
|
4554
|
+
- Default flipped to ON. Set `AGIM_WEB_V2=0` to drop back to the
|
|
4520
4555
|
legacy v1 page handler (still serves the older
|
|
4521
4556
|
`tasks.html` / `reminders.html` / `memos.html` / `settings.html`
|
|
4522
4557
|
for any operator who customised those files; new operators get
|
|
@@ -4540,7 +4575,7 @@ parallel; this release bumps to 1.2.22 to stay above it.)
|
|
|
4540
4575
|
succeeded if given more time.
|
|
4541
4576
|
- The prompt POST now uses an undici Agent with `bodyTimeout: 0` and
|
|
4542
4577
|
`headersTimeout: 0`. Liveness is still bounded by the SSE-side idle
|
|
4543
|
-
watchdog (`OPENCODE_IDLE_TIMEOUT_MS` / `
|
|
4578
|
+
watchdog (`OPENCODE_IDLE_TIMEOUT_MS` / `AGIM_AGENT_IDLE_TIMEOUT_MS`),
|
|
4544
4579
|
so an actually-hung opencode is still reported — we just stop
|
|
4545
4580
|
killing healthy long-running responses.
|
|
4546
4581
|
- The `opencode.http.prompt_failed` log now captures `error.cause`
|
|
@@ -4571,18 +4606,18 @@ parallel; this release bumps to 1.2.22 to stay above it.)
|
|
|
4571
4606
|
|
|
4572
4607
|
- **opencode MCP sidecar silently exits when probe-reuse picks up a stale
|
|
4573
4608
|
serve.** `approval-bus` picks a fresh random socket path on every agim
|
|
4574
|
-
start (`/tmp/
|
|
4609
|
+
start (`/tmp/agim-approval-<32hex>.sock`); any pre-existing
|
|
4575
4610
|
`opencode serve` left over from a previous agim run carries the old
|
|
4576
4611
|
path in its environ snapshot. `OpencodeServeManager` previously reused
|
|
4577
4612
|
the listener unconditionally, so every new MCP sidecar that the
|
|
4578
4613
|
serve forked tried to connect to a deleted socket and exited at
|
|
4579
|
-
startup — `
|
|
4614
|
+
startup — `mcp__agim__save_memo`, `mcp__agim__create_reminder`,
|
|
4580
4615
|
and friends silently dropped out of opencode's tool set.
|
|
4581
4616
|
- The probe-reuse path now reads `/proc/<listener-pid>/environ`, compares
|
|
4582
|
-
`
|
|
4617
|
+
`AGIM_APPROVAL_SOCK` against the live bus path, and SIGTERMs +
|
|
4583
4618
|
respawns when they mismatch (escalates to SIGKILL after 800 ms).
|
|
4584
4619
|
- Spawn path makes the env injection explicit and warns loudly if
|
|
4585
|
-
`
|
|
4620
|
+
`AGIM_APPROVAL_SOCK` is unset at the moment we launch the serve.
|
|
4586
4621
|
|
|
4587
4622
|
(`1.2.3` through `1.2.17` were auto-bumped by the merge-bot but never
|
|
4588
4623
|
manually published; this is the first npm publish since `1.2.2`.)
|
|
@@ -4678,7 +4713,7 @@ and a handful of P0 / P1 hardening fixes uncovered in pre-release CR.
|
|
|
4678
4713
|
|
|
4679
4714
|
Persistent per-user fact store + auto-distilled "persona" summary that gets
|
|
4680
4715
|
injected into every agent prompt. Default OFF; opt in via Settings →
|
|
4681
|
-
**自动化记忆** toggle (or `
|
|
4716
|
+
**自动化记忆** toggle (or `AGIM_MEMORY_ENABLED=1`).
|
|
4682
4717
|
|
|
4683
4718
|
- **Storage**: `~/.agim/memory.db` (SQLite). FTS5 index for keyword recall.
|
|
4684
4719
|
Per-user partition key `${platform}:${userId}` so the same human across
|
|
@@ -4689,7 +4724,7 @@ injected into every agent prompt. Default OFF; opt in via Settings →
|
|
|
4689
4724
|
- **Daily consolidation cron**: rebuilds the persona summary from the
|
|
4690
4725
|
newest 50 facts so the always-on snippet stays small (~150–300 tokens).
|
|
4691
4726
|
- **4 MCP tools** so agents can introspect / extend memory:
|
|
4692
|
-
`
|
|
4727
|
+
`mcp__agim__memory_query`, `_save`, `_list`, `_delete`.
|
|
4693
4728
|
- **Web admin tab** (`/tasks#memory`): per-user user selector → persona
|
|
4694
4729
|
text editor + paginated facts table with FTS5 search + bulk-delete
|
|
4695
4730
|
filters + JSON export.
|
|
@@ -4712,14 +4747,14 @@ ranked list. Backfill button generates embeddings for existing facts.
|
|
|
4712
4747
|
Clear button wipes the index when switching backends (different model =
|
|
4713
4748
|
incompatible vector space).
|
|
4714
4749
|
|
|
4715
|
-
### Added — Agent-initiated push (`
|
|
4750
|
+
### Added — Agent-initiated push (`mcp__agim__push_message`)
|
|
4716
4751
|
|
|
4717
4752
|
Lets a running agent push a follow-up message back into the IM thread
|
|
4718
4753
|
without an inbound trigger. Useful for long-running jobs ("CI green") or
|
|
4719
4754
|
schedule-aware notifications.
|
|
4720
4755
|
|
|
4721
|
-
- Per-user rate limit (`
|
|
4722
|
-
- Cross-thread push gated by `
|
|
4756
|
+
- Per-user rate limit (`AGIM_PUSH_RATE_PER_HOUR`, default 20).
|
|
4757
|
+
- Cross-thread push gated by `AGIM_PUSH_CROSS_THREAD` (default off:
|
|
4723
4758
|
push must target the same thread the run started in).
|
|
4724
4759
|
- `POST /api/notify` HTTP endpoint exposes the same primitive for
|
|
4725
4760
|
webhooks / cron / external tools.
|
|
@@ -4754,7 +4789,7 @@ WeChat-iLink / DingTalk where buttons aren't a primitive.
|
|
|
4754
4789
|
|
|
4755
4790
|
### Changed — Web auth / env editor
|
|
4756
4791
|
|
|
4757
|
-
- `
|
|
4792
|
+
- `AGIM_MEMORY_VECTOR_OPENAI_API_KEY` joins the SECRET_KEYS allowlist:
|
|
4758
4793
|
masked on GET, click-to-reveal for editing, masked-value writes are
|
|
4759
4794
|
no-ops (defense in depth so a stale masked echo can't overwrite).
|
|
4760
4795
|
- `PUT /api/env` rejects masked echoes for any secret key (was only
|
|
@@ -4802,7 +4837,7 @@ WeChat-iLink / DingTalk where buttons aren't a primitive.
|
|
|
4802
4837
|
|
|
4803
4838
|
### Changed — Telemetry / data
|
|
4804
4839
|
|
|
4805
|
-
- `
|
|
4840
|
+
- `AGIM_MEMORY_*` env keys editable via `PUT /api/env`.
|
|
4806
4841
|
- `~/.agim/memory.db` is new; safe to delete — recreated on next save.
|
|
4807
4842
|
- Vector cache: `~/.agim/cache/transformers` (BGE ONNX model files).
|
|
4808
4843
|
- `audit-log` adds `intent='memory.distill'` rows so distillation cost
|
|
@@ -4850,7 +4885,7 @@ adds token-gated login.
|
|
|
4850
4885
|
SHA-256; raw token is shown once at create time.
|
|
4851
4886
|
- **Cookie**: 30-day `agim_token` cookie set on successful login;
|
|
4852
4887
|
`SameSite=Strict`, `Path=/`. Logout via `POST /api/auth/logout`.
|
|
4853
|
-
- **Disable**: `
|
|
4888
|
+
- **Disable**: `AGIM_WEB_AUTH=off` reverts to pre-1.1.10 open access
|
|
4854
4889
|
(for ops who do auth at the reverse proxy layer).
|
|
4855
4890
|
- **Global fetch interceptor** in `_app.js` auto-attaches `Authorization`
|
|
4856
4891
|
+ redirects to `/login` on 401. Existing pages keep working without
|
|
@@ -4860,10 +4895,10 @@ adds token-gated login.
|
|
|
4860
4895
|
|
|
4861
4896
|
The HSTECH / Lens debate sessions surfaced two pain points:
|
|
4862
4897
|
|
|
4863
|
-
- **Default timeout raised from 10 min → 30 min** (`
|
|
4898
|
+
- **Default timeout raised from 10 min → 30 min** (`AGIM_A2A_TIMEOUT_DEFAULT_MS`).
|
|
4864
4899
|
Codex routinely takes 15-25 min for a 4-API-pull + writing-a-report job;
|
|
4865
4900
|
the old 10 min cutoff killed it mid-flight and left orphan files in
|
|
4866
|
-
`_agim-output/`. New `
|
|
4901
|
+
`_agim-output/`. New `AGIM_A2A_MAX_TIMEOUT_MS` (default 1h) caps the
|
|
4867
4902
|
ceiling so an agent can't accidentally write `timeoutMs: 86400000`.
|
|
4868
4903
|
- **Abort on timeout** — `AgentSendOpts.signal` plumbed through `sendPrompt`
|
|
4869
4904
|
→ `spawnStream` so callees actually get SIGTERM'd when A2A gives up.
|
|
@@ -4876,7 +4911,7 @@ The HSTECH / Lens debate sessions surfaced two pain points:
|
|
|
4876
4911
|
- `⌛ codex 超时 (10m 未返回) — 子进程已停` — timeout
|
|
4877
4912
|
- `❌ codex 失败 ... <err>` — failure
|
|
4878
4913
|
- **Verbose heartbeat mode** detects file changes in `_agim-output/`
|
|
4879
|
-
every `
|
|
4914
|
+
every `AGIM_A2A_HEARTBEAT_MIN` minutes (default 5):
|
|
4880
4915
|
- With change: lists new files + links the first new `.md` once.
|
|
4881
4916
|
- Without change: "still thinking" note.
|
|
4882
4917
|
- **Notify scope**: source='system' (never routes through viewer);
|
|
@@ -4904,7 +4939,7 @@ The HSTECH / Lens debate sessions surfaced two pain points:
|
|
|
4904
4939
|
web port publicly. First start auto-creates a bootstrap token — copy
|
|
4905
4940
|
the value from `journalctl -u agim` or `agim status` output.
|
|
4906
4941
|
- Existing users on a reverse proxy with their own auth: set
|
|
4907
|
-
`
|
|
4942
|
+
`AGIM_WEB_AUTH=off` if you don't want a second factor.
|
|
4908
4943
|
- Local-only / loopback users: nothing changes (auth bypassed on
|
|
4909
4944
|
127.0.0.1).
|
|
4910
4945
|
|
|
@@ -4942,12 +4977,12 @@ otherwise expose their agim host, the viewer can now auto-launch a
|
|
|
4942
4977
|
cloudflared "quick tunnel" so /v/:id links in IM are reachable from
|
|
4943
4978
|
a phone with zero infrastructure setup.
|
|
4944
4979
|
|
|
4945
|
-
- **New env var `
|
|
4980
|
+
- **New env var `AGIM_VIEWER_TUNNEL_MODE`** — `off` (default) or
|
|
4946
4981
|
`quick`. When `quick`, agim startup forks `cloudflared tunnel --url`
|
|
4947
4982
|
pointing at the local web port and captures the assigned
|
|
4948
4983
|
`https://*.trycloudflare.com` URL from its log output. The URL
|
|
4949
4984
|
becomes the effective base for link building.
|
|
4950
|
-
- **Precedence**: `
|
|
4985
|
+
- **Precedence**: `AGIM_VIEWER_PUBLIC_BASE_URL` always wins when set.
|
|
4951
4986
|
Tunnel is only used as a fallback. So operators can keep their
|
|
4952
4987
|
static reverse proxy and only switch to tunnel during travel /
|
|
4953
4988
|
testing without changing anything else.
|
|
@@ -4976,7 +5011,7 @@ Quick-tunnel URLs are ephemeral — they change every time cloudflared
|
|
|
4976
5011
|
process (re)starts. Old `/v/:id` links in IM thus become dead after a
|
|
4977
5012
|
restart. Operators who want permanent links should configure a static
|
|
4978
5013
|
reverse proxy (cloudflared named tunnel, caddy, tailscale funnel,
|
|
4979
|
-
nginx, …) and set `
|
|
5014
|
+
nginx, …) and set `AGIM_VIEWER_PUBLIC_BASE_URL` instead. The
|
|
4980
5015
|
auto-tunnel mode is intentionally a "zero-config fallback", not a
|
|
4981
5016
|
recommended permanent deployment.
|
|
4982
5017
|
|
|
@@ -5027,7 +5062,7 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5027
5062
|
- **`GET /api/viewer{,/:id}`** + **`DELETE /api/viewer/:id`** —
|
|
5028
5063
|
list / read / delete pastes from the dashboard or via curl.
|
|
5029
5064
|
- **Permanent storage by default.** No TTL; rows are kept until
|
|
5030
|
-
`
|
|
5065
|
+
`AGIM_VIEWER_MAX_PASTES` (default 10 000) is exceeded, at which
|
|
5031
5066
|
point oldest rows are LRU-pruned.
|
|
5032
5067
|
- **Two-section envelope for agents.** Router prepends a small
|
|
5033
5068
|
`[IM-render hint]` block to every prompt when the viewer is
|
|
@@ -5045,18 +5080,18 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5045
5080
|
|
|
5046
5081
|
| Env var | Default | Notes |
|
|
5047
5082
|
|---|---|---|
|
|
5048
|
-
| `
|
|
5049
|
-
| `
|
|
5050
|
-
| `
|
|
5051
|
-
| `
|
|
5052
|
-
| `
|
|
5053
|
-
| `
|
|
5083
|
+
| `AGIM_VIEWER_ENABLED` | `false` | Master switch. |
|
|
5084
|
+
| `AGIM_VIEWER_PUBLIC_BASE_URL` | _(empty)_ | Your public URL pointing at this agim host, e.g. `https://agim.example.com`. Used to build the link placed in IM. |
|
|
5085
|
+
| `AGIM_VIEWER_CHARS` | `500` | Char-count threshold above which routing to web kicks in. |
|
|
5086
|
+
| `AGIM_VIEWER_LINES` | `12` | Line-count threshold. |
|
|
5087
|
+
| `AGIM_VIEWER_CODE_LINES` | `10` | Single-fence code-block line threshold. |
|
|
5088
|
+
| `AGIM_VIEWER_MAX_PASTES` | `10000` | Local SQLite row cap (LRU prune). |
|
|
5054
5089
|
|
|
5055
5090
|
### Notes
|
|
5056
5091
|
|
|
5057
5092
|
- Reverse-proxy your agim web port (default 3000) to a public
|
|
5058
5093
|
hostname via cloudflared / caddy / tailscale-funnel etc. Set
|
|
5059
|
-
`
|
|
5094
|
+
`AGIM_VIEWER_PUBLIC_BASE_URL` to that hostname.
|
|
5060
5095
|
- Privacy posture: content is stored locally on your host only.
|
|
5061
5096
|
The link uses an unguessable uuidv4 — treat it like a private
|
|
5062
5097
|
share link.
|
|
@@ -5146,7 +5181,7 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5146
5181
|
|
|
5147
5182
|
### Added — Agent-to-Agent Layer 2 (shared artifacts)
|
|
5148
5183
|
|
|
5149
|
-
- **File exchange between agents.** `
|
|
5184
|
+
- **File exchange between agents.** `mcp__agim__call_agent` now accepts
|
|
5150
5185
|
optional `inputs[]` and `expectOutputs[]` so caller and callee can
|
|
5151
5186
|
hand off files instead of round-tripping bytes through prompts /
|
|
5152
5187
|
results.
|
|
@@ -5166,9 +5201,9 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5166
5201
|
`fromCallerOutput` use `link(2)` when source and destination share a
|
|
5167
5202
|
filesystem — near-zero cost for read-only inputs. Falls back to plain
|
|
5168
5203
|
copy on EXDEV.
|
|
5169
|
-
- **Size caps**: `
|
|
5170
|
-
`
|
|
5171
|
-
`
|
|
5204
|
+
- **Size caps**: `AGIM_A2A_ARTIFACT_MAX_BYTES_PER_FILE` (default 50 MB),
|
|
5205
|
+
`AGIM_A2A_ARTIFACT_MAX_BYTES_PER_JOB` (200 MB),
|
|
5206
|
+
`AGIM_A2A_ARTIFACT_MAX_FILES_PER_JOB` (200). Failed setup fails the
|
|
5172
5207
|
job before any tokens are spent.
|
|
5173
5208
|
- **Retention follows the inline-job row.** When job-board's sweep
|
|
5174
5209
|
deletes a row, `pruneArtifactsBatch` removes its directory. Fire-and-
|
|
@@ -5178,7 +5213,7 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5178
5213
|
|
|
5179
5214
|
### Changed
|
|
5180
5215
|
|
|
5181
|
-
- `
|
|
5216
|
+
- `mcp__agim__call_agent` description grew a paragraph documenting the
|
|
5182
5217
|
L2 fields; existing L1 callers (no `inputs` / `expectOutputs`) keep
|
|
5183
5218
|
the L1 string-in / string-out behavior unchanged.
|
|
5184
5219
|
|
|
@@ -5204,7 +5239,7 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5204
5239
|
- `/outbox failed` rows in `giving_up`.
|
|
5205
5240
|
- `/outbox retry <id>` resurrect a `giving_up` row.
|
|
5206
5241
|
- Retention: 24h after `delivered` / `giving_up`. Override with
|
|
5207
|
-
`
|
|
5242
|
+
`AGIM_OUTBOX_RETENTION_HOURS`.
|
|
5208
5243
|
- **Inline-job tracking.** Every inbound agent-bound message now creates
|
|
5209
5244
|
a row in `jobs.db` with `kind='inline'`, going through the full
|
|
5210
5245
|
lifecycle `pending → running → completed → delivered` (or `failed`).
|
|
@@ -5212,8 +5247,8 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5212
5247
|
recovery and A2A both rely on.
|
|
5213
5248
|
- Visible in `/job list` and per-row in `/job check <id>`.
|
|
5214
5249
|
- Retention: 24h (vs 30d for `kind='job'` rows from explicit `/job
|
|
5215
|
-
create`). Override with `
|
|
5216
|
-
- Kill switch: `
|
|
5250
|
+
create`). Override with `AGIM_INLINE_JOB_RETENTION_HOURS`.
|
|
5251
|
+
- Kill switch: `AGIM_INLINE_JOB_TRACKING=0` disables creation; the
|
|
5217
5252
|
user reply path falls back to the unchanged in-memory pipeline.
|
|
5218
5253
|
- **Crash-recovery flow.** When agim exits (SIGTERM/SIGINT/crash), any
|
|
5219
5254
|
in-flight inline job is stamped `interrupted`. On startup, jobs
|
|
@@ -5224,24 +5259,24 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5224
5259
|
stamped `replaced_by=<new id>`.
|
|
5225
5260
|
- Reply `2` → old row marked `cancelled`.
|
|
5226
5261
|
- No reply → old row swept to `abandoned` by the next startup.
|
|
5227
|
-
- Window override: `
|
|
5262
|
+
- Window override: `AGIM_RECOVERY_WINDOW_MS` (default 600000).
|
|
5228
5263
|
|
|
5229
5264
|
### Added — Agent-to-Agent (A2A) Layer 1
|
|
5230
5265
|
|
|
5231
|
-
- **`
|
|
5266
|
+
- **`mcp__agim__call_agent` MCP tool.** A running agent (claude-code /
|
|
5232
5267
|
opencode / codex / copilot) can now program-call another agent and
|
|
5233
5268
|
wait for the result inside its own tool loop. The tool description
|
|
5234
5269
|
uses imperative + Chinese trigger phrases so models invoke it
|
|
5235
5270
|
naturally when the user says e.g. "用 codex 帮我跑 git status" or
|
|
5236
5271
|
"ask opencode to run the tests".
|
|
5237
5272
|
- **Guardrails enforced inside agim, not on the model**:
|
|
5238
|
-
- `
|
|
5273
|
+
- `AGIM_A2A_MAX_DEPTH` (default 3) — caps nested call chains.
|
|
5239
5274
|
- Self-call ban — `claude-code` can't recursively call `claude-code`.
|
|
5240
5275
|
- Workspace whitelist — callee must be in the caller's workspace
|
|
5241
5276
|
`agents[]`. Caller's `userId` carries through.
|
|
5242
|
-
- `
|
|
5277
|
+
- `AGIM_A2A_TIMEOUT_DEFAULT_MS` (default 600_000) — accumulation
|
|
5243
5278
|
timeout. Callee keeps running on timeout; caller stops waiting.
|
|
5244
|
-
- Kill switch: `
|
|
5279
|
+
- Kill switch: `AGIM_A2A_ENABLED=0` disables the whole feature.
|
|
5245
5280
|
- **`/a2a stats | recent [N] | tree <id>`** — observability for A2A
|
|
5246
5281
|
traffic. Each callee row is linked to its caller via `parent_id`
|
|
5247
5282
|
+ `call_depth`, so `/a2a tree <root>` renders the full chain.
|
|
@@ -5295,7 +5330,7 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5295
5330
|
|
|
5296
5331
|
- **Approval timeout default 30 min → 15 min.** Long enough for slow IM
|
|
5297
5332
|
channels to round-trip a y/n; short enough to unblock downstream tools.
|
|
5298
|
-
Override with `
|
|
5333
|
+
Override with `AGIM_APPROVAL_TIMEOUT_MS`.
|
|
5299
5334
|
- **Agent child-process budget switched from 30-min hard total cap →
|
|
5300
5335
|
60-min idle watchdog.** Every stdout / stderr chunk resets the timer,
|
|
5301
5336
|
so slow human-in-the-loop approvals no longer eat the budget. A truly
|
|
@@ -5321,18 +5356,18 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5321
5356
|
|
|
5322
5357
|
### Added
|
|
5323
5358
|
|
|
5324
|
-
- **`
|
|
5359
|
+
- **`AGIM_TIMEOUT_DEFAULT=allow | deny`** env (default `deny`) — what
|
|
5325
5360
|
the bus returns when a normal-mode approval times out with no human
|
|
5326
5361
|
reply. `allow` is "user away" mode. Hot-reloadable from the new Web
|
|
5327
5362
|
Settings → **Approval Policy** card (no service restart needed).
|
|
5328
|
-
- **`
|
|
5363
|
+
- **`AGIM_AGENT_IDLE_TIMEOUT_MS`** global env + `${NAME}_IDLE_TIMEOUT_MS`
|
|
5329
5364
|
per-agent override for the idle watchdog. `0` disables.
|
|
5330
5365
|
- **`OPENCODE_IDLE_TIMEOUT_MS`** env for the opencode HTTP adapter.
|
|
5331
5366
|
- **`humanizeFingerprint()`** — `/approval` listing and auto-allow
|
|
5332
5367
|
receipts now render `命令 git status` / `目录 /tmp` / `主机 api.x.com`
|
|
5333
5368
|
instead of leaking internal scheme prefixes (`cmd:`, `dir:`, `host:`).
|
|
5334
5369
|
- Approval card timeout footer reads the live timeout + the effective
|
|
5335
|
-
`
|
|
5370
|
+
`AGIM_TIMEOUT_DEFAULT` setting (e.g. `15min 未回 → 放行 · req XXX`),
|
|
5336
5371
|
instead of hard-coded "5 分钟未回 = 拒绝".
|
|
5337
5372
|
|
|
5338
5373
|
### Fixed
|
|
@@ -5383,8 +5418,8 @@ chmod +x ~/.agim/bin/cloudflared
|
|
|
5383
5418
|
### Changed — debrand user-facing strings + docs to "agim"
|
|
5384
5419
|
|
|
5385
5420
|
CLI help text, IM messenger adapter error messages, web server log
|
|
5386
|
-
lines, and command-palette titles now say `agim` instead of `
|
|
5387
|
-
or `
|
|
5421
|
+
lines, and command-palette titles now say `agim` instead of `agim`
|
|
5422
|
+
or `agim`. All non-historical docs (README, deployment,
|
|
5388
5423
|
session-model, im-workspaces-guide, etc.) were rewritten accordingly,
|
|
5389
5424
|
including default state-dir / workspace-dir path references
|
|
5390
5425
|
(`~/.agim/`, `~/.agim-workspaces/`).
|
|
@@ -5392,27 +5427,27 @@ including default state-dir / workspace-dir path references
|
|
|
5392
5427
|
### Breaking — Web UI theme key
|
|
5393
5428
|
|
|
5394
5429
|
The localStorage key for the Web UI dark/light theme preference changed
|
|
5395
|
-
from `
|
|
5430
|
+
from `agim-theme` to `agim-theme`. Users will see their theme reset
|
|
5396
5431
|
to system default once on first load after upgrade; re-select if desired.
|
|
5397
5432
|
|
|
5398
5433
|
### Kept for compatibility (intentionally not changed)
|
|
5399
5434
|
|
|
5400
|
-
The following surfaces still use the legacy `
|
|
5435
|
+
The following surfaces still use the legacy `agim` / `agim`
|
|
5401
5436
|
identifier and will not change without a major-version bump:
|
|
5402
5437
|
|
|
5403
|
-
- `
|
|
5438
|
+
- `agim` npm bin alias (`/usr/local/bin/agim` continues to
|
|
5404
5439
|
resolve to the same CLI as `agim`).
|
|
5405
|
-
- `
|
|
5440
|
+
- `agim.service` systemd unit name — installations from the 0.x line
|
|
5406
5441
|
keep their existing unit file; v1.0+ fresh installs write
|
|
5407
5442
|
`agim.service` and `cli-ui/service.ts` falls back to the legacy name.
|
|
5408
|
-
- `X-
|
|
5409
|
-
- WeChat `client_id: '
|
|
5410
|
-
- `~/.
|
|
5443
|
+
- `X-Agim-Token` HTTP header on the ACP server (`acp-server.ts`).
|
|
5444
|
+
- WeChat `client_id: 'agim:…'` (IM-platform-side identifier).
|
|
5445
|
+
- `~/.agim/` data dir + `~/.agim-workspaces/` workspace root are
|
|
5411
5446
|
still detected by `core/agim-paths.ts` as legacy fallback paths; v1.0+
|
|
5412
5447
|
fresh installs land at `~/.agim/` and `~/.agim-workspaces/`.
|
|
5413
5448
|
- `self-protect.ts` process-name regex still matches
|
|
5414
|
-
`(agim|
|
|
5415
|
-
- `npm uninstall -g agim-cli
|
|
5449
|
+
`(agim|agim|agim|dist/cli.js)`.
|
|
5450
|
+
- `npm uninstall -g agim-cli agim agim` (in `cli-ui/cmd-handlers.ts`)
|
|
5416
5451
|
continues to clean up all three historical package names.
|
|
5417
5452
|
|
|
5418
5453
|
## [1.0.14] - 2026-05-13
|
|
@@ -5499,8 +5534,8 @@ who don't restart from WeChat see no behavioral difference.
|
|
|
5499
5534
|
### Removed — Safety card "Skip permissions" toggle
|
|
5500
5535
|
|
|
5501
5536
|
The web /settings Safety card no longer exposes a toggle for
|
|
5502
|
-
`
|
|
5503
|
-
typical systemd deployment:
|
|
5537
|
+
`AGIM_DANGEROUSLY_SKIP_PERMISSIONS`. The toggle was a footgun for the
|
|
5538
|
+
typical systemd deployment: agim runs as root, but Claude CLI itself
|
|
5504
5539
|
hard-refuses `--dangerously-skip-permissions` for uid=0 with
|
|
5505
5540
|
|
|
5506
5541
|
claude-code failed (exit 1):
|
|
@@ -5515,7 +5550,7 @@ The env variable itself is **still honored** by the Claude adapter
|
|
|
5515
5550
|
(`src/plugins/agents/claude-code/index.ts`). Non-root deployments that
|
|
5516
5551
|
genuinely want the bypass can edit `~/.agim/env` manually:
|
|
5517
5552
|
|
|
5518
|
-
|
|
5553
|
+
AGIM_DANGEROUSLY_SKIP_PERMISSIONS=1
|
|
5519
5554
|
|
|
5520
5555
|
The Safety card now contains only the Admin Allowlist editor.
|
|
5521
5556
|
|
|
@@ -5542,14 +5577,14 @@ service mode BEFORE writing the pending file:
|
|
|
5542
5577
|
|
|
5543
5578
|
pgrep -af dist/cli.js # see surviving daemons
|
|
5544
5579
|
pkill -9 -f dist/cli.js
|
|
5545
|
-
systemctl reset-failed
|
|
5546
|
-
systemctl restart
|
|
5580
|
+
systemctl reset-failed agim
|
|
5581
|
+
systemctl restart agim
|
|
5547
5582
|
|
|
5548
5583
|
## [1.0.10] - 2026-05-13
|
|
5549
5584
|
|
|
5550
5585
|
### Added — first-run admin onboarding
|
|
5551
5586
|
|
|
5552
|
-
The v1.0.9 denial message ("set
|
|
5587
|
+
The v1.0.9 denial message ("set AGIM_ADMIN_USERS=… and restart") was
|
|
5553
5588
|
unfriendly to small / non-technical operators. v1.0.10 replaces it with
|
|
5554
5589
|
a guided self-onboarding flow:
|
|
5555
5590
|
|
|
@@ -5565,15 +5600,15 @@ a guided self-onboarding flow:
|
|
|
5565
5600
|
· Token regenerates on every restart while no admin is set.
|
|
5566
5601
|
```
|
|
5567
5602
|
|
|
5568
|
-
2. **Operator** sees this in `journalctl -u
|
|
5569
|
-
~/.
|
|
5603
|
+
2. **Operator** sees this in `journalctl -u agim` (or `tail
|
|
5604
|
+
~/.agim/agim.log`), opens their own IM, and sends
|
|
5570
5605
|
`/setup admin <token>` to the bot.
|
|
5571
5606
|
|
|
5572
5607
|
3. **Bot** verifies the token, calls `promoteAdmin(platform, userId)`
|
|
5573
5608
|
which:
|
|
5574
5609
|
- Adds the entry to the in-memory allowlist (effective immediately,
|
|
5575
5610
|
no restart required)
|
|
5576
|
-
- Persists `
|
|
5611
|
+
- Persists `AGIM_ADMIN_USERS` to `~/.agim/env` so the next restart
|
|
5577
5612
|
keeps it
|
|
5578
5613
|
- Unlinks the token file (single-use)
|
|
5579
5614
|
- Replies "✅ 你 (platform:userId) 已设为管理员"
|
|
@@ -5583,7 +5618,7 @@ a guided self-onboarding flow:
|
|
|
5583
5618
|
|
|
5584
5619
|
### Changed — smarter denial messages
|
|
5585
5620
|
|
|
5586
|
-
The blanket message in v1.0.9 ("
|
|
5621
|
+
The blanket message in v1.0.9 ("AGIM_ADMIN_USERS=… 然后重启服务") leaked
|
|
5587
5622
|
internal env-var format to random visitors. v1.0.10 distinguishes:
|
|
5588
5623
|
|
|
5589
5624
|
- **No admin at all** → "这个 bot 还没配置管理员。如果你是部署者:…
|
|
@@ -5616,7 +5651,7 @@ denial-message + intent/self-protect coverage from v1.0.9. Full suite:
|
|
|
5616
5651
|
|
|
5617
5652
|
### Migration
|
|
5618
5653
|
|
|
5619
|
-
- Existing deployments with `
|
|
5654
|
+
- Existing deployments with `AGIM_ADMIN_USERS` already set: nothing
|
|
5620
5655
|
changes. Token file is auto-cleaned at startup since admins exist.
|
|
5621
5656
|
- New deployments: the bootstrap banner is the entry point. No more
|
|
5622
5657
|
manual env editing required for the typical operator onboarding.
|
|
@@ -5628,7 +5663,7 @@ denial-message + intent/self-protect coverage from v1.0.9. Full suite:
|
|
|
5628
5663
|
A new opt-in lets the operator turn off every approval prompt for Claude
|
|
5629
5664
|
Code, by setting:
|
|
5630
5665
|
|
|
5631
|
-
|
|
5666
|
+
AGIM_DANGEROUSLY_SKIP_PERMISSIONS=1
|
|
5632
5667
|
|
|
5633
5668
|
When set, the Claude Code adapter launches with
|
|
5634
5669
|
`--dangerously-skip-permissions` and skips both the approval-bus pipeline
|
|
@@ -5644,8 +5679,8 @@ respects PreToolUse hooks).
|
|
|
5644
5679
|
|
|
5645
5680
|
1. `opts.planMode` → `--permission-mode plan` (read-only wins over bypass —
|
|
5646
5681
|
you explicitly asked for an exploratory pass).
|
|
5647
|
-
2. `
|
|
5648
|
-
3. `
|
|
5682
|
+
2. `AGIM_DANGEROUSLY_SKIP_PERMISSIONS=1` → `--dangerously-skip-permissions`.
|
|
5683
|
+
3. `AGIM_APPROVAL_DISABLED=1` or no IM context or bus down →
|
|
5649
5684
|
`--permission-mode dontAsk` (unchanged).
|
|
5650
5685
|
4. Default IM-routed → `--permission-mode default --permission-prompt-tool …`
|
|
5651
5686
|
(unchanged).
|
|
@@ -5819,11 +5854,11 @@ just means "no IM channels," not "secretly start WeChat anyway."
|
|
|
5819
5854
|
|
|
5820
5855
|
Agim 的 web 控制台(端口 3000)不再有任何内建鉴权机制:
|
|
5821
5856
|
|
|
5822
|
-
- 删除 `/login` 页面、`POST /api/auth/login` 端点、`
|
|
5857
|
+
- 删除 `/login` 页面、`POST /api/auth/login` 端点、`agim_session` cookie
|
|
5823
5858
|
- 删除 `~/.agim/web-token` 的自动创建(web 端不再读写此文件)
|
|
5824
|
-
- 删除 `
|
|
5859
|
+
- 删除 `AGIM_WEB_REQUIRE_AUTH` 环境变量
|
|
5825
5860
|
- 静态页面 / `/api/*` / `/events` / WebSocket 升级都不再做 token / cookie 校验
|
|
5826
|
-
- 前端代码删除所有 `X-
|
|
5861
|
+
- 前端代码删除所有 `X-Agim-Token` header 注入与 `window.AGIM_TOKEN` 引用
|
|
5827
5862
|
|
|
5828
5863
|
**访问控制责任完全交给上游**——反向代理、防火墙、SSH 隧道、Tailscale /
|
|
5829
5864
|
WireGuard 等。把 web 控制台暴露到 `0.0.0.0` 时务必先在 nginx / Caddy 上加一层
|
|
@@ -5834,7 +5869,7 @@ Basic Auth 或 OAuth2 Proxy;不要直接 HTTP 暴露公网。
|
|
|
5834
5869
|
ACP server 是给第三方 agent 程序化调用的接口,仍走 bearer-token:
|
|
5835
5870
|
|
|
5836
5871
|
- token 文件改为 `~/.agim/acp-token`(自动生成)
|
|
5837
|
-
- 0.x 部署的 `~/.agim/web-token` / `~/.
|
|
5872
|
+
- 0.x 部署的 `~/.agim/web-token` / `~/.agim/web-token` 仍被识别为
|
|
5838
5873
|
legacy 回退路径,已有 ACP 调用方不会断
|
|
5839
5874
|
- 删除 token 文件 + 重启服务即可轮换
|
|
5840
5875
|
|
|
@@ -5842,37 +5877,37 @@ ACP server 是给第三方 agent 程序化调用的接口,仍走 bearer-token
|
|
|
5842
5877
|
|
|
5843
5878
|
- 0.x → 1.0.2 升级:旧 `web-token` 文件留在那里也没事(web 端忽略它,ACP
|
|
5844
5879
|
仍读它做 legacy fallback);可手动删除。
|
|
5845
|
-
- 任何 `X-
|
|
5880
|
+
- 任何 `X-Agim-Token` header 在 web 端会被静默忽略;脚本调用 `/api/*`
|
|
5846
5881
|
现在直接成功,**前提是你已经在反代层加了访问控制**。
|
|
5847
5882
|
|
|
5848
5883
|
## [1.0.1] - 2026-05-12
|
|
5849
5884
|
|
|
5850
|
-
### Changed — config / workspace dir auto-detect (~/.agim/ vs ~/.
|
|
5885
|
+
### Changed — config / workspace dir auto-detect (~/.agim/ vs ~/.agim/)
|
|
5851
5886
|
|
|
5852
5887
|
Follow-up to the v1.0.0 rebrand: the on-disk root is now resolved at
|
|
5853
|
-
startup rather than hard-coded to `~/.
|
|
5888
|
+
startup rather than hard-coded to `~/.agim/`. New module
|
|
5854
5889
|
`src/core/agim-paths.ts` exports `AGIM_HOME` and `AGIM_WORKSPACES`,
|
|
5855
5890
|
computed once with this priority:
|
|
5856
5891
|
|
|
5857
|
-
1. `$AGIM_HOME` / `$AGIM_WORKSPACES` env override (legacy `$
|
|
5892
|
+
1. `$AGIM_HOME` / `$AGIM_WORKSPACES` env override (legacy `$AGIM_HOME`
|
|
5858
5893
|
spelling also honored).
|
|
5859
5894
|
2. `~/.agim/` (or `~/.agim-workspaces/`) if the directory exists — new
|
|
5860
5895
|
canonical name in v1.0+.
|
|
5861
|
-
3. `~/.
|
|
5896
|
+
3. `~/.agim/` (or `~/.agim-workspaces/`) if the directory exists —
|
|
5862
5897
|
legacy 0.x layout. Picked up automatically so upgraded users keep
|
|
5863
5898
|
their data in place with **zero migration**.
|
|
5864
5899
|
4. Default to `~/.agim/` (or `~/.agim-workspaces/`) for fresh installs.
|
|
5865
5900
|
|
|
5866
5901
|
That means:
|
|
5867
|
-
- **Upgraded 0.x user** → `agim` finds the existing `~/.
|
|
5902
|
+
- **Upgraded 0.x user** → `agim` finds the existing `~/.agim/`, uses
|
|
5868
5903
|
it. memos.db / reminders.db / sessions/ / wechat-credentials.json all
|
|
5869
5904
|
stay where they are; nothing is moved.
|
|
5870
5905
|
- **Fresh installer on a clean box** → `agim` creates `~/.agim/`.
|
|
5871
5906
|
- **User who manually moves data** to `~/.agim/` later → `agim` switches
|
|
5872
5907
|
to it automatically on next start.
|
|
5873
5908
|
|
|
5874
|
-
Every hard-coded `join(homedir(), '.
|
|
5875
|
-
`'.
|
|
5909
|
+
Every hard-coded `join(homedir(), '.agim', ...)` and
|
|
5910
|
+
`'.agim-workspaces'` literal across the codebase (22 files,
|
|
5876
5911
|
~30 call sites) was replaced with the resolved root. Modules touched:
|
|
5877
5912
|
`cli.ts`, `web/server.ts`, `core/onboarding.ts`, `core/audit-log.ts`,
|
|
5878
5913
|
`core/job-board.ts`, `core/schedule.ts`, `core/session.ts`,
|
|
@@ -5887,14 +5922,14 @@ literal.
|
|
|
5887
5922
|
|
|
5888
5923
|
## [1.0.0] - 2026-05-12
|
|
5889
5924
|
|
|
5890
|
-
### Changed — Brand rename: `
|
|
5925
|
+
### Changed — Brand rename: `agim` → **Agim · 阿吉姆**
|
|
5891
5926
|
|
|
5892
5927
|
Product upgrade to v1.0 ships under a new brand:
|
|
5893
5928
|
|
|
5894
5929
|
- **English name**: `Agim` (Agent + IM, with a hint of "agile")
|
|
5895
5930
|
- **Chinese name**: `阿吉姆`
|
|
5896
|
-
- **CLI command**: `agim` (was `
|
|
5897
|
-
- **npm package**: `agim-cli` (was `
|
|
5931
|
+
- **CLI command**: `agim` (was `agim`)
|
|
5932
|
+
- **npm package**: `agim-cli` (was `agim`). npm's anti-typosquat
|
|
5898
5933
|
policy rejected the unscoped name `agim` (too similar to existing
|
|
5899
5934
|
`ai`/`aegir`/`gm`), so we ship as `agim-cli` and the installed binary
|
|
5900
5935
|
is still `agim` — the package name only affects the install command
|
|
@@ -5906,33 +5941,33 @@ Cross-cutting policy:
|
|
|
5906
5941
|
|------------------------------------------------------|--------------------|--------|
|
|
5907
5942
|
| npm package name | `agim` | renamed |
|
|
5908
5943
|
| CLI bin command | `agim` | renamed |
|
|
5909
|
-
| Old CLI bin command | `
|
|
5944
|
+
| Old CLI bin command | `agim` | **kept as alias** in the same package — existing systemd units, shell aliases, scripts continue to work |
|
|
5910
5945
|
| Console banner / help text / wizard titles | `Agim` / `阿吉姆` | renamed |
|
|
5911
|
-
| Config dir | `~/.
|
|
5912
|
-
| Workspace dir | `~/.
|
|
5913
|
-
| Env vars | `
|
|
5914
|
-
| HTTP header | `X-
|
|
5915
|
-
| systemd unit name | `agim.service` preferred | **legacy `
|
|
5946
|
+
| Config dir | `~/.agim/` | **unchanged** for backwards compat with all 0.x installs |
|
|
5947
|
+
| Workspace dir | `~/.agim-workspaces/` | **unchanged** |
|
|
5948
|
+
| Env vars | `AGIM_*` | **unchanged** |
|
|
5949
|
+
| HTTP header | `X-Agim-Token` | **unchanged** |
|
|
5950
|
+
| systemd unit name | `agim.service` preferred | **legacy `agim.service` is still recognised** by detection / restart / stop / uninstall code paths |
|
|
5916
5951
|
|
|
5917
5952
|
What this means for users:
|
|
5918
5953
|
- New install: `npm install -g agim` → use `agim …` commands.
|
|
5919
5954
|
- Existing 0.x install: stays working unchanged. Optional upgrade is just
|
|
5920
|
-
`npm uninstall -g
|
|
5921
|
-
(config, env, data) is untouched. The old `
|
|
5955
|
+
`npm uninstall -g agim && npm install -g agim`; everything else
|
|
5956
|
+
(config, env, data) is untouched. The old `agim` bin command
|
|
5922
5957
|
continues to be installed by the new package, so your systemd unit
|
|
5923
|
-
`ExecStart=/usr/local/bin/
|
|
5958
|
+
`ExecStart=/usr/local/bin/agim start` keeps running.
|
|
5924
5959
|
|
|
5925
5960
|
Files touched (non-exhaustive):
|
|
5926
|
-
- `package.json` — name + bin (with `
|
|
5961
|
+
- `package.json` — name + bin (with `agim` alias) + version 1.0.0 + description + keywords
|
|
5927
5962
|
- `src/cli.ts` — banner, program name, help text, comments
|
|
5928
5963
|
- `src/cli-ui/i18n.ts` — every wizard title / status / uninstall string in
|
|
5929
5964
|
both EN and 中文
|
|
5930
5965
|
- `src/cli-ui/service.ts` — accepts either `agim.service` or
|
|
5931
|
-
`
|
|
5966
|
+
`agim.service`; `pgrep` matches both bin names
|
|
5932
5967
|
- `src/cli-ui/cmd-handlers.ts` — restart / uninstall walk both unit paths
|
|
5933
5968
|
- `README.md` + `README.zh-CN.md` — full top-section rewrite, install
|
|
5934
5969
|
commands, migration guide, version history
|
|
5935
|
-
-
|
|
5970
|
+
- agim-site repo — separate brand rollout for the marketing site
|
|
5936
5971
|
|
|
5937
5972
|
## [0.6.3] - 2026-05-12
|
|
5938
5973
|
|
|
@@ -5952,13 +5987,13 @@ the per-platform "what coord system did the payload arrive in?" policy:
|
|
|
5952
5987
|
|
|
5953
5988
|
| Source | Default | Override |
|
|
5954
5989
|
|---------------------------------------|-------------------------|----------|
|
|
5955
|
-
| Telegram native location | WGS-84 pass-through | `
|
|
5990
|
+
| Telegram native location | WGS-84 pass-through | `AGIM_TELEGRAM_COORDS_GCJ02=1` (iOS-zh-CN users) |
|
|
5956
5991
|
| Feishu native location | GCJ-02 → WGS-84 | (server-mandated, no override) |
|
|
5957
5992
|
| DingTalk `link` msgtype, amap.com URL | GCJ-02 → WGS-84 | — |
|
|
5958
5993
|
| DingTalk `link` msgtype, qq.com URL | GCJ-02 → WGS-84 | — |
|
|
5959
5994
|
| DingTalk `link` msgtype, baidu.com URL| **BD-09 → WGS-84** (new)| — |
|
|
5960
5995
|
| DingTalk `link` msgtype, unknown host | WGS-84 pass-through | — |
|
|
5961
|
-
| H5 `/memo here` browser geolocation | WGS-84 pass-through | `
|
|
5996
|
+
| H5 `/memo here` browser geolocation | WGS-84 pass-through | `AGIM_H5_COORDS_GCJ02=1` (iOS Safari users) |
|
|
5962
5997
|
|
|
5963
5998
|
Two **default flips** vs. the old behavior:
|
|
5964
5999
|
1. Telegram: was always GCJ→WGS, now pass-through. Telegram Desktop +
|
|
@@ -6016,7 +6051,7 @@ survive multi-minute agent runs. OpenAPI works for any send.
|
|
|
6016
6051
|
| msgtype on wire | Payload location | Adapter behavior |
|
|
6017
6052
|
|---|---|---|
|
|
6018
6053
|
| `text` | `text.content` | Pass through to agent (no change) |
|
|
6019
|
-
| `picture` | `content.downloadCode` | Download via `/v1.0/robot/messageFiles/download` (the `pictureDownloadCode` field looks tempting but returns 500 — reserved for a different endpoint we don't use). Save under `~/.
|
|
6054
|
+
| `picture` | `content.downloadCode` | Download via `/v1.0/robot/messageFiles/download` (the `pictureDownloadCode` field looks tempting but returns 500 — reserved for a different endpoint we don't use). Save under `~/.agim/media/dingtalk/<thread>/<msgId>.<ext>`. Append `[图片附件:<path>]` to user text. claude-code's Read tool sees the JPG. |
|
|
6020
6055
|
| `audio` | `content.downloadCode` + `content.recognition` | **Prefer the server-side ASR transcript in `recognition`** (zero latency, better Mandarin accuracy than whisper.cpp base model). Still download the source AMR for archive/replay. Fall back to whisper.cpp only when `recognition` is missing. |
|
|
6021
6056
|
| `link` | `link.messageUrl` | Try `tryExtractLatLng()` on the URL (handles Amap, Tencent QMap, generic `?lat=&lng=`, `?location=lat,lng`). On hit → stash in `location-context`, next user text gets the GPS prefix injected. |
|
|
6022
6057
|
| `file` | `content.downloadCode` | Acknowledge only (PDF / Word handling is a separate effort) |
|
|
@@ -6029,7 +6064,7 @@ files land at `msgAB2pLyIgOgo6bJXw9mWAtA__.jpg` and the path-injection
|
|
|
6029
6064
|
guard in `saveDingTalkMedia()` doesn't reject them.
|
|
6030
6065
|
|
|
6031
6066
|
**Config** — `{ dingtalk: { clientId, clientSecret } }` in
|
|
6032
|
-
`~/.
|
|
6067
|
+
`~/.agim/config.json`. `clientId` doubles as `robotCode` for
|
|
6033
6068
|
stream-mode internal apps; we also cache the most-recent `robotCode`
|
|
6034
6069
|
from inbound messages for robustness against multi-bot setups.
|
|
6035
6070
|
|
|
@@ -6056,7 +6091,7 @@ keep existing" for ClientSecret.
|
|
|
6056
6091
|
## [0.5.2] - 2026-05-11
|
|
6057
6092
|
|
|
6058
6093
|
> 0.5.0 introduced the bilingual wizard but 0.5.1 hands-on showed it had
|
|
6059
|
-
> regressed real functionality vs. the old `
|
|
6094
|
+
> regressed real functionality vs. the old `agim config <component>`
|
|
6060
6095
|
> flows — checkbox-only selection couldn't issue WeChat QR codes, prompt
|
|
6061
6096
|
> for Telegram tokens, probe agent CLI installs, etc. 0.5.2 restores all
|
|
6062
6097
|
> of that work inside the new arrow-key UI, plus fixes a pile of paper-
|
|
@@ -6069,7 +6104,7 @@ with the real configuration work the legacy flow did:
|
|
|
6069
6104
|
|
|
6070
6105
|
- **WeChat (iLink)** — `Configure` scans QR via
|
|
6071
6106
|
`ILinkWeChatAdapter.startQRLogin()` + `waitForQRLogin()`; on success the
|
|
6072
|
-
credentials persist to `~/.
|
|
6107
|
+
credentials persist to `~/.agim/wechat-credentials.json` (existing
|
|
6073
6108
|
adapter path) and `wechat-ilink` is added to `cfg.messengers`. Re-running
|
|
6074
6109
|
re-issues a fresh QR.
|
|
6075
6110
|
- **Telegram** — prompts for bot token (hidden) + channel id. On
|
|
@@ -6105,25 +6140,25 @@ default exists is auto-promoted to default.
|
|
|
6105
6140
|
|
|
6106
6141
|
### Added — env reads now find values wherever they actually live
|
|
6107
6142
|
|
|
6108
|
-
The wizard previously only read `~/.
|
|
6143
|
+
The wizard previously only read `~/.agim/env` for SMTP / Baidu prefill,
|
|
6109
6144
|
so machines where those keys were set in the systemd unit's
|
|
6110
6145
|
`Environment=` lines (the common install pattern from before the wizard
|
|
6111
6146
|
existed) showed `(unset)` even though everything was working at runtime.
|
|
6112
6147
|
New `readEffectiveEnv()` falls back through three sources for read:
|
|
6113
6148
|
|
|
6114
|
-
1. `~/.
|
|
6149
|
+
1. `~/.agim/env` (canonical, what the wizard writes)
|
|
6115
6150
|
2. `process.env` (shell-exported)
|
|
6116
|
-
3. `/etc/systemd/system/
|
|
6151
|
+
3. `/etc/systemd/system/agim.service` — parsed `Environment=` lines
|
|
6117
6152
|
(file is world-readable on standard installs, so works for the user's
|
|
6118
|
-
shell-invoked `
|
|
6153
|
+
shell-invoked `agim config`)
|
|
6119
6154
|
|
|
6120
6155
|
Writes still go to the env file only. When `hasProcessEnvOverride(key)`
|
|
6121
6156
|
detects a wizard-managed key that's set somewhere outside the env file,
|
|
6122
6157
|
the SMTP / Baidu save path prints a one-line warning:
|
|
6123
6158
|
|
|
6124
6159
|
```
|
|
6125
|
-
⚠️
|
|
6126
|
-
unit / shell export). Saving to ~/.
|
|
6160
|
+
⚠️ AGIM_BAIDU_MAP_AK is also set by the running environment (systemd
|
|
6161
|
+
unit / shell export). Saving to ~/.agim/env alone will NOT change the
|
|
6127
6162
|
active value — update the unit file or `unset` the shell export first.
|
|
6128
6163
|
```
|
|
6129
6164
|
|
|
@@ -6177,24 +6212,24 @@ this is the actual first published 0.5.x release.
|
|
|
6177
6212
|
|
|
6178
6213
|
## [0.5.0] - 2026-05-11
|
|
6179
6214
|
|
|
6180
|
-
> **核心主题**:`
|
|
6215
|
+
> **核心主题**:`agim` CLI 升级成"运维主入口"——双语 + 上下键交互向导 + 完整服务生命周期管理(status / start --bg / restart / stop / uninstall)。SMTP 和百度地图 AK 终于进入 `config` 一站式配置。
|
|
6181
6216
|
|
|
6182
6217
|
### Added — 双语交互式 `config` 向导
|
|
6183
|
-
之前 `
|
|
6218
|
+
之前 `agim config` 是 per-component 的命令行参数式配置(`config wechat` / `config telegram` / ...),界面是纯 `readline.question` 文本提示,新用户摸不着头脑。
|
|
6184
6219
|
|
|
6185
6220
|
新增基于 `@inquirer/prompts` 的交互向导:
|
|
6186
|
-
- **语言选择**:首次进入弹出 EN / 中文 选择器,记忆到 `~/.
|
|
6221
|
+
- **语言选择**:首次进入弹出 EN / 中文 选择器,记忆到 `~/.agim/cli-lang`,下次进入回车即可
|
|
6187
6222
|
- **5 个分类**(每个分类内部支持 ← Back 回根菜单):
|
|
6188
6223
|
1. **IM 渠道** — 多选 checkbox:微信 / Telegram / 飞书 / Discord / 邮件
|
|
6189
6224
|
2. **AI Agent** — 多选 + 选默认 agent(Claude Code / OpenCode / Codex / Copilot)
|
|
6190
6225
|
3. **远程 ACP agent** — 列表 + 新增 / 编辑 / 删除,支持 Bearer token 认证(输入隐藏)
|
|
6191
|
-
4. **SMTP**(新增)— 4 个预设(Gmail / Outlook / QQ / 163)+ Custom + Skip;写到 `~/.
|
|
6192
|
-
5. **百度地图 AK**(新增)— 输入 / 清除,写到 `~/.
|
|
6226
|
+
4. **SMTP**(新增)— 4 个预设(Gmail / Outlook / QQ / 163)+ Custom + Skip;写到 `~/.agim/env`(chmod 600)
|
|
6227
|
+
5. **百度地图 AK**(新增)— 输入 / 清除,写到 `~/.agim/env`
|
|
6193
6228
|
- **Per-spawn 持久化**:SMTP 密码、Baidu AK 一输入就落盘,wizard 半途崩了不丢
|
|
6194
|
-
- 旧的 `
|
|
6229
|
+
- 旧的 `agim config <component>` 路径保留兼容
|
|
6195
6230
|
|
|
6196
|
-
### Added — bare `
|
|
6197
|
-
直接敲 `
|
|
6231
|
+
### Added — bare `agim` → 运维入口菜单
|
|
6232
|
+
直接敲 `agim`(无参)不再 dump help。改成弹出 8 项菜单:
|
|
6198
6233
|
- Configure
|
|
6199
6234
|
- Show status
|
|
6200
6235
|
- Start (foreground / background)
|
|
@@ -6209,11 +6244,11 @@ this is the actual first published 0.5.x release.
|
|
|
6209
6244
|
|
|
6210
6245
|
| Command | 行为 |
|
|
6211
6246
|
|---|---|
|
|
6212
|
-
| `
|
|
6213
|
-
| `
|
|
6214
|
-
| `
|
|
6215
|
-
| `
|
|
6216
|
-
| `
|
|
6247
|
+
| `agim status` | 探测 systemd / background daemon / foreground;显示 pid + uptime + Web URL |
|
|
6248
|
+
| `agim start --bg` | 后台启动(nohup + setsid + pid 文件 + 日志到 `~/.agim/agim.log`);裸 `start` 仍前台 |
|
|
6249
|
+
| `agim restart` | 自动选 systemctl restart 或 bg daemon 重启 |
|
|
6250
|
+
| `agim stop` | 自动选 systemctl stop 或 SIGTERM bg pid + cleanup pid 文件 |
|
|
6251
|
+
| `agim uninstall` | 双重确认后:停服务 → 卸载 npm 包 → 删 config.json + env + pid + systemd 单元;**保留 `~/.agim-workspaces/`** |
|
|
6217
6252
|
|
|
6218
6253
|
**跨平台后台启动**:Linux / macOS / WSL2 都走 `nohup`+detach 路径。macOS 上想真正开机自启仍要自己写 launchd plist(CHANGELOG 后续版本可加)。
|
|
6219
6254
|
|
|
@@ -6223,7 +6258,7 @@ this is the actual first published 0.5.x release.
|
|
|
6223
6258
|
- `src/cli-ui/lang-picker.ts` — 语言选择 + 持久化
|
|
6224
6259
|
- `src/cli-ui/config-wizard.ts` — 5 个分类的向导主体
|
|
6225
6260
|
- `src/cli-ui/service.ts` — `detectService()` / `spawnBackground()` / `stopService()` / `formatUptime()`
|
|
6226
|
-
- `src/cli-ui/env-file.ts` — 增量更新 `~/.
|
|
6261
|
+
- `src/cli-ui/env-file.ts` — 增量更新 `~/.agim/env`(merge-update + chmod 600)
|
|
6227
6262
|
- `src/cli-ui/cmd-handlers.ts` — status / start / stop / restart / uninstall 实现
|
|
6228
6263
|
- `src/cli-ui/entry-menu.ts` — bare invocation 用的入口菜单
|
|
6229
6264
|
- `src/cli-ui/paths.ts` — 共享路径常量
|
|
@@ -6238,15 +6273,15 @@ this is the actual first published 0.5.x release.
|
|
|
6238
6273
|
- `@inquirer/prompts ^8.4.3` — modern interactive prompts (上下键 / Space / 输入隐藏)。~80KB 加到 dist。
|
|
6239
6274
|
|
|
6240
6275
|
### Migration notes
|
|
6241
|
-
- 老用户升级:`npm install -g
|
|
6242
|
-
- 想跳过新向导:`
|
|
6243
|
-
- 后台启动取代了之前文档里推荐的 `nohup
|
|
6276
|
+
- 老用户升级:`npm install -g agim@0.5.0`。已有 `~/.agim/config.json` 全部兼容,新增 SMTP / Baidu 配置可以走新向导补充
|
|
6277
|
+
- 想跳过新向导:`agim config wechat` / `config telegram` 等老路径仍然能用
|
|
6278
|
+
- 后台启动取代了之前文档里推荐的 `nohup agim start &` 写法
|
|
6244
6279
|
|
|
6245
6280
|
## [0.4.0] - 2026-05-11
|
|
6246
6281
|
|
|
6247
6282
|
> **核心主题(两条)**:
|
|
6248
6283
|
>
|
|
6249
|
-
> 1. **codex 也接
|
|
6284
|
+
> 1. **codex 也接 agim MCP**——/remind 4 工具 + /memo 5 工具,9 个全部对它开放。三大 agent(claude-code / opencode / codex)功能对等。
|
|
6250
6285
|
> 2. **位置消息架构统一化**——Telegram / 飞书的原生位置消息原本走「pending-reply + 启发式拆词」决策链,bug 频出。新版改成 agent-driven:adapter 只缓存坐标,cli.ts 注入结构化 annotation 到用户下一条文本,agent 用 LLM 决策。删除 ~400 行启发式代码,4 个 IM 渠道行为完全一致。
|
|
6251
6286
|
|
|
6252
6287
|
### Refactored — Telegram + 飞书位置消息走 agent-driven 决策(对齐 WeChat H5 流程)
|
|
@@ -6271,32 +6306,32 @@ this is the actual first published 0.5.x release.
|
|
|
6271
6306
|
- 任何长句、短词、混合表达都不再走启发式:「这是我公司」「记下日料店」「不用记了」「这是哪里」都自然处理
|
|
6272
6307
|
- 每个 pin 后续消息额外付出一次 agent 调用(旧版是 deterministic 直存);用稳定性换费用
|
|
6273
6308
|
|
|
6274
|
-
### Added — codex 也能用
|
|
6309
|
+
### Added — codex 也能用 agim MCP 工具
|
|
6275
6310
|
(这一段已在 0.4.0-rc1 时落地,下面是 rc1 的内容)
|
|
6276
6311
|
|
|
6277
6312
|
之前 codex 是唯一一个 reminder/memo 工具完全无法触达的 agent,因为 codex CLI 没有 `--mcp-config` flag。验证发现 codex 0.130.0+ 支持通过 `-c mcp_servers.<name>.{command,args,env}=...` 的 TOML 内联 override 在调用层注册 MCP server——per-spawn、不污染全局 `~/.codex/config.toml`。
|
|
6278
6313
|
|
|
6279
6314
|
实现:
|
|
6280
6315
|
|
|
6281
|
-
- **`src/plugins/agents/codex/build-mcp-cli-args.ts`**:纯函数,输入 `{sockPath, runId}`,输出 6 个 argv entries(3 对 `-c key=value`)。TOML 转义走 `JSON.stringify` 兼容 basic-string 语法。共享 claude-code 那个 `mcp-approval-server.js`(同一个二进制读 `
|
|
6282
|
-
- **`codex/index.ts` 的 `prepareCommand`**:fallback 三道闸——`
|
|
6316
|
+
- **`src/plugins/agents/codex/build-mcp-cli-args.ts`**:纯函数,输入 `{sockPath, runId}`,输出 6 个 argv entries(3 对 `-c key=value`)。TOML 转义走 `JSON.stringify` 兼容 basic-string 语法。共享 claude-code 那个 `mcp-approval-server.js`(同一个二进制读 `AGIM_APPROVAL_SOCK + AGIM_RUN_ID`,已经 channel-agnostic)。
|
|
6317
|
+
- **`codex/index.ts` 的 `prepareCommand`**:fallback 三道闸——`AGIM_APPROVAL_DISABLED=1` / `approvalBus.getSocketPath()` 空 / 无 IM context 任一不满足就降级到无 MCP 模式,codex 仍能正常调用。命中时生成 UUID runId → `approvalBus.registerRun(runId, ...)` → MCP `-c` 参数前置到 argv 头部(codex 的 clap 要求全局参数在 `exec` 之前)→ `cleanup` 在 spawn 退出后 `unregisterRun`。
|
|
6283
6318
|
- **`codex exec resume` 不再接 `-s`**(codex 0.130 改的):resume 路径继承原会话 sandbox,传 `-s` 直接 `unexpected argument` 报错。修复:sandbox flag 仅在 fresh `exec` 加。
|
|
6284
|
-
- **`--dangerously-bypass-approvals-and-sandbox`**:codex 在 `exec --json` 非交互模式下默认会 auto-cancel 所有 MCP 工具调用(找不到 TUI 让用户点 approve)。这个 flag 是 codex 0.130 目前唯一让 MCP 工具在非交互模式下能实际运行的方式。代价是 codex 自己的 bash/edit 也失去 sandbox。提供 `
|
|
6285
|
-
- **AGENTS.md 写明命名差异**:claude-code/opencode 暴露 `
|
|
6319
|
+
- **`--dangerously-bypass-approvals-and-sandbox`**:codex 在 `exec --json` 非交互模式下默认会 auto-cancel 所有 MCP 工具调用(找不到 TUI 让用户点 approve)。这个 flag 是 codex 0.130 目前唯一让 MCP 工具在非交互模式下能实际运行的方式。代价是 codex 自己的 bash/edit 也失去 sandbox。提供 `AGIM_CODEX_SAFE_MODE=1` opt-out(代价:MCP 工具不可用)。
|
|
6320
|
+
- **AGENTS.md 写明命名差异**:claude-code/opencode 暴露 `mcp__agim__save_memo`;codex 暴露 bare name `save_memo`。模型按错名调用会静默失败。
|
|
6286
6321
|
|
|
6287
6322
|
**版本下限**:codex CLI ≥ 0.130.0(`mcp` 子命令 + `-c mcp_servers.*` TOML override 同时存在的最早稳定版)。
|
|
6288
6323
|
|
|
6289
|
-
**不在范围**:codex 自己的 Read/Edit/Bash 走 approval-bus——需要把 codex 跑成 `codex mcp-server` 让
|
|
6324
|
+
**不在范围**:codex 自己的 Read/Edit/Bash 走 approval-bus——需要把 codex 跑成 `codex mcp-server` 让 agim 当 MCP client,是 v0.5.x 级别的大重构。
|
|
6290
6325
|
|
|
6291
6326
|
## [0.3.1] - 2026-05-11
|
|
6292
6327
|
|
|
6293
|
-
### Added — codex 也能用
|
|
6328
|
+
### Added — codex 也能用 agim MCP 工具
|
|
6294
6329
|
之前 codex 是唯一一个 reminder/memo 工具完全无法触达的 agent,因为 codex CLI 没有 `--mcp-config` flag。验证发现 codex 0.130.0+ 支持通过 `-c mcp_servers.<name>.{command,args,env}=...` 的 TOML 内联 override 在调用层注册 MCP server——per-spawn、不污染全局 `~/.codex/config.toml`。
|
|
6295
6330
|
|
|
6296
6331
|
实现:
|
|
6297
6332
|
|
|
6298
|
-
- **`src/plugins/agents/codex/build-mcp-cli-args.ts`**:纯函数,输入 `{sockPath, runId}`,输出 6 个 argv entries(3 对 `-c key=value`)。TOML 转义走 `JSON.stringify` 兼容 basic-string 语法。共享 claude-code 那个 `mcp-approval-server.js`(同一个二进制读 `
|
|
6299
|
-
- **`codex/index.ts` 的 `prepareCommand`**:fallback 三道闸——`
|
|
6333
|
+
- **`src/plugins/agents/codex/build-mcp-cli-args.ts`**:纯函数,输入 `{sockPath, runId}`,输出 6 个 argv entries(3 对 `-c key=value`)。TOML 转义走 `JSON.stringify` 兼容 basic-string 语法。共享 claude-code 那个 `mcp-approval-server.js`(同一个二进制读 `AGIM_APPROVAL_SOCK + AGIM_RUN_ID`,已经 channel-agnostic)。
|
|
6334
|
+
- **`codex/index.ts` 的 `prepareCommand`**:fallback 三道闸——`AGIM_APPROVAL_DISABLED=1` / `approvalBus.getSocketPath()` 空 / 无 IM context(threadId+platform+channelId)任一不满足就降级到无 MCP 模式,codex 仍能正常调用。命中时生成 UUID runId → `approvalBus.registerRun(runId, ...)` → MCP `-c` 参数前置到 argv 头部(codex 的 clap 要求全局参数在 `exec` 之前)→ `cleanup` 在 spawn 退出后 `unregisterRun`。
|
|
6300
6335
|
- **测试**:39 个新单测覆盖 builder(argv shape + TOML 双引号/反斜杠/UUID/空格路径 escaping)+ adapter(fallback 三道、happy path、runId 嵌入、cleanup、cwd+planMode+resume 与 MCP -c 共存、并发产生不同 runId)。
|
|
6301
6336
|
|
|
6302
6337
|
**仍然不做**:
|
|
@@ -6338,7 +6373,7 @@ this is the actual first published 0.5.x release.
|
|
|
6338
6373
|
- 17 单测覆盖 short/heuristic/fallback 各路径 + emoji / 中英混合 / 长句不卷死等 adversarial 输入
|
|
6339
6374
|
|
|
6340
6375
|
### Fixed — 中国境内坐标双重偏移(影响 Telegram + 飞书 + H5 三条路径)
|
|
6341
|
-
**根因**:iOS Core Location(Apple,iOS 7+)和 Android Google Play Services 都会在中国境内**主动**把 WGS-84 偏移成 GCJ-02 才交给应用层(合规要求)。Telegram / 飞书 / 浏览器 `navigator.geolocation` 都吃这个偏移,传给
|
|
6376
|
+
**根因**:iOS Core Location(Apple,iOS 7+)和 Android Google Play Services 都会在中国境内**主动**把 WGS-84 偏移成 GCJ-02 才交给应用层(合规要求)。Telegram / 飞书 / 浏览器 `navigator.geolocation` 都吃这个偏移,传给 agim 时已经是 GCJ-02。我们当 WGS-84 存入库,构 amap URL 时再做一次 WGS→GCJ-02 = 双重偏移,~500m-1km。
|
|
6342
6377
|
|
|
6343
6378
|
**修复**:
|
|
6344
6379
|
|
|
@@ -6355,8 +6390,8 @@ this is the actual first published 0.5.x release.
|
|
|
6355
6390
|
### Fixed — Venue title 在 where_label 中保留
|
|
6356
6391
|
之前 cli.ts pending consumer 写 `where_label` 时是 `venueAddress ?? venueLabel`——`??` 让 venueAddress 优先,title 就被丢了。Telegram venue 通常两者都有("黄龙国际中心" + "学院路77号"),title 是用户最容易认出的那条。改成 `[venueLabel, venueAddress].filter(Boolean).join(' · ')`,两者都存,搜任一 token 都能命中。回复卡片同步加一行 `📍 <title> · <address>` 让用户看见保留。
|
|
6357
6392
|
|
|
6358
|
-
### Site (separate repo:
|
|
6359
|
-
不直接绑 npm 包,但同期
|
|
6393
|
+
### Site (separate repo: agim-site)
|
|
6394
|
+
不直接绑 npm 包,但同期 agim-site 跑了一波 optimization pass:
|
|
6360
6395
|
|
|
6361
6396
|
- 一键安装命令分 Linux / macOS / Windows 三 tab(同一份 install.sh,uname 自检;Windows 走 WSL2)
|
|
6362
6397
|
- `curl ... | bash` 改 `bash -c "$(curl ...)"`:macOS bash 3.2 + /dev/tty 重连不稳的 pipe 形式换成 Homebrew 同款
|
|
@@ -6371,7 +6406,7 @@ this is the actual first published 0.5.x release.
|
|
|
6371
6406
|
> **核心主题**:`/location` 升级为通用 `/memo`(5W1H 持久记忆库),地图服务从腾讯切到百度,opencode HTTP driver 修复 SSE-broken 回归。这是个有意义的里程碑——位置只是 5W1H 中的一个轴。
|
|
6372
6407
|
|
|
6373
6408
|
### Fixed — opencode HTTP driver: SSE 不发事件时从 POST body 拿文本
|
|
6374
|
-
opencode 1.14.45+ 在新的 `node-http-server` runtime 下 `/event` SSE 只发首个 `server.connected` 然后再不广播任何 bus 事件(`message.part.updated` / `session.idle` 全丢),导致
|
|
6409
|
+
opencode 1.14.45+ 在新的 `node-http-server` runtime 下 `/event` SSE 只发首个 `server.connected` 然后再不广播任何 bus 事件(`message.part.updated` / `session.idle` 全丢),导致 agim 这边收 0 字节,用户在微信里看到「opencode无回复」。
|
|
6375
6410
|
|
|
6376
6411
|
直 curl 复现:POST `/session/:id/message` 这个 endpoint 现在改成阻塞直至 LLM 完成,把整条 assistant message 同步以 JSON 还回来。我们就拿这个:
|
|
6377
6412
|
|
|
@@ -6384,7 +6419,7 @@ opencode 1.14.45+ 在新的 `node-http-server` runtime 下 `/event` SSE 只发
|
|
|
6384
6419
|
新增 3 单测覆盖:drained-only / SSE+POST 同 part 的 dedupe / `drainResponseBody` 的过滤逻辑。35/35 adapter 测试全过。
|
|
6385
6420
|
|
|
6386
6421
|
### Added — 部署脚本自动重启 opencode
|
|
6387
|
-
`/root/.claude/bgjobs/scripts/
|
|
6422
|
+
`/root/.claude/bgjobs/scripts/agim-deploy.sh` 末尾加一段:agim 重启完成后如果检测到 `opencode serve --port 14199` 还在跑,调 `opencode-restart.sh` 把它弹一遍,让新 daemon 继承当前 shell 的 `AGIM_APPROVAL_SOCK`(agim 每次重启会换 socket hash,旧 daemon 还指向旧 socket → MCP 工具调用会回「后台消息服务不可用」)。一行钩子,一劳永逸。
|
|
6388
6423
|
|
|
6389
6424
|
### Added — 给 place-like memo 主动追问坐标
|
|
6390
6425
|
agent 落库一条「老孙家」「公司新址」这种**明显是地点但用户没给坐标**的 memo 后,会反问一句「要不要顺带补个坐标?」给三个选项(现在抓 GPS / 告地址解析 / 不用)。`save_memo` tool description 里写死的 PROACTIVE FOLLOW-UP 段。同一段还硬塞一份 TOOL INVENTORY 列表(5 个 memo 工具),并明令「不准跟用户说工具下线了」——之前 agent 在 location→memo 重命名后偶尔会胡说「位置工具已下线」。
|
|
@@ -6409,7 +6444,7 @@ agent 落库一条「老孙家」「公司新址」这种**明显是地点但用
|
|
|
6409
6444
|
- schema 里 `created_at` / `updated_at` 默认值改为 `datetime('now', '+8 hours')`(兜底,正常路径 JS 会显式设)
|
|
6410
6445
|
- tool description 里 `when_at` / `when_after` / `when_before` 都说明:**Asia/Shanghai (UTC+8),"YYYY-MM-DD HH:MM:SS",不要带 T 也不要 Z**
|
|
6411
6446
|
- 11 新增单测覆盖:nowSqliteLocal 形状 / toSqliteLocal +8h shift / normalizeWhenAt 各路径(Z / +08:00 / 已 local / null / unparseable)/ created_at 实际写入 UTC+8 / sweep 用 UTC+8 比较
|
|
6412
|
-
- 时区可调:`
|
|
6447
|
+
- 时区可调:`AGIM_TZ_OFFSET_HOURS` env,默认 8(其他时区部署只改这一个就行)
|
|
6413
6448
|
|
|
6414
6449
|
### Changed — opencode agent 系统提示也加上 memo 工具
|
|
6415
6450
|
opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提了 reminder 那 4 个工具,现在加上 memo 那 5 个 (`save_memo` / `search_memos` / `update_memo` / `delete_memo` / `request_location_capture`) 一起列出,并补一段 timezone 说明。这样 opencode 通过 HTTP daemon mode 跑时也知道要带 `_im_context` + 用 UTC+8。
|
|
@@ -6458,12 +6493,12 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6458
6493
|
- 调整三处用户可见输出:
|
|
6459
6494
|
- `POST /api/loc` 推回的"✅ 已记录" 消息列出 3 条链接
|
|
6460
6495
|
- `/location show <id>` 命令详情列出 3 条
|
|
6461
|
-
- `
|
|
6496
|
+
- `mcp__agim__save_location` 和 `list_locations` 工具返回结构加 `mapUrls: { baidu, amap, google }` 字段;旧 `mapUrl`(百度)保留向后兼容
|
|
6462
6497
|
- MCP 工具描述告诉 agent 优先把三条都展示给用户挑
|
|
6463
6498
|
|
|
6464
6499
|
### Changed — 地图服务从腾讯切到百度
|
|
6465
6500
|
- **地理编码**:`apis.map.qq.com/ws/geocoder/v1/` → `api.map.baidu.com/geocoding/v3/`,强制 `ret_coordtype=wgs84ll`(百度默认返 BD-09,必须显式拉 WGS-84 才和浏览器 `navigator.geolocation` 一致——否则存库坐标 vs 浏览器坐标 50–500m 飘移)
|
|
6466
|
-
- **凭据 env**:`
|
|
6501
|
+
- **凭据 env**:`AGIM_TENCENT_MAP_KEY` / `AGIM_TENCENT_MAP_SK` → `AGIM_BAIDU_MAP_AK`(默认 key 流程不需要 SN 签名;如以后开启 SN 校验,文档说明在 `src/core/locations.ts` 头注释里)
|
|
6467
6502
|
- **地图 URI scheme**:默认从 `apis.map.qq.com/uri/v1/marker?...` 改为 `api.map.baidu.com/marker?location=lat,lng&coord_type=wgs84&...`(注意 `coord_type=wgs84` 关键,否则百度按 BD-09 解读飘 50–500m)
|
|
6468
6503
|
- 错误码分类重写:百度状态码体系不同(200/201/202 = 签名 / Referer / IP;401-405 = 配额;1-4 = 找不到/参数错;5/210/211/220/240 = 各种权限 / 配额家族)
|
|
6469
6504
|
- **腾讯 SK 签名代码移除**:`signTencent` 函数 + 4 条相关单测删除。Baidu 默认 key 流程不需要签名;如以后开启 SN 校验,算法是 `MD5(URLencode(path?qs+sk))`(与腾讯的 `MD5(path?raw_qs+sk)` 不同 —— 多一步整体 URL 编码),实现可参考头注释
|
|
@@ -6483,7 +6518,7 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6483
6518
|
→ bus → location-rpc → 发 token + 返 URL
|
|
6484
6519
|
→ claude 回用户 "好的,点开链接授权: <url>"
|
|
6485
6520
|
→ 用户点 → H5 显示 "正在记录: 车" → 授权 → POST → 写库
|
|
6486
|
-
→
|
|
6521
|
+
→ agim fire-and-forget 推回 "✅ 已记录'车' lat,lng [地图]"
|
|
6487
6522
|
```
|
|
6488
6523
|
```
|
|
6489
6524
|
用户 "我的车在哪" → claude 调 list_locations({query:'车'})
|
|
@@ -6503,11 +6538,11 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6503
6538
|
- **架构权衡**:放弃了 `remind-intent.ts` 那种"消息流前置正则探测器"模式。reminder 的 detector 是历史遗留,每条消息都跑一次额外 LLM 调用(就是修过 80s→3s 那个性能问题的祸根)。location 直接让 agent 看工具描述自己判断,零额外 LLM 调用、零误触代价、对话上下文连续。
|
|
6504
6539
|
|
|
6505
6540
|
### Added — `/location here` 浏览器 GPS 捕获
|
|
6506
|
-
- 新子命令 `/location here [备注]` 或 `/location 当前 [备注]`:bot 回一个一次性 HTTPS 链接,用户在 WeChat 内置浏览器点开,授权后 H5 页面调 `navigator.geolocation.getCurrentPosition` 把坐标 POST 回
|
|
6541
|
+
- 新子命令 `/location here [备注]` 或 `/location 当前 [备注]`:bot 回一个一次性 HTTPS 链接,用户在 WeChat 内置浏览器点开,授权后 H5 页面调 `navigator.geolocation.getCurrentPosition` 把坐标 POST 回 agim,agim 写库 + 推回 IM 线程。
|
|
6507
6542
|
- 数据流:`/location here` → 内存 token store 发 32 hex token (10 min TTL,single-shot) → 用户点 URL → `GET /loc?t=...` 渲 H5 → 用户授权 → `POST /api/loc { t, lat, lng, accuracy }` → 验 token → 写 `location_memos`(source=`browser`)→ messenger.sendMessage 把"✅ 位置已收到 + 地图链接"回推到原线程。
|
|
6508
|
-
- **默认 base URL**:`https://agent.iclaw.host`(公共托管入口)。自托管用户可设 `
|
|
6543
|
+
- **默认 base URL**:`https://agent.iclaw.host`(公共托管入口)。自托管用户可设 `AGIM_LOC_BASE_URL=https://your-host` 覆盖。OSS 用户没有 HTTPS endpoint 时可继续用坐标输入路径。
|
|
6509
6544
|
- 新建 `src/core/location-token.ts`:内存 Map,60s 一次的 sweep timer 清过期;test/diagnostic 钩子 `_pendingCount` `_clearAll` `_stopSweep`。
|
|
6510
|
-
- 新建 `src/web/public/loc.html`:单页 H5(无构建依赖、纯内联 CSS+JS),蓝主题与
|
|
6545
|
+
- 新建 `src/web/public/loc.html`:单页 H5(无构建依赖、纯内联 CSS+JS),蓝主题与 agim-site 视觉一致。错误分支覆盖:缺 token / 浏览器不支持 / 用户拒绝授权 / 网络错误。
|
|
6511
6546
|
- 新增 `src/web/server.ts` 公开路由 `GET /loc` + `POST /api/loc`,放在 auth gate 之前(token 即凭证)。`POST /api/loc` 失败时分类回 410(链接过期 / 已使用)/ 400(参数错);写库/dispatch 是 fail-soft,不阻塞 H5 端 200 响应。
|
|
6512
6547
|
- **agent.iclaw.host 部署**:路由复用现有 :3000,CDN 必须配路径白名单只放行 `/loc` 与 `/api/loc`,其他路径(`/tasks` `/reminders` `/api/*`)必须在 CDN 层 404,否则操作员控制台会被外网暴露。
|
|
6513
6548
|
- 7 单测 `location-token.test.ts`:issue/consume 圆环、单次消费、过期回收(Date.now stub)、多 token 独立、跨用户隔离。
|
|
@@ -6515,12 +6550,12 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6515
6550
|
### Added — `/location` 位置备忘(基础版)
|
|
6516
6551
|
- 新 slash 命令 `/location`(别名 `/loc` `/位置`):记录"在 X 位置干了 Y 事"型备忘。
|
|
6517
6552
|
- **零依赖坐标输入**:`/location 39.908,116.397 [备注]` —— 支持 `,` `,` 或空格分隔,负数支持。
|
|
6518
|
-
- **可选地址解析**:`/location 国贸三期 [备注]`,需配置 `
|
|
6519
|
-
- **腾讯地图 SK 签名支持**:开启了"WebServiceAPI 强制签名校验"的 key 配 `
|
|
6553
|
+
- **可选地址解析**:`/location 国贸三期 [备注]`,需配置 `AGIM_TENCENT_MAP_KEY`([lbs.qq.com](https://lbs.qq.com) 注册免费 key)。无 key 时给友好错误提示,引导用户用坐标路径。
|
|
6554
|
+
- **腾讯地图 SK 签名支持**:开启了"WebServiceAPI 强制签名校验"的 key 配 `AGIM_TENCENT_MAP_SK`,自动 MD5 签名。算法:参数按 key 字典序排序、用未 URL-encode 的原值拼 `k=v&...`、与 `path?qs+SK` 整体 MD5 → 32 位 lowercase hex。已对照官方 API 实测验证。
|
|
6520
6555
|
- **细分错误反馈**:地理编码失败按状态码分类(`signature`/`quota`/`not_found`/`http`/`unknown`),命令直接告诉用户是配额满了还是签名错了或地址不对。
|
|
6521
6556
|
- 子命令:`list [N]` / `show <id>` / `delete <id>` / `help`,全部 per-user owner-scoped(同 `/remind` `/cron` 模式)。
|
|
6522
6557
|
- **地图链接回显**:每条记录附 `https://apis.map.qq.com/uri/v1/marker?...` URI,WeChat 内置浏览器/地图 App 可直接唤起。
|
|
6523
|
-
- 数据:`~/.
|
|
6558
|
+
- 数据:`~/.agim/locations.db`(路径可通过 `AGIM_LOCATIONS_DB` 覆盖),fail-soft via 现有 `sqlite-helper`。
|
|
6524
6559
|
- 18 单测:坐标解析(中文逗号 / 负数 / 范围校验)、地图 URL 构建、地理编码 env 探测、SK 签名(含 reference fixture)、CRUD 全流程 + owner scoping。
|
|
6525
6560
|
- **不包含**:浏览器 geolocation 链接(Phase 2,要求 HTTPS endpoint),LLM 自然语言识别(Phase 3)。
|
|
6526
6561
|
|
|
@@ -6533,7 +6568,7 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6533
6568
|
|
|
6534
6569
|
### Added — 只读工具自动放行(默认开启)
|
|
6535
6570
|
- 新增 `READONLY_TOOLS` 短路:`Read` / `Grep` / `Glob` / `LS` / `NotebookRead` 这 5 个 Claude Code 原生只读工具的审批请求在 `approval-bus._registerPending` 入口被直接放行——不建 pending、不通知、不写 IM 卡片。零 IM 往返,给 LLM 自由探索代码而不打扰用户。
|
|
6536
|
-
- 全局开关:`
|
|
6571
|
+
- 全局开关:`AGIM_AUTOALLOW_READONLY=0`(默认 1)关闭。
|
|
6537
6572
|
- per-thread 开关:`/approval readonly off|on`(别名 `/approval ro`)。仅本会话内存生效,重启后回到全局默认。
|
|
6538
6573
|
- 审计:每次短路写一行 `approval.bus.readonly_auto_allow` info log,并在 metrics 新增 `totalReadonlyAutoAllowed` 计数。
|
|
6539
6574
|
- `/approval`(无参)和 `/approval readonly` 都会显示当前状态行 `🛡 只读自动放行:开启 ...`。
|
|
@@ -6597,7 +6632,7 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6597
6632
|
**Agent MCP 工具(提醒兜底创建)**
|
|
6598
6633
|
- 4 个工具:`create_reminder` / `list_reminders` / `cancel_reminder` / `snooze_reminder`
|
|
6599
6634
|
- claude-code:复用现有 `--mcp-config` per-spawn 注入
|
|
6600
|
-
- opencode (stdio):`prepareCommand` 注入 `
|
|
6635
|
+
- opencode (stdio):`prepareCommand` 注入 `AGIM_RUN_ID` extraEnv,全局 `mcp.agim` config 自动注册
|
|
6601
6636
|
- opencode (http):常驻 daemon 共享 MCP server,agent-asserted `_im_context` 兜底(**单用户限定**——agent 可伪造身份)
|
|
6602
6637
|
- codex:未实施(`codex exec` 不支持外部 MCP)
|
|
6603
6638
|
|
|
@@ -6607,13 +6642,13 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6607
6642
|
|
|
6608
6643
|
### Added — 邮件投递通道
|
|
6609
6644
|
- 注册为 `email` messenger(`threadId` 即邮箱地址)
|
|
6610
|
-
- nodemailer + Gmail / QQ / 163 / 任意 SMTP(env:`
|
|
6645
|
+
- nodemailer + Gmail / QQ / 163 / 任意 SMTP(env:`AGIM_SMTP_HOST/PORT/USER/PASS/FROM/SECURE`)
|
|
6611
6646
|
- `/remind email <addr> <time> <text>` 内联 / `/remind bindemail` 绑定默认 / `/remind email <time> <text>` 走默认
|
|
6612
6647
|
- 邮件 + 循环 + LLM 润色组合自由
|
|
6613
6648
|
|
|
6614
6649
|
### Added — WeChat context_token 持久化
|
|
6615
6650
|
- iLink Bot API 30 分钟 context_token TTL 之前只存内存,重启即丢,导致循环提醒在 wechat 端高概率失败
|
|
6616
|
-
- 新 SQLite 表(`~/.
|
|
6651
|
+
- 新 SQLite 表(`~/.agim/wechat-context.db`),收消息时写穿,启动时 warm 内存 Map,cleanup 同步清 DB
|
|
6617
6652
|
|
|
6618
6653
|
### Schema migrations
|
|
6619
6654
|
新建 / 扩展三张表(在 `reminders.db` 内):
|
|
@@ -6642,7 +6677,7 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6642
6677
|
### Added — WeChat & Telegram rich media support
|
|
6643
6678
|
|
|
6644
6679
|
- **WeChat 图片 / 文件 / 语音 / 视频接收**:`handleIncomingMessage` 现在处理 iLink `item_list` 的全部 5 种类型(TEXT=1, IMAGE=2, VOICE=3, FILE=4, VIDEO=5),此前只处理 TEXT。
|
|
6645
|
-
- **图片**:通过 iLink CDN 下载到 `~/.
|
|
6680
|
+
- **图片**:通过 iLink CDN 下载到 `~/.agim/media/wechat/<userId>/`,转为 `[图片附件:/path]` 标记传递给 Agent
|
|
6646
6681
|
- **语音**:优先使用微信自带转写(`voice_item.text`),无转写时下载音频后走 OpenAI Whisper 或 whisper.cpp(复用 `src/core/transcribe.ts`)
|
|
6647
6682
|
- **文件**:下载并保留原始文件名,显示大小,转为 `[文件附件:/path (name, size)]`
|
|
6648
6683
|
- **视频**:下载并显示时长和大小,转为 `[视频附件:/path (duration, size)]`
|
|
@@ -6671,7 +6706,7 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6671
6706
|
- **审批总线 composite key 测试同步**:P0 #4 把 `ApprovalBus` 的内部 keying 从裸 threadId 改成 `platform:channelId:threadId`,但单元测试仍然按裸 `'thread-A'` 调 `hasPendingFor` / `resolvePending`,导致 `bun test` 红 37 项。所有相关测试(approval-bus、synthetic、router、approval 命令、mcp-approval、opencode-http、discord)改用 `threadKey()` 显式构造 composite,注释中误导性的 "backward compat" 承诺一并删除。
|
|
6672
6707
|
- **Claude session 标记顺序回归**:P1 #5 把 `markClaudeSessionPrimed` 从 `routeMessage` 之前挪到了之后;如果 claude 已写出 jsonl 但 run 中途出错,下一轮就会用 `--session-id` 而不是 `--resume`,触发 "session already exists"。0.2.33 把 markPrimed 移回 `onAgentResolved` 内部、紧跟 `setClaudeSessionId`,恢复"先 mark 再调 adapter"的语义。
|
|
6673
6708
|
- **Cookie 加固**:`web.public_bind_warning` 改在 server 启动时打一次(之前每次登录都打);`Set-Cookie` 在 public bind 或 `X-Forwarded-Proto: https` 时自动附加 `Secure`,纯 localhost dev 不加。
|
|
6674
|
-
- **静态页测试改写**:原 `/tasks` 用例还在断言 `
|
|
6709
|
+
- **静态页测试改写**:原 `/tasks` 用例还在断言 `AGIM_TOKEN` 注入到 HTML,改成走真实流程:未登录 302 到 `/login`,POST `/api/auth/login` 拿 cookie 后 200,断言 HTML 中不再含 token。
|
|
6675
6710
|
- **死代码清理**:`editCardOnThreadResolution` 的 thread-scan fallback 在 composite key 下永远 miss,删掉;签名从 `(threadId, info, decision, by)` 缩为 `(info, decision, by)`。
|
|
6676
6711
|
- **小项**:`web/server.ts` 删未使用的 `lstat` import;`settings.html` toast 调用末尾被误删的 `;` 补回。
|
|
6677
6712
|
- **测试 flake 修复**:`test/integration/acp-server.test.ts` 在全套并发下被 `intent.test.ts` 注册的空-yield 子代理污染(router intent fallback 到 opencode → 返回 '')。ACP 测试在 `beforeAll` 重新注册 4 个 profile 名同名 stub 让其也产出内容。
|
|
@@ -6687,8 +6722,8 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6687
6722
|
|
|
6688
6723
|
### Release
|
|
6689
6724
|
|
|
6690
|
-
- 重新发布生产硬化修复到 npm,确保生产环境通过 `npm install -g
|
|
6691
|
-
- 包含子任务会话隔离、WebSocket 入站串行化、session 元数据写锁、安全默认值加固、release/CI 门禁收紧,以及 `
|
|
6725
|
+
- 重新发布生产硬化修复到 npm,确保生产环境通过 `npm install -g agim@0.2.31` 可以拿到 v0.2.30 严格代码审查后的全部修复。
|
|
6726
|
+
- 包含子任务会话隔离、WebSocket 入站串行化、session 元数据写锁、安全默认值加固、release/CI 门禁收紧,以及 `agim --version` 跟随 `package.json` 的修复。
|
|
6692
6727
|
|
|
6693
6728
|
---
|
|
6694
6729
|
|
|
@@ -6701,10 +6736,10 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6701
6736
|
- **WebSocket 入站串行化**:Web Chat 同一浏览器连接上的多条消息按顺序逐条进入 `routeMessage`,降低快速连发时 Agent 子进程并行、历史乱序和流式回复交错风险。
|
|
6702
6737
|
- **Session 元数据写锁**:`patchSession`、usage roll-up、Claude/OpenCode/Codex session id setters、subtask counter/update、agent switch/reset 等读改写路径纳入 per-key lock;`nextSubtaskId` 并发调用保持唯一递增。
|
|
6703
6738
|
- **安全默认值**:
|
|
6704
|
-
- Web 控制台默认监听 `127.0.0.1`;需要对外暴露时显式设置 `
|
|
6705
|
-
- `~/.
|
|
6739
|
+
- Web 控制台默认监听 `127.0.0.1`;需要对外暴露时显式设置 `AGIM_WEB_BIND=0.0.0.0`,建议放在 HTTPS 反代后。
|
|
6740
|
+
- `~/.agim/config.json` 写入时强制 `0600`,目录创建使用 `0700`。
|
|
6706
6741
|
- Telegram 媒体下载的 `curl` 保留 `--location` 但加 `--max-redirs 0`,拒绝跟随重定向到任意主机。
|
|
6707
|
-
- **CLI 版本号**:`
|
|
6742
|
+
- **CLI 版本号**:`agim --version` 改为读取包内 `package.json`,不再硬编码旧值(之前可能输出 `0.2.18`)。
|
|
6708
6743
|
|
|
6709
6744
|
### Build / release
|
|
6710
6745
|
|
|
@@ -6720,38 +6755,38 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6720
6755
|
|
|
6721
6756
|
## [0.2.26] - 2026-05-08
|
|
6722
6757
|
|
|
6723
|
-
### Changed — Rebrand to `
|
|
6758
|
+
### Changed — Rebrand to `agim`
|
|
6724
6759
|
|
|
6725
|
-
- **npm 包名**:`
|
|
6726
|
-
- **CLI 命令**:`
|
|
6727
|
-
- **仓库 URL**:`package.json.repository.url` 从原作者 `ceociocto/
|
|
6728
|
-
- **Web 控制台品牌**:`/`、`/tasks`、`/settings` 三个静态页的浏览器标题、欢迎语、左上角 logo、Settings 卡里的 `
|
|
6729
|
-
- **README + README.zh-CN**:`What's new` / 安装命令 / Quick Start / CLI 命令表 / Project Structure ASCII 树标签,全部改为新品牌;新增「Migrating from `
|
|
6760
|
+
- **npm 包名**:`agim` → `agim`(产品化分支)。
|
|
6761
|
+
- **CLI 命令**:`agim` → `agim`(`bin` 字段同步更新)。
|
|
6762
|
+
- **仓库 URL**:`package.json.repository.url` 从原作者 `ceociocto/agim` 切到当前仓库 `benking007/agim`,新增 `homepage` / `bugs` / `publishConfig{access:public,provenance:true}` 字段。
|
|
6763
|
+
- **Web 控制台品牌**:`/`、`/tasks`、`/settings` 三个静态页的浏览器标题、欢迎语、左上角 logo、Settings 卡里的 `agim config wechat` 提示文案,全部改为 `agim`。
|
|
6764
|
+
- **README + README.zh-CN**:`What's new` / 安装命令 / Quick Start / CLI 命令表 / Project Structure ASCII 树标签,全部改为新品牌;新增「Migrating from `agim`」回退指引。
|
|
6730
6765
|
- **LICENSE 文件**:补齐 MIT 全文(之前 `package.json` 声明 MIT 但根目录无 LICENSE 文件),版权归属保持 `Jerry`。
|
|
6731
|
-
- **`THEME_KEY`**:localStorage 主题 key 从 `
|
|
6766
|
+
- **`THEME_KEY`**:localStorage 主题 key 从 `agim-theme` → `agim-theme`(用户在升级后第一次访问会丢失主题偏好;其他 localStorage key `agim-lang` / `agim-history` 保留以保住语言与对话历史)。
|
|
6732
6767
|
|
|
6733
6768
|
### Unchanged — drop-in compat
|
|
6734
6769
|
|
|
6735
|
-
为了让老用户 `npm uninstall -g
|
|
6736
|
-
- **配置目录**:`~/.
|
|
6737
|
-
- **环境变量**:60+ 处 `
|
|
6738
|
-
- **HTTP 头**:`X-
|
|
6739
|
-
- **Window 全局**:`window.
|
|
6740
|
-
- **ACP 服务名**:`
|
|
6741
|
-
- **MCP 测试 fixture**:`mcpServers.
|
|
6742
|
-
- **内部 client ID**:`
|
|
6770
|
+
为了让老用户 `npm uninstall -g agim && npm install -g agim` 后零迁移成本运行:
|
|
6771
|
+
- **配置目录**:`~/.agim/`、`~/.agim-workspaces/<agent>/` 路径不变
|
|
6772
|
+
- **环境变量**:60+ 处 `AGIM_*` 前缀不变
|
|
6773
|
+
- **HTTP 头**:`X-Agim-Token` / `x-agim-token` 不变
|
|
6774
|
+
- **Window 全局**:`window.AGIM_TOKEN` 不变
|
|
6775
|
+
- **ACP 服务名**:`agim-gateway` 不变(线上 ACP 客户端通过这个名字 discover)
|
|
6776
|
+
- **MCP 测试 fixture**:`mcpServers.agim` 不变
|
|
6777
|
+
- **内部 client ID**:`agim:${ts}` 格式不变
|
|
6743
6778
|
|
|
6744
6779
|
### Notes
|
|
6745
6780
|
|
|
6746
|
-
- 发布走 npm OIDC trusted publishing(`release.yml` 不需要改),首次发布前需在 npmjs.com 上为 `
|
|
6747
|
-
- 老 `
|
|
6781
|
+
- 发布走 npm OIDC trusted publishing(`release.yml` 不需要改),首次发布前需在 npmjs.com 上为 `agim` 配置 trusted publisher 指向 `benking007/agim` 仓库 + `release.yml` workflow。
|
|
6782
|
+
- 老 `agim@0.2.25` 包在 npmjs.com 上保持不动,可继续安装。
|
|
6748
6783
|
|
|
6749
6784
|
---
|
|
6750
6785
|
|
|
6751
6786
|
## [0.2.23] - 2026-05-07
|
|
6752
6787
|
|
|
6753
6788
|
### Added — Web console PR-D
|
|
6754
|
-
- **Agent workspace 文件浏览器**:`/tasks` 新增 **Files** tab,只读浏览 `~/.
|
|
6789
|
+
- **Agent workspace 文件浏览器**:`/tasks` 新增 **Files** tab,只读浏览 `~/.agim-workspaces/<agent>/`(CLAUDE.md / AGENTS.md / 临时笔记等)。左侧目录树 + 右侧文件预览,点目录进入、点文件预览,文件 1 MiB 上限 + 二进制(首 8 KB NUL 探测)走 base64。后端 `GET /api/workspace-files?agent=&path=` 双重防 traversal:agent 必须在 `registry.listAgents()` 白名单,路径必须等于或位于 `defaultAgentCwd(agent)` base 之下,否则 400。
|
|
6755
6790
|
- **Job 批量操作**:Jobs tab 加多选 checkbox + 全选表头 + 隐藏式批量工具栏(Run selected / Cancel selected);选中态跨刷新保留——按可见行 reconcile,不会被 list mutation 抹掉。后端新 `POST /api/jobs/batch-cancel` / `batch-run` 接受 `{ ids: number[] }`(最多 100),per-id 结果不互相阻断。
|
|
6756
6791
|
|
|
6757
6792
|
### Changed
|
|
@@ -6764,7 +6799,7 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6764
6799
|
- **SSE 实时事件流**:新建 `src/core/event-bus.ts`——进程内 publish/subscribe,4 类事件(`audit` / `approval` / `job` / `metrics`),200 条 ring buffer。新连接 replay 一次避免空白等待。
|
|
6765
6800
|
- **`GET /events` 端点**:token 走 `?token=...`(EventSource 不支持自定义 header),25s 心跳防 nginx idle close,listener 错误在 `publish()` 内吞掉避免拖坏起源动作。
|
|
6766
6801
|
- **Dashboard 实时刷新**:`tasks.html` 用 `EventSource('/events?token=...')`,事件触发 `refreshIfVisible(paneId, loader)` 只刷可见 tab;轮询保留作为 fallback。`approval requested` 事件让 Approvals tab 标签闪一下高亮(动态注入的 CSS keyframe)。
|
|
6767
|
-
- **Workspace 完整 CRUD UI**:`settings.html` 新增 Workspaces 卡片,列表 + 新增 / 编辑 / 删除表单(id 锁定防误改、default 行不可删)。后端 `GET /api/workspaces?full=1` / `POST` upsert / `PATCH /:id` / `DELETE /:id`,每次 mutation persist 回 `~/.
|
|
6802
|
+
- **Workspace 完整 CRUD UI**:`settings.html` 新增 Workspaces 卡片,列表 + 新增 / 编辑 / 删除表单(id 锁定防误改、default 行不可删)。后端 `GET /api/workspaces?full=1` / `POST` upsert / `PATCH /:id` / `DELETE /:id`,每次 mutation persist 回 `~/.agim/config.json`。
|
|
6768
6803
|
- `WorkspaceRegistry.remove(id)` 拒绝 `'default'`,`listFull()` 返回完整 `WorkspaceConfig[]`(含 member ids)。
|
|
6769
6804
|
|
|
6770
6805
|
## [0.2.21] - 2026-05-07
|
|
@@ -6778,7 +6813,7 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6778
6813
|
|
|
6779
6814
|
### Added — Web console PR-A
|
|
6780
6815
|
- **三态主题**:light / dark / system 三档循环切换,按钮在 head 加载完前同步应用 `:root[data-theme]`,避免主题闪烁。`prefers-color-scheme: dark` 仅在 `data-theme` 缺失(system 模式)时生效。语言 + 主题偏好都落在 localStorage。
|
|
6781
|
-
- **错误边界**:新建 `src/web/public/_app.js`——`window.
|
|
6816
|
+
- **错误边界**:新建 `src/web/public/_app.js`——`window.agim` 命名空间提供 `theme` / `i18n` / `api` / `showError`,自动安装 `window.onerror` + `unhandledrejection` 监听,让脚本错误以浮层形式可见,不再静默死掉。
|
|
6782
6817
|
- **In-chat 审批卡**:`/` 聊天界面收到工具审批请求时弹出 inline 卡片(Allow / Deny / Allow + Auto),点击通过 WS `approval-action` 走回 `approvalBus.resolvePending()`,跟 Telegram inline-button 同一条路径。
|
|
6783
6818
|
- `approval-router` 默认 `buttonCallbackPlatforms` 加 `'discord'` / `'web'`;新导出 `bindButtonHandlerForPlatform(platform)` 给延迟注册的 messenger(web 是其中之一)调用,避免 install-before-register 时序问题。
|
|
6784
6819
|
|
|
@@ -6820,7 +6855,7 @@ opencode http adapter 的 `buildImContextInstruction` system prompt 之前只提
|
|
|
6820
6855
|
### Fixed — P2 web/HTTP hardening
|
|
6821
6856
|
- **M1** 静态页响应头:`X-Frame-Options: DENY` / `X-Content-Type-Options: nosniff` / `Referrer-Policy: no-referrer` / Content-Type 加 `charset=utf-8` / CSP 锁第三方资源(`script-src` / `style-src` 暂留 `'unsafe-inline'`,nonce 化留 P3)。
|
|
6822
6857
|
- **M2** Prometheus 标签基数白名单:`KNOWN_INTENTS = {default,explicit,fallback,llm,topic,keyword,sticky}`、`KNOWN_PLATFORMS = {telegram,feishu,wechat,discord,web,acp,acp-server,rest,rest-msg}`,命中外的桶到 `'other'`。
|
|
6823
|
-
- **M3** WS 连接上限:默认 100,env `
|
|
6858
|
+
- **M3** WS 连接上限:默认 100,env `AGIM_MAX_WS_CLIENTS` 覆盖;超限时 `1013 Try Again Later`。
|
|
6824
6859
|
- **M4** `/api/health` 改为 token gate 之前公开(k8s liveness 友好)。
|
|
6825
6860
|
- **M11** ACP 测试入口的 `JSON.parse` 包 `try/catch` + endpoint 类型校验,错误 body 落 400 而非 500。
|
|
6826
6861
|
|
|
@@ -6863,21 +6898,21 @@ P0 + P1 安全收口,配 `docs/code-review-2026-05-06-main.md`。
|
|
|
6863
6898
|
|
|
6864
6899
|
### Fixed — P0 hotfix
|
|
6865
6900
|
- **H1** Web REST/WS token 比较切到 `crypto.timingSafeEqual`,抽 `src/utils/safe-equal.ts` 与 `acp-server.ts` 共用。
|
|
6866
|
-
- **H2** `serveIndexHtml` 用 `JSON.stringify(token)` 注入 `window.
|
|
6867
|
-
- **H3** Schedule `notify_url` SSRF 防护:`validateWebhookUrl` 白名单 `http(s)`、黑名单 RFC1918 / loopback / link-local / CGNAT / IPv6 ULA / fe80::;`
|
|
6901
|
+
- **H2** `serveIndexHtml` 用 `JSON.stringify(token)` 注入 `window.AGIM_TOKEN`,防 token 含 `'` / `</script>` 破坏 JS 字面量。
|
|
6902
|
+
- **H3** Schedule `notify_url` SSRF 防护:`validateWebhookUrl` 白名单 `http(s)`、黑名单 RFC1918 / loopback / link-local / CGNAT / IPv6 ULA / fe80::;`AGIM_ALLOW_PRIVATE_WEBHOOKS=1` 显式 opt-in;fetch 加 10s `AbortSignal` + `redirect: 'manual'` + 64 KiB 响应上限;`createSchedule` 与 `fireSchedule` 双层校验。
|
|
6868
6903
|
- **H8** `settings.html` ACP 测试按钮:原代码 `const res` 重复声明 + 引用未定义 `endpoint`/`auth`,整页脚本 SyntaxError,功能必坏。改读 `agent.endpoint` / `agent.auth`。
|
|
6869
|
-
- **H10** Telegram bot token 不再随错误日志泄露:`logger.ts` 加 `redact.paths`(`*.token` / `*.botToken` / `*.apiKey` / `headers.authorization` / `x-
|
|
6904
|
+
- **H10** Telegram bot token 不再随错误日志泄露:`logger.ts` 加 `redact.paths`(`*.token` / `*.botToken` / `*.apiKey` / `headers.authorization` / `x-agim-token` 等);图片 / 语音下载 catch 路径用本地 `scrub()` 把 token 字面量替换 `[REDACTED]`,覆盖 curl stderr 带回 URL 的场景。
|
|
6870
6905
|
|
|
6871
6906
|
### Fixed — P1 runtime hardening
|
|
6872
6907
|
- **H4** `RateLimiter` bucket 无界:`allow()` 内置 `maybeSweep`,每 30 min 机会式触发 cleanup(不引入 `setInterval` timer);新增 `size()` 诊断访问器。
|
|
6873
|
-
- **H6** Job result 大小:`resolveMaxResultBytes()` 默认 1 MiB,env `
|
|
6908
|
+
- **H6** Job result 大小:`resolveMaxResultBytes()` 默认 1 MiB,env `AGIM_JOB_RESULT_MAX_BYTES` 覆盖;超过 cap 整 chunk 丢弃(边界落在 UTF-8/JSON 事件分隔上),尾部拼 truncation footer,落 warn `event: 'job.result.truncated'`。
|
|
6874
6909
|
- **H9** WeChat 凭证文件权限:`saveCredentials` 用 `mkdir(.., {mode:0o700})` + `writeFile(.., {mode:0o600})`;`loadCredentials` 读时 `stat`,松权落 warn 提示用户 `chmod 600`(不主动改老文件)。
|
|
6875
6910
|
- **H11** Approval socket 路径熵 + 权限:`defaultSocketPath` 改用 `randomBytes(16).toString('hex')`(128 位熵),listen 后 `chmod 0o600` + `stat` 验证;防同主机非特权用户预占 socket 的 TOCTOU。
|
|
6876
6911
|
- **H12** `Session.addMessage` 并发:`SessionManager` 加 `writeQueues<key, Promise>` + `withLock<T>(key, fn)`,per-key 串行化 RMW,跨 thread 仍并行。
|
|
6877
6912
|
|
|
6878
6913
|
### Fixed — P1 multi-tenant ACL
|
|
6879
6914
|
- **H5** `/job` `/schedule` `/audit` 命令补 owner 隔离:`jobs` / `schedules` 表加 `creator_id` / `workspace_id`(幂等 `ALTER TABLE`,老库无痛升级);`createJob` / `createSchedule` 接 `{ creatorId, workspaceId }` 由 handler 注入;查询/取消/删/启停加 `OwnerOpts`,`creator_id = ? OR creator_id = ''`(老库 `''` 对所有 owner 可见,避免升级当天列表看似消失);`/audit user=<other>` 强制 overwrite 到 `ctx.userId`,结果末尾追加忽略提示。
|
|
6880
|
-
- **H7** Job 表 retention:`resolveRetentionDays()` 默认 30 天,env `
|
|
6915
|
+
- **H7** Job 表 retention:`resolveRetentionDays()` 默认 30 天,env `AGIM_JOB_RETENTION_DAYS` 覆盖;`pruneOldJobs()` 删 `completed`/`failed`/`cancelled` 超期行,`pending`/`running` 永不修剪;启动跑一次 + 每 6h `setInterval(..unref())`;新增 `idx_jobs_created` / `idx_jobs_creator` / `idx_jobs_status_created` 索引。
|
|
6881
6916
|
- **M6** Workspace 白名单从路由层下沉到命令层:`/job create <agent>` 与 `/schedule create <agent>` 在 `createJob` / `createSchedule` 之前调 `workspaceRegistry.resolve(ctx.userId).hasAgent(agent.name)`。
|
|
6882
6917
|
|
|
6883
6918
|
### Tests
|
|
@@ -6896,13 +6931,13 @@ P0 + P1 安全收口,配 `docs/code-review-2026-05-06-main.md`。
|
|
|
6896
6931
|
|
|
6897
6932
|
### Added
|
|
6898
6933
|
- **Discord messenger adapter** — full IM bridge for Discord (Gateway WebSocket via `discord.js`)
|
|
6899
|
-
- `
|
|
6934
|
+
- `agim config discord` interactive setup wizard
|
|
6900
6935
|
- Typing indicator (10s TTL, 8s refresh)
|
|
6901
6936
|
- Markdown → Discord-flavored format conversion
|
|
6902
6937
|
- Guild / Channel whitelist filtering
|
|
6903
6938
|
- Setup guide: [`docs/discord-setup.md`](docs/discord-setup.md)
|
|
6904
6939
|
- **Tasks dashboard upgrades** — `/tasks` page now surfaces background work
|
|
6905
|
-
- **Background tab**: lists `~/.claude/bgjobs` + `~/.config/opencode/bgjobs` jobs (override via `
|
|
6940
|
+
- **Background tab**: lists `~/.claude/bgjobs` + `~/.config/opencode/bgjobs` jobs (override via `AGIM_BGJOB_ROOTS`); per-root selector, 5s auto-refresh, detail modal with `cmd` / `workdir` / `log_tail`
|
|
6906
6941
|
- **Subtasks tab**: flattens every subtask in every session file, with parent platform / threadId / agent attached
|
|
6907
6942
|
- Bilingual labels (EN + ZH)
|
|
6908
6943
|
- **REST endpoints (read-only)**:
|
|
@@ -6927,8 +6962,8 @@ P0 + P1 安全收口,配 `docs/code-review-2026-05-06-main.md`。
|
|
|
6927
6962
|
- Replaces the legacy `--permission-mode dontAsk + blanket-allow PreToolUse hook` shortcut with a real approval flow over IM.
|
|
6928
6963
|
- Architecture:
|
|
6929
6964
|
```
|
|
6930
|
-
claude --permission-prompt-tool
|
|
6931
|
-
└─> MCP sidecar (mcp-approval-server.ts) ── unix socket ──>
|
|
6965
|
+
claude --permission-prompt-tool mcp__agim__request --mcp-config <tmp>
|
|
6966
|
+
└─> MCP sidecar (mcp-approval-server.ts) ── unix socket ──> agim
|
|
6932
6967
|
└─> approval-bus
|
|
6933
6968
|
└─> approval-router → messenger.sendMessage
|
|
6934
6969
|
↑
|
|
@@ -6936,7 +6971,7 @@ P0 + P1 安全收口,配 `docs/code-review-2026-05-06-main.md`。
|
|
|
6936
6971
|
```
|
|
6937
6972
|
- cli intercepts approval replies *before* the agent router; unrecognized replies during a pending request auto-deny so the sidecar (and Claude) don't hang.
|
|
6938
6973
|
- Per-spawn state lives in the `SpawnPlan` returned by `AgentBase.prepareCommand` (closure-local, not `this.*`) — fixes a singleton race where parallel IM threads running claude clobbered each other's `mcp-config` and the second run died with *MCP config file not found*.
|
|
6939
|
-
- Graceful fallbacks: `
|
|
6974
|
+
- Graceful fallbacks: `AGIM_APPROVAL_DISABLED=1`, missing IM context, approval-bus not started, or `mkdtemp/writeFile` failure all degrade to the legacy `--permission-mode dontAsk` path.
|
|
6940
6975
|
|
|
6941
6976
|
### Notes
|
|
6942
6977
|
- Approvals are platform-agnostic — the same chain works for WeChat / Telegram / Feishu / Discord with no per-platform changes.
|
|
@@ -6954,7 +6989,7 @@ A large multi-phase release: structured logging, observability, multi-tenant rou
|
|
|
6954
6989
|
- **Zod config schema validation** at startup and PUT `/api/config` — invalid configs reject with a useful error instead of crashing the bridge mid-run.
|
|
6955
6990
|
- **`AgentBase` abstraction** for CLI-based adapters (claude-code / codex / copilot / opencode) — shared spawn-stream, abort/timeout, line buffer, error formatting, healthCheck. ADR: [`docs/adr/0001-agent-base-abstraction.md`](docs/adr/0001-agent-base-abstraction.md).
|
|
6956
6991
|
- **Agent availability TTL cache** on top of `healthCheck` — avoids spawning a probe process on every `/<agent>` switch.
|
|
6957
|
-
- **Audit log** with SQLite (`~/.
|
|
6992
|
+
- **Audit log** with SQLite (`~/.agim/audit.db`, 30-day retention) + `/audit [n]` chat command.
|
|
6958
6993
|
|
|
6959
6994
|
#### Fixed
|
|
6960
6995
|
- P0 batch: WebSocket auth, nested config-mask leaks, timeout coercion, `/api/notify` token validation, agent-name prefix collisions, session path traversal (ADR [`0003`](docs/adr/0003-session-path-safety.md)).
|
|
@@ -6975,10 +7010,10 @@ A large multi-phase release: structured logging, observability, multi-tenant rou
|
|
|
6975
7010
|
### Phase 3 — ACP server, workspaces, persistent jobs
|
|
6976
7011
|
|
|
6977
7012
|
#### Added
|
|
6978
|
-
- **ACP server mode** —
|
|
7013
|
+
- **ACP server mode** — agim itself is now an ACP-compatible agent at `POST /tasks` (sync + SSE) with timing-safe auth and a 1 MiB body cap.
|
|
6979
7014
|
- **`/.well-known/acp` discovery** for ACP custom agents (A-1).
|
|
6980
7015
|
- **Multi-tenant workspace registry** (`src/core/workspace.ts`) with per-workspace agent whitelist + rate limits + member lists.
|
|
6981
|
-
- **Persistent Job Board** with SQLite (`~/.
|
|
7016
|
+
- **Persistent Job Board** with SQLite (`~/.agim/jobs.db`) and `/job` chat commands — survives restarts; ACP-server tasks become durable jobs.
|
|
6982
7017
|
- **Subtask sessions** + `/task` aliases for backward compatibility.
|
|
6983
7018
|
- **`AbortController` signal** plumbed through job board for real cancellation (Phase 3.5).
|
|
6984
7019
|
- **Cron scheduler** (`src/core/schedule.ts`) — 30-second tick, fires registered job specs.
|