agim-cli 1.0.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 +1234 -0
- package/LICENSE +21 -0
- package/README.md +422 -0
- package/README.zh-CN.md +414 -0
- package/dist/cli-ui/cmd-handlers.d.ts +11 -0
- package/dist/cli-ui/cmd-handlers.d.ts.map +1 -0
- package/dist/cli-ui/cmd-handlers.js +240 -0
- package/dist/cli-ui/cmd-handlers.js.map +1 -0
- package/dist/cli-ui/config-wizard.d.ts +3 -0
- package/dist/cli-ui/config-wizard.d.ts.map +1 -0
- package/dist/cli-ui/config-wizard.js +851 -0
- package/dist/cli-ui/config-wizard.js.map +1 -0
- package/dist/cli-ui/entry-menu.d.ts +28 -0
- package/dist/cli-ui/entry-menu.d.ts.map +1 -0
- package/dist/cli-ui/entry-menu.js +50 -0
- package/dist/cli-ui/entry-menu.js.map +1 -0
- package/dist/cli-ui/env-file.d.ts +35 -0
- package/dist/cli-ui/env-file.d.ts.map +1 -0
- package/dist/cli-ui/env-file.js +163 -0
- package/dist/cli-ui/env-file.js.map +1 -0
- package/dist/cli-ui/i18n.d.ts +204 -0
- package/dist/cli-ui/i18n.d.ts.map +1 -0
- package/dist/cli-ui/i18n.js +455 -0
- package/dist/cli-ui/i18n.js.map +1 -0
- package/dist/cli-ui/lang-picker.d.ts +10 -0
- package/dist/cli-ui/lang-picker.d.ts.map +1 -0
- package/dist/cli-ui/lang-picker.js +33 -0
- package/dist/cli-ui/lang-picker.js.map +1 -0
- package/dist/cli-ui/paths.d.ts +4 -0
- package/dist/cli-ui/paths.d.ts.map +1 -0
- package/dist/cli-ui/paths.js +11 -0
- package/dist/cli-ui/paths.js.map +1 -0
- package/dist/cli-ui/prompts.d.ts +65 -0
- package/dist/cli-ui/prompts.d.ts.map +1 -0
- package/dist/cli-ui/prompts.js +125 -0
- package/dist/cli-ui/prompts.js.map +1 -0
- package/dist/cli-ui/service.d.ts +41 -0
- package/dist/cli-ui/service.d.ts.map +1 -0
- package/dist/cli-ui/service.js +241 -0
- package/dist/cli-ui/service.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1143 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/acp-server.d.ts +8 -0
- package/dist/core/acp-server.d.ts.map +1 -0
- package/dist/core/acp-server.js +266 -0
- package/dist/core/acp-server.js.map +1 -0
- package/dist/core/agent-base.d.ts +94 -0
- package/dist/core/agent-base.d.ts.map +1 -0
- package/dist/core/agent-base.js +373 -0
- package/dist/core/agent-base.js.map +1 -0
- package/dist/core/agent-cwd.d.ts +48 -0
- package/dist/core/agent-cwd.d.ts.map +1 -0
- package/dist/core/agent-cwd.js +181 -0
- package/dist/core/agent-cwd.js.map +1 -0
- package/dist/core/agent-helper.d.ts +65 -0
- package/dist/core/agent-helper.d.ts.map +1 -0
- package/dist/core/agent-helper.js +150 -0
- package/dist/core/agent-helper.js.map +1 -0
- package/dist/core/agim-paths.d.ts +10 -0
- package/dist/core/agim-paths.d.ts.map +1 -0
- package/dist/core/agim-paths.js +64 -0
- package/dist/core/agim-paths.js.map +1 -0
- package/dist/core/approval-bus.d.ts +300 -0
- package/dist/core/approval-bus.d.ts.map +1 -0
- package/dist/core/approval-bus.js +990 -0
- package/dist/core/approval-bus.js.map +1 -0
- package/dist/core/approval-router.d.ts +101 -0
- package/dist/core/approval-router.d.ts.map +1 -0
- package/dist/core/approval-router.js +540 -0
- package/dist/core/approval-router.js.map +1 -0
- package/dist/core/audit-log.d.ts +55 -0
- package/dist/core/audit-log.d.ts.map +1 -0
- package/dist/core/audit-log.js +203 -0
- package/dist/core/audit-log.js.map +1 -0
- package/dist/core/bgjob-reader.d.ts +65 -0
- package/dist/core/bgjob-reader.d.ts.map +1 -0
- package/dist/core/bgjob-reader.js +212 -0
- package/dist/core/bgjob-reader.js.map +1 -0
- package/dist/core/circuit-breaker.d.ts +37 -0
- package/dist/core/circuit-breaker.d.ts.map +1 -0
- package/dist/core/circuit-breaker.js +115 -0
- package/dist/core/circuit-breaker.js.map +1 -0
- package/dist/core/commands/agent.d.ts +4 -0
- package/dist/core/commands/agent.d.ts.map +1 -0
- package/dist/core/commands/agent.js +40 -0
- package/dist/core/commands/agent.js.map +1 -0
- package/dist/core/commands/approval.d.ts +3 -0
- package/dist/core/commands/approval.d.ts.map +1 -0
- package/dist/core/commands/approval.js +85 -0
- package/dist/core/commands/approval.js.map +1 -0
- package/dist/core/commands/audit.d.ts +3 -0
- package/dist/core/commands/audit.d.ts.map +1 -0
- package/dist/core/commands/audit.js +84 -0
- package/dist/core/commands/audit.js.map +1 -0
- package/dist/core/commands/builtin.d.ts +3 -0
- package/dist/core/commands/builtin.d.ts.map +1 -0
- package/dist/core/commands/builtin.js +304 -0
- package/dist/core/commands/builtin.js.map +1 -0
- package/dist/core/commands/cron.d.ts +3 -0
- package/dist/core/commands/cron.d.ts.map +1 -0
- package/dist/core/commands/cron.js +128 -0
- package/dist/core/commands/cron.js.map +1 -0
- package/dist/core/commands/job.d.ts +3 -0
- package/dist/core/commands/job.d.ts.map +1 -0
- package/dist/core/commands/job.js +195 -0
- package/dist/core/commands/job.js.map +1 -0
- package/dist/core/commands/memo.d.ts +3 -0
- package/dist/core/commands/memo.d.ts.map +1 -0
- package/dist/core/commands/memo.js +151 -0
- package/dist/core/commands/memo.js.map +1 -0
- package/dist/core/commands/model.d.ts +9 -0
- package/dist/core/commands/model.d.ts.map +1 -0
- package/dist/core/commands/model.js +183 -0
- package/dist/core/commands/model.js.map +1 -0
- package/dist/core/commands/plan.d.ts +3 -0
- package/dist/core/commands/plan.d.ts.map +1 -0
- package/dist/core/commands/plan.js +75 -0
- package/dist/core/commands/plan.js.map +1 -0
- package/dist/core/commands/remind.d.ts +3 -0
- package/dist/core/commands/remind.d.ts.map +1 -0
- package/dist/core/commands/remind.js +271 -0
- package/dist/core/commands/remind.js.map +1 -0
- package/dist/core/commands/router.d.ts +3 -0
- package/dist/core/commands/router.d.ts.map +1 -0
- package/dist/core/commands/router.js +71 -0
- package/dist/core/commands/router.js.map +1 -0
- package/dist/core/commands/sessions.d.ts +3 -0
- package/dist/core/commands/sessions.d.ts.map +1 -0
- package/dist/core/commands/sessions.js +88 -0
- package/dist/core/commands/sessions.js.map +1 -0
- package/dist/core/commands/stats.d.ts +3 -0
- package/dist/core/commands/stats.d.ts.map +1 -0
- package/dist/core/commands/stats.js +73 -0
- package/dist/core/commands/stats.js.map +1 -0
- package/dist/core/commands/think.d.ts +3 -0
- package/dist/core/commands/think.d.ts.map +1 -0
- package/dist/core/commands/think.js +28 -0
- package/dist/core/commands/think.js.map +1 -0
- package/dist/core/commands/workspaces.d.ts +3 -0
- package/dist/core/commands/workspaces.d.ts.map +1 -0
- package/dist/core/commands/workspaces.js +47 -0
- package/dist/core/commands/workspaces.js.map +1 -0
- package/dist/core/config-schema.d.ts +60 -0
- package/dist/core/config-schema.d.ts.map +1 -0
- package/dist/core/config-schema.js +75 -0
- package/dist/core/config-schema.js.map +1 -0
- package/dist/core/coord-systems.d.ts +65 -0
- package/dist/core/coord-systems.d.ts.map +1 -0
- package/dist/core/coord-systems.js +229 -0
- package/dist/core/coord-systems.js.map +1 -0
- package/dist/core/cron.d.ts +29 -0
- package/dist/core/cron.d.ts.map +1 -0
- package/dist/core/cron.js +184 -0
- package/dist/core/cron.js.map +1 -0
- package/dist/core/event-bus.d.ts +80 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +62 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/intent-llm.d.ts +27 -0
- package/dist/core/intent-llm.d.ts.map +1 -0
- package/dist/core/intent-llm.js +170 -0
- package/dist/core/intent-llm.js.map +1 -0
- package/dist/core/intent.d.ts +12 -0
- package/dist/core/intent.d.ts.map +1 -0
- package/dist/core/intent.js +187 -0
- package/dist/core/intent.js.map +1 -0
- package/dist/core/job-board.d.ts +82 -0
- package/dist/core/job-board.d.ts.map +1 -0
- package/dist/core/job-board.js +379 -0
- package/dist/core/job-board.js.map +1 -0
- package/dist/core/location-context.d.ts +32 -0
- package/dist/core/location-context.d.ts.map +1 -0
- package/dist/core/location-context.js +69 -0
- package/dist/core/location-context.js.map +1 -0
- package/dist/core/location-token.d.ts +57 -0
- package/dist/core/location-token.d.ts.map +1 -0
- package/dist/core/location-token.js +128 -0
- package/dist/core/location-token.js.map +1 -0
- package/dist/core/logger.d.ts +6 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +54 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/memo-rpc.d.ts +13 -0
- package/dist/core/memo-rpc.d.ts.map +1 -0
- package/dist/core/memo-rpc.js +288 -0
- package/dist/core/memo-rpc.js.map +1 -0
- package/dist/core/memos.d.ts +163 -0
- package/dist/core/memos.d.ts.map +1 -0
- package/dist/core/memos.js +502 -0
- package/dist/core/memos.js.map +1 -0
- package/dist/core/metrics.d.ts +55 -0
- package/dist/core/metrics.d.ts.map +1 -0
- package/dist/core/metrics.js +291 -0
- package/dist/core/metrics.js.map +1 -0
- package/dist/core/onboarding.d.ts +99 -0
- package/dist/core/onboarding.d.ts.map +1 -0
- package/dist/core/onboarding.js +426 -0
- package/dist/core/onboarding.js.map +1 -0
- package/dist/core/pending-reminder.d.ts +25 -0
- package/dist/core/pending-reminder.d.ts.map +1 -0
- package/dist/core/pending-reminder.js +53 -0
- package/dist/core/pending-reminder.js.map +1 -0
- package/dist/core/rate-limiter.d.ts +44 -0
- package/dist/core/rate-limiter.d.ts.map +1 -0
- package/dist/core/rate-limiter.js +115 -0
- package/dist/core/rate-limiter.js.map +1 -0
- package/dist/core/registry.d.ts +32 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +126 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/remind-intent.d.ts +25 -0
- package/dist/core/remind-intent.d.ts.map +1 -0
- package/dist/core/remind-intent.js +196 -0
- package/dist/core/remind-intent.js.map +1 -0
- package/dist/core/reminder-rpc.d.ts +17 -0
- package/dist/core/reminder-rpc.d.ts.map +1 -0
- package/dist/core/reminder-rpc.js +169 -0
- package/dist/core/reminder-rpc.js.map +1 -0
- package/dist/core/reminders.d.ts +159 -0
- package/dist/core/reminders.d.ts.map +1 -0
- package/dist/core/reminders.js +977 -0
- package/dist/core/reminders.js.map +1 -0
- package/dist/core/router.d.ts +55 -0
- package/dist/core/router.d.ts.map +1 -0
- package/dist/core/router.js +497 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/schedule.d.ts +65 -0
- package/dist/core/schedule.d.ts.map +1 -0
- package/dist/core/schedule.js +323 -0
- package/dist/core/schedule.js.map +1 -0
- package/dist/core/session.d.ts +182 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +807 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/sqlite-helper.d.ts +37 -0
- package/dist/core/sqlite-helper.d.ts.map +1 -0
- package/dist/core/sqlite-helper.js +79 -0
- package/dist/core/sqlite-helper.js.map +1 -0
- package/dist/core/transcribe.d.ts +25 -0
- package/dist/core/transcribe.d.ts.map +1 -0
- package/dist/core/transcribe.js +217 -0
- package/dist/core/transcribe.js.map +1 -0
- package/dist/core/types.d.ts +360 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/workspace.d.ts +67 -0
- package/dist/core/workspace.d.ts.map +1 -0
- package/dist/core/workspace.js +113 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/agents/acp/acp-adapter.d.ts +16 -0
- package/dist/plugins/agents/acp/acp-adapter.d.ts.map +1 -0
- package/dist/plugins/agents/acp/acp-adapter.js +49 -0
- package/dist/plugins/agents/acp/acp-adapter.js.map +1 -0
- package/dist/plugins/agents/acp/acp-client.d.ts +32 -0
- package/dist/plugins/agents/acp/acp-client.d.ts.map +1 -0
- package/dist/plugins/agents/acp/acp-client.js +177 -0
- package/dist/plugins/agents/acp/acp-client.js.map +1 -0
- package/dist/plugins/agents/acp/discovery.d.ts +19 -0
- package/dist/plugins/agents/acp/discovery.d.ts.map +1 -0
- package/dist/plugins/agents/acp/discovery.js +111 -0
- package/dist/plugins/agents/acp/discovery.js.map +1 -0
- package/dist/plugins/agents/acp/index.d.ts +4 -0
- package/dist/plugins/agents/acp/index.d.ts.map +1 -0
- package/dist/plugins/agents/acp/index.js +4 -0
- package/dist/plugins/agents/acp/index.js.map +1 -0
- package/dist/plugins/agents/acp/types.d.ts +62 -0
- package/dist/plugins/agents/acp/types.d.ts.map +1 -0
- package/dist/plugins/agents/acp/types.js +5 -0
- package/dist/plugins/agents/acp/types.js.map +1 -0
- package/dist/plugins/agents/claude-code/index.d.ts +25 -0
- package/dist/plugins/agents/claude-code/index.d.ts.map +1 -0
- package/dist/plugins/agents/claude-code/index.js +184 -0
- package/dist/plugins/agents/claude-code/index.js.map +1 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +59 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.js +645 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -0
- package/dist/plugins/agents/codex/build-mcp-cli-args.d.ts +28 -0
- package/dist/plugins/agents/codex/build-mcp-cli-args.d.ts.map +1 -0
- package/dist/plugins/agents/codex/build-mcp-cli-args.js +74 -0
- package/dist/plugins/agents/codex/build-mcp-cli-args.js.map +1 -0
- package/dist/plugins/agents/codex/index.d.ts +53 -0
- package/dist/plugins/agents/codex/index.d.ts.map +1 -0
- package/dist/plugins/agents/codex/index.js +341 -0
- package/dist/plugins/agents/codex/index.js.map +1 -0
- package/dist/plugins/agents/copilot/index.d.ts +35 -0
- package/dist/plugins/agents/copilot/index.d.ts.map +1 -0
- package/dist/plugins/agents/copilot/index.js +182 -0
- package/dist/plugins/agents/copilot/index.js.map +1 -0
- package/dist/plugins/agents/opencode/ensure-mcp-config.d.ts +11 -0
- package/dist/plugins/agents/opencode/ensure-mcp-config.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/ensure-mcp-config.js +100 -0
- package/dist/plugins/agents/opencode/ensure-mcp-config.js.map +1 -0
- package/dist/plugins/agents/opencode/index.d.ts +5 -0
- package/dist/plugins/agents/opencode/index.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/index.js +30 -0
- package/dist/plugins/agents/opencode/index.js.map +1 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +166 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.js +682 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +32 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +137 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -0
- package/dist/plugins/agents/opencode/serve-manager.d.ts +27 -0
- package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/serve-manager.js +194 -0
- package/dist/plugins/agents/opencode/serve-manager.js.map +1 -0
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.d.ts +57 -0
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js +409 -0
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js.map +1 -0
- package/dist/plugins/messengers/dingtalk/dingtalk-client.d.ts +48 -0
- package/dist/plugins/messengers/dingtalk/dingtalk-client.d.ts.map +1 -0
- package/dist/plugins/messengers/dingtalk/dingtalk-client.js +236 -0
- package/dist/plugins/messengers/dingtalk/dingtalk-client.js.map +1 -0
- package/dist/plugins/messengers/dingtalk/index.d.ts +3 -0
- package/dist/plugins/messengers/dingtalk/index.d.ts.map +1 -0
- package/dist/plugins/messengers/dingtalk/index.js +3 -0
- package/dist/plugins/messengers/dingtalk/index.js.map +1 -0
- package/dist/plugins/messengers/dingtalk/link-coords.d.ts +23 -0
- package/dist/plugins/messengers/dingtalk/link-coords.d.ts.map +1 -0
- package/dist/plugins/messengers/dingtalk/link-coords.js +89 -0
- package/dist/plugins/messengers/dingtalk/link-coords.js.map +1 -0
- package/dist/plugins/messengers/dingtalk/media-store.d.ts +16 -0
- package/dist/plugins/messengers/dingtalk/media-store.d.ts.map +1 -0
- package/dist/plugins/messengers/dingtalk/media-store.js +77 -0
- package/dist/plugins/messengers/dingtalk/media-store.js.map +1 -0
- package/dist/plugins/messengers/dingtalk/types.d.ts +82 -0
- package/dist/plugins/messengers/dingtalk/types.d.ts.map +1 -0
- package/dist/plugins/messengers/dingtalk/types.js +14 -0
- package/dist/plugins/messengers/dingtalk/types.js.map +1 -0
- package/dist/plugins/messengers/discord/discord-adapter.d.ts +21 -0
- package/dist/plugins/messengers/discord/discord-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/discord-adapter.js +238 -0
- package/dist/plugins/messengers/discord/discord-adapter.js.map +1 -0
- package/dist/plugins/messengers/discord/index.d.ts +4 -0
- package/dist/plugins/messengers/discord/index.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/index.js +4 -0
- package/dist/plugins/messengers/discord/index.js.map +1 -0
- package/dist/plugins/messengers/discord/markdown-to-discord.d.ts +11 -0
- package/dist/plugins/messengers/discord/markdown-to-discord.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/markdown-to-discord.js +59 -0
- package/dist/plugins/messengers/discord/markdown-to-discord.js.map +1 -0
- package/dist/plugins/messengers/discord/types.d.ts +9 -0
- package/dist/plugins/messengers/discord/types.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/types.js +3 -0
- package/dist/plugins/messengers/discord/types.js.map +1 -0
- package/dist/plugins/messengers/email/email-adapter.d.ts +33 -0
- package/dist/plugins/messengers/email/email-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/email/email-adapter.js +137 -0
- package/dist/plugins/messengers/email/email-adapter.js.map +1 -0
- package/dist/plugins/messengers/feishu/card-builder.d.ts +23 -0
- package/dist/plugins/messengers/feishu/card-builder.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/card-builder.js +89 -0
- package/dist/plugins/messengers/feishu/card-builder.js.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-adapter.d.ts +23 -0
- package/dist/plugins/messengers/feishu/feishu-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-adapter.js +250 -0
- package/dist/plugins/messengers/feishu/feishu-adapter.js.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-client.d.ts +43 -0
- package/dist/plugins/messengers/feishu/feishu-client.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-client.js +118 -0
- package/dist/plugins/messengers/feishu/feishu-client.js.map +1 -0
- package/dist/plugins/messengers/feishu/index.d.ts +4 -0
- package/dist/plugins/messengers/feishu/index.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/index.js +4 -0
- package/dist/plugins/messengers/feishu/index.js.map +1 -0
- package/dist/plugins/messengers/feishu/types.d.ts +113 -0
- package/dist/plugins/messengers/feishu/types.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/types.js +4 -0
- package/dist/plugins/messengers/feishu/types.js.map +1 -0
- package/dist/plugins/messengers/telegram/index.d.ts +4 -0
- package/dist/plugins/messengers/telegram/index.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/index.js +4 -0
- package/dist/plugins/messengers/telegram/index.js.map +1 -0
- package/dist/plugins/messengers/telegram/markdown-to-html.d.ts +5 -0
- package/dist/plugins/messengers/telegram/markdown-to-html.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/markdown-to-html.js +186 -0
- package/dist/plugins/messengers/telegram/markdown-to-html.js.map +1 -0
- package/dist/plugins/messengers/telegram/media-download.d.ts +59 -0
- package/dist/plugins/messengers/telegram/media-download.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/media-download.js +228 -0
- package/dist/plugins/messengers/telegram/media-download.js.map +1 -0
- package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +77 -0
- package/dist/plugins/messengers/telegram/telegram-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/telegram-adapter.js +880 -0
- package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -0
- package/dist/plugins/messengers/telegram/types.d.ts +47 -0
- package/dist/plugins/messengers/telegram/types.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/types.js +3 -0
- package/dist/plugins/messengers/telegram/types.js.map +1 -0
- package/dist/plugins/messengers/wechat/context-store.d.ts +18 -0
- package/dist/plugins/messengers/wechat/context-store.d.ts.map +1 -0
- package/dist/plugins/messengers/wechat/context-store.js +105 -0
- package/dist/plugins/messengers/wechat/context-store.js.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.d.ts +71 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.js +664 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-client.d.ts +75 -0
- package/dist/plugins/messengers/wechat/ilink-client.d.ts.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-client.js +331 -0
- package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-types.d.ts +181 -0
- package/dist/plugins/messengers/wechat/ilink-types.d.ts.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-types.js +22 -0
- package/dist/plugins/messengers/wechat/ilink-types.js.map +1 -0
- package/dist/plugins/messengers/wechat/media-download.d.ts +32 -0
- package/dist/plugins/messengers/wechat/media-download.d.ts.map +1 -0
- package/dist/plugins/messengers/wechat/media-download.js +78 -0
- package/dist/plugins/messengers/wechat/media-download.js.map +1 -0
- package/dist/scripts/migrate-gcj02-to-wgs84.d.ts +3 -0
- package/dist/scripts/migrate-gcj02-to-wgs84.d.ts.map +1 -0
- package/dist/scripts/migrate-gcj02-to-wgs84.js +52 -0
- package/dist/scripts/migrate-gcj02-to-wgs84.js.map +1 -0
- package/dist/utils/backoff.d.ts +35 -0
- package/dist/utils/backoff.d.ts.map +1 -0
- package/dist/utils/backoff.js +59 -0
- package/dist/utils/backoff.js.map +1 -0
- package/dist/utils/cross-platform.d.ts +26 -0
- package/dist/utils/cross-platform.d.ts.map +1 -0
- package/dist/utils/cross-platform.js +58 -0
- package/dist/utils/cross-platform.js.map +1 -0
- package/dist/utils/message-split.d.ts +14 -0
- package/dist/utils/message-split.d.ts.map +1 -0
- package/dist/utils/message-split.js +65 -0
- package/dist/utils/message-split.js.map +1 -0
- package/dist/utils/safe-equal.d.ts +2 -0
- package/dist/utils/safe-equal.d.ts.map +1 -0
- package/dist/utils/safe-equal.js +11 -0
- package/dist/utils/safe-equal.js.map +1 -0
- package/dist/web/public/_app.js +196 -0
- package/dist/web/public/index.html +936 -0
- package/dist/web/public/loc.html +305 -0
- package/dist/web/public/login.html +106 -0
- package/dist/web/public/memos.html +271 -0
- package/dist/web/public/reminders.html +234 -0
- package/dist/web/public/settings.html +1355 -0
- package/dist/web/public/tasks.html +1835 -0
- package/dist/web/server.d.ts +12 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +2399 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
// DingTalk (钉钉) messenger adapter — implements MessengerAdapter
|
|
2
|
+
// against the official `dingtalk-stream` SDK in Stream mode.
|
|
3
|
+
//
|
|
4
|
+
// Stream mode characteristics that shaped this adapter:
|
|
5
|
+
// * No public webhook needed — DingTalk pushes events over WebSocket.
|
|
6
|
+
// The SDK handles reconnect/heartbeat/access-token rotation.
|
|
7
|
+
// * Inbound only fires when the user @-mentions the bot in a group,
|
|
8
|
+
// or sends a 1:1 message. DingTalk strips the @ prefix server-side.
|
|
9
|
+
// * Bot can only send back to (a) the user who messaged it (1:1) or
|
|
10
|
+
// (b) the group conversation the message came from. There is no
|
|
11
|
+
// concept of "DM any user without being messaged first" outside of
|
|
12
|
+
// proactive workflow messages, which we don't use.
|
|
13
|
+
// * threadId encoding: `user:<senderStaffId>` for 1:1, `group:<convId>`
|
|
14
|
+
// for groups. This lets sendMessage route to the right OpenAPI
|
|
15
|
+
// endpoint without consulting external state.
|
|
16
|
+
// * Inbound type is `text` only — DingTalk Stream doesn't deliver
|
|
17
|
+
// image / voice / location messages to bots. /memo coordinate flow
|
|
18
|
+
// therefore needs the user to type coords (no native location msg).
|
|
19
|
+
import { readFile } from 'node:fs/promises';
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { logger as rootLogger } from '../../../core/logger.js';
|
|
22
|
+
import { setLocationContext } from '../../../core/location-context.js';
|
|
23
|
+
import { normalizeIncomingCoords } from '../../../core/coord-systems.js';
|
|
24
|
+
import { detectProvider, transcribe, TranscribeError } from '../../../core/transcribe.js';
|
|
25
|
+
import { AGIM_HOME } from '../../../core/agim-paths.js';
|
|
26
|
+
import { DingTalkClient } from './dingtalk-client.js';
|
|
27
|
+
import { tryExtractLatLng } from './link-coords.js';
|
|
28
|
+
import { pickDingTalkExtension, saveDingTalkMedia } from './media-store.js';
|
|
29
|
+
const log = rootLogger.child({ component: 'dingtalk' });
|
|
30
|
+
const CONFIG_FILE = join(AGIM_HOME, 'config.json');
|
|
31
|
+
// Match Feishu's dedup window — DingTalk's gateway also re-delivers if
|
|
32
|
+
// the ack races the next reconnect.
|
|
33
|
+
const DEDUP_TTL_MS = 10 * 60 * 1000;
|
|
34
|
+
const DEDUP_MAX = 2000;
|
|
35
|
+
export class DingTalkAdapter {
|
|
36
|
+
name = 'dingtalk';
|
|
37
|
+
client = null;
|
|
38
|
+
config = null;
|
|
39
|
+
messageHandler;
|
|
40
|
+
seenMessages = new Map();
|
|
41
|
+
async start() {
|
|
42
|
+
try {
|
|
43
|
+
const raw = await readFile(CONFIG_FILE, 'utf-8');
|
|
44
|
+
const full = JSON.parse(raw);
|
|
45
|
+
this.config = full.dingtalk ?? null;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
throw new Error('DingTalk config not found. Run `agim` → Configure → DingTalk first.');
|
|
49
|
+
}
|
|
50
|
+
if (!this.config?.clientId || !this.config?.clientSecret) {
|
|
51
|
+
throw new Error('DingTalk ClientID or ClientSecret missing. Re-run the configure flow.');
|
|
52
|
+
}
|
|
53
|
+
this.client = new DingTalkClient(this.config);
|
|
54
|
+
this.client.onMessage(async (msg) => { await this.handleInbound(msg); });
|
|
55
|
+
await this.client.start();
|
|
56
|
+
log.info('DingTalk adapter started (WebSocket Stream mode, no webhook needed)');
|
|
57
|
+
}
|
|
58
|
+
async stop() {
|
|
59
|
+
if (this.client) {
|
|
60
|
+
await this.client.stop();
|
|
61
|
+
this.client = null;
|
|
62
|
+
}
|
|
63
|
+
log.info('DingTalk adapter stopped');
|
|
64
|
+
}
|
|
65
|
+
onMessage(handler) {
|
|
66
|
+
this.messageHandler = handler;
|
|
67
|
+
}
|
|
68
|
+
async sendMessage(threadId, text) {
|
|
69
|
+
if (!this.client)
|
|
70
|
+
throw new Error('DingTalk adapter not started');
|
|
71
|
+
await this.client.sendMessage(threadId, text);
|
|
72
|
+
}
|
|
73
|
+
// No sendTyping / sendThinking — DingTalk doesn't expose a typing
|
|
74
|
+
// indicator API for stream-mode bots, and the client UI already shows
|
|
75
|
+
// a "正在输入" hint when a message is being processed in 1:1 chats.
|
|
76
|
+
// Group chats get nothing; the agent's first chunk is the user's signal.
|
|
77
|
+
// ─── inbound ─────────────────────────────────────────────────────────
|
|
78
|
+
/** Returns true on duplicate; otherwise records and prunes. Same shape
|
|
79
|
+
* as the Feishu adapter's dedup helper. */
|
|
80
|
+
isDuplicate(msgId) {
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
const seenAt = this.seenMessages.get(msgId);
|
|
83
|
+
if (seenAt !== undefined && now - seenAt < DEDUP_TTL_MS)
|
|
84
|
+
return true;
|
|
85
|
+
this.seenMessages.set(msgId, now);
|
|
86
|
+
if (this.seenMessages.size > DEDUP_MAX) {
|
|
87
|
+
const cutoff = now - DEDUP_TTL_MS;
|
|
88
|
+
for (const [k, t] of this.seenMessages) {
|
|
89
|
+
if (t < cutoff)
|
|
90
|
+
this.seenMessages.delete(k);
|
|
91
|
+
if (this.seenMessages.size <= DEDUP_MAX * 0.8)
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
while (this.seenMessages.size > DEDUP_MAX) {
|
|
95
|
+
const oldest = this.seenMessages.keys().next().value;
|
|
96
|
+
if (!oldest)
|
|
97
|
+
break;
|
|
98
|
+
this.seenMessages.delete(oldest);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
/** Build the threadId we expose to the rest of im-hub. 1:1 routes by
|
|
104
|
+
* sender staffId; group chats route by openConversationId so any
|
|
105
|
+
* member triggers a shared session in that group. */
|
|
106
|
+
threadIdFor(msg) {
|
|
107
|
+
return msg.conversationType === '2'
|
|
108
|
+
? `group:${msg.conversationId}`
|
|
109
|
+
: `user:${msg.senderStaffId}`;
|
|
110
|
+
}
|
|
111
|
+
async handleInbound(msg) {
|
|
112
|
+
if (!this.messageHandler) {
|
|
113
|
+
log.debug('no message handler registered');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (msg.msgId && this.isDuplicate(msg.msgId)) {
|
|
117
|
+
log.info({ messageId: msg.msgId, event: 'dingtalk.dedup.skip' }, 'dropping replayed msgId');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const channelId = this.config?.channelId || 'default';
|
|
121
|
+
const threadId = this.threadIdFor(msg);
|
|
122
|
+
// ─── text / markdown — the happy path ────────────────────────────
|
|
123
|
+
// Markdown messages from DingTalk also carry `text.content`; treat
|
|
124
|
+
// them like plain text since the agent already speaks markdown.
|
|
125
|
+
if (msg.msgtype === 'text' || msg.msgtype === 'markdown') {
|
|
126
|
+
const text = msg.text?.content?.trim() ?? '';
|
|
127
|
+
if (!text) {
|
|
128
|
+
log.debug('empty text in dingtalk message — ignored');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
await this.dispatchText(msg, text, threadId, channelId);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// ─── link — could be a shared location, a deep link, etc. ────────
|
|
135
|
+
// We log the full link block and try to recognise common GPS-bearing
|
|
136
|
+
// URL shapes (amap, qmap, baidu, dingtalk map mini-app). When we
|
|
137
|
+
// find lat/lng we feed location-context so cli.ts can annotate the
|
|
138
|
+
// user's next text turn — same architecture as Telegram / Feishu
|
|
139
|
+
// native location sharing.
|
|
140
|
+
if (msg.msgtype === 'link') {
|
|
141
|
+
log.info({
|
|
142
|
+
event: 'dingtalk.inbound.link',
|
|
143
|
+
messageId: msg.msgId,
|
|
144
|
+
link: msg.link,
|
|
145
|
+
threadId,
|
|
146
|
+
}, 'received link msgtype');
|
|
147
|
+
const coords = msg.link?.messageUrl ? tryExtractLatLng(msg.link.messageUrl) : null;
|
|
148
|
+
if (coords) {
|
|
149
|
+
// Apply the right coord-system conversion based on which map
|
|
150
|
+
// provider's URL we just parsed (amap/qq=GCJ-02, baidu=BD-09).
|
|
151
|
+
// See core/coord-systems.ts for the full per-source policy.
|
|
152
|
+
const norm = normalizeIncomingCoords(coords.source, coords.lat, coords.lng);
|
|
153
|
+
const threadKey = `dingtalk:${channelId}:${threadId}`;
|
|
154
|
+
setLocationContext(threadKey, {
|
|
155
|
+
lat: norm.lat,
|
|
156
|
+
lng: norm.lng,
|
|
157
|
+
venueLabel: msg.link?.title || undefined,
|
|
158
|
+
venueAddress: msg.link?.text || undefined,
|
|
159
|
+
});
|
|
160
|
+
log.info({
|
|
161
|
+
event: 'dingtalk.location_context.set',
|
|
162
|
+
source: coords.source,
|
|
163
|
+
raw_lat: coords.lat, raw_lng: coords.lng,
|
|
164
|
+
wgs_lat: norm.lat, wgs_lng: norm.lng,
|
|
165
|
+
applied: norm.applied,
|
|
166
|
+
});
|
|
167
|
+
if (this.client) {
|
|
168
|
+
await this.client.sendMessage(threadId, `📍 已收到位置${msg.link?.title ? `「${msg.link.title}」` : ''}。告诉我要做什么(例如 /memo 食堂、记下、提醒我下次来)。`)
|
|
169
|
+
.catch(err => log.warn({ err: err instanceof Error ? err.message : String(err) }, 'failed to ack dingtalk location'));
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// Not a recognised map URL — fall through to "tell user we can't"
|
|
174
|
+
// by sending a generic hint and stop here.
|
|
175
|
+
if (this.client) {
|
|
176
|
+
await this.client.sendMessage(threadId, '👁 链接已收到,但我只能阅读文本——请把要做的事情用文字告诉我。')
|
|
177
|
+
.catch(() => undefined);
|
|
178
|
+
}
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// ─── picture — download via messageFiles/download → save → enrich ──
|
|
182
|
+
// (msgtype is 'picture' on the wire — community docs say 'image' but
|
|
183
|
+
// empirically DingTalk delivers 'picture'.)
|
|
184
|
+
if (msg.msgtype === 'picture') {
|
|
185
|
+
await this.handleImageInbound(msg, threadId, channelId);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// ─── audio — DingTalk includes server-side ASR ─────────────────────
|
|
189
|
+
// (msgtype is 'audio' on the wire — community docs say 'voice'.)
|
|
190
|
+
// Inbound `content.recognition` carries the transcript already; we
|
|
191
|
+
// prefer it over re-running whisper locally for two reasons:
|
|
192
|
+
// 1. accuracy: DingTalk's Mandarin ASR is generally better than the
|
|
193
|
+
// ggml-base whisper.cpp model on the same clip.
|
|
194
|
+
// 2. latency: zero round-trip vs. 5-30 s on CPU.
|
|
195
|
+
// We still pull the audio file when we have a downloadCode so the
|
|
196
|
+
// agent can replay / archive the source recording.
|
|
197
|
+
if (msg.msgtype === 'audio') {
|
|
198
|
+
await this.handleVoiceInbound(msg, threadId, channelId);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
// ─── file — out of scope for now; ack only ───────────────────────
|
|
202
|
+
// Files can be PDFs / Word / spreadsheets etc. — multimodal agent
|
|
203
|
+
// handling is a separate effort. Acknowledge so user knows we saw it.
|
|
204
|
+
if (msg.msgtype === 'file') {
|
|
205
|
+
log.info({
|
|
206
|
+
event: 'dingtalk.inbound.file',
|
|
207
|
+
messageId: msg.msgId,
|
|
208
|
+
msgtype: msg.msgtype,
|
|
209
|
+
threadId,
|
|
210
|
+
content: msg.content,
|
|
211
|
+
}, 'received file msgtype — currently no handler');
|
|
212
|
+
if (this.client) {
|
|
213
|
+
await this.client.sendMessage(threadId, '📎 文件收到了,但我暂时还不能解析文件内容——请打字告诉我或上传图片。')
|
|
214
|
+
.catch(() => undefined);
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// ─── unknown msgtype — dump full payload for diagnosis ──────────
|
|
219
|
+
// This is the fallback for things like "user shared a native
|
|
220
|
+
// location" (msgtype undocumented). The dump lets us inspect the
|
|
221
|
+
// real shape in journalctl and teach the adapter next iteration.
|
|
222
|
+
log.warn({
|
|
223
|
+
event: 'dingtalk.inbound.unknown_msgtype',
|
|
224
|
+
messageId: msg.msgId,
|
|
225
|
+
msgtype: msg.msgtype,
|
|
226
|
+
threadId,
|
|
227
|
+
fullPayload: msg,
|
|
228
|
+
}, 'unknown dingtalk msgtype — full payload logged for analysis');
|
|
229
|
+
if (this.client) {
|
|
230
|
+
await this.client.sendMessage(threadId, `❓ 收到一条 \`${msg.msgtype}\` 类型消息,我还不认得这种格式,已记录到日志便于调试。请打字告诉我要做什么。`)
|
|
231
|
+
.catch(() => undefined);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/** Image inbound: exchange downloadCode → CDN bytes → save under
|
|
235
|
+
* ~/.im-hub/media/dingtalk/<thread>/, then dispatch a Message whose
|
|
236
|
+
* text contains an `[图片附件:<path>]` marker. claude-code's Read
|
|
237
|
+
* tool already understands that marker — it'll fetch the file off
|
|
238
|
+
* disk and pass it to the multimodal model the user is talking to.
|
|
239
|
+
*
|
|
240
|
+
* On download failure we still dispatch (with a `[图片附件下载失败]`
|
|
241
|
+
* marker) so the user's interaction isn't silently dropped. */
|
|
242
|
+
async handleImageInbound(msg, threadId, channelId) {
|
|
243
|
+
// DingTalk picture inbound carries TWO codes. Empirically only the
|
|
244
|
+
// generic `downloadCode` is accepted by /v1.0/robot/messageFiles/download
|
|
245
|
+
// — `pictureDownloadCode` returns 500 "unknownError" (it's reserved for
|
|
246
|
+
// a different endpoint we don't use). Picture's `downloadCode` resolves
|
|
247
|
+
// to a high-resolution version, not a thumbnail, despite the field
|
|
248
|
+
// name overlap with what the wire format calls a "thumb code". Confirmed
|
|
249
|
+
// 2026-05-11 via real msg dumps.
|
|
250
|
+
const downloadCode = msg.content?.downloadCode ?? msg.content?.pictureDownloadCode;
|
|
251
|
+
if (!downloadCode) {
|
|
252
|
+
log.warn({ event: 'dingtalk.image.no_download_code', messageId: msg.msgId, content: msg.content }, 'image msg arrived without downloadCode — falling back to ack hint');
|
|
253
|
+
if (this.client) {
|
|
254
|
+
await this.client.sendMessage(threadId, '🖼 图片收到了但我没拿到下载凭据,没法看。请重发或打字描述。')
|
|
255
|
+
.catch(() => undefined);
|
|
256
|
+
}
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const subPath = this.subPathFor(msg);
|
|
260
|
+
let attachmentLine;
|
|
261
|
+
try {
|
|
262
|
+
if (!this.client)
|
|
263
|
+
throw new Error('client not ready');
|
|
264
|
+
const dl = await this.client.downloadMessageFile(downloadCode);
|
|
265
|
+
if (!dl)
|
|
266
|
+
throw new Error('messageFiles/download returned null');
|
|
267
|
+
const ext = pickDingTalkExtension(dl.contentType, undefined);
|
|
268
|
+
const path = await saveDingTalkMedia(dl.buffer, subPath, `${this.safeFilenameStem(msg.msgId)}.${ext}`);
|
|
269
|
+
attachmentLine = `[图片附件:${path}]`;
|
|
270
|
+
log.info({ event: 'dingtalk.image.saved', path, bytes: dl.buffer.length }, 'dingtalk image saved');
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
274
|
+
log.warn({ event: 'dingtalk.image.download_failed', err: reason, messageId: msg.msgId }, 'image download/save failed');
|
|
275
|
+
attachmentLine = `[图片附件下载失败:${reason}]`;
|
|
276
|
+
}
|
|
277
|
+
await this.dispatchText(msg, attachmentLine, threadId, channelId);
|
|
278
|
+
}
|
|
279
|
+
/** Voice inbound: download AMR (or whatever the CDN serves) → transcribe
|
|
280
|
+
* via the shared whisper provider → dispatch the transcript as the
|
|
281
|
+
* user's text. The saved source file path is appended so the agent can
|
|
282
|
+
* reference it (replay, archive, etc.) — same shape as the Telegram
|
|
283
|
+
* voice path so claude-code's prompts work uniformly.
|
|
284
|
+
*
|
|
285
|
+
* Surfaces failures inline so the user gets feedback:
|
|
286
|
+
* - no downloadCode → `[语音附件无下载凭据]`
|
|
287
|
+
* - download failed → `[语音附件下载失败:…]`
|
|
288
|
+
* - no provider set → `[语音附件未转写(未配置 OPENAI_API_KEY 或 IMHUB_WHISPERCPP_BIN):path]`
|
|
289
|
+
* - transcribe threw → `[语音转写失败(provider: reason)\n源文件:path]` */
|
|
290
|
+
async handleVoiceInbound(msg, threadId, channelId) {
|
|
291
|
+
const recognition = (msg.content?.recognition ?? '').trim();
|
|
292
|
+
const downloadCode = msg.content?.downloadCode;
|
|
293
|
+
const durationRaw = msg.content?.duration;
|
|
294
|
+
const durationSec = typeof durationRaw === 'number'
|
|
295
|
+
? durationRaw
|
|
296
|
+
: typeof durationRaw === 'string' && durationRaw
|
|
297
|
+
? parseInt(durationRaw, 10)
|
|
298
|
+
: undefined;
|
|
299
|
+
// Try to grab the source audio file so the agent can reference /
|
|
300
|
+
// replay it. Best-effort: a missing or failed download doesn't
|
|
301
|
+
// block the conversation when DingTalk's server-side ASR already
|
|
302
|
+
// gave us the transcript text.
|
|
303
|
+
let savedPath = null;
|
|
304
|
+
let downloadErr = null;
|
|
305
|
+
if (downloadCode) {
|
|
306
|
+
try {
|
|
307
|
+
if (!this.client)
|
|
308
|
+
throw new Error('client not ready');
|
|
309
|
+
const dl = await this.client.downloadMessageFile(downloadCode);
|
|
310
|
+
if (!dl)
|
|
311
|
+
throw new Error('messageFiles/download returned null');
|
|
312
|
+
const ext = pickDingTalkExtension(dl.contentType, undefined);
|
|
313
|
+
savedPath = await saveDingTalkMedia(dl.buffer, this.subPathFor(msg), `${this.safeFilenameStem(msg.msgId)}.${ext}`);
|
|
314
|
+
log.info({ event: 'dingtalk.voice.saved', path: savedPath, bytes: dl.buffer.length }, 'dingtalk voice saved');
|
|
315
|
+
}
|
|
316
|
+
catch (err) {
|
|
317
|
+
downloadErr = err instanceof Error ? err.message : String(err);
|
|
318
|
+
log.warn({ event: 'dingtalk.voice.download_failed', err: downloadErr, messageId: msg.msgId }, 'voice download/save failed (transcript may still be available via DingTalk ASR)');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// Resolve a transcript. Priority order:
|
|
322
|
+
// 1. DingTalk server-side ASR (msg.content.recognition) — accurate
|
|
323
|
+
// for Mandarin, zero latency on our side.
|
|
324
|
+
// 2. Local whisper.cpp / OpenAI Whisper on the downloaded audio,
|
|
325
|
+
// if the platform ASR is missing AND we have the source file.
|
|
326
|
+
// 3. Failure markers so the agent + user both see something.
|
|
327
|
+
let voiceLine;
|
|
328
|
+
if (recognition) {
|
|
329
|
+
const dur = durationSec != null ? `${durationSec}s, ` : '';
|
|
330
|
+
const sourceTail = savedPath ? `\n源文件:${savedPath}]`
|
|
331
|
+
: downloadErr ? `\n源文件下载失败:${downloadErr}]`
|
|
332
|
+
: ']';
|
|
333
|
+
voiceLine = `[语音转写(${dur}provider=dingtalk-asr):\n${recognition}${sourceTail}`;
|
|
334
|
+
}
|
|
335
|
+
else if (!savedPath) {
|
|
336
|
+
voiceLine = `[语音附件下载失败:${downloadErr ?? '钉钉未提供 downloadCode'}]`;
|
|
337
|
+
}
|
|
338
|
+
else if (detectProvider() === 'none') {
|
|
339
|
+
voiceLine = `[语音附件未转写(钉钉未返回 recognition,且本地未配置 OPENAI_API_KEY 或 IMHUB_WHISPERCPP_BIN):${savedPath}]`;
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
try {
|
|
343
|
+
const result = await transcribe(savedPath, { language: 'zh' });
|
|
344
|
+
const dur = durationSec != null ? `${durationSec}s, ` : '';
|
|
345
|
+
voiceLine = [
|
|
346
|
+
`[语音转写(${dur}provider=${result.provider}, ${result.elapsedMs}ms):`,
|
|
347
|
+
result.text || '(空)',
|
|
348
|
+
`源文件:${savedPath}]`,
|
|
349
|
+
].join('\n');
|
|
350
|
+
}
|
|
351
|
+
catch (err) {
|
|
352
|
+
const reason = err instanceof TranscribeError
|
|
353
|
+
? `${err.provider}: ${err.reason}`
|
|
354
|
+
: err instanceof Error ? err.message : String(err);
|
|
355
|
+
voiceLine = `[语音转写失败(${reason})\n源文件:${savedPath}]`;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
await this.dispatchText(msg, voiceLine, threadId, channelId);
|
|
359
|
+
}
|
|
360
|
+
/** Build a filesystem-safe sub-path under MEDIA_ROOT/dingtalk/.
|
|
361
|
+
* Uses senderStaffId for 1:1 and openConversationId for groups; both
|
|
362
|
+
* are alphanumeric+`=` from DingTalk so we sanitise the `=` (and any
|
|
363
|
+
* other path-unsafe chars) to `_` to avoid surprises on Windows ports
|
|
364
|
+
* or shell quoting. */
|
|
365
|
+
subPathFor(msg) {
|
|
366
|
+
const raw = msg.conversationType === '2' ? msg.conversationId : msg.senderStaffId;
|
|
367
|
+
return (raw || 'unknown').replace(/[^A-Za-z0-9_-]/g, '_');
|
|
368
|
+
}
|
|
369
|
+
/** DingTalk msgIds are base64-shaped (`msgABC/DEF+xyz==`) and contain
|
|
370
|
+
* `/` + `+` + `=` — all reserved for path or shell quoting. Replace
|
|
371
|
+
* every non-[A-Za-z0-9_-] char with `_` so the resulting filename
|
|
372
|
+
* passes saveDingTalkMedia's safety check and is portable. */
|
|
373
|
+
safeFilenameStem(msgId) {
|
|
374
|
+
return (msgId || 'unknown').replace(/[^A-Za-z0-9_-]/g, '_');
|
|
375
|
+
}
|
|
376
|
+
/** Shared text-dispatch path used by text / markdown msgtypes. */
|
|
377
|
+
async dispatchText(msg, text, threadId, channelId) {
|
|
378
|
+
const out = {
|
|
379
|
+
id: msg.msgId,
|
|
380
|
+
threadId,
|
|
381
|
+
userId: msg.senderStaffId || 'unknown',
|
|
382
|
+
text,
|
|
383
|
+
timestamp: msg.createAt ? new Date(msg.createAt) : new Date(),
|
|
384
|
+
channelId,
|
|
385
|
+
};
|
|
386
|
+
const ctx = {
|
|
387
|
+
message: out,
|
|
388
|
+
platform: 'dingtalk',
|
|
389
|
+
channelId,
|
|
390
|
+
};
|
|
391
|
+
try {
|
|
392
|
+
await this.messageHandler(ctx);
|
|
393
|
+
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
log.error({
|
|
396
|
+
err: err instanceof Error ? err.message : String(err),
|
|
397
|
+
stack: err instanceof Error ? err.stack : undefined,
|
|
398
|
+
}, 'error in dingtalk message handler');
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
// tryExtractLatLng + MapUrlSource live in ./link-coords.ts so tests for
|
|
403
|
+
// the URL classifier can import them without pulling in this adapter's
|
|
404
|
+
// heavy side-effecting transitive deps (media-store, dingtalk-stream,
|
|
405
|
+
// transcribe, …). Re-exported here for any external callers that import
|
|
406
|
+
// from the adapter module.
|
|
407
|
+
export { tryExtractLatLng } from './link-coords.js';
|
|
408
|
+
export const dingtalkAdapter = new DingTalkAdapter();
|
|
409
|
+
//# sourceMappingURL=dingtalk-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dingtalk-adapter.js","sourceRoot":"","sources":["../../../../src/plugins/messengers/dingtalk/dingtalk-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { DingTalkConfig, DingTalkInboundMessage } from './types.js';
|
|
2
|
+
type MessageHandler = (msg: DingTalkInboundMessage) => Promise<void>;
|
|
3
|
+
export declare class DingTalkClient {
|
|
4
|
+
private dw;
|
|
5
|
+
private config;
|
|
6
|
+
private messageHandler?;
|
|
7
|
+
/** Cached robotCode from the most recent inbound (== clientId for
|
|
8
|
+
* stream-mode internal apps, but we read it from messages so we're
|
|
9
|
+
* tolerant of multi-bot setups in one app). */
|
|
10
|
+
private lastSeenRobotCode;
|
|
11
|
+
constructor(config: DingTalkConfig);
|
|
12
|
+
onMessage(handler: MessageHandler): void;
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
stop(): Promise<void>;
|
|
15
|
+
/** Send a plain-text message to a thread we previously received from
|
|
16
|
+
* (encoded as `user:<staffId>` for 1:1, `group:<convId>` for groups).
|
|
17
|
+
* Uses OpenAPI under the bot's access token. */
|
|
18
|
+
sendMessage(threadId: string, text: string): Promise<void>;
|
|
19
|
+
/** Send a markdown-formatted message. DingTalk's `sampleMarkdown` only
|
|
20
|
+
* takes `title` + `text`; we derive title from the first line so the
|
|
21
|
+
* user sees something meaningful in the notification preview. */
|
|
22
|
+
sendMarkdown(threadId: string, text: string, title?: string): Promise<void>;
|
|
23
|
+
/** Download an inbound image / voice / file message's binary payload.
|
|
24
|
+
*
|
|
25
|
+
* DingTalk hands the bot a short-lived `downloadCode` in each media
|
|
26
|
+
* inbound; we trade it (plus our robotCode) for a presigned downloadUrl
|
|
27
|
+
* on alibaba CDN, then GET that URL and return the bytes.
|
|
28
|
+
*
|
|
29
|
+
* Returns null on any error (caller surfaces a "[download failed:...]"
|
|
30
|
+
* marker instead of silently dropping the user's message). MAX cap is
|
|
31
|
+
* enforced; oversize payloads throw before allocating the buffer.
|
|
32
|
+
*
|
|
33
|
+
* Reference: POST /v1.0/robot/messageFiles/download
|
|
34
|
+
* { downloadCode, robotCode }
|
|
35
|
+
* header: x-acs-dingtalk-access-token
|
|
36
|
+
* response: { downloadUrl } (sometimes nested under .data)
|
|
37
|
+
*/
|
|
38
|
+
downloadMessageFile(downloadCode: string): Promise<{
|
|
39
|
+
buffer: Buffer;
|
|
40
|
+
contentType: string;
|
|
41
|
+
} | null>;
|
|
42
|
+
/** Shared POST path. msgKey + msgParam (stringified inner object) is
|
|
43
|
+
* DingTalk's "templated message" convention — covers text, markdown,
|
|
44
|
+
* cards via the same endpoint. */
|
|
45
|
+
private sendTemplated;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=dingtalk-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dingtalk-client.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/dingtalk/dingtalk-client.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAcxE,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAoBpE,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAAU;IACpB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAgB;IACvC;;oDAEgD;IAChD,OAAO,CAAC,iBAAiB,CAAQ;gBAErB,MAAM,EAAE,cAAc;IAYlC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B;;qDAEiD;IAC3C,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE;;sEAEkE;IAC5D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjF;;;;;;;;;;;;;;OAcG;IACG,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CACtD;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAC/C;IA6ED;;uCAEmC;YACrB,aAAa;CAyC5B"}
|