@xopcai/xopc 0.0.98 → 0.0.100
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/account-manager.d.ts +3 -3
- package/dist/extensions/telegram/src/account-manager.js +8 -8
- package/dist/extensions/telegram/src/account-manager.js.map +1 -1
- package/dist/extensions/telegram/src/actions/message-actions.d.ts +4 -0
- package/dist/extensions/telegram/src/actions/message-actions.js +71 -0
- package/dist/extensions/telegram/src/actions/message-actions.js.map +1 -0
- package/dist/extensions/telegram/src/adapters/config-adapter.js +9 -1
- package/dist/extensions/telegram/src/adapters/config-adapter.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/config-surface.js +1 -1
- package/dist/extensions/telegram/src/adapters/config-surface.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/outbound-adapter.d.ts +2 -1
- package/dist/extensions/telegram/src/adapters/outbound-adapter.js +18 -4
- package/dist/extensions/telegram/src/adapters/outbound-adapter.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/security-adapter.js +2 -1
- package/dist/extensions/telegram/src/adapters/security-adapter.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +90 -6
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/types.d.ts +9 -1
- package/dist/extensions/telegram/src/api-root.d.ts +4 -0
- package/dist/extensions/telegram/src/api-root.js +42 -0
- package/dist/extensions/telegram/src/api-root.js.map +1 -0
- package/dist/extensions/telegram/src/approval-delivery.d.ts +9 -0
- package/dist/extensions/telegram/src/approval-delivery.js +36 -0
- package/dist/extensions/telegram/src/approval-delivery.js.map +1 -0
- package/dist/extensions/telegram/src/approval-store.d.ts +25 -0
- package/dist/extensions/telegram/src/approval-store.js +61 -0
- package/dist/extensions/telegram/src/approval-store.js.map +1 -0
- package/dist/extensions/telegram/src/config-schema.d.ts +185 -35
- package/dist/extensions/telegram/src/config-schema.js +67 -45
- package/dist/extensions/telegram/src/config-schema.js.map +1 -1
- package/dist/extensions/telegram/src/conversation-id.d.ts +6 -0
- package/dist/extensions/telegram/src/conversation-id.js +18 -0
- package/dist/extensions/telegram/src/conversation-id.js.map +1 -0
- package/dist/extensions/telegram/src/doctor.d.ts +5 -0
- package/dist/extensions/telegram/src/doctor.js +80 -0
- package/dist/extensions/telegram/src/doctor.js.map +1 -0
- package/dist/extensions/telegram/src/exec-approval-handler.d.ts +7 -0
- package/dist/extensions/telegram/src/exec-approval-handler.js +36 -0
- package/dist/extensions/telegram/src/exec-approval-handler.js.map +1 -0
- package/dist/extensions/telegram/src/exec-approvals.d.ts +8 -0
- package/dist/extensions/telegram/src/exec-approvals.js +20 -0
- package/dist/extensions/telegram/src/exec-approvals.js.map +1 -0
- package/dist/extensions/telegram/src/focus-handler.d.ts +12 -0
- package/dist/extensions/telegram/src/focus-handler.js +55 -0
- package/dist/extensions/telegram/src/focus-handler.js.map +1 -0
- package/dist/extensions/telegram/src/group-config-resolver.d.ts +12 -0
- package/dist/extensions/telegram/src/group-config-resolver.js +17 -0
- package/dist/extensions/telegram/src/group-config-resolver.js.map +1 -0
- package/dist/extensions/telegram/src/inbound-coalescer.d.ts +15 -0
- package/dist/extensions/telegram/src/inbound-coalescer.js +107 -0
- package/dist/extensions/telegram/src/inbound-coalescer.js.map +1 -0
- package/dist/extensions/telegram/src/inbound-processor.d.ts +1 -0
- package/dist/extensions/telegram/src/inbound-processor.js +41 -4
- package/dist/extensions/telegram/src/inbound-processor.js.map +1 -1
- package/dist/extensions/telegram/src/network-errors.d.ts +2 -0
- package/dist/extensions/telegram/src/network-errors.js +23 -0
- package/dist/extensions/telegram/src/network-errors.js.map +1 -0
- package/dist/extensions/telegram/src/plugin.d.ts +11 -0
- package/dist/extensions/telegram/src/plugin.js +192 -58
- package/dist/extensions/telegram/src/plugin.js.map +1 -1
- package/dist/extensions/telegram/src/polling-session.d.ts +17 -0
- package/dist/extensions/telegram/src/polling-session.js +112 -0
- package/dist/extensions/telegram/src/polling-session.js.map +1 -0
- package/dist/extensions/telegram/src/proxy-fetch.d.ts +2 -0
- package/dist/extensions/telegram/src/proxy-fetch.js +14 -0
- package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -0
- package/dist/extensions/telegram/src/reactions.d.ts +14 -0
- package/dist/extensions/telegram/src/reactions.js +48 -0
- package/dist/extensions/telegram/src/reactions.js.map +1 -0
- package/dist/extensions/telegram/src/reply-params.d.ts +15 -0
- package/dist/extensions/telegram/src/reply-params.js +28 -0
- package/dist/extensions/telegram/src/reply-params.js.map +1 -0
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/startup-errors.d.ts +3 -0
- package/dist/extensions/telegram/src/startup-errors.js +27 -0
- package/dist/extensions/telegram/src/startup-errors.js.map +1 -0
- package/dist/extensions/telegram/src/telegram-actions.d.ts +25 -0
- package/dist/extensions/telegram/src/telegram-actions.js +65 -0
- package/dist/extensions/telegram/src/telegram-actions.js.map +1 -0
- package/dist/extensions/telegram/src/thread-bindings.d.ts +15 -0
- package/dist/extensions/telegram/src/thread-bindings.js +22 -0
- package/dist/extensions/telegram/src/thread-bindings.js.map +1 -0
- package/dist/extensions/telegram/src/token-resolver.d.ts +8 -0
- package/dist/extensions/telegram/src/token-resolver.js +34 -0
- package/dist/extensions/telegram/src/token-resolver.js.map +1 -0
- package/dist/extensions/telegram/src/update-offset-store.d.ts +9 -0
- package/dist/extensions/telegram/src/update-offset-store.js +66 -0
- package/dist/extensions/telegram/src/update-offset-store.js.map +1 -0
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/{agents-NI7FFR-h.js → agents-C5jtBK-H.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-BB4iSCrJ.js → apps-page-smJl-qf_.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-CH6KgFK6.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-CV70xvY7.js +8 -0
- package/dist/gateway/static/root/assets/{cron-api-1dHoVFEA.js → cron-api-CgBO8B7I.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-CVX6FPfb.js → cron-page-Be0cW1cR.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-BZnl4G4p.js → dist-P8HRGUuh.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DwQp_4Qv.js → extension-debug-page-BowuycYu.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-l9crxSvM.js → extension-page-27-Zpv8O.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CXzLbq9B.js → extension-settings-page-DDFa_rIq.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-BLLOP2CM.js → fetch-drJUxxKP.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-BRnEyxSl.js → field-primitives-BWLssxEb.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-eMo0k381.js → heartbeat-config-api-BVuYNYT_.js} +1 -1
- package/dist/gateway/static/root/assets/index-CRDAmr3W.js +4840 -0
- package/dist/gateway/static/root/assets/index-DjNDHzwG.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-BvTEevBZ.js → logs-page-BDX8IrDQ.js} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-page-Dl3jhcWg.js → note-detail-page-BmQ9KeiA.js} +1 -1
- package/dist/gateway/static/root/assets/{note-time-D8Tlyotb.js → note-time-14I9Sgqh.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-BWILOitx.js → notes-page-BMfP0FFf.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-3EJRugZg.js → sessions-page-C3scyChq.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-advanced-gate-CZ5wlM_q.js → settings-advanced-gate-2ODuCjHP.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-C6RYGnKK.js → settings-form-section-DUoGKAiW.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-0egNvAMr.js → settings-page-CttAfOWV.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-BVJtaSoK.js → share-preview-page-B77xqiiI.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-DVnRQ5Mo.js → skills-page-B_bAZGzB.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-e2q2yjs4.js → theme-store-BgCPrmxU.js} +1 -1
- package/dist/gateway/static/root/assets/url-q28QhI7l.js +3 -0
- package/dist/gateway/static/root/assets/{utils-Bl-94YzI.js → utils-CCGejlcX.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-B53JA8qW.js → voice-api-key-field-DZzzihcY.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-page.utils-ontUT7yL.js → workflow-page.utils-D5RMAmT4.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-Bz7YRTdp.js → workflows-page-DEYpC6Bv.js} +1 -1
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +4 -0
- package/dist/src/agent/agent-manager.js +75 -11
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +1 -0
- package/dist/src/agent/child-agent-factory.js +13 -10
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/context/workspace-state.js +1 -1
- package/dist/src/agent/embedded/run-for-session.d.ts +1 -0
- package/dist/src/agent/embedded/run-for-session.js +1 -0
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/embedded/run-turn.js +1 -17
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.js +3 -1
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.d.ts +1 -0
- package/dist/src/agent/embedded/session-tool-result-guard.js +1 -0
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/inbound/attachment-pipeline.d.ts +37 -0
- package/dist/src/agent/inbound/attachment-pipeline.js +169 -0
- package/dist/src/agent/inbound/attachment-pipeline.js.map +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +3 -5
- package/dist/src/agent/inbound/turn-dispatcher.js +1 -2
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/index.d.ts +2 -0
- package/dist/src/agent/memory/index.js +2 -1
- package/dist/src/agent/memory/memory-flush.d.ts +27 -0
- package/dist/src/agent/memory/memory-flush.js +124 -0
- package/dist/src/agent/memory/memory-flush.js.map +1 -0
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/messaging/outbound-coordinator.js +2 -1
- package/dist/src/agent/messaging/outbound-coordinator.js.map +1 -1
- package/dist/src/agent/messaging/stream-manager.d.ts +2 -0
- package/dist/src/agent/messaging/stream-manager.js +3 -0
- package/dist/src/agent/messaging/stream-manager.js.map +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +40 -107
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/prompt/contribution.d.ts +9 -0
- package/dist/src/agent/prompt/contribution.js +1 -0
- package/dist/src/agent/prompt/safety.js +0 -10
- package/dist/src/agent/prompt/safety.js.map +1 -1
- package/dist/src/agent/prompt/sanitize-for-prompt.d.ts +6 -0
- package/dist/src/agent/prompt/sanitize-for-prompt.js +13 -0
- package/dist/src/agent/prompt/sanitize-for-prompt.js.map +1 -0
- package/dist/src/agent/prompt/sections/behavior.d.ts +5 -0
- package/dist/src/agent/prompt/sections/behavior.js +50 -0
- package/dist/src/agent/prompt/sections/behavior.js.map +1 -0
- package/dist/src/agent/prompt/sections/memory-skills.d.ts +9 -0
- package/dist/src/agent/prompt/sections/memory-skills.js +59 -0
- package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -0
- package/dist/src/agent/prompt/sections/messaging-runtime.d.ts +16 -0
- package/dist/src/agent/prompt/sections/messaging-runtime.js +69 -0
- package/dist/src/agent/prompt/sections/messaging-runtime.js.map +1 -0
- package/dist/src/agent/prompt/sections/project-context.d.ts +16 -0
- package/dist/src/agent/prompt/sections/project-context.js +58 -0
- package/dist/src/agent/prompt/sections/project-context.js.map +1 -0
- package/dist/src/agent/prompt/sections/tooling.d.ts +5 -0
- package/dist/src/agent/prompt/sections/tooling.js +119 -0
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -0
- package/dist/src/agent/prompt/sections/workspace-runtime.d.ts +11 -0
- package/dist/src/agent/prompt/sections/workspace-runtime.js +32 -0
- package/dist/src/agent/prompt/sections/workspace-runtime.js.map +1 -0
- package/dist/src/agent/prompt/service-prompt-builder.d.ts +13 -0
- package/dist/src/agent/prompt/service-prompt-builder.js +56 -15
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/subagent-context.d.ts +15 -0
- package/dist/src/agent/prompt/subagent-context.js +68 -0
- package/dist/src/agent/prompt/subagent-context.js.map +1 -0
- package/dist/src/agent/prompt/system-prompt-params.d.ts +53 -0
- package/dist/src/agent/prompt/system-prompt-params.js +74 -0
- package/dist/src/agent/prompt/system-prompt-params.js.map +1 -0
- package/dist/src/agent/prompt/system-prompt.d.ts +22 -11
- package/dist/src/agent/prompt/system-prompt.js +79 -193
- package/dist/src/agent/prompt/system-prompt.js.map +1 -1
- package/dist/src/agent/prompt/types.d.ts +3 -0
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.d.ts +5 -21
- package/dist/src/agent/service/build-direct-message-content.js +11 -64
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +7 -0
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
- package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -3
- package/dist/src/agent/service/process-direct-one-shot.js +22 -17
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +6 -20
- package/dist/src/agent/service/process-direct-streaming.js +39 -40
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +4 -9
- package/dist/src/agent/service/webchat-tts.js +9 -20
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.d.ts +8 -19
- package/dist/src/agent/service.js +57 -15
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +3 -1
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/media-read-tool.d.ts +2 -0
- package/dist/src/agent/tools/media-read-tool.js +89 -0
- package/dist/src/agent/tools/media-read-tool.js.map +1 -0
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +3 -3
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/attachment-classifiers.d.ts +8 -0
- package/dist/src/channels/attachments/attachment-classifiers.js +11 -0
- package/dist/src/channels/attachments/attachment-classifiers.js.map +1 -0
- package/dist/src/channels/attachments/inbound-persist.d.ts +13 -34
- package/dist/src/channels/attachments/inbound-persist.js +34 -102
- package/dist/src/channels/attachments/inbound-persist.js.map +1 -1
- package/dist/src/channels/attachments/inbound-types.d.ts +13 -0
- package/dist/src/channels/attachments/inbound-types.js +30 -0
- package/dist/src/channels/attachments/inbound-types.js.map +1 -0
- package/dist/src/channels/attachments/outbound-tts-persist.d.ts +3 -12
- package/dist/src/channels/attachments/outbound-tts-persist.js +28 -48
- package/dist/src/channels/attachments/outbound-tts-persist.js.map +1 -1
- package/dist/src/channels/attachments/voice-stt-webchat.d.ts +3 -3
- package/dist/src/channels/attachments/voice-stt-webchat.js +8 -14
- package/dist/src/channels/attachments/voice-stt-webchat.js.map +1 -1
- package/dist/src/channels/channel-domain.d.ts +30 -2
- package/dist/src/channels/exec-approval-runtime.d.ts +29 -0
- package/dist/src/channels/exec-approval-runtime.js +30 -0
- package/dist/src/channels/exec-approval-runtime.js.map +1 -0
- package/dist/src/channels/index.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/channels/plugin-types.d.ts +1 -0
- package/dist/src/channels/transport-types.d.ts +2 -2
- package/dist/src/chat-commands/agent-edit.js +2 -2
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.d.ts +2 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +62 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js.map +1 -0
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/doctor/flow.js +2 -0
- package/dist/src/cli/commands/doctor/flow.js.map +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +5 -60
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/onboard/channels/registry.js +1 -1
- package/dist/src/cli/commands/setup.js +6 -5
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -3
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/commands/agents.config.js +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +7 -7
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/paths.d.ts +0 -13
- package/dist/src/config/paths.js +1 -20
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/rules.js +1 -1
- package/dist/src/config/schema.d.ts +24 -0
- package/dist/src/config/schema.js +33 -2
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.js +4 -4
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agents-admin.js +3 -3
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +2 -2
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/channels.js +3 -3
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/media.d.ts +3 -0
- package/dist/src/gateway/hono/routes/media.js +50 -0
- package/dist/src/gateway/hono/routes/media.js.map +1 -0
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +6 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +3 -89
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service/sessions-api.js +3 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.js +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/brew.js +1 -1
- package/dist/src/infra/package-json.js +1 -1
- package/dist/src/infra/package-update-steps.js +1 -1
- package/dist/src/infra/path-env.js +2 -2
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/stable-node-path.js +1 -1
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/media/index.d.ts +5 -0
- package/dist/src/media/index.js +5 -0
- package/dist/src/media/media-reference.d.ts +23 -0
- package/dist/src/media/media-reference.js +34 -0
- package/dist/src/media/media-reference.js.map +1 -0
- package/dist/src/media/paths.d.ts +5 -0
- package/dist/src/media/paths.js +20 -0
- package/dist/src/media/paths.js.map +1 -0
- package/dist/src/media/session-references.d.ts +8 -0
- package/dist/src/media/session-references.js +45 -0
- package/dist/src/media/session-references.js.map +1 -0
- package/dist/src/media/store.d.ts +19 -0
- package/dist/src/media/store.js +131 -0
- package/dist/src/media/store.js.map +1 -0
- package/dist/src/media/types.d.ts +34 -0
- package/dist/src/media/types.js +1 -0
- package/dist/src/media/uri.d.ts +15 -0
- package/dist/src/media/uri.js +51 -0
- package/dist/src/media/uri.js.map +1 -0
- package/dist/src/notes/store.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/init-session-turn.js +2 -2
- package/dist/src/session/resolve-session.js +3 -3
- package/dist/src/session/session-title.js +8 -5
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/session/store.js +3 -3
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/types.d.ts +12 -7
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/storage/sqlite/connection.js +2 -2
- package/dist/src/storage/sqlite/index.d.ts +4 -1
- package/dist/src/storage/sqlite/index.js +6 -2
- package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
- package/dist/src/storage/sqlite/migrations/002_add_flush_columns.sql +3 -0
- package/dist/src/storage/sqlite/migrations/discover.d.ts +4 -0
- package/dist/src/storage/sqlite/migrations/discover.js +38 -0
- package/dist/src/storage/sqlite/migrations/discover.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/discover.ts +52 -0
- package/dist/src/storage/sqlite/migrations/errors.d.ts +11 -0
- package/dist/src/storage/sqlite/migrations/errors.js +27 -0
- package/dist/src/storage/sqlite/migrations/errors.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/errors.ts +32 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +22 -0
- package/dist/src/storage/sqlite/migrations/runner.js +97 -0
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/runner.ts +153 -0
- package/dist/src/storage/sqlite/migrations/types.d.ts +12 -0
- package/dist/src/storage/sqlite/migrations/types.js +1 -0
- package/dist/src/storage/sqlite/migrations/types.ts +13 -0
- package/dist/src/storage/sqlite/row-mappers.d.ts +4 -0
- package/dist/src/storage/sqlite/row-mappers.js +4 -0
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
- package/dist/src/storage/sqlite/schema-version.d.ts +6 -0
- package/dist/src/storage/sqlite/schema-version.js +29 -0
- package/dist/src/storage/sqlite/schema-version.js.map +1 -0
- package/dist/src/storage/sqlite/schema.d.ts +5 -3
- package/dist/src/storage/sqlite/schema.js +25 -29
- package/dist/src/storage/sqlite/schema.js.map +1 -1
- package/dist/src/storage/sqlite/schema.sql +2 -0
- package/dist/src/storage/sqlite/session-metadata.js +1 -0
- package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
- package/dist/src/storage/sqlite/session-repository.js +7 -3
- package/dist/src/storage/sqlite/session-repository.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +3 -3
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/channels-settings-BmN5udFV.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-LXGc1lXo.js +0 -8
- package/dist/gateway/static/root/assets/index-BJDmBCSl.css +0 -1
- package/dist/gateway/static/root/assets/index-DsmZjtSc.js +0 -4707
- package/dist/gateway/static/root/assets/url-DpFBIyN9.js +0 -3
- package/dist/src/cli/commands/onboard/workspace.d.ts +0 -14
- package/dist/src/cli/commands/onboard/workspace.js +0 -33
- package/dist/src/cli/commands/onboard/workspace.js.map +0 -1
- package/dist/src/cli/utils/workspace.d.ts +0 -35
- package/dist/src/cli/utils/workspace.js +0 -72
- package/dist/src/cli/utils/workspace.js.map +0 -1
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { resolveRoute } from "../../../src/routing/resolve-route.js";
|
|
1
2
|
import { createLogger } from "../../../src/utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../../../src/utils/logger.js";
|
|
3
4
|
import { normalizeTelegramCommandName, parseSlashCommand } from "../../../src/chat-commands/command-parse.js";
|
|
4
5
|
import { checkMentionInTranscription } from "../../../src/voice/stt/preflight.js";
|
|
6
|
+
import "../../../src/voice/stt/index.js";
|
|
5
7
|
import { tryConsumeTelegramClarifyFreeText } from "../../../src/gateway/clarify-runtime.js";
|
|
6
8
|
import { buildTelegramUpdateKey, telegramUpdateDedupe } from "./dedupe.js";
|
|
9
|
+
import "../../../src/routing/index.js";
|
|
10
|
+
import { resolveTelegramGroupContext } from "./group-config-resolver.js";
|
|
11
|
+
import { buildTelegramConversationId } from "./conversation-id.js";
|
|
12
|
+
import { resolveTelegramFocusedSessionKey } from "./focus-handler.js";
|
|
7
13
|
//#region extensions/telegram/src/inbound-processor.ts
|
|
8
14
|
init_logger();
|
|
9
15
|
const log = createLogger("TelegramInboundProcessor");
|
|
@@ -41,6 +47,11 @@ function extractMediaItems(message) {
|
|
|
41
47
|
type: "voice",
|
|
42
48
|
fileId: message.voice.file_id
|
|
43
49
|
});
|
|
50
|
+
if (message.sticker) media.push({
|
|
51
|
+
type: "sticker",
|
|
52
|
+
fileId: message.sticker.file_id,
|
|
53
|
+
emoji: message.sticker.emoji
|
|
54
|
+
});
|
|
44
55
|
return media;
|
|
45
56
|
}
|
|
46
57
|
/**
|
|
@@ -196,7 +207,7 @@ function createInboundProcessor(deps) {
|
|
|
196
207
|
log.warn({ accountId }, "Bot username not available");
|
|
197
208
|
return;
|
|
198
209
|
}
|
|
199
|
-
const message = ctx.message;
|
|
210
|
+
const message = ctx.message ?? ctx.channelPost;
|
|
200
211
|
if (!message) return;
|
|
201
212
|
const chatId = String(ctx.chat?.id);
|
|
202
213
|
const senderId = String(ctx.from?.id);
|
|
@@ -277,14 +288,35 @@ function createInboundProcessor(deps) {
|
|
|
277
288
|
}
|
|
278
289
|
}
|
|
279
290
|
const cleanContent = isGroup ? accessControl.removeBotMention(content, botUsername) : content;
|
|
280
|
-
const
|
|
291
|
+
const groupCtx = resolveTelegramGroupContext({
|
|
292
|
+
account,
|
|
293
|
+
chatId,
|
|
294
|
+
threadId
|
|
295
|
+
});
|
|
296
|
+
const route = resolveRoute({
|
|
297
|
+
config,
|
|
298
|
+
channel: "telegram",
|
|
299
|
+
accountId,
|
|
300
|
+
peerKind: isGroup ? "group" : "dm",
|
|
301
|
+
peerId: isGroup ? chatId : senderId,
|
|
302
|
+
threadId: threadId ? String(threadId) : null
|
|
303
|
+
});
|
|
304
|
+
const routedAgentId = groupCtx.agentId ?? route.agentId;
|
|
305
|
+
const defaultSessionKey = sessionKeyService.generateSessionKey({
|
|
281
306
|
source: "telegram",
|
|
282
307
|
chatId,
|
|
283
308
|
senderId,
|
|
284
309
|
isGroup,
|
|
285
310
|
threadId: threadId ? String(threadId) : void 0,
|
|
286
|
-
accountId
|
|
311
|
+
accountId,
|
|
312
|
+
agentId: routedAgentId
|
|
313
|
+
});
|
|
314
|
+
const sessionKey = resolveTelegramFocusedSessionKey({
|
|
315
|
+
chatId,
|
|
316
|
+
threadId: threadId ? String(threadId) : void 0,
|
|
317
|
+
defaultSessionKey
|
|
287
318
|
});
|
|
319
|
+
const conversationId = buildTelegramConversationId(chatId, threadId);
|
|
288
320
|
const media = extractMediaItems(message);
|
|
289
321
|
const bot = accountManager.getBot(accountId);
|
|
290
322
|
const botToken = account.botToken;
|
|
@@ -296,7 +328,9 @@ function createInboundProcessor(deps) {
|
|
|
296
328
|
transcribedText = mediaResult.transcribedText;
|
|
297
329
|
}
|
|
298
330
|
const captionIsCommand = cleanContent.trim().startsWith("/");
|
|
299
|
-
|
|
331
|
+
let finalContent = transcribedText ? captionIsCommand && cleanContent ? cleanContent.trim() + (transcribedText ? `\n\n${transcribedText}` : "") : transcribedText + (cleanContent ? "\n\n" + cleanContent : "") : cleanContent;
|
|
332
|
+
const stickerItem = media.find((m) => m.type === "sticker");
|
|
333
|
+
if (stickerItem && !finalContent.trim()) finalContent = stickerItem.emoji?.trim() ? `[Sticker ${stickerItem.emoji}]` : "[Sticker]";
|
|
300
334
|
const isCommand = cleanContent.trim().startsWith("/");
|
|
301
335
|
log.info({
|
|
302
336
|
accountId,
|
|
@@ -325,6 +359,9 @@ function createInboundProcessor(deps) {
|
|
|
325
359
|
isGroup,
|
|
326
360
|
isCommand,
|
|
327
361
|
threadId: threadId ? String(threadId) : void 0,
|
|
362
|
+
conversationId,
|
|
363
|
+
channelSystemPrompt: groupCtx.systemPrompt,
|
|
364
|
+
channelAgentId: routedAgentId,
|
|
328
365
|
media: media.length > 0 ? media : void 0,
|
|
329
366
|
transcribedVoice: !!transcribedText || void 0
|
|
330
367
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbound-processor.js","names":[],"sources":["../../../../extensions/telegram/src/inbound-processor.ts"],"sourcesContent":["/**\n * Telegram Inbound Processor\n *\n * Handles inbound message processing from Telegram:\n * - Message queuing (per chat)\n * - Deduplication\n * - Access control\n * - Media download\n * - STT transcription\n * - Event publishing to bus\n */\n\nimport type { Bot, Context } from 'grammy';\nimport type { Message } from '@grammyjs/types';\nimport type { Config } from '@xopcai/xopc/config/schema.js';\nimport type { MessageBus } from '@xopcai/xopc/infra/bus/index.js';\nimport type { TelegramAccountManager } from './account-manager.js';\nimport { telegramUpdateDedupe, buildTelegramUpdateKey } from './dedupe.js';\nimport { createLogger } from '@xopcai/xopc/utils/logger.js';\nimport { normalizeTelegramCommandName, parseSlashCommand } from '@xopcai/xopc/chat-commands/command-parse.js';\nimport { tryConsumeTelegramClarifyFreeText } from '@xopcai/xopc/gateway/clarify-runtime.js';\nimport { checkMentionInTranscription } from '@xopcai/xopc/voice/stt/preflight.js';\n\nconst log = createLogger('TelegramInboundProcessor');\n\n/** Must bypass the per-chat queue so /abort can cancel an in-flight turn. */\nfunction isAbortSlashCommand(text: string): boolean {\n const parsed = parseSlashCommand(text);\n if (!parsed) return false;\n const cmd = normalizeTelegramCommandName(parsed.command);\n return cmd === 'abort' || cmd === 'stop' || cmd === 'cancel';\n}\n\n/** Maximum voice message duration for STT in seconds */\nconst STT_MAX_VOICE_DURATION_SECONDS = 60;\n\n// =============================================================================\n// External Service Interfaces (for dependency injection)\n// =============================================================================\n\nexport interface AccessControlService {\n normalizeAllowFromWithStore(options: { allowFrom?: Array<string | number> }): unknown;\n evaluateGroupBaseAccess(options: {\n isGroup: boolean;\n groupConfig?: unknown;\n topicConfig?: unknown;\n hasGroupAllowOverride: boolean;\n effectiveGroupAllow: unknown;\n senderId?: string;\n senderUsername?: string;\n }): { allowed: boolean; reason?: string };\n resolveRequireMention(options: {\n topicConfig?: unknown;\n groupConfig?: unknown;\n defaultRequireMention?: boolean;\n }): boolean;\n hasBotMention(options: { botUsername: string; text?: string; entities?: unknown }): boolean;\n removeBotMention(text: string, botUsername: string): string;\n}\n\nexport interface SessionKeyService {\n generateSessionKey(options: {\n source: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n threadId?: string;\n accountId?: string;\n }): string;\n}\n\nexport interface STTService {\n transcribe(buffer: Buffer, config: unknown, options?: { language?: string }): Promise<{ text: string }>;\n isSTTAvailable(config: unknown): boolean;\n}\n\nexport interface MediaUtils {\n getMimeType(type: string, filePath?: string): string;\n}\n\n// =============================================================================\n// Dependencies Interface\n// =============================================================================\n\nexport interface InboundProcessorDeps {\n bus: MessageBus;\n config: Config;\n accountManager: TelegramAccountManager;\n // External services (injected for testability)\n accessControl: AccessControlService;\n sessionKeyService: SessionKeyService;\n sttService: STTService;\n mediaUtils: MediaUtils;\n}\n\ninterface QueuedMessage {\n ctx: Context;\n accountId: string;\n resolve: () => void;\n reject: (err: Error) => void;\n}\n\n// =============================================================================\n// Media Processing Types\n// =============================================================================\n\ninterface MediaItem {\n type: string;\n fileId: string;\n}\n\ninterface ProcessedAttachment {\n type: string;\n mimeType: string;\n data: string;\n name?: string;\n size?: number;\n}\n\n// =============================================================================\n// Helper Functions (reduce nesting in main processor)\n// =============================================================================\n\n/**\n * Extract media items from message\n */\nfunction extractMediaItems(message: Message): MediaItem[] {\n const media: MediaItem[] = [];\n \n if (message.photo?.length) {\n media.push({ type: 'photo', fileId: message.photo[message.photo.length - 1].file_id });\n }\n if (message.document) {\n media.push({ type: 'document', fileId: message.document.file_id });\n }\n if (message.video) {\n media.push({ type: 'video', fileId: message.video.file_id });\n }\n if (message.audio) {\n media.push({ type: 'audio', fileId: message.audio.file_id });\n }\n if (message.voice) {\n media.push({ type: 'voice', fileId: message.voice.file_id });\n }\n \n return media;\n}\n\n/**\n * Download + STT a Telegram voice message (for mention probe or media pipeline).\n */\nasync function downloadAndTranscribeTelegramVoice(params: {\n voice: NonNullable<Message['voice']>;\n bot: Bot;\n botToken: string;\n accountApiRoot: string;\n sttService: STTService;\n sttConfig: unknown;\n}): Promise<string> {\n const { voice, bot, botToken, accountApiRoot, sttService, sttConfig } = params;\n const voiceDuration = voice.duration || 0;\n if (voiceDuration > STT_MAX_VOICE_DURATION_SECONDS) {\n return '';\n }\n if (!sttService.isSTTAvailable(sttConfig)) {\n return '';\n }\n try {\n const file = await bot.api.getFile(voice.file_id);\n const downloadUrl = `${accountApiRoot}/file/bot${botToken}/${file.file_path}`;\n const response = await fetch(downloadUrl);\n if (!response.ok) {\n return '';\n }\n const buffer = Buffer.from(await response.arrayBuffer());\n if (buffer.length === 0) {\n return '';\n }\n const sttResult = await sttService.transcribe(buffer, sttConfig, {\n language: (sttConfig as { provider?: string })?.provider === 'alibaba' ? 'zh' : undefined,\n });\n return sttResult.text?.trim() ?? '';\n } catch {\n return '';\n }\n}\n\n/**\n * Process a single media item (download + optional STT)\n */\nasync function processMediaItem(\n item: MediaItem,\n bot: Bot,\n botToken: string,\n accountApiRoot: string,\n message: Message,\n sttService: STTService,\n mediaUtils: MediaUtils,\n sttConfig: unknown,\n reuseVoiceTranscript?: string,\n): Promise<{ attachment: ProcessedAttachment | null; transcribedText: string }> {\n try {\n const file = await bot.api.getFile(item.fileId);\n const downloadUrl = `${accountApiRoot}/file/bot${botToken}/${file.file_path}`;\n const response = await fetch(downloadUrl);\n\n // Debug log for media download\n log.info({\n type: item.type,\n fileId: item.fileId,\n downloadUrl,\n responseStatus: response.status,\n }, 'Media download response');\n\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.status}`);\n }\n\n const buffer = await response.arrayBuffer();\n\n // Debug log for buffer size\n log.info({\n type: item.type,\n fileId: item.fileId,\n bufferSize: buffer.byteLength,\n filePath: file.file_path,\n }, 'Media buffer downloaded');\n\n if (buffer.byteLength === 0) {\n log.warn({\n type: item.type,\n fileId: item.fileId,\n filePath: file.file_path,\n }, 'Media buffer is empty, may cause issues');\n }\n let transcribedText = '';\n\n // Handle voice messages with STT\n if (item.type === 'voice' && sttService.isSTTAvailable(sttConfig)) {\n if (reuseVoiceTranscript !== undefined && reuseVoiceTranscript !== '') {\n transcribedText = reuseVoiceTranscript;\n } else {\n const voiceDuration = message.voice?.duration || 0;\n if (voiceDuration <= STT_MAX_VOICE_DURATION_SECONDS) {\n try {\n const sttResult = await sttService.transcribe(Buffer.from(buffer), sttConfig, {\n language: (sttConfig as { provider?: string })?.provider === 'alibaba' ? 'zh' : undefined,\n });\n transcribedText = sttResult.text;\n } catch (sttError) {\n log.error({ sttError }, 'STT transcription failed');\n transcribedText = '[STT failed]';\n }\n } else {\n transcribedText = `[Voice message too long (>${STT_MAX_VOICE_DURATION_SECONDS}s)]`;\n }\n }\n }\n\n const base64 = Buffer.from(buffer).toString('base64');\n const mimeType = mediaUtils.getMimeType(item.type, file.file_path);\n\n // Debug log for attachment creation\n log.info({\n type: item.type,\n mimeType,\n base64Length: base64.length,\n size: buffer.byteLength,\n name: file.file_path?.split('/').pop(),\n }, 'Attachment created');\n\n return {\n attachment: {\n type: item.type,\n mimeType,\n data: base64,\n name: file.file_path?.split('/').pop(),\n size: buffer.byteLength,\n },\n transcribedText,\n };\n } catch (err) {\n log.error({ type: item.type, fileId: item.fileId, err }, 'Failed to download media');\n return { attachment: null, transcribedText: '' };\n }\n}\n\n/**\n * Process all media items\n */\nasync function processAllMedia(\n media: MediaItem[],\n bot: Bot,\n botToken: string,\n accountApiRoot: string,\n message: Message,\n sttService: STTService,\n mediaUtils: MediaUtils,\n sttConfig: unknown,\n reuseVoiceTranscript?: string,\n): Promise<{ attachments: ProcessedAttachment[]; transcribedText: string }> {\n const attachments: ProcessedAttachment[] = [];\n let transcribedText = '';\n let voiceReuseConsumed = false;\n\n for (const item of media) {\n const reuse =\n item.type === 'voice' && reuseVoiceTranscript && !voiceReuseConsumed\n ? reuseVoiceTranscript\n : undefined;\n if (reuse) {\n voiceReuseConsumed = true;\n }\n const result = await processMediaItem(\n item,\n bot,\n botToken,\n accountApiRoot,\n message,\n sttService,\n mediaUtils,\n sttConfig,\n reuse,\n );\n \n if (result.attachment) {\n attachments.push(result.attachment);\n }\n if (result.transcribedText) {\n transcribedText = result.transcribedText;\n }\n }\n\n return { attachments, transcribedText };\n}\n\n// =============================================================================\n// Main Processor Factory\n// =============================================================================\n\n/**\n * Create inbound message processor\n */\nexport function createInboundProcessor(deps: InboundProcessorDeps) {\n const {\n bus,\n config,\n accountManager,\n accessControl,\n sessionKeyService,\n sttService,\n mediaUtils,\n } = deps;\n\n const messageQueues = new Map<string, QueuedMessage[]>();\n const processingLocks = new Map<string, Promise<void>>();\n\n const getChatKey = (accountId: string, chatId: string): string => `${accountId}:${chatId}`;\n\n const processNextMessage = async (chatKey: string): Promise<void> => {\n if (processingLocks.has(chatKey)) return;\n\n const queue = messageQueues.get(chatKey);\n if (!queue || queue.length === 0) return;\n\n let lockResolve: () => void;\n const lockPromise = new Promise<void>((resolve) => {\n lockResolve = resolve;\n });\n processingLocks.set(chatKey, lockPromise);\n\n const { ctx, accountId, resolve, reject } = queue.shift()!;\n\n try {\n await processMessageInternal(ctx, accountId);\n resolve();\n } catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)));\n } finally {\n lockResolve?.();\n processingLocks.delete(chatKey);\n if (queue.length > 0) {\n processNextMessage(chatKey);\n } else {\n messageQueues.delete(chatKey);\n }\n }\n };\n\n const processMessageInternal = async (ctx: Context, accountId: string) => {\n // Deduplication check\n const updateKey = buildTelegramUpdateKey(ctx);\n if (updateKey && telegramUpdateDedupe.checkAndAdd(updateKey)) {\n log.debug({ updateKey, accountId }, 'Duplicate update detected, skipping');\n return;\n }\n\n const account = accountManager.getAccount(accountId);\n if (!account) {\n log.warn({ accountId }, 'Account not found for message processing');\n return;\n }\n\n const botUsername = accountManager.getBotUsername(accountId);\n if (!botUsername) {\n log.warn({ accountId }, 'Bot username not available');\n return;\n }\n\n const message = ctx.message;\n if (!message) return;\n\n const chatId = String(ctx.chat?.id);\n const senderId = String(ctx.from?.id);\n const senderUsername = ctx.from?.username;\n const content = message.text ?? message.caption ?? '';\n const isGroup = ctx.chat?.type === 'group' || ctx.chat?.type === 'supergroup';\n const threadId = (message as { message_thread_id?: number }).message_thread_id;\n\n // Access control (group/topic allowlists, mention gating)\n const effectiveAllowFrom = accessControl.normalizeAllowFromWithStore({\n allowFrom: isGroup ? account.groupAllowFrom : account.allowFrom,\n });\n\n const baseAccess = accessControl.evaluateGroupBaseAccess({\n isGroup,\n groupConfig: account.groups?.[chatId],\n topicConfig: threadId ? account.groups?.[chatId]?.topics?.[String(threadId)] : undefined,\n hasGroupAllowOverride: !!(account.groups?.[chatId]?.allowFrom ||\n (threadId && account.groups?.[chatId]?.topics?.[String(threadId)]?.allowFrom)),\n effectiveGroupAllow: effectiveAllowFrom,\n senderId,\n senderUsername,\n });\n\n if (!baseAccess.allowed) {\n log.debug({ accountId, chatId, reason: baseAccess.reason }, 'Message blocked by base access');\n return;\n }\n\n const botEarly = accountManager.getBot(accountId);\n const botTokenEarly = account.botToken;\n const accountApiRootEarly = account.apiRoot?.replace(/\\/$/, '') || 'https://api.telegram.org';\n\n let voiceProbeText = '';\n if (\n isGroup &&\n message.voice &&\n botEarly &&\n botTokenEarly &&\n sttService.isSTTAvailable(config?.tools?.media?.audio)\n ) {\n voiceProbeText = await downloadAndTranscribeTelegramVoice({\n voice: message.voice,\n bot: botEarly,\n botToken: botTokenEarly,\n accountApiRoot: accountApiRootEarly,\n sttService,\n sttConfig: config?.tools?.media?.audio,\n });\n }\n\n if (isGroup) {\n const requireMention = accessControl.resolveRequireMention({\n topicConfig: threadId ? account.groups?.[chatId]?.topics?.[String(threadId)] : undefined,\n groupConfig: account.groups?.[chatId],\n defaultRequireMention: true,\n });\n\n const hasMedia = !!(message.photo || message.document || message.video || message.audio || message.voice);\n const captionEntities = (message as any).caption_entities;\n const voiceMention = voiceProbeText.trim();\n const hasMention =\n accessControl.hasBotMention({ botUsername, text: content, entities: message.entities }) ||\n (hasMedia &&\n accessControl.hasBotMention({\n botUsername,\n text: message.caption ?? '',\n entities: captionEntities,\n })) ||\n (voiceMention.length > 0 &&\n (accessControl.hasBotMention({ botUsername, text: voiceMention }) ||\n checkMentionInTranscription(voiceMention, [botUsername])));\n\n if (requireMention && !hasMention) {\n const isVoiceOnly =\n !!message.voice &&\n !message.photo &&\n !message.document &&\n !message.video &&\n !message.audio &&\n !(message.caption ?? '').trim() &&\n !content.trim();\n\n if (isVoiceOnly) {\n log.debug({ accountId, chatId }, 'Group voice without mention after STT probe, ignored');\n return;\n }\n\n if (!hasMedia || content.trim().length > 0) {\n log.debug({ accountId, chatId }, 'Group message without mention ignored');\n return;\n }\n log.debug({ accountId, chatId }, 'Group media message without mention - processing anyway');\n }\n }\n\n const cleanContent = isGroup ? accessControl.removeBotMention(content, botUsername) : content;\n\n // Generate session key\n const sessionKey = sessionKeyService.generateSessionKey({\n source: 'telegram',\n chatId,\n senderId,\n isGroup,\n threadId: threadId ? String(threadId) : undefined,\n accountId,\n });\n\n // Collect and process media\n const media = extractMediaItems(message);\n const bot = accountManager.getBot(accountId);\n const botToken = account.botToken;\n\n let attachments: ProcessedAttachment[] = [];\n let transcribedText = '';\n\n if (bot && botToken && media.length > 0) {\n const accountApiRoot = account.apiRoot?.replace(/\\/$/, '') || 'https://api.telegram.org';\n const mediaResult = await processAllMedia(\n media,\n bot,\n botToken,\n accountApiRoot,\n message,\n sttService,\n mediaUtils,\n config?.tools?.media?.audio,\n voiceProbeText || undefined,\n );\n attachments = mediaResult.attachments;\n transcribedText = mediaResult.transcribedText;\n }\n\n // Combine transcribed text with content. If the user caption is a slash command, put it first\n // so routing and logs match a normal `/cmd` message (STT prefix no longer hides the command).\n const captionIsCommand = cleanContent.trim().startsWith('/');\n const finalContent = transcribedText\n ? captionIsCommand && cleanContent\n ? cleanContent.trim() + (transcribedText ? `\\n\\n${transcribedText}` : '')\n : transcribedText + (cleanContent ? '\\n\\n' + cleanContent : '')\n : cleanContent;\n\n const isCommand = cleanContent.trim().startsWith('/');\n\n log.info({\n accountId,\n chatId,\n senderId,\n isGroup,\n sessionKey,\n contentLength: finalContent.length,\n attachmentCount: attachments.length,\n isCommand,\n }, 'Processing Telegram message');\n\n if (\n finalContent.trim().length > 0 &&\n !isCommand &&\n tryConsumeTelegramClarifyFreeText(sessionKey, finalContent.trim())\n ) {\n log.debug({ sessionKey }, 'Telegram: consumed message as clarify reply');\n return;\n }\n\n await bus.publishInbound({\n channel: 'telegram',\n sender_id: senderId,\n chat_id: chatId,\n content: finalContent,\n metadata: {\n accountId,\n sessionKey,\n senderUsername,\n messageId: String(message.message_id),\n isGroup,\n isCommand,\n threadId: threadId ? String(threadId) : undefined,\n media: media.length > 0 ? media : undefined,\n transcribedVoice: !!transcribedText || undefined,\n },\n attachments: attachments.length > 0 ? attachments : undefined,\n });\n };\n\n // Main enqueue function\n return (ctx: Context, accountId: string): Promise<void> => {\n const message = ctx.message;\n if (message) {\n const raw = message.text ?? message.caption ?? '';\n if (raw.trim() && isAbortSlashCommand(raw.trim())) {\n return processMessageInternal(ctx, accountId);\n }\n }\n\n const chatId = String(ctx.chat?.id);\n const chatKey = getChatKey(accountId, chatId);\n\n return new Promise((resolve, reject) => {\n const queue = messageQueues.get(chatKey) || [];\n queue.push({ ctx, accountId, resolve, reject });\n messageQueues.set(chatKey, queue);\n processNextMessage(chatKey);\n });\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"inbound-processor.js","names":[],"sources":["../../../../extensions/telegram/src/inbound-processor.ts"],"sourcesContent":["/**\n * Telegram Inbound Processor\n *\n * Handles inbound message processing from Telegram:\n * - Message queuing (per chat)\n * - Deduplication\n * - Access control\n * - Media download\n * - STT transcription\n * - Event publishing to bus\n */\n\nimport type { Bot, Context } from 'grammy';\nimport type { Message } from '@grammyjs/types';\nimport type { Config } from '@xopcai/xopc/config/schema.js';\nimport type { MessageBus } from '@xopcai/xopc/infra/bus/index.js';\nimport type { TelegramAccountManager } from './account-manager.js';\nimport { telegramUpdateDedupe, buildTelegramUpdateKey } from './dedupe.js';\nimport { createLogger } from '@xopcai/xopc/utils/logger.js';\nimport { normalizeTelegramCommandName, parseSlashCommand } from '@xopcai/xopc/chat-commands/command-parse.js';\nimport { tryConsumeTelegramClarifyFreeText } from '@xopcai/xopc/gateway/clarify-runtime.js';\nimport { resolveRoute } from '@xopcai/xopc/routing/index.js';\nimport { resolveTelegramGroupContext } from './group-config-resolver.js';\nimport { resolveTelegramFocusedSessionKey } from './focus-handler.js';\nimport { buildTelegramConversationId } from './conversation-id.js';\nimport { checkMentionInTranscription } from '@xopcai/xopc/voice/stt/index.js';\n\nconst log = createLogger('TelegramInboundProcessor');\n\n/** Must bypass the per-chat queue so /abort can cancel an in-flight turn. */\nfunction isAbortSlashCommand(text: string): boolean {\n const parsed = parseSlashCommand(text);\n if (!parsed) return false;\n const cmd = normalizeTelegramCommandName(parsed.command);\n return cmd === 'abort' || cmd === 'stop' || cmd === 'cancel';\n}\n\n/** Maximum voice message duration for STT in seconds */\nconst STT_MAX_VOICE_DURATION_SECONDS = 60;\n\n// =============================================================================\n// External Service Interfaces (for dependency injection)\n// =============================================================================\n\nexport interface AccessControlService {\n normalizeAllowFromWithStore(options: { allowFrom?: Array<string | number> }): unknown;\n evaluateGroupBaseAccess(options: {\n isGroup: boolean;\n groupConfig?: unknown;\n topicConfig?: unknown;\n hasGroupAllowOverride: boolean;\n effectiveGroupAllow: unknown;\n senderId?: string;\n senderUsername?: string;\n }): { allowed: boolean; reason?: string };\n resolveRequireMention(options: {\n topicConfig?: unknown;\n groupConfig?: unknown;\n defaultRequireMention?: boolean;\n }): boolean;\n hasBotMention(options: { botUsername: string; text?: string; entities?: unknown }): boolean;\n removeBotMention(text: string, botUsername: string): string;\n}\n\nexport interface SessionKeyService {\n generateSessionKey(options: {\n source: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n threadId?: string;\n accountId?: string;\n agentId?: string;\n }): string;\n}\n\nexport interface STTService {\n transcribe(buffer: Buffer, config: unknown, options?: { language?: string }): Promise<{ text: string }>;\n isSTTAvailable(config: unknown): boolean;\n}\n\nexport interface MediaUtils {\n getMimeType(type: string, filePath?: string): string;\n}\n\n// =============================================================================\n// Dependencies Interface\n// =============================================================================\n\nexport interface InboundProcessorDeps {\n bus: MessageBus;\n config: Config;\n accountManager: TelegramAccountManager;\n // External services (injected for testability)\n accessControl: AccessControlService;\n sessionKeyService: SessionKeyService;\n sttService: STTService;\n mediaUtils: MediaUtils;\n}\n\ninterface QueuedMessage {\n ctx: Context;\n accountId: string;\n resolve: () => void;\n reject: (err: Error) => void;\n}\n\n// =============================================================================\n// Media Processing Types\n// =============================================================================\n\ninterface MediaItem {\n type: string;\n fileId: string;\n emoji?: string;\n}\n\ninterface ProcessedAttachment {\n type: string;\n mimeType: string;\n data: string;\n name?: string;\n size?: number;\n}\n\n// =============================================================================\n// Helper Functions (reduce nesting in main processor)\n// =============================================================================\n\n/**\n * Extract media items from message\n */\nfunction extractMediaItems(message: Message): MediaItem[] {\n const media: MediaItem[] = [];\n \n if (message.photo?.length) {\n media.push({ type: 'photo', fileId: message.photo[message.photo.length - 1].file_id });\n }\n if (message.document) {\n media.push({ type: 'document', fileId: message.document.file_id });\n }\n if (message.video) {\n media.push({ type: 'video', fileId: message.video.file_id });\n }\n if (message.audio) {\n media.push({ type: 'audio', fileId: message.audio.file_id });\n }\n if (message.voice) {\n media.push({ type: 'voice', fileId: message.voice.file_id });\n }\n if (message.sticker) {\n media.push({ type: 'sticker', fileId: message.sticker.file_id, emoji: message.sticker.emoji });\n }\n\n return media;\n}\n\n/**\n * Download + STT a Telegram voice message (for mention probe or media pipeline).\n */\nasync function downloadAndTranscribeTelegramVoice(params: {\n voice: NonNullable<Message['voice']>;\n bot: Bot;\n botToken: string;\n accountApiRoot: string;\n sttService: STTService;\n sttConfig: unknown;\n}): Promise<string> {\n const { voice, bot, botToken, accountApiRoot, sttService, sttConfig } = params;\n const voiceDuration = voice.duration || 0;\n if (voiceDuration > STT_MAX_VOICE_DURATION_SECONDS) {\n return '';\n }\n if (!sttService.isSTTAvailable(sttConfig)) {\n return '';\n }\n try {\n const file = await bot.api.getFile(voice.file_id);\n const downloadUrl = `${accountApiRoot}/file/bot${botToken}/${file.file_path}`;\n const response = await fetch(downloadUrl);\n if (!response.ok) {\n return '';\n }\n const buffer = Buffer.from(await response.arrayBuffer());\n if (buffer.length === 0) {\n return '';\n }\n const sttResult = await sttService.transcribe(buffer, sttConfig, {\n language: (sttConfig as { provider?: string })?.provider === 'alibaba' ? 'zh' : undefined,\n });\n return sttResult.text?.trim() ?? '';\n } catch {\n return '';\n }\n}\n\n/**\n * Process a single media item (download + optional STT)\n */\nasync function processMediaItem(\n item: MediaItem,\n bot: Bot,\n botToken: string,\n accountApiRoot: string,\n message: Message,\n sttService: STTService,\n mediaUtils: MediaUtils,\n sttConfig: unknown,\n reuseVoiceTranscript?: string,\n): Promise<{ attachment: ProcessedAttachment | null; transcribedText: string }> {\n try {\n const file = await bot.api.getFile(item.fileId);\n const downloadUrl = `${accountApiRoot}/file/bot${botToken}/${file.file_path}`;\n const response = await fetch(downloadUrl);\n\n // Debug log for media download\n log.info({\n type: item.type,\n fileId: item.fileId,\n downloadUrl,\n responseStatus: response.status,\n }, 'Media download response');\n\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.status}`);\n }\n\n const buffer = await response.arrayBuffer();\n\n // Debug log for buffer size\n log.info({\n type: item.type,\n fileId: item.fileId,\n bufferSize: buffer.byteLength,\n filePath: file.file_path,\n }, 'Media buffer downloaded');\n\n if (buffer.byteLength === 0) {\n log.warn({\n type: item.type,\n fileId: item.fileId,\n filePath: file.file_path,\n }, 'Media buffer is empty, may cause issues');\n }\n let transcribedText = '';\n\n // Handle voice messages with STT\n if (item.type === 'voice' && sttService.isSTTAvailable(sttConfig)) {\n if (reuseVoiceTranscript !== undefined && reuseVoiceTranscript !== '') {\n transcribedText = reuseVoiceTranscript;\n } else {\n const voiceDuration = message.voice?.duration || 0;\n if (voiceDuration <= STT_MAX_VOICE_DURATION_SECONDS) {\n try {\n const sttResult = await sttService.transcribe(Buffer.from(buffer), sttConfig, {\n language: (sttConfig as { provider?: string })?.provider === 'alibaba' ? 'zh' : undefined,\n });\n transcribedText = sttResult.text;\n } catch (sttError) {\n log.error({ sttError }, 'STT transcription failed');\n transcribedText = '[STT failed]';\n }\n } else {\n transcribedText = `[Voice message too long (>${STT_MAX_VOICE_DURATION_SECONDS}s)]`;\n }\n }\n }\n\n const base64 = Buffer.from(buffer).toString('base64');\n const mimeType = mediaUtils.getMimeType(item.type, file.file_path);\n\n // Debug log for attachment creation\n log.info({\n type: item.type,\n mimeType,\n base64Length: base64.length,\n size: buffer.byteLength,\n name: file.file_path?.split('/').pop(),\n }, 'Attachment created');\n\n return {\n attachment: {\n type: item.type,\n mimeType,\n data: base64,\n name: file.file_path?.split('/').pop(),\n size: buffer.byteLength,\n },\n transcribedText,\n };\n } catch (err) {\n log.error({ type: item.type, fileId: item.fileId, err }, 'Failed to download media');\n return { attachment: null, transcribedText: '' };\n }\n}\n\n/**\n * Process all media items\n */\nasync function processAllMedia(\n media: MediaItem[],\n bot: Bot,\n botToken: string,\n accountApiRoot: string,\n message: Message,\n sttService: STTService,\n mediaUtils: MediaUtils,\n sttConfig: unknown,\n reuseVoiceTranscript?: string,\n): Promise<{ attachments: ProcessedAttachment[]; transcribedText: string }> {\n const attachments: ProcessedAttachment[] = [];\n let transcribedText = '';\n let voiceReuseConsumed = false;\n\n for (const item of media) {\n const reuse =\n item.type === 'voice' && reuseVoiceTranscript && !voiceReuseConsumed\n ? reuseVoiceTranscript\n : undefined;\n if (reuse) {\n voiceReuseConsumed = true;\n }\n const result = await processMediaItem(\n item,\n bot,\n botToken,\n accountApiRoot,\n message,\n sttService,\n mediaUtils,\n sttConfig,\n reuse,\n );\n \n if (result.attachment) {\n attachments.push(result.attachment);\n }\n if (result.transcribedText) {\n transcribedText = result.transcribedText;\n }\n }\n\n return { attachments, transcribedText };\n}\n\n// =============================================================================\n// Main Processor Factory\n// =============================================================================\n\n/**\n * Create inbound message processor\n */\nexport function createInboundProcessor(deps: InboundProcessorDeps) {\n const {\n bus,\n config,\n accountManager,\n accessControl,\n sessionKeyService,\n sttService,\n mediaUtils,\n } = deps;\n\n const messageQueues = new Map<string, QueuedMessage[]>();\n const processingLocks = new Map<string, Promise<void>>();\n\n const getChatKey = (accountId: string, chatId: string): string => `${accountId}:${chatId}`;\n\n const processNextMessage = async (chatKey: string): Promise<void> => {\n if (processingLocks.has(chatKey)) return;\n\n const queue = messageQueues.get(chatKey);\n if (!queue || queue.length === 0) return;\n\n let lockResolve: () => void;\n const lockPromise = new Promise<void>((resolve) => {\n lockResolve = resolve;\n });\n processingLocks.set(chatKey, lockPromise);\n\n const { ctx, accountId, resolve, reject } = queue.shift()!;\n\n try {\n await processMessageInternal(ctx, accountId);\n resolve();\n } catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)));\n } finally {\n lockResolve?.();\n processingLocks.delete(chatKey);\n if (queue.length > 0) {\n processNextMessage(chatKey);\n } else {\n messageQueues.delete(chatKey);\n }\n }\n };\n\n const processMessageInternal = async (ctx: Context, accountId: string) => {\n // Deduplication check\n const updateKey = buildTelegramUpdateKey(ctx);\n if (updateKey && telegramUpdateDedupe.checkAndAdd(updateKey)) {\n log.debug({ updateKey, accountId }, 'Duplicate update detected, skipping');\n return;\n }\n\n const account = accountManager.getAccount(accountId);\n if (!account) {\n log.warn({ accountId }, 'Account not found for message processing');\n return;\n }\n\n const botUsername = accountManager.getBotUsername(accountId);\n if (!botUsername) {\n log.warn({ accountId }, 'Bot username not available');\n return;\n }\n\n const message = ctx.message ?? ctx.channelPost;\n if (!message) return;\n\n const chatId = String(ctx.chat?.id);\n const senderId = String(ctx.from?.id);\n const senderUsername = ctx.from?.username;\n const content = message.text ?? message.caption ?? '';\n const isGroup = ctx.chat?.type === 'group' || ctx.chat?.type === 'supergroup';\n const threadId = (message as { message_thread_id?: number }).message_thread_id;\n\n // Access control (group/topic allowlists, mention gating)\n const effectiveAllowFrom = accessControl.normalizeAllowFromWithStore({\n allowFrom: isGroup ? account.groupAllowFrom : account.allowFrom,\n });\n\n const baseAccess = accessControl.evaluateGroupBaseAccess({\n isGroup,\n groupConfig: account.groups?.[chatId],\n topicConfig: threadId ? account.groups?.[chatId]?.topics?.[String(threadId)] : undefined,\n hasGroupAllowOverride: !!(account.groups?.[chatId]?.allowFrom ||\n (threadId && account.groups?.[chatId]?.topics?.[String(threadId)]?.allowFrom)),\n effectiveGroupAllow: effectiveAllowFrom,\n senderId,\n senderUsername,\n });\n\n if (!baseAccess.allowed) {\n log.debug({ accountId, chatId, reason: baseAccess.reason }, 'Message blocked by base access');\n return;\n }\n\n const botEarly = accountManager.getBot(accountId);\n const botTokenEarly = account.botToken;\n const accountApiRootEarly = account.apiRoot?.replace(/\\/$/, '') || 'https://api.telegram.org';\n\n let voiceProbeText = '';\n if (\n isGroup &&\n message.voice &&\n botEarly &&\n botTokenEarly &&\n sttService.isSTTAvailable(config?.tools?.media?.audio)\n ) {\n voiceProbeText = await downloadAndTranscribeTelegramVoice({\n voice: message.voice,\n bot: botEarly,\n botToken: botTokenEarly,\n accountApiRoot: accountApiRootEarly,\n sttService,\n sttConfig: config?.tools?.media?.audio,\n });\n }\n\n if (isGroup) {\n const requireMention = accessControl.resolveRequireMention({\n topicConfig: threadId ? account.groups?.[chatId]?.topics?.[String(threadId)] : undefined,\n groupConfig: account.groups?.[chatId],\n defaultRequireMention: true,\n });\n\n const hasMedia = !!(message.photo || message.document || message.video || message.audio || message.voice);\n const captionEntities = (message as any).caption_entities;\n const voiceMention = voiceProbeText.trim();\n const hasMention =\n accessControl.hasBotMention({ botUsername, text: content, entities: message.entities }) ||\n (hasMedia &&\n accessControl.hasBotMention({\n botUsername,\n text: message.caption ?? '',\n entities: captionEntities,\n })) ||\n (voiceMention.length > 0 &&\n (accessControl.hasBotMention({ botUsername, text: voiceMention }) ||\n checkMentionInTranscription(voiceMention, [botUsername])));\n\n if (requireMention && !hasMention) {\n const isVoiceOnly =\n !!message.voice &&\n !message.photo &&\n !message.document &&\n !message.video &&\n !message.audio &&\n !(message.caption ?? '').trim() &&\n !content.trim();\n\n if (isVoiceOnly) {\n log.debug({ accountId, chatId }, 'Group voice without mention after STT probe, ignored');\n return;\n }\n\n if (!hasMedia || content.trim().length > 0) {\n log.debug({ accountId, chatId }, 'Group message without mention ignored');\n return;\n }\n log.debug({ accountId, chatId }, 'Group media message without mention - processing anyway');\n }\n }\n\n const cleanContent = isGroup ? accessControl.removeBotMention(content, botUsername) : content;\n\n const groupCtx = resolveTelegramGroupContext({ account, chatId, threadId });\n const route = resolveRoute({\n config,\n channel: 'telegram',\n accountId,\n peerKind: isGroup ? 'group' : 'dm',\n peerId: isGroup ? chatId : senderId,\n threadId: threadId ? String(threadId) : null,\n });\n const routedAgentId = groupCtx.agentId ?? route.agentId;\n\n const defaultSessionKey = sessionKeyService.generateSessionKey({\n source: 'telegram',\n chatId,\n senderId,\n isGroup,\n threadId: threadId ? String(threadId) : undefined,\n accountId,\n agentId: routedAgentId,\n });\n\n const sessionKey = resolveTelegramFocusedSessionKey({\n chatId,\n threadId: threadId ? String(threadId) : undefined,\n defaultSessionKey,\n });\n\n const conversationId = buildTelegramConversationId(chatId, threadId);\n\n // Collect and process media\n const media = extractMediaItems(message);\n const bot = accountManager.getBot(accountId);\n const botToken = account.botToken;\n\n let attachments: ProcessedAttachment[] = [];\n let transcribedText = '';\n\n if (bot && botToken && media.length > 0) {\n const accountApiRoot = account.apiRoot?.replace(/\\/$/, '') || 'https://api.telegram.org';\n const mediaResult = await processAllMedia(\n media,\n bot,\n botToken,\n accountApiRoot,\n message,\n sttService,\n mediaUtils,\n config?.tools?.media?.audio,\n voiceProbeText || undefined,\n );\n attachments = mediaResult.attachments;\n transcribedText = mediaResult.transcribedText;\n }\n\n // Combine transcribed text with content. If the user caption is a slash command, put it first\n // so routing and logs match a normal `/cmd` message (STT prefix no longer hides the command).\n const captionIsCommand = cleanContent.trim().startsWith('/');\n let finalContent = transcribedText\n ? captionIsCommand && cleanContent\n ? cleanContent.trim() + (transcribedText ? `\\n\\n${transcribedText}` : '')\n : transcribedText + (cleanContent ? '\\n\\n' + cleanContent : '')\n : cleanContent;\n\n const stickerItem = media.find((m) => m.type === 'sticker');\n if (stickerItem && !finalContent.trim()) {\n finalContent = stickerItem.emoji?.trim()\n ? `[Sticker ${stickerItem.emoji}]`\n : '[Sticker]';\n }\n\n const isCommand = cleanContent.trim().startsWith('/');\n\n log.info({\n accountId,\n chatId,\n senderId,\n isGroup,\n sessionKey,\n contentLength: finalContent.length,\n attachmentCount: attachments.length,\n isCommand,\n }, 'Processing Telegram message');\n\n if (\n finalContent.trim().length > 0 &&\n !isCommand &&\n tryConsumeTelegramClarifyFreeText(sessionKey, finalContent.trim())\n ) {\n log.debug({ sessionKey }, 'Telegram: consumed message as clarify reply');\n return;\n }\n\n await bus.publishInbound({\n channel: 'telegram',\n sender_id: senderId,\n chat_id: chatId,\n content: finalContent,\n metadata: {\n accountId,\n sessionKey,\n senderUsername,\n messageId: String(message.message_id),\n isGroup,\n isCommand,\n threadId: threadId ? String(threadId) : undefined,\n conversationId,\n channelSystemPrompt: groupCtx.systemPrompt,\n channelAgentId: routedAgentId,\n media: media.length > 0 ? media : undefined,\n transcribedVoice: !!transcribedText || undefined,\n },\n attachments: attachments.length > 0 ? attachments : undefined,\n });\n };\n\n // Main enqueue function\n return (ctx: Context, accountId: string): Promise<void> => {\n const message = ctx.message;\n if (message) {\n const raw = message.text ?? message.caption ?? '';\n if (raw.trim() && isAbortSlashCommand(raw.trim())) {\n return processMessageInternal(ctx, accountId);\n }\n }\n\n const chatId = String(ctx.chat?.id);\n const chatKey = getChatKey(accountId, chatId);\n\n return new Promise((resolve, reject) => {\n const queue = messageQueues.get(chatKey) || [];\n queue.push({ ctx, accountId, resolve, reject });\n messageQueues.set(chatKey, queue);\n processNextMessage(chatKey);\n });\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region extensions/telegram/src/network-errors.ts
|
|
2
|
+
const RECOVERABLE_NETWORK_RE = /ETIMEDOUT|ENETUNREACH|EHOSTUNREACH|ECONNRESET|ECONNREFUSED|ENOTFOUND|EAI_AGAIN|socket hang up|fetch failed|network/i;
|
|
3
|
+
function isRecoverableTelegramNetworkError(err) {
|
|
4
|
+
const text = extractErrorText(err);
|
|
5
|
+
return RECOVERABLE_NETWORK_RE.test(text);
|
|
6
|
+
}
|
|
7
|
+
function isTelegramClientRejection(err) {
|
|
8
|
+
const text = extractErrorText(err);
|
|
9
|
+
return /400:|403:|429:|Bad Request|Forbidden|Too Many Requests/i.test(text);
|
|
10
|
+
}
|
|
11
|
+
function extractErrorText(err) {
|
|
12
|
+
if (typeof err === "string") return err;
|
|
13
|
+
if (err instanceof Error) return err.message;
|
|
14
|
+
if (err && typeof err === "object" && "description" in err) {
|
|
15
|
+
const d = err.description;
|
|
16
|
+
return typeof d === "string" ? d : "";
|
|
17
|
+
}
|
|
18
|
+
return String(err);
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { isRecoverableTelegramNetworkError, isTelegramClientRejection };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=network-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-errors.js","names":[],"sources":["../../../../extensions/telegram/src/network-errors.ts"],"sourcesContent":["const RECOVERABLE_NETWORK_RE =\n /ETIMEDOUT|ENETUNREACH|EHOSTUNREACH|ECONNRESET|ECONNREFUSED|ENOTFOUND|EAI_AGAIN|socket hang up|fetch failed|network/i;\n\nexport function isRecoverableTelegramNetworkError(err: unknown): boolean {\n const text = extractErrorText(err);\n return RECOVERABLE_NETWORK_RE.test(text);\n}\n\nexport function isTelegramClientRejection(err: unknown): boolean {\n const text = extractErrorText(err);\n return /400:|403:|429:|Bad Request|Forbidden|Too Many Requests/i.test(text);\n}\n\nfunction extractErrorText(err: unknown): string {\n if (typeof err === 'string') return err;\n if (err instanceof Error) return err.message;\n if (err && typeof err === 'object' && 'description' in err) {\n const d = (err as { description?: unknown }).description;\n return typeof d === 'string' ? d : '';\n }\n return String(err);\n}\n"],"mappings":";AAAA,MAAM,yBACJ;AAEF,SAAgB,kCAAkC,KAAuB;CACvE,MAAM,OAAO,iBAAiB,IAAI;AAClC,QAAO,uBAAuB,KAAK,KAAK;;AAG1C,SAAgB,0BAA0B,KAAuB;CAC/D,MAAM,OAAO,iBAAiB,IAAI;AAClC,QAAO,0DAA0D,KAAK,KAAK;;AAG7E,SAAS,iBAAiB,KAAsB;AAC9C,KAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,KAAI,eAAe,MAAO,QAAO,IAAI;AACrC,KAAI,OAAO,OAAO,QAAQ,YAAY,iBAAiB,KAAK;EAC1D,MAAM,IAAK,IAAkC;AAC7C,SAAO,OAAO,MAAM,WAAW,IAAI;;AAErC,QAAO,OAAO,IAAI"}
|
|
@@ -8,6 +8,7 @@ import type { Config } from '@xopcai/xopc/config/index.js';
|
|
|
8
8
|
import type { ChannelPlugin, ChannelPluginDefaults, ChannelPluginInitOptions, ChannelPluginReloadMeta, ChannelPluginStartOptions, ChannelOutboundAdapter, ChannelGatewayAdapter, ChannelStreamingAdapter, ChannelCommandAdapter } from '@xopcai/xopc/channels/plugin-types.js';
|
|
9
9
|
import type { TelegramResolvedAccount } from './adapters/index.js';
|
|
10
10
|
import type { ChannelCronDeliveryAdapter } from '@xopcai/xopc/channels/plugins/types.adapters.js';
|
|
11
|
+
import { handleTelegramChannelAction } from './actions/message-actions.js';
|
|
11
12
|
export type { TelegramResolvedAccount as TelegramAccount } from './channel.js';
|
|
12
13
|
export declare class TelegramChannelPlugin implements ChannelPlugin<TelegramResolvedAccount> {
|
|
13
14
|
readonly id: "telegram";
|
|
@@ -37,6 +38,11 @@ export declare class TelegramChannelPlugin implements ChannelPlugin<TelegramReso
|
|
|
37
38
|
readonly cronDelivery: ChannelCronDeliveryAdapter;
|
|
38
39
|
readonly configSurface: import("@xopcai/xopc/channels/plugins/types.adapters.js").ChannelConfigSurfaceAdapter;
|
|
39
40
|
readonly onboard: import("@xopcai/xopc/channels/plugins/types.adapters.js").ChannelOnboardAdapter;
|
|
41
|
+
readonly doctor: {
|
|
42
|
+
check: (params: {
|
|
43
|
+
cfg: Config;
|
|
44
|
+
}) => Promise<import("@xopcai/xopc/channels/plugin-types.js").ChannelDoctorCheckResult[]>;
|
|
45
|
+
};
|
|
40
46
|
readonly pairing: import("@xopcai/xopc/channels/plugins/types.adapters.js").ChannelPairingAdapter;
|
|
41
47
|
private bus;
|
|
42
48
|
private cfg;
|
|
@@ -48,6 +54,11 @@ export declare class TelegramChannelPlugin implements ChannelPlugin<TelegramReso
|
|
|
48
54
|
private sessionModelHooks?;
|
|
49
55
|
/** Unregister fn for the workflow-progress capability registered against the global broker. */
|
|
50
56
|
private workflowProgressUnregister;
|
|
57
|
+
private inboundCoalescer;
|
|
58
|
+
private execApprovalUnregister;
|
|
59
|
+
readonly actions: {
|
|
60
|
+
handleAction: typeof handleTelegramChannelAction;
|
|
61
|
+
};
|
|
51
62
|
config: import('@xopcai/xopc/channels/plugin-types.js').ChannelConfigAdapter<TelegramResolvedAccount>;
|
|
52
63
|
security: import('@xopcai/xopc/channels/plugin-types.js').ChannelSecurityAdapter<TelegramResolvedAccount>;
|
|
53
64
|
status: import('@xopcai/xopc/channels/plugin-types.js').ChannelStatusAdapter<TelegramResolvedAccount>;
|