@0xmaxma/claude-gateway 1.8.14 → 2.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/README.md +28 -1613
- package/config.template.json +7 -1
- package/dist/agent/runner.d.ts +419 -0
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +736 -24
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/skill-learning/index.d.ts +6 -4
- package/dist/agent/skill-learning/index.d.ts.map +1 -1
- package/dist/agent/skill-learning/index.js +3 -3
- package/dist/agent/skill-learning/index.js.map +1 -1
- package/dist/agent/skill-learning/notifier.d.ts +3 -4
- package/dist/agent/skill-learning/notifier.d.ts.map +1 -1
- package/dist/agent/skill-learning/notifier.js +15 -13
- package/dist/agent/skill-learning/notifier.js.map +1 -1
- package/dist/agent/skill-learning/reviewer.d.ts.map +1 -1
- package/dist/agent/skill-learning/reviewer.js +3 -1
- package/dist/agent/skill-learning/reviewer.js.map +1 -1
- package/dist/api/connectors-router.d.ts.map +1 -1
- package/dist/api/connectors-router.js +110 -4
- package/dist/api/connectors-router.js.map +1 -1
- package/dist/api/gateway-router.d.ts +1 -0
- package/dist/api/gateway-router.d.ts.map +1 -1
- package/dist/api/gateway-router.js +13 -1
- package/dist/api/gateway-router.js.map +1 -1
- package/dist/api/line-webhook-router.d.ts +2 -2
- package/dist/api/line-webhook-router.d.ts.map +1 -1
- package/dist/api/line-webhook-router.js +264 -230
- package/dist/api/line-webhook-router.js.map +1 -1
- package/dist/api/router.d.ts.map +1 -1
- package/dist/api/router.js +162 -10
- package/dist/api/router.js.map +1 -1
- package/dist/api/share-router.d.ts.map +1 -1
- package/dist/api/share-router.js +29 -10
- package/dist/api/share-router.js.map +1 -1
- package/dist/api/slack-client.d.ts +2 -0
- package/dist/api/slack-client.d.ts.map +1 -1
- package/dist/api/slack-client.js +6 -2
- package/dist/api/slack-client.js.map +1 -1
- package/dist/api/slack-webhook-router.d.ts +3 -0
- package/dist/api/slack-webhook-router.d.ts.map +1 -1
- package/dist/api/slack-webhook-router.js +226 -131
- package/dist/api/slack-webhook-router.js.map +1 -1
- package/dist/api/voice-router.d.ts +21 -0
- package/dist/api/voice-router.d.ts.map +1 -0
- package/dist/api/voice-router.js +372 -0
- package/dist/api/voice-router.js.map +1 -0
- package/dist/api/voice-settings-router.d.ts +5 -0
- package/dist/api/voice-settings-router.d.ts.map +1 -0
- package/dist/api/voice-settings-router.js +318 -0
- package/dist/api/voice-settings-router.js.map +1 -0
- package/dist/apps/agent-container-migration.d.ts +11 -0
- package/dist/apps/agent-container-migration.d.ts.map +1 -0
- package/dist/apps/agent-container-migration.js +85 -0
- package/dist/apps/agent-container-migration.js.map +1 -0
- package/dist/apps/installer.d.ts +1 -1
- package/dist/apps/installer.d.ts.map +1 -1
- package/dist/apps/installer.js +2 -1
- package/dist/apps/installer.js.map +1 -1
- package/dist/cli/commands/tasks.d.ts +5 -0
- package/dist/cli/commands/tasks.d.ts.map +1 -0
- package/dist/cli/commands/tasks.js +92 -0
- package/dist/cli/commands/tasks.js.map +1 -0
- package/dist/cli/http-client.d.ts +2 -0
- package/dist/cli/http-client.d.ts.map +1 -1
- package/dist/cli/http-client.js +8 -3
- package/dist/cli/http-client.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +5 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/config/config-write-lock.d.ts +2 -0
- package/dist/config/config-write-lock.d.ts.map +1 -1
- package/dist/config/config-write-lock.js +5 -0
- package/dist/config/config-write-lock.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +87 -2
- package/dist/config/loader.js.map +1 -1
- package/dist/config/migrator.d.ts.map +1 -1
- package/dist/config/migrator.js +12 -1
- package/dist/config/migrator.js.map +1 -1
- package/dist/config/watcher.d.ts.map +1 -1
- package/dist/config/watcher.js +6 -0
- package/dist/config/watcher.js.map +1 -1
- package/dist/connectors/resolve.d.ts.map +1 -1
- package/dist/connectors/resolve.js +3 -1
- package/dist/connectors/resolve.js.map +1 -1
- package/dist/connectors/types.d.ts +8 -0
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/cron/manager.d.ts.map +1 -1
- package/dist/cron/manager.js +21 -2
- package/dist/cron/manager.js.map +1 -1
- package/dist/discord/receiver.d.ts +2 -1
- package/dist/discord/receiver.d.ts.map +1 -1
- package/dist/discord/receiver.js +5 -1
- package/dist/discord/receiver.js.map +1 -1
- package/dist/history/db.d.ts +3 -0
- package/dist/history/db.d.ts.map +1 -1
- package/dist/history/db.js +21 -1
- package/dist/history/db.js.map +1 -1
- package/dist/history/types.d.ts +2 -0
- package/dist/history/types.d.ts.map +1 -1
- package/dist/index.js +48 -9
- package/dist/index.js.map +1 -1
- package/dist/orchestration/bounded-queue.d.ts +15 -0
- package/dist/orchestration/bounded-queue.d.ts.map +1 -0
- package/dist/orchestration/bounded-queue.js +58 -0
- package/dist/orchestration/bounded-queue.js.map +1 -0
- package/dist/orchestration/bridge.d.ts +55 -0
- package/dist/orchestration/bridge.d.ts.map +1 -0
- package/dist/orchestration/bridge.js +234 -0
- package/dist/orchestration/bridge.js.map +1 -0
- package/dist/orchestration/browser-routing.d.ts +7 -0
- package/dist/orchestration/browser-routing.d.ts.map +1 -0
- package/dist/orchestration/browser-routing.js +22 -0
- package/dist/orchestration/browser-routing.js.map +1 -0
- package/dist/orchestration/capabilities.d.ts +49 -0
- package/dist/orchestration/capabilities.d.ts.map +1 -0
- package/dist/orchestration/capabilities.js +417 -0
- package/dist/orchestration/capabilities.js.map +1 -0
- package/dist/orchestration/capacity.d.ts +14 -0
- package/dist/orchestration/capacity.d.ts.map +1 -0
- package/dist/orchestration/capacity.js +52 -0
- package/dist/orchestration/capacity.js.map +1 -0
- package/dist/orchestration/channel-activity.d.ts +21 -0
- package/dist/orchestration/channel-activity.d.ts.map +1 -0
- package/dist/orchestration/channel-activity.js +72 -0
- package/dist/orchestration/channel-activity.js.map +1 -0
- package/dist/orchestration/channel-controls.d.ts +32 -0
- package/dist/orchestration/channel-controls.d.ts.map +1 -0
- package/dist/orchestration/channel-controls.js +105 -0
- package/dist/orchestration/channel-controls.js.map +1 -0
- package/dist/orchestration/channel-input-media.d.ts +11 -0
- package/dist/orchestration/channel-input-media.d.ts.map +1 -0
- package/dist/orchestration/channel-input-media.js +54 -0
- package/dist/orchestration/channel-input-media.js.map +1 -0
- package/dist/orchestration/channel-media.d.ts +4 -0
- package/dist/orchestration/channel-media.d.ts.map +1 -0
- package/dist/orchestration/channel-media.js +70 -0
- package/dist/orchestration/channel-media.js.map +1 -0
- package/dist/orchestration/channel-speech.d.ts +7 -0
- package/dist/orchestration/channel-speech.d.ts.map +1 -0
- package/dist/orchestration/channel-speech.js +65 -0
- package/dist/orchestration/channel-speech.js.map +1 -0
- package/dist/orchestration/cli-skills.d.ts +12 -0
- package/dist/orchestration/cli-skills.d.ts.map +1 -0
- package/dist/orchestration/cli-skills.js +132 -0
- package/dist/orchestration/cli-skills.js.map +1 -0
- package/dist/orchestration/config.d.ts +260 -0
- package/dist/orchestration/config.d.ts.map +1 -0
- package/dist/orchestration/config.js +110 -0
- package/dist/orchestration/config.js.map +1 -0
- package/dist/orchestration/container.d.ts +21 -0
- package/dist/orchestration/container.d.ts.map +1 -0
- package/dist/orchestration/container.js +195 -0
- package/dist/orchestration/container.js.map +1 -0
- package/dist/orchestration/control-delivery.d.ts +5 -0
- package/dist/orchestration/control-delivery.d.ts.map +1 -0
- package/dist/orchestration/control-delivery.js +50 -0
- package/dist/orchestration/control-delivery.js.map +1 -0
- package/dist/orchestration/conversation-intake.d.ts +32 -0
- package/dist/orchestration/conversation-intake.d.ts.map +1 -0
- package/dist/orchestration/conversation-intake.js +92 -0
- package/dist/orchestration/conversation-intake.js.map +1 -0
- package/dist/orchestration/decisions.d.ts +27 -0
- package/dist/orchestration/decisions.d.ts.map +1 -0
- package/dist/orchestration/decisions.js +151 -0
- package/dist/orchestration/decisions.js.map +1 -0
- package/dist/orchestration/delivery.d.ts +34 -0
- package/dist/orchestration/delivery.d.ts.map +1 -0
- package/dist/orchestration/delivery.js +235 -0
- package/dist/orchestration/delivery.js.map +1 -0
- package/dist/orchestration/display-stream.d.ts +4 -0
- package/dist/orchestration/display-stream.d.ts.map +1 -0
- package/dist/orchestration/display-stream.js +77 -0
- package/dist/orchestration/display-stream.js.map +1 -0
- package/dist/orchestration/events.d.ts +30 -0
- package/dist/orchestration/events.d.ts.map +1 -0
- package/dist/orchestration/events.js +65 -0
- package/dist/orchestration/events.js.map +1 -0
- package/dist/orchestration/execution-observation.d.ts +38 -0
- package/dist/orchestration/execution-observation.d.ts.map +1 -0
- package/dist/orchestration/execution-observation.js +25 -0
- package/dist/orchestration/execution-observation.js.map +1 -0
- package/dist/orchestration/file-delivery.d.ts +16 -0
- package/dist/orchestration/file-delivery.d.ts.map +1 -0
- package/dist/orchestration/file-delivery.js +139 -0
- package/dist/orchestration/file-delivery.js.map +1 -0
- package/dist/orchestration/gateway-config.d.ts +17 -0
- package/dist/orchestration/gateway-config.d.ts.map +1 -0
- package/dist/orchestration/gateway-config.js +128 -0
- package/dist/orchestration/gateway-config.js.map +1 -0
- package/dist/orchestration/history.d.ts +13 -0
- package/dist/orchestration/history.d.ts.map +1 -0
- package/dist/orchestration/history.js +48 -0
- package/dist/orchestration/history.js.map +1 -0
- package/dist/orchestration/identity.d.ts +6 -0
- package/dist/orchestration/identity.d.ts.map +1 -0
- package/dist/orchestration/identity.js +13 -0
- package/dist/orchestration/identity.js.map +1 -0
- package/dist/orchestration/inference-errors.d.ts +3 -0
- package/dist/orchestration/inference-errors.d.ts.map +1 -0
- package/dist/orchestration/inference-errors.js +16 -0
- package/dist/orchestration/inference-errors.js.map +1 -0
- package/dist/orchestration/input-images.d.ts +12 -0
- package/dist/orchestration/input-images.d.ts.map +1 -0
- package/dist/orchestration/input-images.js +66 -0
- package/dist/orchestration/input-images.js.map +1 -0
- package/dist/orchestration/instance-lock.d.ts +5 -0
- package/dist/orchestration/instance-lock.d.ts.map +1 -0
- package/dist/orchestration/instance-lock.js +33 -0
- package/dist/orchestration/instance-lock.js.map +1 -0
- package/dist/orchestration/line-loading.d.ts +21 -0
- package/dist/orchestration/line-loading.d.ts.map +1 -0
- package/dist/orchestration/line-loading.js +89 -0
- package/dist/orchestration/line-loading.js.map +1 -0
- package/dist/orchestration/media.d.ts +3 -0
- package/dist/orchestration/media.d.ts.map +1 -0
- package/dist/orchestration/media.js +46 -0
- package/dist/orchestration/media.js.map +1 -0
- package/dist/orchestration/migrations/schema.d.ts +3 -0
- package/dist/orchestration/migrations/schema.d.ts.map +1 -0
- package/dist/orchestration/migrations/schema.js +80 -0
- package/dist/orchestration/migrations/schema.js.map +1 -0
- package/dist/orchestration/notification-mailbox.d.ts +5 -0
- package/dist/orchestration/notification-mailbox.d.ts.map +1 -0
- package/dist/orchestration/notification-mailbox.js +29 -0
- package/dist/orchestration/notification-mailbox.js.map +1 -0
- package/dist/orchestration/process-activity.d.ts +23 -0
- package/dist/orchestration/process-activity.d.ts.map +1 -0
- package/dist/orchestration/process-activity.js +95 -0
- package/dist/orchestration/process-activity.js.map +1 -0
- package/dist/orchestration/process-supervisor.d.ts +15 -0
- package/dist/orchestration/process-supervisor.d.ts.map +1 -0
- package/dist/orchestration/process-supervisor.js +92 -0
- package/dist/orchestration/process-supervisor.js.map +1 -0
- package/dist/orchestration/process-turn.d.ts +35 -0
- package/dist/orchestration/process-turn.d.ts.map +1 -0
- package/dist/orchestration/process-turn.js +246 -0
- package/dist/orchestration/process-turn.js.map +1 -0
- package/dist/orchestration/progress-review.d.ts +28 -0
- package/dist/orchestration/progress-review.d.ts.map +1 -0
- package/dist/orchestration/progress-review.js +48 -0
- package/dist/orchestration/progress-review.js.map +1 -0
- package/dist/orchestration/recovery.d.ts +8 -0
- package/dist/orchestration/recovery.d.ts.map +1 -0
- package/dist/orchestration/recovery.js +35 -0
- package/dist/orchestration/recovery.js.map +1 -0
- package/dist/orchestration/reply-context.d.ts +7 -0
- package/dist/orchestration/reply-context.d.ts.map +1 -0
- package/dist/orchestration/reply-context.js +54 -0
- package/dist/orchestration/reply-context.js.map +1 -0
- package/dist/orchestration/runtime.d.ts +237 -0
- package/dist/orchestration/runtime.d.ts.map +1 -0
- package/dist/orchestration/runtime.js +1031 -0
- package/dist/orchestration/runtime.js.map +1 -0
- package/dist/orchestration/skills.d.ts +17 -0
- package/dist/orchestration/skills.d.ts.map +1 -0
- package/dist/orchestration/skills.js +32 -0
- package/dist/orchestration/skills.js.map +1 -0
- package/dist/orchestration/source-policy.d.ts +6 -0
- package/dist/orchestration/source-policy.d.ts.map +1 -0
- package/dist/orchestration/source-policy.js +16 -0
- package/dist/orchestration/source-policy.js.map +1 -0
- package/dist/orchestration/speech.d.ts +24 -0
- package/dist/orchestration/speech.d.ts.map +1 -0
- package/dist/orchestration/speech.js +61 -0
- package/dist/orchestration/speech.js.map +1 -0
- package/dist/orchestration/stop-controls.d.ts +30 -0
- package/dist/orchestration/stop-controls.d.ts.map +1 -0
- package/dist/orchestration/stop-controls.js +79 -0
- package/dist/orchestration/stop-controls.js.map +1 -0
- package/dist/orchestration/store.d.ts +92 -0
- package/dist/orchestration/store.d.ts.map +1 -0
- package/dist/orchestration/store.js +326 -0
- package/dist/orchestration/store.js.map +1 -0
- package/dist/orchestration/task-controls.d.ts +172 -0
- package/dist/orchestration/task-controls.d.ts.map +1 -0
- package/dist/orchestration/task-controls.js +59 -0
- package/dist/orchestration/task-controls.js.map +1 -0
- package/dist/orchestration/task-files.d.ts +29 -0
- package/dist/orchestration/task-files.d.ts.map +1 -0
- package/dist/orchestration/task-files.js +200 -0
- package/dist/orchestration/task-files.js.map +1 -0
- package/dist/orchestration/task-questions.d.ts +26 -0
- package/dist/orchestration/task-questions.d.ts.map +1 -0
- package/dist/orchestration/task-questions.js +160 -0
- package/dist/orchestration/task-questions.js.map +1 -0
- package/dist/orchestration/task-report.d.ts +7 -0
- package/dist/orchestration/task-report.d.ts.map +1 -0
- package/dist/orchestration/task-report.js +33 -0
- package/dist/orchestration/task-report.js.map +1 -0
- package/dist/orchestration/tasks/checkpoint-hook.d.ts +19 -0
- package/dist/orchestration/tasks/checkpoint-hook.d.ts.map +1 -0
- package/dist/orchestration/tasks/checkpoint-hook.js +49 -0
- package/dist/orchestration/tasks/checkpoint-hook.js.map +1 -0
- package/dist/orchestration/tasks/cleanup.d.ts +18 -0
- package/dist/orchestration/tasks/cleanup.d.ts.map +1 -0
- package/dist/orchestration/tasks/cleanup.js +113 -0
- package/dist/orchestration/tasks/cleanup.js.map +1 -0
- package/dist/orchestration/tasks/driver.d.ts +23 -0
- package/dist/orchestration/tasks/driver.d.ts.map +1 -0
- package/dist/orchestration/tasks/driver.js +209 -0
- package/dist/orchestration/tasks/driver.js.map +1 -0
- package/dist/orchestration/tasks/failure.d.ts +5 -0
- package/dist/orchestration/tasks/failure.d.ts.map +1 -0
- package/dist/orchestration/tasks/failure.js +17 -0
- package/dist/orchestration/tasks/failure.js.map +1 -0
- package/dist/orchestration/tasks/pool.d.ts +18 -0
- package/dist/orchestration/tasks/pool.d.ts.map +1 -0
- package/dist/orchestration/tasks/pool.js +73 -0
- package/dist/orchestration/tasks/pool.js.map +1 -0
- package/dist/orchestration/tasks/scheduler.d.ts +38 -0
- package/dist/orchestration/tasks/scheduler.d.ts.map +1 -0
- package/dist/orchestration/tasks/scheduler.js +160 -0
- package/dist/orchestration/tasks/scheduler.js.map +1 -0
- package/dist/orchestration/tasks/service.d.ts +114 -0
- package/dist/orchestration/tasks/service.d.ts.map +1 -0
- package/dist/orchestration/tasks/service.js +760 -0
- package/dist/orchestration/tasks/service.js.map +1 -0
- package/dist/orchestration/tasks/shared-workspace.d.ts +25 -0
- package/dist/orchestration/tasks/shared-workspace.d.ts.map +1 -0
- package/dist/orchestration/tasks/shared-workspace.js +162 -0
- package/dist/orchestration/tasks/shared-workspace.js.map +1 -0
- package/dist/orchestration/tasks/task-directive.d.ts +6 -0
- package/dist/orchestration/tasks/task-directive.d.ts.map +1 -0
- package/dist/orchestration/tasks/task-directive.js +41 -0
- package/dist/orchestration/tasks/task-directive.js.map +1 -0
- package/dist/orchestration/tasks/timing.d.ts +15 -0
- package/dist/orchestration/tasks/timing.d.ts.map +1 -0
- package/dist/orchestration/tasks/timing.js +48 -0
- package/dist/orchestration/tasks/timing.js.map +1 -0
- package/dist/orchestration/tasks/tool-repetition.d.ts +3 -0
- package/dist/orchestration/tasks/tool-repetition.d.ts.map +1 -0
- package/dist/orchestration/tasks/tool-repetition.js +30 -0
- package/dist/orchestration/tasks/tool-repetition.js.map +1 -0
- package/dist/orchestration/tasks/workspace.d.ts +24 -0
- package/dist/orchestration/tasks/workspace.d.ts.map +1 -0
- package/dist/orchestration/tasks/workspace.js +147 -0
- package/dist/orchestration/tasks/workspace.js.map +1 -0
- package/dist/orchestration/telegram-speech.d.ts +17 -0
- package/dist/orchestration/telegram-speech.d.ts.map +1 -0
- package/dist/orchestration/telegram-speech.js +55 -0
- package/dist/orchestration/telegram-speech.js.map +1 -0
- package/dist/orchestration/telegram-tool-status.d.ts +23 -0
- package/dist/orchestration/telegram-tool-status.d.ts.map +1 -0
- package/dist/orchestration/telegram-tool-status.js +207 -0
- package/dist/orchestration/telegram-tool-status.js.map +1 -0
- package/dist/orchestration/telegram-voices.d.ts +42 -0
- package/dist/orchestration/telegram-voices.d.ts.map +1 -0
- package/dist/orchestration/telegram-voices.js +70 -0
- package/dist/orchestration/telegram-voices.js.map +1 -0
- package/dist/orchestration/tool-activity.d.ts +10 -0
- package/dist/orchestration/tool-activity.d.ts.map +1 -0
- package/dist/orchestration/tool-activity.js +38 -0
- package/dist/orchestration/tool-activity.js.map +1 -0
- package/dist/orchestration/types.d.ts +177 -0
- package/dist/orchestration/types.d.ts.map +1 -0
- package/dist/orchestration/types.js +13 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/orchestration/voice-reply-policy.d.ts +8 -0
- package/dist/orchestration/voice-reply-policy.d.ts.map +1 -0
- package/dist/orchestration/voice-reply-policy.js +46 -0
- package/dist/orchestration/voice-reply-policy.js.map +1 -0
- package/dist/orchestration/worker-shares.d.ts +8 -0
- package/dist/orchestration/worker-shares.d.ts.map +1 -0
- package/dist/orchestration/worker-shares.js +59 -0
- package/dist/orchestration/worker-shares.js.map +1 -0
- package/dist/orchestration/workflow.d.ts +121 -0
- package/dist/orchestration/workflow.d.ts.map +1 -0
- package/dist/orchestration/workflow.js +69 -0
- package/dist/orchestration/workflow.js.map +1 -0
- package/dist/session/input-image.d.ts +10 -0
- package/dist/session/input-image.d.ts.map +1 -0
- package/dist/session/input-image.js +3 -0
- package/dist/session/input-image.js.map +1 -0
- package/dist/session/process.d.ts +15 -3
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +143 -35
- package/dist/session/process.js.map +1 -1
- package/dist/session/runtime-profile.d.ts +36 -0
- package/dist/session/runtime-profile.d.ts.map +1 -0
- package/dist/session/runtime-profile.js +63 -0
- package/dist/session/runtime-profile.js.map +1 -0
- package/dist/session/store.d.ts.map +1 -1
- package/dist/session/store.js +23 -1
- package/dist/session/store.js.map +1 -1
- package/dist/share/share-store.d.ts +3 -1
- package/dist/share/share-store.d.ts.map +1 -1
- package/dist/share/share-store.js +13 -2
- package/dist/share/share-store.js.map +1 -1
- package/dist/shared/line-request-order.d.ts +2 -0
- package/dist/shared/line-request-order.d.ts.map +1 -0
- package/dist/shared/line-request-order.js +16 -0
- package/dist/shared/line-request-order.js.map +1 -0
- package/dist/shared/task-elapsed.d.ts +3 -0
- package/dist/shared/task-elapsed.d.ts.map +1 -0
- package/dist/shared/task-elapsed.js +12 -0
- package/dist/shared/task-elapsed.js.map +1 -0
- package/dist/shared/task-updated-time.d.ts +3 -0
- package/dist/shared/task-updated-time.d.ts.map +1 -0
- package/dist/shared/task-updated-time.js +15 -0
- package/dist/shared/task-updated-time.js.map +1 -0
- package/dist/skills/loader.d.ts +2 -0
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js.map +1 -1
- package/dist/telegram/chunks.d.ts +19 -0
- package/dist/telegram/chunks.d.ts.map +1 -0
- package/dist/telegram/chunks.js +129 -0
- package/dist/telegram/chunks.js.map +1 -0
- package/dist/telegram/markdown.d.ts.map +1 -1
- package/dist/telegram/markdown.js +18 -3
- package/dist/telegram/markdown.js.map +1 -1
- package/dist/telegram/receiver.d.ts +2 -1
- package/dist/telegram/receiver.d.ts.map +1 -1
- package/dist/telegram/receiver.js +6 -1
- package/dist/telegram/receiver.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/web-ui.d.ts.map +1 -1
- package/dist/ui/web-ui.js +31 -5
- package/dist/ui/web-ui.js.map +1 -1
- package/dist/voice/diagnostics.d.ts +29 -0
- package/dist/voice/diagnostics.d.ts.map +1 -0
- package/dist/voice/diagnostics.js +37 -0
- package/dist/voice/diagnostics.js.map +1 -0
- package/dist/voice/errors.d.ts +19 -0
- package/dist/voice/errors.d.ts.map +1 -0
- package/dist/voice/errors.js +133 -0
- package/dist/voice/errors.js.map +1 -0
- package/dist/voice/line-audio.d.ts +4 -0
- package/dist/voice/line-audio.d.ts.map +1 -0
- package/dist/voice/line-audio.js +27 -0
- package/dist/voice/line-audio.js.map +1 -0
- package/dist/voice/managed-quota.d.ts +5 -0
- package/dist/voice/managed-quota.d.ts.map +1 -0
- package/dist/voice/managed-quota.js +35 -0
- package/dist/voice/managed-quota.js.map +1 -0
- package/dist/voice/mp3.d.ts +3 -0
- package/dist/voice/mp3.d.ts.map +1 -0
- package/dist/voice/mp3.js +30 -0
- package/dist/voice/mp3.js.map +1 -0
- package/dist/voice/notes.d.ts +9 -0
- package/dist/voice/notes.d.ts.map +1 -0
- package/dist/voice/notes.js +68 -0
- package/dist/voice/notes.js.map +1 -0
- package/dist/voice/playback.d.ts +22 -0
- package/dist/voice/playback.d.ts.map +1 -0
- package/dist/voice/playback.js +52 -0
- package/dist/voice/playback.js.map +1 -0
- package/dist/voice/preview.d.ts +6 -0
- package/dist/voice/preview.d.ts.map +1 -0
- package/dist/voice/preview.js +44 -0
- package/dist/voice/preview.js.map +1 -0
- package/dist/voice/protocol.d.ts +10 -0
- package/dist/voice/protocol.d.ts.map +1 -0
- package/dist/voice/protocol.js +30 -0
- package/dist/voice/protocol.js.map +1 -0
- package/dist/voice/providers/cartesia-tts.d.ts +26 -0
- package/dist/voice/providers/cartesia-tts.d.ts.map +1 -0
- package/dist/voice/providers/cartesia-tts.js +95 -0
- package/dist/voice/providers/cartesia-tts.js.map +1 -0
- package/dist/voice/providers/deepgram-stt.d.ts +20 -0
- package/dist/voice/providers/deepgram-stt.d.ts.map +1 -0
- package/dist/voice/providers/deepgram-stt.js +66 -0
- package/dist/voice/providers/deepgram-stt.js.map +1 -0
- package/dist/voice/providers/elevenlabs-stt.d.ts +20 -0
- package/dist/voice/providers/elevenlabs-stt.d.ts.map +1 -0
- package/dist/voice/providers/elevenlabs-stt.js +92 -0
- package/dist/voice/providers/elevenlabs-stt.js.map +1 -0
- package/dist/voice/providers/elevenlabs-tts.d.ts +26 -0
- package/dist/voice/providers/elevenlabs-tts.d.ts.map +1 -0
- package/dist/voice/providers/elevenlabs-tts.js +82 -0
- package/dist/voice/providers/elevenlabs-tts.js.map +1 -0
- package/dist/voice/providers/encoded-audio-tts.d.ts +21 -0
- package/dist/voice/providers/encoded-audio-tts.d.ts.map +1 -0
- package/dist/voice/providers/encoded-audio-tts.js +175 -0
- package/dist/voice/providers/encoded-audio-tts.js.map +1 -0
- package/dist/voice/providers/fake.d.ts +39 -0
- package/dist/voice/providers/fake.d.ts.map +1 -0
- package/dist/voice/providers/fake.js +41 -0
- package/dist/voice/providers/fake.js.map +1 -0
- package/dist/voice/providers/gemini-live-stt.d.ts +21 -0
- package/dist/voice/providers/gemini-live-stt.d.ts.map +1 -0
- package/dist/voice/providers/gemini-live-stt.js +158 -0
- package/dist/voice/providers/gemini-live-stt.js.map +1 -0
- package/dist/voice/providers/gemini.d.ts +60 -0
- package/dist/voice/providers/gemini.d.ts.map +1 -0
- package/dist/voice/providers/gemini.js +124 -0
- package/dist/voice/providers/gemini.js.map +1 -0
- package/dist/voice/providers/model-ref.d.ts +9 -0
- package/dist/voice/providers/model-ref.d.ts.map +1 -0
- package/dist/voice/providers/model-ref.js +31 -0
- package/dist/voice/providers/model-ref.js.map +1 -0
- package/dist/voice/providers/openrouter.d.ts +39 -0
- package/dist/voice/providers/openrouter.d.ts.map +1 -0
- package/dist/voice/providers/openrouter.js +154 -0
- package/dist/voice/providers/openrouter.js.map +1 -0
- package/dist/voice/providers/paxalabs-stt.d.ts +12 -0
- package/dist/voice/providers/paxalabs-stt.d.ts.map +1 -0
- package/dist/voice/providers/paxalabs-stt.js +41 -0
- package/dist/voice/providers/paxalabs-stt.js.map +1 -0
- package/dist/voice/providers/paxalabs-tts.d.ts +23 -0
- package/dist/voice/providers/paxalabs-tts.d.ts.map +1 -0
- package/dist/voice/providers/paxalabs-tts.js +80 -0
- package/dist/voice/providers/paxalabs-tts.js.map +1 -0
- package/dist/voice/providers/recorded-stt.d.ts +34 -0
- package/dist/voice/providers/recorded-stt.d.ts.map +1 -0
- package/dist/voice/providers/recorded-stt.js +59 -0
- package/dist/voice/providers/recorded-stt.js.map +1 -0
- package/dist/voice/providers/registry.d.ts +10 -0
- package/dist/voice/providers/registry.d.ts.map +1 -0
- package/dist/voice/providers/registry.js +77 -0
- package/dist/voice/providers/registry.js.map +1 -0
- package/dist/voice/providers/socket.d.ts +10 -0
- package/dist/voice/providers/socket.d.ts.map +1 -0
- package/dist/voice/providers/socket.js +91 -0
- package/dist/voice/providers/socket.js.map +1 -0
- package/dist/voice/providers/upstream.d.ts +9 -0
- package/dist/voice/providers/upstream.d.ts.map +1 -0
- package/dist/voice/providers/upstream.js +51 -0
- package/dist/voice/providers/upstream.js.map +1 -0
- package/dist/voice/providers/voice-catalog.d.ts +17 -0
- package/dist/voice/providers/voice-catalog.d.ts.map +1 -0
- package/dist/voice/providers/voice-catalog.js +167 -0
- package/dist/voice/providers/voice-catalog.js.map +1 -0
- package/dist/voice/queue.d.ts +2 -0
- package/dist/voice/queue.d.ts.map +1 -0
- package/dist/voice/queue.js +6 -0
- package/dist/voice/queue.js.map +1 -0
- package/dist/voice/session.d.ts +86 -0
- package/dist/voice/session.d.ts.map +1 -0
- package/dist/voice/session.js +464 -0
- package/dist/voice/session.js.map +1 -0
- package/dist/voice/turn-manager.d.ts +27 -0
- package/dist/voice/turn-manager.d.ts.map +1 -0
- package/dist/voice/turn-manager.js +75 -0
- package/dist/voice/turn-manager.js.map +1 -0
- package/dist/voice/types.d.ts +78 -0
- package/dist/voice/types.d.ts.map +1 -0
- package/dist/voice/types.js +18 -0
- package/dist/voice/types.js.map +1 -0
- package/dist/voice/wav.d.ts +2 -0
- package/dist/voice/wav.d.ts.map +1 -0
- package/dist/voice/wav.js +21 -0
- package/dist/voice/wav.js.map +1 -0
- package/dist/wechat/ilink-client.d.ts +13 -0
- package/dist/wechat/ilink-client.d.ts.map +1 -1
- package/dist/wechat/ilink-client.js +19 -0
- package/dist/wechat/ilink-client.js.map +1 -1
- package/dist/whatsapp/manager.d.ts.map +1 -1
- package/dist/whatsapp/manager.js +51 -1
- package/dist/whatsapp/manager.js.map +1 -1
- package/mcp/capability-catalog.ts +206 -0
- package/mcp/modules.ts +56 -0
- package/mcp/server.ts +18 -37
- package/mcp/tools/browser/module.ts +1 -1
- package/mcp/tools/browser/skills/open-browser/SKILL.md +5 -3
- package/mcp/tools/discord/commands.ts +17 -1
- package/mcp/tools/discord/inbound.ts +11 -0
- package/mcp/tools/discord/module.ts +42 -2
- package/mcp/tools/discord/receiver-server.ts +10 -0
- package/mcp/tools/discord/types.ts +4 -1
- package/mcp/tools/image/module.ts +3 -1
- package/mcp/tools/receiver-spool.test.ts +28 -0
- package/mcp/tools/receiver-spool.ts +56 -0
- package/mcp/tools/share-file/module.ts +9 -1
- package/mcp/tools/shared/share-client.ts +19 -0
- package/mcp/tools/tasks/module.ts +35 -0
- package/mcp/tools/telegram/media-group.ts +21 -0
- package/mcp/tools/telegram/receiver-server.ts +246 -11
- package/mcp/tools/telegram/selection-confirmation.ts +20 -0
- package/mcp/tools/telegram/task-browser.ts +117 -0
- package/mcp/tools/telegram/task-detail.ts +36 -0
- package/mcp/tools/telegram/task-elapsed.ts +1 -0
- package/mcp/tools/telegram/typing.ts +6 -116
- package/mcp/tools/video/module.ts +1 -1
- package/mcp/types.ts +5 -0
- package/package.json +2 -1
- package/resource/claude_gateway.jpeg +0 -0
- package/scripts/orchestration/bench-store.cjs +30 -0
- package/scripts/orchestration/inspect.cjs +16 -0
- package/scripts/orchestration/probe-profile.cjs +67 -0
- package/scripts/orchestration/reconcile.cjs +21 -0
- package/scripts/orchestration/smoke-elevenlabs.cjs +90 -0
- package/scripts/orchestration/smoke-media.cjs +70 -0
- package/scripts/orchestration/smoke-text.cjs +101 -0
- package/scripts/orchestration/smoke-vision.cjs +49 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/** Metadata only. Never initialize channel receivers or call an MCP tool. */
|
|
2
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
3
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
4
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
5
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
6
|
+
import { gatewayModules } from './modules';
|
|
7
|
+
import { AGENT_TASK_TOOLS, WORKER_REPORT_TOOLS } from './tools/tasks/module';
|
|
8
|
+
|
|
9
|
+
type Entry = {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
server: string;
|
|
13
|
+
status: string;
|
|
14
|
+
via: 'agent' | 'worker' | 'unavailable';
|
|
15
|
+
};
|
|
16
|
+
const entries: Entry[] = [];
|
|
17
|
+
const servers: Array<{ name: string; status: string }> = [];
|
|
18
|
+
const chunks: Buffer[] = [];
|
|
19
|
+
let bytes = 0;
|
|
20
|
+
for await (const chunk of process.stdin) {
|
|
21
|
+
bytes += chunk.length;
|
|
22
|
+
if (bytes > 4 * 1024 * 1024) throw Error('CATALOG_INPUT_TOO_LARGE');
|
|
23
|
+
chunks.push(Buffer.from(chunk));
|
|
24
|
+
}
|
|
25
|
+
const input = JSON.parse(Buffer.concat(chunks).toString());
|
|
26
|
+
// Mirror the worker module gates for metadata, without issuing a usable ticket.
|
|
27
|
+
const profileKeys = [
|
|
28
|
+
'GATEWAY_ORCHESTRATION_ROLE',
|
|
29
|
+
'GATEWAY_ORCHESTRATION_MEDIA',
|
|
30
|
+
'GATEWAY_ORCHESTRATION_TICKET_FILE',
|
|
31
|
+
];
|
|
32
|
+
const original = profileKeys.map((key) => process.env[key]);
|
|
33
|
+
Object.assign(process.env, {
|
|
34
|
+
GATEWAY_ORCHESTRATION_ROLE: 'worker',
|
|
35
|
+
GATEWAY_ORCHESTRATION_MEDIA: 'true',
|
|
36
|
+
GATEWAY_ORCHESTRATION_TICKET_FILE: '/capability-discovery-no-execution',
|
|
37
|
+
});
|
|
38
|
+
const worker = new Set(
|
|
39
|
+
gatewayModules('worker', true).flatMap((m) =>
|
|
40
|
+
m.isEnabled() ? m.getTools().map((t) => t.name) : []
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
for (const module of gatewayModules()) {
|
|
44
|
+
let enabled = false;
|
|
45
|
+
try {
|
|
46
|
+
enabled = module.isEnabled();
|
|
47
|
+
} catch {
|
|
48
|
+
/* Unavailable, not absent. */
|
|
49
|
+
}
|
|
50
|
+
for (const tool of module.getTools())
|
|
51
|
+
entries.push({
|
|
52
|
+
name: `mcp__gateway__${tool.name}`,
|
|
53
|
+
description: tool.description,
|
|
54
|
+
server: 'gateway',
|
|
55
|
+
status: !enabled
|
|
56
|
+
? 'not_configured'
|
|
57
|
+
: worker.has(tool.name)
|
|
58
|
+
? tool.name.startsWith('memory_shared_')
|
|
59
|
+
? 'requires_memory_permission'
|
|
60
|
+
: 'available'
|
|
61
|
+
: 'not_exposed_to_workers',
|
|
62
|
+
via:
|
|
63
|
+
enabled && ['memory_search', 'memory_get'].includes(tool.name)
|
|
64
|
+
? 'agent'
|
|
65
|
+
: enabled && worker.has(tool.name)
|
|
66
|
+
? 'worker'
|
|
67
|
+
: 'unavailable',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
for (const tool of AGENT_TASK_TOOLS)
|
|
71
|
+
entries.push({
|
|
72
|
+
name: `mcp__gateway__${tool.name}`,
|
|
73
|
+
description: tool.description,
|
|
74
|
+
server: 'gateway',
|
|
75
|
+
status:
|
|
76
|
+
tool.name === 'conversation_intake'
|
|
77
|
+
? 'requires_semantic_intake'
|
|
78
|
+
: 'available',
|
|
79
|
+
via: 'agent',
|
|
80
|
+
});
|
|
81
|
+
for (const tool of WORKER_REPORT_TOOLS)
|
|
82
|
+
entries.push({
|
|
83
|
+
name: `mcp__gateway__${tool.name}`,
|
|
84
|
+
description: tool.description,
|
|
85
|
+
server: 'gateway',
|
|
86
|
+
status:
|
|
87
|
+
tool.name === 'task_memory_append'
|
|
88
|
+
? 'requires_memory_permission'
|
|
89
|
+
: 'available',
|
|
90
|
+
via: 'worker',
|
|
91
|
+
});
|
|
92
|
+
profileKeys.forEach((key, i) => {
|
|
93
|
+
if (original[i] === undefined) delete process.env[key];
|
|
94
|
+
else process.env[key] = original[i];
|
|
95
|
+
});
|
|
96
|
+
servers.push({ name: 'gateway', status: 'available' });
|
|
97
|
+
for (const [name, value] of Object.entries(input.servers ?? {})) {
|
|
98
|
+
const config = value as {
|
|
99
|
+
type?: string;
|
|
100
|
+
command?: string;
|
|
101
|
+
args?: string[];
|
|
102
|
+
env?: Record<string, string>;
|
|
103
|
+
url?: string;
|
|
104
|
+
headers?: Record<string, string>;
|
|
105
|
+
};
|
|
106
|
+
const client = new Client({
|
|
107
|
+
name: 'gateway-capability-discovery',
|
|
108
|
+
version: '1',
|
|
109
|
+
});
|
|
110
|
+
let transport:
|
|
111
|
+
| StdioClientTransport
|
|
112
|
+
| StreamableHTTPClientTransport
|
|
113
|
+
| SSEClientTransport
|
|
114
|
+
| undefined;
|
|
115
|
+
const timeout = setTimeout(() => {
|
|
116
|
+
void client.close();
|
|
117
|
+
}, 5000);
|
|
118
|
+
try {
|
|
119
|
+
if (config.command)
|
|
120
|
+
transport = new StdioClientTransport({
|
|
121
|
+
command: config.command,
|
|
122
|
+
args: config.args,
|
|
123
|
+
env: {
|
|
124
|
+
...Object.fromEntries(
|
|
125
|
+
Object.entries(process.env).filter(
|
|
126
|
+
(e): e is [string, string] => typeof e[1] === 'string'
|
|
127
|
+
)
|
|
128
|
+
),
|
|
129
|
+
...config.env,
|
|
130
|
+
},
|
|
131
|
+
stderr: 'ignore',
|
|
132
|
+
});
|
|
133
|
+
else if (config.url)
|
|
134
|
+
transport =
|
|
135
|
+
config.type === 'sse'
|
|
136
|
+
? new SSEClientTransport(new URL(config.url), {
|
|
137
|
+
requestInit: { headers: config.headers },
|
|
138
|
+
})
|
|
139
|
+
: new StreamableHTTPClientTransport(new URL(config.url), {
|
|
140
|
+
requestInit: { headers: config.headers },
|
|
141
|
+
});
|
|
142
|
+
else throw Error('INVALID_MCP_CONFIG');
|
|
143
|
+
await client.connect(transport, { timeout: 5000 });
|
|
144
|
+
let cursor: string | undefined;
|
|
145
|
+
const seen = new Set<string>();
|
|
146
|
+
do {
|
|
147
|
+
const result = await client.listTools(cursor ? { cursor } : {}, {
|
|
148
|
+
timeout: 5000,
|
|
149
|
+
});
|
|
150
|
+
for (const tool of result.tools)
|
|
151
|
+
entries.push({
|
|
152
|
+
name: `mcp__${name.replace(/[^a-zA-Z0-9_-]/g, '_')}__${tool.name.replace(/[^a-zA-Z0-9_-]/g, '_')}`,
|
|
153
|
+
description: tool.description ?? '',
|
|
154
|
+
server: name,
|
|
155
|
+
status: 'available',
|
|
156
|
+
via: 'worker',
|
|
157
|
+
});
|
|
158
|
+
cursor = result.nextCursor;
|
|
159
|
+
if (cursor && seen.has(cursor)) throw Error('CATALOG_CURSOR_LOOP');
|
|
160
|
+
if (cursor) seen.add(cursor);
|
|
161
|
+
if (Buffer.byteLength(JSON.stringify(entries)) > 3 * 1024 * 1024)
|
|
162
|
+
throw Error('CATALOG_TOO_LARGE');
|
|
163
|
+
} while (cursor);
|
|
164
|
+
servers.push({ name, status: 'available' });
|
|
165
|
+
} catch {
|
|
166
|
+
// Do not publish connection errors: URLs/headers may include secrets.
|
|
167
|
+
for (const entry of entries)
|
|
168
|
+
if (entry.server === name) {
|
|
169
|
+
entry.status = 'discovery_incomplete';
|
|
170
|
+
entry.via = 'unavailable';
|
|
171
|
+
}
|
|
172
|
+
const observed = input.observed?.find(
|
|
173
|
+
(s: { name: string; status: string }) =>
|
|
174
|
+
s.name === name && s.status === 'connected'
|
|
175
|
+
);
|
|
176
|
+
if (observed) {
|
|
177
|
+
for (const tool of observed.tools ?? []) {
|
|
178
|
+
const fullName = `mcp__${name.replace(/[^a-zA-Z0-9_-]/g, '_')}__${String(tool.name).replace(/[^a-zA-Z0-9_-]/g, '_')}`;
|
|
179
|
+
if (!entries.some((e) => e.name === fullName))
|
|
180
|
+
entries.push({
|
|
181
|
+
name: fullName,
|
|
182
|
+
description:
|
|
183
|
+
tool.description ||
|
|
184
|
+
'Tool reported by the Claude Code MCP runtime; detailed metadata unavailable.',
|
|
185
|
+
server: name,
|
|
186
|
+
status: 'available',
|
|
187
|
+
via: 'worker',
|
|
188
|
+
});
|
|
189
|
+
else
|
|
190
|
+
for (const entry of entries)
|
|
191
|
+
if (entry.name === fullName) {
|
|
192
|
+
entry.status = 'available';
|
|
193
|
+
entry.via = 'worker';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
servers.push({ name, status: 'available_names_only' });
|
|
197
|
+
} else servers.push({ name, status: 'discovery_unavailable' });
|
|
198
|
+
} finally {
|
|
199
|
+
clearTimeout(timeout);
|
|
200
|
+
await client.close().catch(() => {});
|
|
201
|
+
await transport?.close().catch(() => {});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
process.stdout.write(
|
|
205
|
+
JSON.stringify({ entries, servers, observedAt: new Date().toISOString() })
|
|
206
|
+
);
|
package/mcp/modules.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { TelegramModule } from './tools/telegram/module';
|
|
2
|
+
import { DiscordModule } from './tools/discord/module';
|
|
3
|
+
import { LineModule } from './tools/line/module';
|
|
4
|
+
import { SlackModule } from './tools/slack/module';
|
|
5
|
+
import { WhatsAppModule } from './tools/whatsapp/module';
|
|
6
|
+
import { WhatsAppCloudModule } from './tools/whatsapp-cloud/module';
|
|
7
|
+
import { WeChatModule } from './tools/wechat/module';
|
|
8
|
+
import { CronModule } from './tools/cron/module';
|
|
9
|
+
import { SkillsModule } from './tools/skills/module';
|
|
10
|
+
import { AgentModule } from './tools/agent/module';
|
|
11
|
+
import { BrowserModule } from './tools/browser/module';
|
|
12
|
+
import { ImageModule } from './tools/image/module';
|
|
13
|
+
import { VideoModule } from './tools/video/module';
|
|
14
|
+
import { ShareFileModule } from './tools/share-file/module';
|
|
15
|
+
import { AppsModule } from './tools/apps/module';
|
|
16
|
+
import { ApiModule } from './tools/api/module';
|
|
17
|
+
import { MemoryModule } from './tools/memory/module';
|
|
18
|
+
import type { ChannelModule, ToolModule } from './types';
|
|
19
|
+
|
|
20
|
+
/** Shared registration for execution and read-only capability discovery. */
|
|
21
|
+
export function gatewayModules(
|
|
22
|
+
role?: string,
|
|
23
|
+
media = false
|
|
24
|
+
): Array<ChannelModule | ToolModule> {
|
|
25
|
+
return role
|
|
26
|
+
? [
|
|
27
|
+
new MemoryModule(),
|
|
28
|
+
...(role === 'worker' && media
|
|
29
|
+
? [
|
|
30
|
+
new ImageModule(),
|
|
31
|
+
new VideoModule(),
|
|
32
|
+
new ShareFileModule(),
|
|
33
|
+
new BrowserModule(),
|
|
34
|
+
]
|
|
35
|
+
: []),
|
|
36
|
+
]
|
|
37
|
+
: [
|
|
38
|
+
new TelegramModule(),
|
|
39
|
+
new DiscordModule(),
|
|
40
|
+
new LineModule(),
|
|
41
|
+
new SlackModule(),
|
|
42
|
+
new WhatsAppModule(),
|
|
43
|
+
new WhatsAppCloudModule(),
|
|
44
|
+
new WeChatModule(),
|
|
45
|
+
new CronModule(),
|
|
46
|
+
new SkillsModule(),
|
|
47
|
+
new AgentModule(),
|
|
48
|
+
new BrowserModule(),
|
|
49
|
+
new ImageModule(),
|
|
50
|
+
new VideoModule(),
|
|
51
|
+
new ShareFileModule(),
|
|
52
|
+
new AppsModule(),
|
|
53
|
+
new ApiModule(),
|
|
54
|
+
new MemoryModule(),
|
|
55
|
+
];
|
|
56
|
+
}
|
package/mcp/server.ts
CHANGED
|
@@ -12,27 +12,14 @@ import {
|
|
|
12
12
|
ListToolsRequestSchema,
|
|
13
13
|
CallToolRequestSchema,
|
|
14
14
|
} from '@modelcontextprotocol/sdk/types.js';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { LineModule } from './tools/line/module';
|
|
18
|
-
import { SlackModule } from './tools/slack/module';
|
|
19
|
-
import { WhatsAppModule } from './tools/whatsapp/module';
|
|
20
|
-
import { WhatsAppCloudModule } from './tools/whatsapp-cloud/module';
|
|
21
|
-
import { WeChatModule } from './tools/wechat/module';
|
|
22
|
-
import { CronModule } from './tools/cron/module';
|
|
23
|
-
import { SkillsModule } from './tools/skills/module';
|
|
24
|
-
import { AgentModule } from './tools/agent/module';
|
|
25
|
-
import { BrowserModule } from './tools/browser/module';
|
|
26
|
-
import { ImageModule } from './tools/image/module';
|
|
27
|
-
import { VideoModule } from './tools/video/module';
|
|
28
|
-
import { ShareFileModule } from './tools/share-file/module';
|
|
29
|
-
import { AppsModule } from './tools/apps/module';
|
|
30
|
-
import { ApiModule } from './tools/api/module';
|
|
31
|
-
import { MemoryModule } from './tools/memory/module';
|
|
15
|
+
import { gatewayModules } from './modules';
|
|
16
|
+
import { AGENT_TASK_TOOLS, WORKER_REPORT_TOOLS, callTaskBridge } from './tools/tasks/module';
|
|
32
17
|
import { buildChannelInstructions } from './instructions';
|
|
33
18
|
import type { ChannelModule, ToolModule, McpToolDefinition } from './types';
|
|
34
19
|
|
|
35
20
|
const ORIGIN_CHANNEL = process.env.GATEWAY_ORIGIN_CHANNEL ?? '';
|
|
21
|
+
const ORCHESTRATION_ROLE = process.env.GATEWAY_ORCHESTRATION_ROLE;
|
|
22
|
+
if (ORCHESTRATION_ROLE && !['agent', 'worker'].includes(ORCHESTRATION_ROLE)) throw new Error('Invalid orchestration MCP role');
|
|
36
23
|
|
|
37
24
|
type AnyModule = ChannelModule | ToolModule;
|
|
38
25
|
|
|
@@ -40,25 +27,7 @@ function isChannelModule(mod: AnyModule): mod is ChannelModule {
|
|
|
40
27
|
return 'start' in mod && typeof (mod as ChannelModule).start === 'function';
|
|
41
28
|
}
|
|
42
29
|
|
|
43
|
-
const modules
|
|
44
|
-
new TelegramModule(),
|
|
45
|
-
new DiscordModule(),
|
|
46
|
-
new LineModule(),
|
|
47
|
-
new SlackModule(),
|
|
48
|
-
new WhatsAppModule(),
|
|
49
|
-
new WhatsAppCloudModule(),
|
|
50
|
-
new WeChatModule(),
|
|
51
|
-
new CronModule(),
|
|
52
|
-
new SkillsModule(),
|
|
53
|
-
new AgentModule(),
|
|
54
|
-
new BrowserModule(),
|
|
55
|
-
new ImageModule(),
|
|
56
|
-
new VideoModule(),
|
|
57
|
-
new ShareFileModule(),
|
|
58
|
-
new AppsModule(),
|
|
59
|
-
new ApiModule(),
|
|
60
|
-
new MemoryModule(),
|
|
61
|
-
];
|
|
30
|
+
const modules = gatewayModules(ORCHESTRATION_ROLE, process.env.GATEWAY_ORCHESTRATION_MEDIA === 'true');
|
|
62
31
|
|
|
63
32
|
// Build tool-to-module mapping for enabled modules
|
|
64
33
|
const toolMap = new Map<string, AnyModule>();
|
|
@@ -76,11 +45,16 @@ for (const mod of modules) {
|
|
|
76
45
|
if (!visible) continue;
|
|
77
46
|
|
|
78
47
|
for (const tool of mod.getTools()) {
|
|
48
|
+
if (ORCHESTRATION_ROLE && !['memory_search', 'memory_get'].includes(tool.name) && !(ORCHESTRATION_ROLE === 'worker' &&
|
|
49
|
+
((mod.id === 'image' || mod.id === 'video' || mod.id === 'share-file' || mod.id === 'browser') || (mod.id === 'memory' && process.env.GATEWAY_ORCHESTRATION_WRITE_MEMORY === 'true')))) continue;
|
|
79
50
|
toolMap.set(tool.name, mod);
|
|
80
51
|
visibleTools.push(tool);
|
|
81
52
|
}
|
|
82
53
|
}
|
|
83
54
|
|
|
55
|
+
const taskTools = ORCHESTRATION_ROLE === 'agent' ? AGENT_TASK_TOOLS.filter(tool => (tool.name !== 'conversation_intake' || process.env.GATEWAY_SEMANTIC_INTAKE === 'true') && (tool.name !== 'capabilities_list' || process.env.GATEWAY_CAPABILITY_CATALOG === 'true')) : ORCHESTRATION_ROLE === 'worker' ? WORKER_REPORT_TOOLS.filter(tool => tool.name !== 'task_memory_append' || process.env.GATEWAY_ORCHESTRATION_WRITE_MEMORY === 'true') : [];
|
|
56
|
+
if (ORCHESTRATION_ROLE && process.env.GATEWAY_ORCHESTRATION_TICKET_FILE) visibleTools.push(...taskTools);
|
|
57
|
+
|
|
84
58
|
// Initialize channel modules so their bot API clients are ready for tool calls.
|
|
85
59
|
// initBot() returns immediately after creating the client — no blocking.
|
|
86
60
|
for (const mod of modules) {
|
|
@@ -105,7 +79,7 @@ const mcp = new Server(
|
|
|
105
79
|
'claude/channel/permission': {},
|
|
106
80
|
},
|
|
107
81
|
},
|
|
108
|
-
instructions: buildChannelInstructions(imageEnabled, videoEnabled),
|
|
82
|
+
instructions: ORCHESTRATION_ROLE ? 'Use scoped capability discovery, task tools and memory retrieval. The agent writes user-facing responses; workers return task results and orchestration handles delivery.' : buildChannelInstructions(imageEnabled, videoEnabled),
|
|
109
83
|
},
|
|
110
84
|
);
|
|
111
85
|
|
|
@@ -116,6 +90,9 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
116
90
|
mcp.setRequestHandler(CallToolRequestSchema, async (req, extra) => {
|
|
117
91
|
const toolName = req.params.name;
|
|
118
92
|
const args = (req.params.arguments ?? {}) as Record<string, unknown>;
|
|
93
|
+
if (ORCHESTRATION_ROLE && process.env.GATEWAY_ORCHESTRATION_TICKET_FILE && taskTools.some(tool => tool.name === toolName)) {
|
|
94
|
+
return callTaskBridge(toolName, args, String(extra.requestId), AbortSignal.any([extra.signal, shutdownController.signal]));
|
|
95
|
+
}
|
|
119
96
|
|
|
120
97
|
const mod = toolMap.get(toolName);
|
|
121
98
|
if (!mod) {
|
|
@@ -124,6 +101,10 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req, extra) => {
|
|
|
124
101
|
isError: true,
|
|
125
102
|
};
|
|
126
103
|
}
|
|
104
|
+
if (ORCHESTRATION_ROLE === 'worker' && process.env.GATEWAY_ORCHESTRATION_MEDIA === 'true') {
|
|
105
|
+
const validation = await callTaskBridge('task_validate', {}, String(extra.requestId), AbortSignal.any([extra.signal, shutdownController.signal]));
|
|
106
|
+
if (validation.isError) return validation;
|
|
107
|
+
}
|
|
127
108
|
|
|
128
109
|
// extra.signal fires on notifications/cancelled for THIS call (the SDK matches
|
|
129
110
|
// it by requestId) — the CLI sends that when a user Stop/Ctrl-C interrupts an
|
|
@@ -159,7 +159,7 @@ async function callGetpodBrowser(
|
|
|
159
159
|
const browserToolDefs: McpToolDefinition[] = [
|
|
160
160
|
{
|
|
161
161
|
name: 'browser_create_session',
|
|
162
|
-
description: 'Create or resume a browser
|
|
162
|
+
description: 'Create or resume GetPod Cloud Browser, NOT the user Chrome or Remote Browser connector. Use only when Cloud Browser is selected, or no Remote Browser is connected for a generic browser request. Returns session status.',
|
|
163
163
|
inputSchema: {
|
|
164
164
|
type: 'object',
|
|
165
165
|
properties: {
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: open-browser
|
|
3
|
-
description: "
|
|
3
|
+
description: "Open a website in GetPod Cloud Browser after that environment is selected. Does not control the user Chrome or Remote Browser connector."
|
|
4
4
|
user-invocable: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# open-browser
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use this skill only for GetPod Cloud Browser. Remote Browser is a separate connector controlling the user's approved device tabs.
|
|
10
|
+
|
|
11
|
+
If a Remote Browser connector is enabled and the user has not selected an environment, ask whether to use Remote Browser (recommended) or GetPod Cloud Browser before taking browser actions. An explicit remote/device request must use that connector instead of this skill. Reuse the selection for related follow-ups. With no Remote Browser connector, ordinary browser requests may use Cloud Browser. Never fall back from Remote Browser to Cloud Browser without user approval.
|
|
10
12
|
|
|
11
13
|
## Rules
|
|
12
14
|
|
|
13
|
-
-
|
|
15
|
+
- For the selected Cloud Browser workflow, use ONLY `mcp__gateway__browser_*` tools — never Python, never CDP direct, never filesystem
|
|
14
16
|
- NEVER use `wait: "networkidle"` — it hangs on SPAs. Omit `wait` entirely (fire-and-forget)
|
|
15
17
|
- Always check tab state before navigating — tab IDs change between sessions
|
|
16
18
|
- Do NOT pass `session_id` — it is injected automatically from agent context
|
|
@@ -24,15 +24,31 @@ export const SLASH_COMMANDS: SlashCommandDef[] = [
|
|
|
24
24
|
},
|
|
25
25
|
];
|
|
26
26
|
|
|
27
|
+
export function commandDefinitions(orchestration:boolean,interactive:boolean):SlashCommandDef[]{
|
|
28
|
+
return [...SLASH_COMMANDS,
|
|
29
|
+
...(orchestration ? [
|
|
30
|
+
{name:'voice',description:'Turn automatic voice replies on or off',options:[{name:'mode',description:'on or off (omit to show buttons)',required:false,type:'STRING' as const}]},
|
|
31
|
+
{name:'voices',description:'Choose the agent voice'},
|
|
32
|
+
{name:'tasks',description:'View pending tasks in this conversation'},
|
|
33
|
+
{name:'help',description:'Show available orchestration controls'},
|
|
34
|
+
] : []),
|
|
35
|
+
{name:'stop',description:orchestration?'Stop a response or choose a task to stop':'Stop the agent response'},
|
|
36
|
+
...(interactive && !orchestration ? [{name:'cli',description:'Open the live terminal viewer'}] : []),
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
export async function registerCommands(
|
|
28
41
|
client: any,
|
|
29
42
|
token: string,
|
|
43
|
+
orchestration = false,
|
|
44
|
+
interactive = false,
|
|
30
45
|
): Promise<void> {
|
|
31
46
|
// @ts-ignore — discord.js in mcp/node_modules
|
|
32
47
|
const { REST, Routes, SlashCommandBuilder } = await import('discord.js');
|
|
33
48
|
const rest = new REST().setToken(token);
|
|
34
49
|
|
|
35
|
-
const
|
|
50
|
+
const commands=commandDefinitions(orchestration,interactive);
|
|
51
|
+
const bodies = commands.map(cmd => {
|
|
36
52
|
const builder = new SlashCommandBuilder()
|
|
37
53
|
.setName(cmd.name)
|
|
38
54
|
.setDescription(cmd.description);
|
|
@@ -45,9 +45,20 @@ export function createMessageHandler(
|
|
|
45
45
|
messageId: message.id,
|
|
46
46
|
threadId: isThread ? message.channelId : undefined,
|
|
47
47
|
attachmentFileId: message.attachments.first()?.url,
|
|
48
|
+
attachmentKind: (message.attachments.first()?.contentType?.startsWith('audio/') || (typeof message.flags==='number' ? !!(message.flags&8192) : message.flags?.has(8192))) ? 'voice' : 'file',
|
|
48
49
|
ts: message.createdTimestamp,
|
|
49
50
|
};
|
|
50
51
|
|
|
52
|
+
const attachments = (msg: DiscordMessage, quoted=false) => (msg.attachments.values ? [...msg.attachments.values()] : [msg.attachments.first()].filter(Boolean)).slice(0,10).map(a=>({url:a!.url,name:a!.name,kind:a!.contentType?.startsWith('image/')?'image':a!.contentType?.startsWith('audio/')?'audio':'file',quoted}));
|
|
53
|
+
inbound.attachments = attachments(message);
|
|
54
|
+
if (message.reference?.messageId && (!message.reference.channelId || message.reference.channelId === message.channelId)) {
|
|
55
|
+
inbound.replyToMessageId = message.reference.messageId;
|
|
56
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
57
|
+
try {
|
|
58
|
+
const replied = await Promise.race([message.fetchReference?.(), new Promise<undefined>(resolve=>{timer=setTimeout(()=>resolve(undefined),3000);})]);
|
|
59
|
+
if (replied && replied.channelId === message.channelId) { inbound.repliedText=replied.content; inbound.repliedSender=replied.author.username; inbound.attachments.push(...attachments(replied,true)); }
|
|
60
|
+
} catch { /* ID still resolves from scoped local history when available. */ } finally { if(timer)clearTimeout(timer); }
|
|
61
|
+
}
|
|
51
62
|
await handler(inbound);
|
|
52
63
|
};
|
|
53
64
|
}
|
|
@@ -190,6 +190,10 @@ export class DiscordModule implements ChannelModule {
|
|
|
190
190
|
const { createDiscordClient } = await import('./client');
|
|
191
191
|
this.client = await createDiscordClient(token);
|
|
192
192
|
this.running = true;
|
|
193
|
+
if(process.env.CLAUDE_CHANNEL_CALLBACK){
|
|
194
|
+
const {registerCommands}=await import('./commands');
|
|
195
|
+
await registerCommands(this.client,token,process.env.GATEWAY_ORCHESTRATION_ENABLED==='true',process.env.GATEWAY_INTERACTIVE_CLI_ENABLED==='true').catch(err=>process.stderr.write(`discord: command registration failed: ${err}\n`));
|
|
196
|
+
}
|
|
193
197
|
}
|
|
194
198
|
|
|
195
199
|
async start(handler: InboundMessageHandler, signal: AbortSignal): Promise<void> {
|
|
@@ -296,7 +300,12 @@ export class DiscordModule implements ChannelModule {
|
|
|
296
300
|
// button) instead of forwarding the text to the agent. Only reached after
|
|
297
301
|
// gate() authorized this user, so it inherits the channel's access control.
|
|
298
302
|
const cliText = (msg.content ?? '').replace(/<@!?\d+>/g, '').trim().toLowerCase();
|
|
303
|
+
if(/^\/(voice|voices|tasks|stop|help|orch)(?:\s|$)/.test(cliText)){
|
|
304
|
+
await handler({channel:'discord',accountId:this.client.user?.id??'discord',senderId:context.userId,chatId:context.channelId,chatType:isDM?'direct':'group',text:(msg.content??'').replace(/<@!?\d+>/g,'').trim(),messageId:msg.id,ts:Date.now()});
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
299
307
|
if (cliText === '/cli') {
|
|
308
|
+
if(process.env.GATEWAY_INTERACTIVE_CLI_ENABLED!=='true'){await msg.channel.send('The terminal viewer requires interactive mode.');return;}
|
|
300
309
|
const base = cliCallbackBase();
|
|
301
310
|
try {
|
|
302
311
|
const res = await fetch(base + '/command', {
|
|
@@ -336,7 +345,7 @@ export class DiscordModule implements ChannelModule {
|
|
|
336
345
|
const typingFileDir = path.join(this.stateDir, 'typing');
|
|
337
346
|
try {
|
|
338
347
|
fs.mkdirSync(typingFileDir, { recursive: true });
|
|
339
|
-
fs.writeFileSync(path.join(typingFileDir, channelId), '');
|
|
348
|
+
if (process.env.GATEWAY_ORCHESTRATION_ENABLED !== 'true') fs.writeFileSync(path.join(typingFileDir, channelId), '');
|
|
340
349
|
await fetch(`https://discord.com/api/v10/channels/${channelId}/typing`, {
|
|
341
350
|
method: 'POST',
|
|
342
351
|
headers: { Authorization: `Bot ${this.getToken()!}`, 'Content-Length': '0' },
|
|
@@ -388,7 +397,14 @@ export class DiscordModule implements ChannelModule {
|
|
|
388
397
|
// Security mirrors the message path: the access gate must return 'deliver'.
|
|
389
398
|
// discord.js client is typed as `any` (dynamic import) so we narrow locally.
|
|
390
399
|
interface ButtonInteraction {
|
|
400
|
+
id?: string;
|
|
391
401
|
isButton?: () => boolean;
|
|
402
|
+
isChatInputCommand?: () => boolean;
|
|
403
|
+
commandName?: string;
|
|
404
|
+
options?: {getString(name:string):string|null};
|
|
405
|
+
deferUpdate?: () => Promise<unknown>;
|
|
406
|
+
deferReply?: (options: {ephemeral:boolean}) => Promise<unknown>;
|
|
407
|
+
deleteReply?: () => Promise<unknown>;
|
|
392
408
|
customId?: string;
|
|
393
409
|
guildId?: string | null;
|
|
394
410
|
channelId: string;
|
|
@@ -401,6 +417,28 @@ export class DiscordModule implements ChannelModule {
|
|
|
401
417
|
}
|
|
402
418
|
this.client.on('interactionCreate', async (interaction: ButtonInteraction) => {
|
|
403
419
|
try {
|
|
420
|
+
const orchButton=interaction.isButton?.()&&/^orch:(?:[a-f0-9-]{36}|q:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}:(?:snooze|mute))$/.test(interaction.customId??'');
|
|
421
|
+
const slash=interaction.isChatInputCommand?.();
|
|
422
|
+
if(orchButton||slash){
|
|
423
|
+
const isDM=!interaction.guildId,isThread=interaction.channel?.isThread?.()??false;
|
|
424
|
+
const context:DiscordMessageContext={guildId:interaction.guildId??null,channelId:interaction.channelId,threadId:isThread?interaction.channelId:null,userId:interaction.user.id,username:interaction.user.username,messageId:interaction.message?.id??'',isDM,isThread,mentionsBot:true};
|
|
425
|
+
const access=gate(loadAccessFn(),context,saveAccessFn,()=>randomBytes(3).toString('hex'));
|
|
426
|
+
if(access.action!=='deliver'){await interaction.reply({content:'Not authorized.',ephemeral:true});return;}
|
|
427
|
+
if(orchButton)await interaction.deferUpdate?.();else await interaction.deferReply?.({ephemeral:true});
|
|
428
|
+
let text=orchButton?`/orch ${interaction.customId!.slice(5)}`:`/${interaction.commandName}`;
|
|
429
|
+
if(slash){
|
|
430
|
+
const name=interaction.commandName;
|
|
431
|
+
const arg=interaction.options?.getString(name==='voice'?'mode':name==='ask'?'question':'name');
|
|
432
|
+
if(name==='ask')text=arg??'';else if(arg)text+=' '+arg;
|
|
433
|
+
if(name==='cli'){
|
|
434
|
+
const channel=await this.client.channels.fetch(interaction.channelId);
|
|
435
|
+
await handleDiscordMessage({id:randomBytes(12).toString('hex'),content:'/cli',author:{id:interaction.user.id,username:interaction.user.username,bot:false},guild:interaction.guildId?{id:interaction.guildId}:null,guildId:interaction.guildId,channelId:interaction.channelId,channel,mentions:{has:()=>true}} as any);
|
|
436
|
+
await interaction.deleteReply?.();return;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
await handler({channel:'discord',accountId:interaction.client.user?.id??'discord',senderId:interaction.user.id,chatId:interaction.channelId,chatType:isDM?'direct':'group',text,messageId:interaction.id??randomBytes(12).toString('hex'),controlMessageId:orchButton?interaction.message?.id:undefined,ts:Date.now()});
|
|
440
|
+
if(slash)await interaction.deleteReply?.();return;
|
|
441
|
+
}
|
|
404
442
|
if (!interaction.isButton?.()) return;
|
|
405
443
|
|
|
406
444
|
// `/cli` approve/deny — unlock (or reject) a pending terminal-viewer
|
|
@@ -518,7 +556,7 @@ export class DiscordModule implements ChannelModule {
|
|
|
518
556
|
const typingFileDir = path.join(this.stateDir, 'typing');
|
|
519
557
|
try {
|
|
520
558
|
fs.mkdirSync(typingFileDir, { recursive: true });
|
|
521
|
-
fs.writeFileSync(path.join(typingFileDir, channelId), '');
|
|
559
|
+
if (process.env.GATEWAY_ORCHESTRATION_ENABLED !== 'true') fs.writeFileSync(path.join(typingFileDir, channelId), '');
|
|
522
560
|
} catch {}
|
|
523
561
|
|
|
524
562
|
const inbound: InboundMessage = {
|
|
@@ -621,6 +659,8 @@ export class DiscordModule implements ChannelModule {
|
|
|
621
659
|
}
|
|
622
660
|
|
|
623
661
|
private async processTypingSignals(typingDir: string, token: string): Promise<void> {
|
|
662
|
+
// Managed activity is derived from durable Agent/Worker state; stale legacy files are not work.
|
|
663
|
+
if (process.env.GATEWAY_ORCHESTRATION_ENABLED === 'true') return;
|
|
624
664
|
let files: string[];
|
|
625
665
|
try { files = fs.readdirSync(typingDir); } catch { return; }
|
|
626
666
|
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
import { DiscordModule } from './module';
|
|
9
9
|
import type { InboundMessage } from '../../types';
|
|
10
|
+
import { ReceiverSpool } from '../receiver-spool';
|
|
10
11
|
|
|
11
12
|
const CALLBACK_URL = process.env.CLAUDE_CHANNEL_CALLBACK;
|
|
13
|
+
const spool = process.env.GATEWAY_ORCHESTRATION_INGRESS_DIR && CALLBACK_URL ? new ReceiverSpool(process.env.GATEWAY_ORCHESTRATION_INGRESS_DIR, CALLBACK_URL) : undefined;
|
|
12
14
|
if (!CALLBACK_URL) {
|
|
13
15
|
process.stderr.write('discord receiver: CLAUDE_CHANNEL_CALLBACK required\n');
|
|
14
16
|
process.exit(1);
|
|
@@ -30,6 +32,14 @@ async function postCallback(inbound: InboundMessage): Promise<void> {
|
|
|
30
32
|
if (inbound.attachmentFileId) {
|
|
31
33
|
meta['attachment_file_id'] = inbound.attachmentFileId;
|
|
32
34
|
}
|
|
35
|
+
if(inbound.attachments?.length)meta.attachments_json=JSON.stringify(inbound.attachments.map(a=>({ref:a.url,name:a.name,kind:a.kind,quoted:a.quoted})));
|
|
36
|
+
if(inbound.replyToMessageId)meta.replied_message_id=inbound.replyToMessageId;
|
|
37
|
+
if(inbound.repliedText)meta.replied_text=inbound.repliedText;
|
|
38
|
+
if(inbound.repliedSender)meta.replied_user=inbound.repliedSender;
|
|
39
|
+
if(inbound.threadId)meta.thread_ts=inbound.threadId;
|
|
40
|
+
if(inbound.attachmentKind)meta.attachment_kind=inbound.attachmentKind;
|
|
41
|
+
if(inbound.controlMessageId)meta.control_message_id=inbound.controlMessageId;
|
|
42
|
+
if (spool && !/^\/(voice|voices|tasks|stop|orch)(?:\s|$)/.test(inbound.text??'')) { spool.enqueue({ content: inbound.text ?? '', meta }); return; }
|
|
33
43
|
|
|
34
44
|
try {
|
|
35
45
|
await fetch(CALLBACK_URL!, {
|
|
@@ -108,7 +108,10 @@ export interface DiscordMessage {
|
|
|
108
108
|
parentId?: string | null;
|
|
109
109
|
};
|
|
110
110
|
createdTimestamp: number;
|
|
111
|
-
|
|
111
|
+
reference?: {messageId?:string;channelId?:string};
|
|
112
|
+
fetchReference?(): Promise<DiscordMessage>;
|
|
113
|
+
flags?: number | {has(bit:number):boolean};
|
|
114
|
+
attachments: { first(): { url: string; contentType?: string | null; name?: string } | undefined; values?(): IterableIterator<{url:string;contentType?:string|null;name?:string}> };
|
|
112
115
|
client: { user: { id: string } | null };
|
|
113
116
|
startThread(options: { name: string; autoArchiveDuration: number }): Promise<{ id: string }>;
|
|
114
117
|
}
|
|
@@ -735,7 +735,9 @@ export class ImageModule implements ToolModule {
|
|
|
735
735
|
files,
|
|
736
736
|
...(artifacts ? { artifacts } : {}),
|
|
737
737
|
...(droppedImages > 0 ? { dropped_images: droppedImages } : {}),
|
|
738
|
-
note:
|
|
738
|
+
note: (process.env.GATEWAY_ORCHESTRATION_ROLE === 'worker'
|
|
739
|
+
? 'Image saved. Call task_stage_file for each output path, then finish this task. The agent orchestration engine owns user-facing delivery.'
|
|
740
|
+
: 'Image saved. Deliver it to the user with your channel delivery tool — api_reply/reply (files: [...]), or line_image on LINE. Do NOT open/Read the file to inspect it first; attach it and answer briefly.')
|
|
739
741
|
+ (model ? ` Mention which model made it (${model}).` : '')
|
|
740
742
|
+ (artifacts ? ' To edit this image later, reference it via its artifact_ref (e.g. image: "artifact:...").' : '')
|
|
741
743
|
+ (droppedImages > 0 ? ` (${droppedImages} extra image(s) beyond the cap were not saved)` : ''),
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { test, expect } from 'bun:test';
|
|
2
|
+
import { mkdtempSync, readdirSync, rmSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { ReceiverSpool } from './receiver-spool';
|
|
6
|
+
|
|
7
|
+
test('receiver restart retains unacknowledged input and removes it only after gateway acceptance', async () => {
|
|
8
|
+
const root = mkdtempSync(join(tmpdir(), 'receiver-spool-'));
|
|
9
|
+
let fail = true;
|
|
10
|
+
const delivered: unknown[] = [];
|
|
11
|
+
const request = (async (_url: string | URL | Request, options?: RequestInit) => {
|
|
12
|
+
delivered.push(JSON.parse(String(options?.body)));
|
|
13
|
+
return new Response('', { status: fail ? 503 : 200 });
|
|
14
|
+
}) as typeof fetch;
|
|
15
|
+
let spool = new ReceiverSpool(root, 'http://fixture.invalid/channel', request);
|
|
16
|
+
try {
|
|
17
|
+
const input = { content: 'hello', meta: { chat_id: 'original', message_id: '1' } };
|
|
18
|
+
spool.enqueue(input);
|
|
19
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
20
|
+
const file = readdirSync(root).find(file => file.endsWith('.json'))!;
|
|
21
|
+
expect(JSON.parse(readFileSync(join(root, file), 'utf8'))).toEqual(input);
|
|
22
|
+
spool.close(); fail = false;
|
|
23
|
+
spool = new ReceiverSpool(root, 'http://fixture.invalid/channel', request);
|
|
24
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
25
|
+
expect(readdirSync(root)).toEqual([]);
|
|
26
|
+
expect(delivered.at(-1)).toEqual(input);
|
|
27
|
+
} finally { spool.close(); rmSync(root, { recursive: true, force: true }); }
|
|
28
|
+
});
|