@0xmaxma/claude-gateway 1.8.14 → 2.0.0
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 +377 -0
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +680 -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 +135 -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 +256 -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 +148 -0
- package/dist/orchestration/decisions.js.map +1 -0
- package/dist/orchestration/delivery.d.ts +30 -0
- package/dist/orchestration/delivery.d.ts.map +1 -0
- package/dist/orchestration/delivery.js +219 -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 +232 -0
- package/dist/orchestration/runtime.d.ts.map +1 -0
- package/dist/orchestration/runtime.js +962 -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 +86 -0
- package/dist/orchestration/store.d.ts.map +1 -0
- package/dist/orchestration/store.js +275 -0
- package/dist/orchestration/store.js.map +1 -0
- package/dist/orchestration/task-controls.d.ts +130 -0
- package/dist/orchestration/task-controls.d.ts.map +1 -0
- package/dist/orchestration/task-controls.js +55 -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-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 +109 -0
- package/dist/orchestration/tasks/service.d.ts.map +1 -0
- package/dist/orchestration/tasks/service.js +697 -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 +232 -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
|
@@ -40,6 +40,7 @@ exports.markMediaUnavailable = markMediaUnavailable;
|
|
|
40
40
|
exports.parseCliPostback = parseCliPostback;
|
|
41
41
|
exports.normalizeLinePostback = normalizeLinePostback;
|
|
42
42
|
exports.createLineWebhookHandler = createLineWebhookHandler;
|
|
43
|
+
const line_request_order_1 = require("../shared/line-request-order");
|
|
43
44
|
const fs = __importStar(require("fs"));
|
|
44
45
|
const os = __importStar(require("os"));
|
|
45
46
|
const path = __importStar(require("path"));
|
|
@@ -336,7 +337,7 @@ function pairingMessage(code, kind) {
|
|
|
336
337
|
/**
|
|
337
338
|
* Normalize a LINE webhook event into the gateway's {content, meta} intake shape.
|
|
338
339
|
* Returns null for anything we don't handle (message types other than text/image/
|
|
339
|
-
* file, or a source we can't key a conversation on).
|
|
340
|
+
* file/audio, or a source we can't key a conversation on).
|
|
340
341
|
*
|
|
341
342
|
* `resolved` lets the caller pass the source it already resolved for the access
|
|
342
343
|
* gate, so a single event isn't re-parsed; omitted, it resolves here.
|
|
@@ -345,11 +346,11 @@ function normalizeLineEvent(event, resolved) {
|
|
|
345
346
|
if (event.type !== 'message')
|
|
346
347
|
return null;
|
|
347
348
|
const msg = event.message;
|
|
348
|
-
// Text, image, and
|
|
349
|
+
// Text, image, file and audio are normalized; audio routing is orchestration-only. Image/file bytes are fetched separately in
|
|
349
350
|
// handlePost (via the LINE blob API) and surfaced to the agent through
|
|
350
351
|
// meta.image_path — the generic "local path the agent should Read" channel,
|
|
351
352
|
// which the runner stages into MediaStore regardless of media kind.
|
|
352
|
-
if (!msg || (msg.type !== 'text' && msg.type !== 'image' && msg.type !== 'file'))
|
|
353
|
+
if (!msg || (msg.type !== 'text' && msg.type !== 'image' && msg.type !== 'file' && msg.type !== 'audio'))
|
|
353
354
|
return null;
|
|
354
355
|
// Accept 1:1 user, group, and room sources. chat_id is the conversation key
|
|
355
356
|
// (userId / groupId / roomId — the reply/push target); user_id is the human
|
|
@@ -368,9 +369,17 @@ function normalizeLineEvent(event, resolved) {
|
|
|
368
369
|
ts: new Date(event.timestamp ?? Date.now()).toISOString(),
|
|
369
370
|
line_chat_type: kind, // 'user' | 'group' | 'room'
|
|
370
371
|
};
|
|
372
|
+
const quoted = msg.quotedMessageId;
|
|
373
|
+
if (typeof quoted === 'string')
|
|
374
|
+
meta.replied_message_id = quoted;
|
|
371
375
|
if (msg.type === 'image')
|
|
372
376
|
meta.media_type = 'image';
|
|
373
377
|
let content = text;
|
|
378
|
+
if (msg.type === 'audio') {
|
|
379
|
+
meta.media_type = 'audio';
|
|
380
|
+
meta.attachment_kind = 'voice';
|
|
381
|
+
content = '(voice message)';
|
|
382
|
+
}
|
|
374
383
|
if (msg.type === 'file') {
|
|
375
384
|
const file = msg;
|
|
376
385
|
meta.media_type = 'file';
|
|
@@ -410,7 +419,7 @@ function normalizeLineEvent(event, resolved) {
|
|
|
410
419
|
function markMediaUnavailable(norm, mediaType, reason) {
|
|
411
420
|
delete norm.meta.image_path;
|
|
412
421
|
const name = norm.meta.attachment_name;
|
|
413
|
-
const label = mediaType === 'image' ? 'image' : name ? `file: ${name}` : 'file';
|
|
422
|
+
const label = mediaType === 'image' ? 'image' : mediaType === 'audio' ? 'audio' : name ? `file: ${name}` : 'file';
|
|
414
423
|
norm.content = `(${label} — not available: ${reason})`;
|
|
415
424
|
}
|
|
416
425
|
/** Parse a `/cli` approve/deny postback payload, or null when it's not ours. */
|
|
@@ -509,257 +518,282 @@ function createLineWebhookHandler(agents, logDir, opts = {}) {
|
|
|
509
518
|
req.headers.host ||
|
|
510
519
|
'';
|
|
511
520
|
persistPublicBase(runner.getAgentConfig().workspace, host, logger);
|
|
512
|
-
//
|
|
513
|
-
|
|
514
|
-
|
|
521
|
+
// Orchestrated conversations retain durable admission while draining after opt-out.
|
|
522
|
+
const orchestrationConfig = runner.getAgentConfig().orchestration;
|
|
523
|
+
const durableIngress = runner.requiresDurableChannelIngress?.('line') ?? (orchestrationConfig?.enabled && (orchestrationConfig.channels ?? ['api']).includes('line'));
|
|
524
|
+
if (!durableIngress)
|
|
525
|
+
res.status(200).json({ ok: true });
|
|
515
526
|
try {
|
|
516
|
-
events =
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
527
|
+
let events = [];
|
|
528
|
+
try {
|
|
529
|
+
events = JSON.parse(buf.toString('utf8')).events ?? [];
|
|
530
|
+
}
|
|
531
|
+
catch (err) {
|
|
532
|
+
logger.warn('LINE webhook: bad JSON', { error: err.message });
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
const token = cfg?.channelAccessToken ?? '';
|
|
536
|
+
const client = token
|
|
537
|
+
? new bot_sdk_1.messagingApi.MessagingApiClient({
|
|
538
|
+
channelAccessToken: token,
|
|
539
|
+
...(opts.apiBase ? { baseURL: opts.apiBase } : {}),
|
|
540
|
+
})
|
|
541
|
+
: null;
|
|
542
|
+
// Blob/data API lives on a different host (api-data.line.me) than the
|
|
543
|
+
// messaging API, so it takes its own base override (used by tests).
|
|
544
|
+
const blobClient = token
|
|
545
|
+
? new bot_sdk_1.messagingApi.MessagingApiBlobClient({
|
|
546
|
+
channelAccessToken: token,
|
|
547
|
+
...(opts.dataApiBase ? { baseURL: opts.dataApiBase } : {}),
|
|
548
|
+
})
|
|
549
|
+
: null;
|
|
550
|
+
for (const event of events) {
|
|
551
|
+
// Postback BEFORE access gate: a tap on our slow-LLM button must reach the
|
|
552
|
+
// cache even if the user's allowlist status changed since the button was sent.
|
|
553
|
+
// The postback data is opaque (request_id we issued), so bypassing the gate here
|
|
554
|
+
// is safe — only users who received the button can tap it.
|
|
555
|
+
const pb = normalizeLinePostback(event);
|
|
556
|
+
if (pb) {
|
|
557
|
+
if (/^orch:[a-f0-9-]{36}$/.test(pb.data)) {
|
|
558
|
+
if (!(0, line_access_1.isResolvedSourceAllowed)(cfg, (0, line_access_1.resolveLineSource)(event.source)))
|
|
559
|
+
continue;
|
|
560
|
+
const forwarded = await fetch(`http://127.0.0.1:${runner.getCallbackPort()}/channel`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: `/orch ${pb.data.slice(5)}`, meta: { source: 'line', chat_id: pb.chatId, user_id: event.source?.userId ?? pb.chatId, reply_token: pb.replyToken } }) });
|
|
561
|
+
if (!forwarded.ok)
|
|
562
|
+
throw Error('Control unavailable');
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
// `/cli` approve/deny — unlock (or reject) a terminal-viewer pairing.
|
|
566
|
+
// The pairing binds the requesting user; approveCliPairing checks the
|
|
567
|
+
// tapping user (pb.chatId, a LINE-verified id) matches, so bypassing the
|
|
568
|
+
// access gate here is safe — same as the slow-LLM postback below.
|
|
569
|
+
const cli = parseCliPostback(pb.data);
|
|
570
|
+
if (cli) {
|
|
571
|
+
const result = runner.approveCliPairing('line', cli.pairingId, pb.chatId, cli.deny);
|
|
572
|
+
if (client && pb.replyToken) {
|
|
573
|
+
const text = cli.deny
|
|
574
|
+
? 'Denied.'
|
|
575
|
+
: result === 'ok'
|
|
576
|
+
? 'Approved — return to the browser.'
|
|
577
|
+
: 'Could not approve (the link may have expired). Send /cli again.';
|
|
578
|
+
await client
|
|
579
|
+
.replyMessage({ replyToken: pb.replyToken, messages: [{ type: 'text', text }] })
|
|
580
|
+
.catch(() => { });
|
|
581
|
+
}
|
|
582
|
+
continue;
|
|
583
|
+
}
|
|
584
|
+
try {
|
|
585
|
+
await runner.handleLinePostback(pb.chatId, pb.replyToken, pb.data);
|
|
586
|
+
}
|
|
587
|
+
catch (err) {
|
|
588
|
+
logger.error('LINE webhook: postback handling failed', {
|
|
589
|
+
error: err.message,
|
|
590
|
+
});
|
|
560
591
|
}
|
|
561
592
|
continue;
|
|
562
593
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
594
|
+
// Access gate (single choke point — mirrors hermes _dispatch_event):
|
|
595
|
+
// resolve the source once and gate before any message handling.
|
|
596
|
+
// Closed by default for both DMs (dmPolicy/dmAllowlist) and groups/rooms
|
|
597
|
+
// (groupPolicy/groupAllowlist). `'open'` restores answer-to-anyone.
|
|
598
|
+
const resolved = (0, line_access_1.resolveLineSource)(event.source);
|
|
599
|
+
if (!(0, line_access_1.isResolvedSourceAllowed)(cfg, resolved)) {
|
|
600
|
+
logger.debug('LINE webhook: source not allowed', {
|
|
601
|
+
agentId: runner.getAgentConfig().id,
|
|
602
|
+
kind: resolved.kind,
|
|
603
|
+
policy: (resolved.kind === 'user' ? cfg?.dmPolicy : cfg?.groupPolicy) ?? '(closed)',
|
|
604
|
+
conversationId: resolved.conversationId,
|
|
569
605
|
});
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const prev = (0, pending_senders_1.getPendingSender)('line', deniedAgentId, knockId);
|
|
598
|
-
const code = prev?.code ?? (isPairing ? (0, pending_senders_1.generatePairingCode)() : undefined);
|
|
599
|
-
let wasNew = false;
|
|
600
|
-
if (resolved.kind === 'user') {
|
|
601
|
-
wasNew = (0, pending_senders_1.recordDeniedSender)('line', deniedAgentId, knockId, undefined, Date.now(), code);
|
|
602
|
-
if (client) {
|
|
603
|
-
void client
|
|
604
|
-
.getProfile(knockId)
|
|
605
|
-
.then((p) => {
|
|
606
|
-
const e = (0, pending_senders_1.getPendingSender)('line', deniedAgentId, knockId);
|
|
607
|
-
if (e && p?.displayName && !e.displayName)
|
|
608
|
-
e.displayName = p.displayName;
|
|
609
|
-
})
|
|
610
|
-
.catch(() => { });
|
|
606
|
+
// Remember the knock so an admin can find + add it from the UI without
|
|
607
|
+
// grepping logs, and (pairing mode) reply a one-time code the admin can
|
|
608
|
+
// visually match before +Add. The id we track is the sender (DM) or the
|
|
609
|
+
// conversation (group/room). Names are backfilled best-effort without
|
|
610
|
+
// bumping the knock count.
|
|
611
|
+
const deniedAgentId = runner.getAgentConfig().id;
|
|
612
|
+
const knockId = resolved.kind === 'user' ? resolved.senderId : resolved.conversationId;
|
|
613
|
+
if (knockId) {
|
|
614
|
+
// Pairing applies only under allowlist/closed-default (open never
|
|
615
|
+
// denies; disabled is hard-off) and unless explicitly turned off.
|
|
616
|
+
const sourcePolicy = resolved.kind === 'user' ? cfg?.dmPolicy : cfg?.groupPolicy;
|
|
617
|
+
const isPairing = cfg?.pairing !== false && sourcePolicy !== 'open' && sourcePolicy !== 'disabled';
|
|
618
|
+
const prev = (0, pending_senders_1.getPendingSender)('line', deniedAgentId, knockId);
|
|
619
|
+
const code = prev?.code ?? (isPairing ? (0, pending_senders_1.generatePairingCode)() : undefined);
|
|
620
|
+
let wasNew = false;
|
|
621
|
+
if (resolved.kind === 'user') {
|
|
622
|
+
wasNew = (0, pending_senders_1.recordDeniedSender)('line', deniedAgentId, knockId, undefined, Date.now(), code);
|
|
623
|
+
if (client) {
|
|
624
|
+
void client
|
|
625
|
+
.getProfile(knockId)
|
|
626
|
+
.then((p) => {
|
|
627
|
+
const e = (0, pending_senders_1.getPendingSender)('line', deniedAgentId, knockId);
|
|
628
|
+
if (e && p?.displayName && !e.displayName)
|
|
629
|
+
e.displayName = p.displayName;
|
|
630
|
+
})
|
|
631
|
+
.catch(() => { });
|
|
632
|
+
}
|
|
611
633
|
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
634
|
+
else if (resolved.kind === 'group') {
|
|
635
|
+
wasNew = (0, pending_senders_1.recordDeniedConversation)('line', deniedAgentId, knockId, 'group', undefined, Date.now(), code);
|
|
636
|
+
if (client) {
|
|
637
|
+
void client
|
|
638
|
+
.getGroupSummary(knockId)
|
|
639
|
+
.then((s) => {
|
|
640
|
+
const e = (0, pending_senders_1.getPendingSender)('line', deniedAgentId, knockId);
|
|
641
|
+
if (e && s?.groupName && !e.displayName)
|
|
642
|
+
e.displayName = s.groupName;
|
|
643
|
+
})
|
|
644
|
+
.catch(() => { });
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
else if (resolved.kind === 'room') {
|
|
648
|
+
wasNew = (0, pending_senders_1.recordDeniedConversation)('line', deniedAgentId, knockId, 'room', undefined, Date.now(), code);
|
|
649
|
+
}
|
|
650
|
+
// Send the pairing code exactly once — on first contact only — via the
|
|
651
|
+
// free reply token (never push; don't spend quota on strangers).
|
|
652
|
+
const replyToken = event.replyToken;
|
|
653
|
+
if (isPairing && wasNew && code && client && typeof replyToken === 'string' && replyToken) {
|
|
616
654
|
void client
|
|
617
|
-
.
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
if (e && s?.groupName && !e.displayName)
|
|
621
|
-
e.displayName = s.groupName;
|
|
655
|
+
.replyMessage({
|
|
656
|
+
replyToken,
|
|
657
|
+
messages: [{ type: 'text', text: pairingMessage(code, resolved.kind) }],
|
|
622
658
|
})
|
|
623
|
-
.catch(() => { });
|
|
659
|
+
.catch((err) => logger.debug('LINE pairing code reply failed', { error: err.message }));
|
|
624
660
|
}
|
|
625
661
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
// Normalize the event into our /channel intake format.
|
|
665
|
+
const norm = normalizeLineEvent(event, resolved);
|
|
666
|
+
if (!norm)
|
|
667
|
+
continue;
|
|
668
|
+
const userId = norm.meta.chat_id;
|
|
669
|
+
// `/cli` opens the live terminal viewer (DM only). Mint a pairing and reply
|
|
670
|
+
// with an open-link + Approve/Deny buttons instead of forwarding to the
|
|
671
|
+
// agent. Reached only after the access gate above authorized this source.
|
|
672
|
+
if ((norm.content ?? '').trim().toLowerCase() === '/cli') {
|
|
673
|
+
if (norm.meta['line_chat_type'] === 'user' && client) {
|
|
674
|
+
const replyToken = norm.meta['reply_token'] ?? '';
|
|
675
|
+
const pairing = runner.createCliPairing('line', userId);
|
|
676
|
+
if (replyToken) {
|
|
677
|
+
const messages = pairing
|
|
678
|
+
? [{
|
|
679
|
+
type: 'template',
|
|
680
|
+
altText: 'Live terminal viewer',
|
|
681
|
+
template: {
|
|
682
|
+
type: 'buttons',
|
|
683
|
+
text: `Live terminal viewer\nCode ${pairing.code} — open, confirm the code, then Approve.`,
|
|
684
|
+
actions: [
|
|
685
|
+
{ type: 'uri', label: 'Open terminal', uri: pairing.url },
|
|
686
|
+
{ type: 'postback', label: `Approve ${pairing.code}`, data: JSON.stringify({ action: 'cli_approve', pairing_id: pairing.pairingId }), displayText: 'Approve terminal viewer' },
|
|
687
|
+
{ type: 'postback', label: 'Deny', data: JSON.stringify({ action: 'cli_deny', pairing_id: pairing.pairingId }) },
|
|
688
|
+
],
|
|
689
|
+
},
|
|
690
|
+
}]
|
|
691
|
+
: [{ type: 'text', text: 'Terminal viewer is not configured. Set gateway.publicUrl in config.json first.' }];
|
|
692
|
+
await client.replyMessage({ replyToken, messages }).catch((err) => {
|
|
693
|
+
logger.debug('LINE /cli reply failed', { error: err.message });
|
|
694
|
+
});
|
|
695
|
+
}
|
|
639
696
|
}
|
|
697
|
+
continue;
|
|
640
698
|
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
if (norm.meta
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
altText: 'Live terminal viewer',
|
|
660
|
-
template: {
|
|
661
|
-
type: 'buttons',
|
|
662
|
-
text: `Live terminal viewer\nCode ${pairing.code} — open, confirm the code, then Approve.`,
|
|
663
|
-
actions: [
|
|
664
|
-
{ type: 'uri', label: 'Open terminal', uri: pairing.url },
|
|
665
|
-
{ type: 'postback', label: `Approve ${pairing.code}`, data: JSON.stringify({ action: 'cli_approve', pairing_id: pairing.pairingId }), displayText: 'Approve terminal viewer' },
|
|
666
|
-
{ type: 'postback', label: 'Deny', data: JSON.stringify({ action: 'cli_deny', pairing_id: pairing.pairingId }) },
|
|
667
|
-
],
|
|
668
|
-
},
|
|
669
|
-
}]
|
|
670
|
-
: [{ type: 'text', text: 'Terminal viewer is not configured. Set gateway.publicUrl in config.json first.' }];
|
|
671
|
-
await client.replyMessage({ replyToken, messages }).catch((err) => {
|
|
672
|
-
logger.debug('LINE /cli reply failed', { error: err.message });
|
|
699
|
+
// Group/room activation gate: unless requireMention is explicitly false,
|
|
700
|
+
// only respond when the bot is @mentioned (native isSelf or its name).
|
|
701
|
+
// DMs (line_chat_type === 'user') always pass. This runs after normalize
|
|
702
|
+
// so unhandled message types are already filtered out.
|
|
703
|
+
//
|
|
704
|
+
// NOTE: LINE attaches `mention` to TEXT messages only, so an image or file
|
|
705
|
+
// posted in a group can never satisfy this gate — such media reaches the
|
|
706
|
+
// agent in DMs, and in groups only when requireMention is false. That is
|
|
707
|
+
// the pre-existing behaviour for images and is left unchanged for files:
|
|
708
|
+
// waiving the gate for media would let any group member push attachments
|
|
709
|
+
// at the agent without ever addressing it.
|
|
710
|
+
if (norm.meta.line_chat_type !== 'user' && cfg?.requireMention !== false) {
|
|
711
|
+
const msg = event.message;
|
|
712
|
+
if (!(0, line_mention_1.wasBotMentioned)(msg)) {
|
|
713
|
+
logger.debug('LINE webhook: group/room message without bot mention, ignoring', {
|
|
714
|
+
agentId: runner.getAgentConfig().id,
|
|
715
|
+
chatType: norm.meta.line_chat_type,
|
|
716
|
+
conversationId: userId,
|
|
673
717
|
});
|
|
718
|
+
continue;
|
|
674
719
|
}
|
|
675
720
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
//
|
|
683
|
-
// NOTE: LINE attaches `mention` to TEXT messages only, so an image or file
|
|
684
|
-
// posted in a group can never satisfy this gate — such media reaches the
|
|
685
|
-
// agent in DMs, and in groups only when requireMention is false. That is
|
|
686
|
-
// the pre-existing behaviour for images and is left unchanged for files:
|
|
687
|
-
// waiving the gate for media would let any group member push attachments
|
|
688
|
-
// at the agent without ever addressing it.
|
|
689
|
-
if (norm.meta.line_chat_type !== 'user' && cfg?.requireMention !== false) {
|
|
690
|
-
const msg = event.message;
|
|
691
|
-
if (!(0, line_mention_1.wasBotMentioned)(msg)) {
|
|
692
|
-
logger.debug('LINE webhook: group/room message without bot mention, ignoring', {
|
|
693
|
-
agentId: runner.getAgentConfig().id,
|
|
694
|
-
chatType: norm.meta.line_chat_type,
|
|
695
|
-
conversationId: userId,
|
|
696
|
-
});
|
|
721
|
+
// Inbound media: fetch the bytes via the blob API and hand the agent an
|
|
722
|
+
// absolute path (meta.image_path). The runner persists it to MediaStore
|
|
723
|
+
// and instructs the agent to Read it, same as Telegram attachments.
|
|
724
|
+
// Images and files share that path; meta.media_type tells them apart.
|
|
725
|
+
const mediaType = norm.meta.media_type;
|
|
726
|
+
if (mediaType === 'audio' && !(runner.getAgentConfig().orchestration?.enabled && (runner.getAgentConfig().orchestration?.channels ?? ['api']).includes('line')))
|
|
697
727
|
continue;
|
|
728
|
+
// Loading animation (best-effort, 1:1 only — LINE rejects it for
|
|
729
|
+
// groups/rooms, where chat_id is a groupId/roomId).
|
|
730
|
+
if (client && norm.meta.line_chat_type === 'user') {
|
|
731
|
+
await (0, line_request_order_1.orderLineRequest)(runner.getAgentConfig().id, userId, () => client.showLoadingAnimation({ chatId: userId, loadingSeconds: LOADING_SECONDS }))
|
|
732
|
+
.catch((err) => logger.debug('showLoadingAnimation failed', { error: err.message }));
|
|
698
733
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
734
|
+
if ((mediaType === 'image' || mediaType === 'file' || mediaType === 'audio') && blobClient && norm.meta.message_id) {
|
|
735
|
+
try {
|
|
736
|
+
let mediaPath;
|
|
737
|
+
if (mediaType === 'image') {
|
|
738
|
+
mediaPath = await downloadLineImage(blobClient, norm.meta.message_id);
|
|
739
|
+
}
|
|
740
|
+
else if (mediaType === 'audio') {
|
|
741
|
+
mediaPath = await downloadLineFile(blobClient, norm.meta.message_id, 'voice.m4a');
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
// The extension comes from the RAW event name (safeFileExt sanitises
|
|
745
|
+
// it itself) — meta.attachment_name is the display label and has
|
|
746
|
+
// already had characters stripped, which could corrupt the suffix.
|
|
747
|
+
const file = event.message;
|
|
748
|
+
mediaPath = await downloadLineFile(blobClient, norm.meta.message_id, file.fileName, file.fileSize);
|
|
749
|
+
}
|
|
750
|
+
// A null path means the blob API answered with zero bytes. Both that and
|
|
751
|
+
// a throw leave the agent with no file, so both must say so — see
|
|
752
|
+
// markMediaUnavailable.
|
|
753
|
+
if (mediaPath) {
|
|
754
|
+
norm.meta.image_path = mediaPath;
|
|
755
|
+
// Staging copy under os.tmpdir(): the runner owns it from here and
|
|
756
|
+
// deletes it once MediaStore has its permanent copy. Nothing else
|
|
757
|
+
// sweeps the temp dir, so without this every inbound attachment —
|
|
758
|
+
// up to MediaStore.maxUploadBytes each — stays on disk forever.
|
|
759
|
+
norm.meta.media_ephemeral = '1';
|
|
760
|
+
}
|
|
761
|
+
else
|
|
762
|
+
markMediaUnavailable(norm, mediaType, 'the sender uploaded no content');
|
|
717
763
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
norm.meta.media_ephemeral = '1';
|
|
764
|
+
catch (err) {
|
|
765
|
+
logger.warn('LINE webhook: media download failed', {
|
|
766
|
+
mediaType,
|
|
767
|
+
messageId: norm.meta.message_id,
|
|
768
|
+
error: err.message,
|
|
769
|
+
});
|
|
770
|
+
markMediaUnavailable(norm, mediaType, err instanceof MediaTooLargeError
|
|
771
|
+
? `larger than the ${Math.floor(MAX_MEDIA_BYTES / (1024 * 1024))} MB limit`
|
|
772
|
+
: 'the download failed');
|
|
728
773
|
}
|
|
729
|
-
|
|
730
|
-
|
|
774
|
+
}
|
|
775
|
+
// Forward to the agent's existing /channel intake (same path Telegram uses).
|
|
776
|
+
try {
|
|
777
|
+
const forwarded = await fetch(`http://127.0.0.1:${runner.getCallbackPort()}/channel`, {
|
|
778
|
+
method: 'POST',
|
|
779
|
+
headers: { 'Content-Type': 'application/json' },
|
|
780
|
+
body: JSON.stringify(norm),
|
|
781
|
+
});
|
|
782
|
+
if (durableIngress && !forwarded.ok)
|
|
783
|
+
throw new Error('Durable input admission failed');
|
|
731
784
|
}
|
|
732
785
|
catch (err) {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
786
|
+
if (durableIngress && !res.headersSent)
|
|
787
|
+
res.status(503).json({ error: 'Input admission unavailable' });
|
|
788
|
+
logger.error('LINE webhook: failed to forward to callback', {
|
|
736
789
|
error: err.message,
|
|
737
790
|
});
|
|
738
|
-
markMediaUnavailable(norm, mediaType, err instanceof MediaTooLargeError
|
|
739
|
-
? `larger than the ${Math.floor(MAX_MEDIA_BYTES / (1024 * 1024))} MB limit`
|
|
740
|
-
: 'the download failed');
|
|
741
791
|
}
|
|
742
792
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
if (
|
|
746
|
-
|
|
747
|
-
.showLoadingAnimation({ chatId: userId, loadingSeconds: LOADING_SECONDS })
|
|
748
|
-
.catch((err) => logger.debug('showLoadingAnimation failed', { error: err.message }));
|
|
749
|
-
}
|
|
750
|
-
// Forward to the agent's existing /channel intake (same path Telegram uses).
|
|
751
|
-
try {
|
|
752
|
-
await fetch(`http://127.0.0.1:${runner.getCallbackPort()}/channel`, {
|
|
753
|
-
method: 'POST',
|
|
754
|
-
headers: { 'Content-Type': 'application/json' },
|
|
755
|
-
body: JSON.stringify(norm),
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
catch (err) {
|
|
759
|
-
logger.error('LINE webhook: failed to forward to callback', {
|
|
760
|
-
error: err.message,
|
|
761
|
-
});
|
|
762
|
-
}
|
|
793
|
+
}
|
|
794
|
+
finally {
|
|
795
|
+
if (!res.headersSent)
|
|
796
|
+
res.status(200).json({ ok: true });
|
|
763
797
|
}
|
|
764
798
|
};
|
|
765
799
|
return { verify: handleGet, handlePost };
|