@xopcai/xopc 0.0.99 → 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/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 +191 -57
- 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/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/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agents-4KTK-Ku7.js → agents-C5jtBK-H.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-DkgInY2w.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-BRDli2Mm.js → cron-api-CgBO8B7I.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-BzEr5Za8.js → cron-page-Be0cW1cR.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-BsHh1vX0.js → dist-P8HRGUuh.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-TWt5q_ef.js → extension-debug-page-BowuycYu.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C3kV8ZvZ.js → extension-page-27-Zpv8O.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Csy9LNC6.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-MXbM8HvY.js → field-primitives-BWLssxEb.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-CkoyqfRx.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-B2vY41ph.js → logs-page-BDX8IrDQ.js} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-page-B7qE5pkO.js → note-detail-page-BmQ9KeiA.js} +1 -1
- package/dist/gateway/static/root/assets/{note-time-NBBReVR4.js → note-time-14I9Sgqh.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-CsWYaqYM.js → notes-page-BMfP0FFf.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-BPGY3SCT.js → sessions-page-C3scyChq.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-advanced-gate-DtA451RM.js → settings-advanced-gate-2ODuCjHP.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DYR_SPlX.js → settings-form-section-DUoGKAiW.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BJUgZQzN.js → settings-page-CttAfOWV.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-3u8VFmdo.js → share-preview-page-B77xqiiI.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-DuyhcH4U.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-B4Vw3fnc.js → utils-CCGejlcX.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-BFY67Hhp.js → voice-api-key-field-DZzzihcY.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-page.utils-yUJ5jexd.js → workflow-page.utils-D5RMAmT4.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-DIMHCpNt.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 +68 -4
- package/dist/src/agent/agent-manager.js.map +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/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/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/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/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/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 +54 -13
- 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/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 +53 -11
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/tools/factory.js +2 -0
- package/dist/src/agent/tools/factory.js.map +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/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/plugin-types.d.ts +1 -0
- package/dist/src/channels/transport-types.d.ts +2 -2
- package/dist/src/cli/commands/channels.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/flow.js +2 -0
- package/dist/src/cli/commands/doctor/flow.js.map +1 -1
- package/dist/src/cli/commands/init.js +2 -57
- 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 +1 -2
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/config/index.js +2 -2
- 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/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/cron/executor.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.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/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/sessions.js +6 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +1 -87
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.js +3 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- 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/session/session-title.js +6 -3
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/session/store.js +1 -1
- 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/storage/sqlite/index.d.ts +4 -1
- package/dist/src/storage/sqlite/index.js +6 -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 +24 -28
- 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/package.json +1 -1
- package/dist/gateway/static/root/assets/channels-settings-BxW1Xio4.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-Cxm6AvQO.js +0 -8
- package/dist/gateway/static/root/assets/index-BJDmBCSl.css +0 -1
- package/dist/gateway/static/root/assets/index-Cbg5TS5m.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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-schema.js","names":[],"sources":["../../../../extensions/telegram/src/config-schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const TelegramTopicConfigSchema = z.object({\n topicId: z.string(),\n requireMention: z.boolean().optional(),\n enabled: z.boolean().optional(),\n allowFrom: z.array(z.union([z.string(), z.number()])).optional(),\n systemPrompt: z.string().optional(),\n});\n\nexport const TelegramGroupConfigSchema = z.object({\n groupId: z.string(),\n requireMention: z.boolean().optional(),\n enabled: z.boolean().optional(),\n allowFrom: z.array(z.union([z.string(), z.number()])).optional(),\n systemPrompt: z.string().optional(),\n topics: z.record(z.string(), TelegramTopicConfigSchema).optional(),\n});\n\nexport const TelegramAccountConfigSchema = z.object({\n accountId: z.string(),\n name: z.string().optional(),\n enabled: z.boolean().default(true),\n botToken: z.string().default(''),\n tokenFile: z.string().optional(),\n allowFrom: z.array(z.union([z.string(), z.number()])).default([]),\n groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),\n dmPolicy: z.enum(['pairing', 'allowlist', 'open', 'disabled']).default('pairing'),\n groupPolicy: z.enum(['open', 'disabled', 'allowlist']).default('open'),\n replyToMode: z.enum(['off', 'first', 'all']).default('off'),\n groups: z.record(z.string(), TelegramGroupConfigSchema).optional(),\n historyLimit: z.number().default(50),\n textChunkLimit: z.number().default(4000),\n
|
|
1
|
+
{"version":3,"file":"config-schema.js","names":[],"sources":["../../../../extensions/telegram/src/config-schema.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const TelegramStreamingBlockCoalesceSchema = z.object({\n minChars: z.number().default(800),\n idleMs: z.number().default(1000),\n}).strict();\n\nexport const TelegramStreamingPreviewSchema = z.object({\n toolProgress: z.boolean().default(true),\n}).strict();\n\nexport const TelegramStreamingConfigSchema = z.object({\n mode: z.enum(['off', 'partial', 'block']).default('partial'),\n preview: TelegramStreamingPreviewSchema.optional(),\n block: z\n .object({\n coalesce: TelegramStreamingBlockCoalesceSchema.optional(),\n })\n .strict()\n .optional(),\n}).strict();\n\nexport const TelegramTopicConfigSchema = z.object({\n topicId: z.string().optional(),\n requireMention: z.boolean().optional(),\n enabled: z.boolean().optional(),\n allowFrom: z.array(z.union([z.string(), z.number()])).optional(),\n systemPrompt: z.string().optional(),\n agentId: z.string().optional(),\n}).strict();\n\nexport const TelegramGroupConfigSchema = z.object({\n groupId: z.string().optional(),\n requireMention: z.boolean().optional(),\n enabled: z.boolean().optional(),\n allowFrom: z.array(z.union([z.string(), z.number()])).optional(),\n systemPrompt: z.string().optional(),\n agentId: z.string().optional(),\n topics: z.record(z.string(), TelegramTopicConfigSchema).optional(),\n}).strict();\n\nexport const TelegramActionsConfigSchema = z.object({\n reactions: z.boolean().default(true),\n sendMessage: z.boolean().default(true),\n editMessage: z.boolean().default(true),\n deleteMessage: z.boolean().default(false),\n poll: z.boolean().default(false),\n sticker: z.boolean().default(false),\n createForumTopic: z.boolean().default(false),\n}).strict();\n\nexport const TelegramExecApprovalsConfigSchema = z.object({\n enabled: z.boolean().default(false),\n approvers: z.array(z.union([z.string(), z.number()])).optional(),\n}).strict();\n\nexport const TelegramThreadBindingsConfigSchema = z.object({\n enabled: z.boolean().default(false),\n idleTimeoutMs: z.number().optional(),\n maxAgeMs: z.number().optional(),\n}).strict();\n\nexport const TelegramAccountConfigSchema = z.object({\n accountId: z.string().optional(),\n name: z.string().optional(),\n enabled: z.boolean().default(true),\n botToken: z.string().default(''),\n tokenFile: z.string().optional(),\n allowFrom: z.array(z.union([z.string(), z.number()])).default([]),\n groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),\n dmPolicy: z.enum(['pairing', 'allowlist', 'open', 'disabled']).default('pairing'),\n groupPolicy: z.enum(['open', 'disabled', 'allowlist']).default('open'),\n replyToMode: z.enum(['off', 'first', 'all']).default('off'),\n groups: z.record(z.string(), TelegramGroupConfigSchema).optional(),\n historyLimit: z.number().default(50),\n textChunkLimit: z.number().default(4000),\n streaming: TelegramStreamingConfigSchema.optional(),\n proxy: z.string().optional(),\n apiRoot: z.string().optional(),\n pollingStallThresholdMs: z.number().min(30_000).max(600_000).optional(),\n reactionLevel: z.enum(['off', 'ack', 'minimal', 'extensive']).default('ack'),\n reactionNotifications: z.enum(['off', 'own', 'all']).default('own'),\n ackReaction: z.string().optional(),\n actions: TelegramActionsConfigSchema.optional(),\n execApprovals: TelegramExecApprovalsConfigSchema.optional(),\n threadBindings: TelegramThreadBindingsConfigSchema.optional(),\n}).strict();\n\nexport const TelegramConfigSchema = z.object({\n enabled: z.boolean().default(false),\n allowFrom: z.array(z.union([z.string(), z.number()])).default([]),\n groupAllowFrom: z.array(z.union([z.string(), z.number()])).default([]),\n apiRoot: z.string().optional(),\n debug: z.boolean().default(false),\n accounts: z.record(z.string(), TelegramAccountConfigSchema).optional(),\n dmPolicy: z.enum(['pairing', 'allowlist', 'open', 'disabled']).default('pairing'),\n groupPolicy: z.enum(['open', 'disabled', 'allowlist']).default('open'),\n replyToMode: z.enum(['off', 'first', 'all']).default('off'),\n streaming: TelegramStreamingConfigSchema.optional(),\n historyLimit: z.number().default(50),\n textChunkLimit: z.number().default(4000),\n proxy: z.string().optional(),\n}).strict();\n\nexport type TelegramConfig = z.infer<typeof TelegramConfigSchema>;\nexport type TelegramStreamingConfig = z.infer<typeof TelegramStreamingConfigSchema>;\n\n/** Resolve effective streaming mode for an account. */\nexport function resolveTelegramStreamingMode(account: {\n streaming?: { mode?: 'off' | 'partial' | 'block' };\n}): 'off' | 'partial' | 'block' {\n return account.streaming?.mode ?? 'partial';\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Canonical Telegram conversation id for forum/DM topics. */
|
|
2
|
+
export declare function buildTelegramConversationId(chatId: string, threadId?: string | number): string;
|
|
3
|
+
export declare function parseTelegramConversationId(conversationId: string): {
|
|
4
|
+
chatId: string;
|
|
5
|
+
threadId?: string;
|
|
6
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region extensions/telegram/src/conversation-id.ts
|
|
2
|
+
/** Canonical Telegram conversation id for forum/DM topics. */
|
|
3
|
+
function buildTelegramConversationId(chatId, threadId) {
|
|
4
|
+
if (threadId == null || threadId === "") return chatId;
|
|
5
|
+
return `${chatId}:topic:${threadId}`;
|
|
6
|
+
}
|
|
7
|
+
function parseTelegramConversationId(conversationId) {
|
|
8
|
+
const idx = conversationId.indexOf(":topic:");
|
|
9
|
+
if (idx === -1) return { chatId: conversationId };
|
|
10
|
+
return {
|
|
11
|
+
chatId: conversationId.slice(0, idx),
|
|
12
|
+
threadId: conversationId.slice(idx + 7)
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { buildTelegramConversationId, parseTelegramConversationId };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=conversation-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-id.js","names":[],"sources":["../../../../extensions/telegram/src/conversation-id.ts"],"sourcesContent":["/** Canonical Telegram conversation id for forum/DM topics. */\nexport function buildTelegramConversationId(chatId: string, threadId?: string | number): string {\n if (threadId == null || threadId === '') return chatId;\n return `${chatId}:topic:${threadId}`;\n}\n\nexport function parseTelegramConversationId(conversationId: string): {\n chatId: string;\n threadId?: string;\n} {\n const marker = ':topic:';\n const idx = conversationId.indexOf(marker);\n if (idx === -1) {\n return { chatId: conversationId };\n }\n return {\n chatId: conversationId.slice(0, idx),\n threadId: conversationId.slice(idx + marker.length),\n };\n}\n"],"mappings":";;AACA,SAAgB,4BAA4B,QAAgB,UAAoC;AAC9F,KAAI,YAAY,QAAQ,aAAa,GAAI,QAAO;AAChD,QAAO,GAAG,OAAO,SAAS;;AAG5B,SAAgB,4BAA4B,gBAG1C;CAEA,MAAM,MAAM,eAAe,QAAQ,UAAO;AAC1C,KAAI,QAAQ,GACV,QAAO,EAAE,QAAQ,gBAAgB;AAEnC,QAAO;EACL,QAAQ,eAAe,MAAM,GAAG,IAAI;EACpC,UAAU,eAAe,MAAM,MAAM,EAAc;EACpD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { hasTelegramBotEndpointApiRoot, normalizeTelegramApiRoot } from "./api-root.js";
|
|
2
|
+
import { resolveTelegramBotToken } from "./token-resolver.js";
|
|
3
|
+
//#region extensions/telegram/src/doctor.ts
|
|
4
|
+
function collectTokens(cfg) {
|
|
5
|
+
const map = /* @__PURE__ */ new Map();
|
|
6
|
+
const accounts = cfg.accounts ?? {};
|
|
7
|
+
for (const [id, acc] of Object.entries(accounts)) {
|
|
8
|
+
const { token } = resolveTelegramBotToken({
|
|
9
|
+
botToken: acc.botToken,
|
|
10
|
+
tokenFile: acc.tokenFile
|
|
11
|
+
});
|
|
12
|
+
if (!token) continue;
|
|
13
|
+
const list = map.get(token) ?? [];
|
|
14
|
+
list.push(id);
|
|
15
|
+
map.set(token, list);
|
|
16
|
+
}
|
|
17
|
+
return map;
|
|
18
|
+
}
|
|
19
|
+
async function runTelegramDoctorChecks(params) {
|
|
20
|
+
const results = [];
|
|
21
|
+
const tg = params.cfg.channels?.telegram;
|
|
22
|
+
if (!tg) return results;
|
|
23
|
+
if (tg.enabled && tg.dmPolicy === "open") {
|
|
24
|
+
const hasWildcard = (tg.allowFrom ?? []).some((e) => String(e).trim() === "*");
|
|
25
|
+
results.push({
|
|
26
|
+
id: "telegram-dm-open-wildcard",
|
|
27
|
+
label: "Telegram DM open policy",
|
|
28
|
+
status: hasWildcard ? "pass" : "warn",
|
|
29
|
+
message: hasWildcard ? "DM policy is open with allowFrom wildcard." : "dmPolicy \"open\" should include allowFrom: [\"*\"] for explicit opt-in.",
|
|
30
|
+
hints: hasWildcard ? [] : ["Add `\"allowFrom\": [\"*\"]` or switch to pairing/allowlist."]
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (hasTelegramBotEndpointApiRoot(tg.apiRoot)) results.push({
|
|
34
|
+
id: "telegram-api-root-bot-endpoint",
|
|
35
|
+
label: "Telegram apiRoot",
|
|
36
|
+
status: "warn",
|
|
37
|
+
message: "apiRoot includes a bot token path segment; it will be normalized to the API root.",
|
|
38
|
+
hints: [`Use "${normalizeTelegramApiRoot(tg.apiRoot)}" instead.`]
|
|
39
|
+
});
|
|
40
|
+
const tokenMap = collectTokens(tg);
|
|
41
|
+
for (const [token, accountIds] of tokenMap) if (accountIds.length > 1) results.push({
|
|
42
|
+
id: `telegram-duplicate-token-${accountIds.join("-")}`,
|
|
43
|
+
label: "Telegram duplicate bot token",
|
|
44
|
+
status: "fail",
|
|
45
|
+
message: `Bot token is shared by accounts: ${accountIds.join(", ")}.`,
|
|
46
|
+
hints: ["Use one token per account or disable duplicate accounts."]
|
|
47
|
+
});
|
|
48
|
+
for (const [id, acc] of Object.entries(tg.accounts ?? {})) {
|
|
49
|
+
if (hasTelegramBotEndpointApiRoot(acc.apiRoot)) results.push({
|
|
50
|
+
id: `telegram-account-api-root-${id}`,
|
|
51
|
+
label: `Telegram apiRoot (${id})`,
|
|
52
|
+
status: "warn",
|
|
53
|
+
message: `Account "${id}" apiRoot includes bot endpoint; will be normalized.`,
|
|
54
|
+
hints: [`Use "${normalizeTelegramApiRoot(acc.apiRoot)}"`]
|
|
55
|
+
});
|
|
56
|
+
const { token, source } = resolveTelegramBotToken({
|
|
57
|
+
botToken: acc.botToken,
|
|
58
|
+
tokenFile: acc.tokenFile
|
|
59
|
+
});
|
|
60
|
+
if (tg.enabled && acc && source === "none" && acc.enabled !== false) results.push({
|
|
61
|
+
id: `telegram-account-token-${id}`,
|
|
62
|
+
label: `Telegram token (${id})`,
|
|
63
|
+
status: "fail",
|
|
64
|
+
message: `Account "${id}" has no bot token or readable tokenFile.`,
|
|
65
|
+
hints: ["Set botToken or tokenFile in channels.telegram.accounts." + id]
|
|
66
|
+
});
|
|
67
|
+
if (token && token.length < 20) results.push({
|
|
68
|
+
id: `telegram-account-token-short-${id}`,
|
|
69
|
+
label: `Telegram token (${id})`,
|
|
70
|
+
status: "warn",
|
|
71
|
+
message: `Account "${id}" bot token looks too short.`,
|
|
72
|
+
hints: ["Verify the token from @BotFather."]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return results;
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
export { runTelegramDoctorChecks };
|
|
79
|
+
|
|
80
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","names":[],"sources":["../../../../extensions/telegram/src/doctor.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\nimport type { ChannelDoctorCheckResult } from '@xopcai/xopc/channels/plugin-types.js';\nimport { hasTelegramBotEndpointApiRoot, normalizeTelegramApiRoot } from './api-root.js';\nimport { resolveTelegramBotToken } from './token-resolver.js';\n\ntype TelegramCfg = {\n enabled?: boolean;\n dmPolicy?: string;\n allowFrom?: Array<string | number>;\n apiRoot?: string;\n accounts?: Record<\n string,\n {\n botToken?: string;\n tokenFile?: string;\n apiRoot?: string;\n dmPolicy?: string;\n allowFrom?: Array<string | number>;\n }\n >;\n};\n\nfunction collectTokens(cfg: TelegramCfg): Map<string, string[]> {\n const map = new Map<string, string[]>();\n const accounts = cfg.accounts ?? {};\n for (const [id, acc] of Object.entries(accounts)) {\n const { token } = resolveTelegramBotToken({\n botToken: acc.botToken,\n tokenFile: acc.tokenFile,\n });\n if (!token) continue;\n const list = map.get(token) ?? [];\n list.push(id);\n map.set(token, list);\n }\n return map;\n}\n\nexport async function runTelegramDoctorChecks(params: {\n cfg: Config;\n}): Promise<ChannelDoctorCheckResult[]> {\n const results: ChannelDoctorCheckResult[] = [];\n const tg = params.cfg.channels?.telegram as TelegramCfg | undefined;\n if (!tg) {\n return results;\n }\n\n if (tg.enabled && tg.dmPolicy === 'open') {\n const allow = tg.allowFrom ?? [];\n const hasWildcard = allow.some((e) => String(e).trim() === '*');\n results.push({\n id: 'telegram-dm-open-wildcard',\n label: 'Telegram DM open policy',\n status: hasWildcard ? 'pass' : 'warn',\n message: hasWildcard\n ? 'DM policy is open with allowFrom wildcard.'\n : 'dmPolicy \"open\" should include allowFrom: [\"*\"] for explicit opt-in.',\n hints: hasWildcard ? [] : ['Add `\"allowFrom\": [\"*\"]` or switch to pairing/allowlist.'],\n });\n }\n\n if (hasTelegramBotEndpointApiRoot(tg.apiRoot)) {\n results.push({\n id: 'telegram-api-root-bot-endpoint',\n label: 'Telegram apiRoot',\n status: 'warn',\n message: 'apiRoot includes a bot token path segment; it will be normalized to the API root.',\n hints: [`Use \"${normalizeTelegramApiRoot(tg.apiRoot)}\" instead.`],\n });\n }\n\n const tokenMap = collectTokens(tg);\n for (const [token, accountIds] of tokenMap) {\n if (accountIds.length > 1) {\n results.push({\n id: `telegram-duplicate-token-${accountIds.join('-')}`,\n label: 'Telegram duplicate bot token',\n status: 'fail',\n message: `Bot token is shared by accounts: ${accountIds.join(', ')}.`,\n hints: ['Use one token per account or disable duplicate accounts.'],\n });\n }\n void token;\n }\n\n for (const [id, acc] of Object.entries(tg.accounts ?? {})) {\n if (hasTelegramBotEndpointApiRoot(acc.apiRoot)) {\n results.push({\n id: `telegram-account-api-root-${id}`,\n label: `Telegram apiRoot (${id})`,\n status: 'warn',\n message: `Account \"${id}\" apiRoot includes bot endpoint; will be normalized.`,\n hints: [`Use \"${normalizeTelegramApiRoot(acc.apiRoot)}\"`],\n });\n }\n const { token, source } = resolveTelegramBotToken({\n botToken: acc.botToken,\n tokenFile: acc.tokenFile,\n });\n if (tg.enabled && acc && source === 'none' && (acc as { enabled?: boolean }).enabled !== false) {\n results.push({\n id: `telegram-account-token-${id}`,\n label: `Telegram token (${id})`,\n status: 'fail',\n message: `Account \"${id}\" has no bot token or readable tokenFile.`,\n hints: ['Set botToken or tokenFile in channels.telegram.accounts.' + id],\n });\n }\n if (token && token.length < 20) {\n results.push({\n id: `telegram-account-token-short-${id}`,\n label: `Telegram token (${id})`,\n status: 'warn',\n message: `Account \"${id}\" bot token looks too short.`,\n hints: ['Verify the token from @BotFather.'],\n });\n }\n }\n\n return results;\n}\n"],"mappings":";;;AAsBA,SAAS,cAAc,KAAyC;CAC9D,MAAM,sBAAM,IAAI,KAAuB;CACvC,MAAM,WAAW,IAAI,YAAY,EAAE;AACnC,MAAK,MAAM,CAAC,IAAI,QAAQ,OAAO,QAAQ,SAAS,EAAE;EAChD,MAAM,EAAE,UAAU,wBAAwB;GACxC,UAAU,IAAI;GACd,WAAW,IAAI;GAChB,CAAC;AACF,MAAI,CAAC,MAAO;EACZ,MAAM,OAAO,IAAI,IAAI,MAAM,IAAI,EAAE;AACjC,OAAK,KAAK,GAAG;AACb,MAAI,IAAI,OAAO,KAAK;;AAEtB,QAAO;;AAGT,eAAsB,wBAAwB,QAEN;CACtC,MAAM,UAAsC,EAAE;CAC9C,MAAM,KAAK,OAAO,IAAI,UAAU;AAChC,KAAI,CAAC,GACH,QAAO;AAGT,KAAI,GAAG,WAAW,GAAG,aAAa,QAAQ;EAExC,MAAM,eADQ,GAAG,aAAa,EAAE,EACN,MAAM,MAAM,OAAO,EAAE,CAAC,MAAM,KAAK,IAAI;AAC/D,UAAQ,KAAK;GACX,IAAI;GACJ,OAAO;GACP,QAAQ,cAAc,SAAS;GAC/B,SAAS,cACL,+CACA;GACJ,OAAO,cAAc,EAAE,GAAG,CAAC,+DAA2D;GACvF,CAAC;;AAGJ,KAAI,8BAA8B,GAAG,QAAQ,CAC3C,SAAQ,KAAK;EACX,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,CAAC,QAAQ,yBAAyB,GAAG,QAAQ,CAAC,YAAY;EAClE,CAAC;CAGJ,MAAM,WAAW,cAAc,GAAG;AAClC,MAAK,MAAM,CAAC,OAAO,eAAe,SAChC,KAAI,WAAW,SAAS,EACtB,SAAQ,KAAK;EACX,IAAI,4BAA4B,WAAW,KAAK,IAAI;EACpD,OAAO;EACP,QAAQ;EACR,SAAS,oCAAoC,WAAW,KAAK,KAAK,CAAC;EACnE,OAAO,CAAC,2DAA2D;EACpE,CAAC;AAKN,MAAK,MAAM,CAAC,IAAI,QAAQ,OAAO,QAAQ,GAAG,YAAY,EAAE,CAAC,EAAE;AACzD,MAAI,8BAA8B,IAAI,QAAQ,CAC5C,SAAQ,KAAK;GACX,IAAI,6BAA6B;GACjC,OAAO,qBAAqB,GAAG;GAC/B,QAAQ;GACR,SAAS,YAAY,GAAG;GACxB,OAAO,CAAC,QAAQ,yBAAyB,IAAI,QAAQ,CAAC,GAAG;GAC1D,CAAC;EAEJ,MAAM,EAAE,OAAO,WAAW,wBAAwB;GAChD,UAAU,IAAI;GACd,WAAW,IAAI;GAChB,CAAC;AACF,MAAI,GAAG,WAAW,OAAO,WAAW,UAAW,IAA8B,YAAY,MACvF,SAAQ,KAAK;GACX,IAAI,0BAA0B;GAC9B,OAAO,mBAAmB,GAAG;GAC7B,QAAQ;GACR,SAAS,YAAY,GAAG;GACxB,OAAO,CAAC,6DAA6D,GAAG;GACzE,CAAC;AAEJ,MAAI,SAAS,MAAM,SAAS,GAC1B,SAAQ,KAAK;GACX,IAAI,gCAAgC;GACpC,OAAO,mBAAmB,GAAG;GAC7B,QAAQ;GACR,SAAS,YAAY,GAAG;GACxB,OAAO,CAAC,oCAAoC;GAC7C,CAAC;;AAIN,QAAO"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Config } from '@xopcai/xopc/config/index.js';
|
|
2
|
+
import type { ExecApprovalHandler } from '@xopcai/xopc/channels/exec-approval-runtime.js';
|
|
3
|
+
import type { TelegramAccountManager } from './account-manager.js';
|
|
4
|
+
export declare function createTelegramExecApprovalHandler(deps: {
|
|
5
|
+
accountManager: TelegramAccountManager;
|
|
6
|
+
getConfig: () => Config;
|
|
7
|
+
}): ExecApprovalHandler;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createTelegramPendingApproval, waitForTelegramApproval } from "./approval-store.js";
|
|
2
|
+
import { isTelegramExecApprovalEnabled, resolveTelegramExecApprovers } from "./exec-approvals.js";
|
|
3
|
+
import { deliverTelegramExecApprovalPrompt } from "./approval-delivery.js";
|
|
4
|
+
//#region extensions/telegram/src/exec-approval-handler.ts
|
|
5
|
+
function createTelegramExecApprovalHandler(deps) {
|
|
6
|
+
return {
|
|
7
|
+
isEnabled(cfg, params) {
|
|
8
|
+
if (params.channel !== "telegram") return false;
|
|
9
|
+
return isTelegramExecApprovalEnabled(cfg, params.accountId ?? "default");
|
|
10
|
+
},
|
|
11
|
+
async requestApproval(cfg, payload) {
|
|
12
|
+
const accountId = payload.accountId ?? "default";
|
|
13
|
+
if (resolveTelegramExecApprovers(cfg, accountId).length === 0) return false;
|
|
14
|
+
const bot = deps.accountManager.getBot(accountId);
|
|
15
|
+
if (!bot) return false;
|
|
16
|
+
const approval = createTelegramPendingApproval({
|
|
17
|
+
accountId,
|
|
18
|
+
sessionKey: payload.sessionKey,
|
|
19
|
+
chatId: payload.chatId,
|
|
20
|
+
toolName: payload.toolName,
|
|
21
|
+
summary: payload.summary
|
|
22
|
+
});
|
|
23
|
+
await deliverTelegramExecApprovalPrompt({
|
|
24
|
+
bot,
|
|
25
|
+
cfg: deps.getConfig(),
|
|
26
|
+
accountId,
|
|
27
|
+
approval
|
|
28
|
+
});
|
|
29
|
+
return waitForTelegramApproval(approval.id);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { createTelegramExecApprovalHandler };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=exec-approval-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-approval-handler.js","names":[],"sources":["../../../../extensions/telegram/src/exec-approval-handler.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\nimport type { ExecApprovalHandler, ExecApprovalRequestPayload } from '@xopcai/xopc/channels/exec-approval-runtime.js';\nimport type { TelegramAccountManager } from './account-manager.js';\nimport {\n createTelegramPendingApproval,\n waitForTelegramApproval,\n} from './approval-store.js';\nimport { deliverTelegramExecApprovalPrompt } from './approval-delivery.js';\nimport { isTelegramExecApprovalEnabled, resolveTelegramExecApprovers } from './exec-approvals.js';\n\nexport function createTelegramExecApprovalHandler(deps: {\n accountManager: TelegramAccountManager;\n getConfig: () => Config;\n}): ExecApprovalHandler {\n return {\n isEnabled(cfg, params) {\n if (params.channel !== 'telegram') return false;\n return isTelegramExecApprovalEnabled(cfg, params.accountId ?? 'default');\n },\n\n async requestApproval(cfg, payload: ExecApprovalRequestPayload): Promise<boolean> {\n const accountId = payload.accountId ?? 'default';\n const approvers = resolveTelegramExecApprovers(cfg, accountId);\n if (approvers.length === 0) {\n return false;\n }\n\n const bot = deps.accountManager.getBot(accountId);\n if (!bot) {\n return false;\n }\n\n const approval = createTelegramPendingApproval({\n accountId,\n sessionKey: payload.sessionKey,\n chatId: payload.chatId,\n toolName: payload.toolName,\n summary: payload.summary,\n });\n\n await deliverTelegramExecApprovalPrompt({ bot, cfg: deps.getConfig(), accountId, approval });\n return waitForTelegramApproval(approval.id);\n },\n };\n}\n"],"mappings":";;;;AAUA,SAAgB,kCAAkC,MAG1B;AACtB,QAAO;EACL,UAAU,KAAK,QAAQ;AACrB,OAAI,OAAO,YAAY,WAAY,QAAO;AAC1C,UAAO,8BAA8B,KAAK,OAAO,aAAa,UAAU;;EAG1E,MAAM,gBAAgB,KAAK,SAAuD;GAChF,MAAM,YAAY,QAAQ,aAAa;AAEvC,OADkB,6BAA6B,KAAK,UACvC,CAAC,WAAW,EACvB,QAAO;GAGT,MAAM,MAAM,KAAK,eAAe,OAAO,UAAU;AACjD,OAAI,CAAC,IACH,QAAO;GAGT,MAAM,WAAW,8BAA8B;IAC7C;IACA,YAAY,QAAQ;IACpB,QAAQ,QAAQ;IAChB,UAAU,QAAQ;IAClB,SAAS,QAAQ;IAClB,CAAC;AAEF,SAAM,kCAAkC;IAAE;IAAK,KAAK,KAAK,WAAW;IAAE;IAAW;IAAU,CAAC;AAC5F,UAAO,wBAAwB,SAAS,GAAG;;EAE9C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Config } from '@xopcai/xopc/config/index.js';
|
|
2
|
+
export declare function isTelegramExecApprovalEnabled(cfg: Config, accountId?: string): boolean;
|
|
3
|
+
export declare function resolveTelegramExecApprovers(cfg: Config, accountId?: string): string[];
|
|
4
|
+
export declare function isTelegramExecApprovalApprover(params: {
|
|
5
|
+
cfg: Config;
|
|
6
|
+
accountId: string;
|
|
7
|
+
senderId: string;
|
|
8
|
+
}): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region extensions/telegram/src/exec-approvals.ts
|
|
2
|
+
function isTelegramExecApprovalEnabled(cfg, accountId = "default") {
|
|
3
|
+
return ((cfg.channels?.telegram)?.accounts?.[accountId])?.execApprovals?.enabled === true;
|
|
4
|
+
}
|
|
5
|
+
function resolveTelegramExecApprovers(cfg, accountId = "default") {
|
|
6
|
+
const tg = cfg.channels?.telegram;
|
|
7
|
+
const acc = tg?.accounts?.[accountId];
|
|
8
|
+
const explicit = acc?.execApprovals?.approvers ?? [];
|
|
9
|
+
const fallback = acc?.allowFrom ?? tg?.allowFrom ?? [];
|
|
10
|
+
return (explicit.length > 0 ? explicit : fallback).map((v) => String(v).trim()).filter((v) => v && v !== "*" && /^\d+$/.test(v.replace(/^(telegram|tg):/i, ""))).map((v) => v.replace(/^(telegram|tg):/i, ""));
|
|
11
|
+
}
|
|
12
|
+
function isTelegramExecApprovalApprover(params) {
|
|
13
|
+
const approvers = resolveTelegramExecApprovers(params.cfg, params.accountId);
|
|
14
|
+
const sid = params.senderId.replace(/^(telegram|tg):/i, "");
|
|
15
|
+
return approvers.includes(sid);
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { isTelegramExecApprovalApprover, isTelegramExecApprovalEnabled, resolveTelegramExecApprovers };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=exec-approvals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-approvals.js","names":[],"sources":["../../../../extensions/telegram/src/exec-approvals.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\n\nexport function isTelegramExecApprovalEnabled(cfg: Config, accountId = 'default'): boolean {\n const tg = cfg.channels?.telegram as\n | { accounts?: Record<string, { execApprovals?: { enabled?: boolean } }> }\n | undefined;\n const acc = tg?.accounts?.[accountId];\n return acc?.execApprovals?.enabled === true;\n}\n\nexport function resolveTelegramExecApprovers(\n cfg: Config,\n accountId = 'default',\n): string[] {\n const tg = cfg.channels?.telegram as\n | {\n allowFrom?: Array<string | number>;\n accounts?: Record<\n string,\n {\n execApprovals?: { approvers?: Array<string | number> };\n allowFrom?: Array<string | number>;\n }\n >;\n }\n | undefined;\n const acc = tg?.accounts?.[accountId];\n const explicit = acc?.execApprovals?.approvers ?? [];\n const fallback = acc?.allowFrom ?? tg?.allowFrom ?? [];\n const merged = explicit.length > 0 ? explicit : fallback;\n return merged\n .map((v) => String(v).trim())\n .filter((v) => v && v !== '*' && /^\\d+$/.test(v.replace(/^(telegram|tg):/i, '')))\n .map((v) => v.replace(/^(telegram|tg):/i, ''));\n}\n\nexport function isTelegramExecApprovalApprover(params: {\n cfg: Config;\n accountId: string;\n senderId: string;\n}): boolean {\n const approvers = resolveTelegramExecApprovers(params.cfg, params.accountId);\n const sid = params.senderId.replace(/^(telegram|tg):/i, '');\n return approvers.includes(sid);\n}\n"],"mappings":";AAEA,SAAgB,8BAA8B,KAAa,YAAY,WAAoB;AAKzF,UAJW,IAAI,UAAU,WAGT,WAAW,aACf,eAAe,YAAY;;AAGzC,SAAgB,6BACd,KACA,YAAY,WACF;CACV,MAAM,KAAK,IAAI,UAAU;CAYzB,MAAM,MAAM,IAAI,WAAW;CAC3B,MAAM,WAAW,KAAK,eAAe,aAAa,EAAE;CACpD,MAAM,WAAW,KAAK,aAAa,IAAI,aAAa,EAAE;AAEtD,SADe,SAAS,SAAS,IAAI,WAAW,UAE7C,KAAK,MAAM,OAAO,EAAE,CAAC,MAAM,CAAC,CAC5B,QAAQ,MAAM,KAAK,MAAM,OAAO,QAAQ,KAAK,EAAE,QAAQ,oBAAoB,GAAG,CAAC,CAAC,CAChF,KAAK,MAAM,EAAE,QAAQ,oBAAoB,GAAG,CAAC;;AAGlD,SAAgB,+BAA+B,QAInC;CACV,MAAM,YAAY,6BAA6B,OAAO,KAAK,OAAO,UAAU;CAC5E,MAAM,MAAM,OAAO,SAAS,QAAQ,oBAAoB,GAAG;AAC3D,QAAO,UAAU,SAAS,IAAI"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Context } from 'grammy';
|
|
2
|
+
import type { Config } from '@xopcai/xopc/config/index.js';
|
|
3
|
+
export declare function handleTelegramFocusCommand(params: {
|
|
4
|
+
ctx: Context;
|
|
5
|
+
accountId: string;
|
|
6
|
+
config: Config;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
export declare function resolveTelegramFocusedSessionKey(params: {
|
|
9
|
+
chatId: string;
|
|
10
|
+
threadId?: string;
|
|
11
|
+
defaultSessionKey: string;
|
|
12
|
+
}): string;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createLogger } from "../../../src/utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../../../src/utils/logger.js";
|
|
3
|
+
import { generateSessionKey } from "../../../src/chat-commands/session-key.js";
|
|
4
|
+
import { clearTelegramThreadBinding, getTelegramThreadBinding, setTelegramThreadBinding } from "./thread-bindings.js";
|
|
5
|
+
import { buildTelegramConversationId } from "./conversation-id.js";
|
|
6
|
+
//#region extensions/telegram/src/focus-handler.ts
|
|
7
|
+
init_logger();
|
|
8
|
+
const log = createLogger("TelegramFocus");
|
|
9
|
+
async function handleTelegramFocusCommand(params) {
|
|
10
|
+
const { ctx, accountId } = params;
|
|
11
|
+
const chatId = String(ctx.chat?.id ?? "");
|
|
12
|
+
const senderId = String(ctx.from?.id ?? "");
|
|
13
|
+
const isGroup = ctx.chat?.type === "group" || ctx.chat?.type === "supergroup";
|
|
14
|
+
const threadId = ctx.message?.message_thread_id;
|
|
15
|
+
const parts = (ctx.message?.text?.trim() ?? "").split(/\s+/);
|
|
16
|
+
const sub = parts[1]?.toLowerCase();
|
|
17
|
+
if (sub === "off" || sub === "clear") {
|
|
18
|
+
clearTelegramThreadBinding(chatId, threadId != null ? String(threadId) : void 0);
|
|
19
|
+
await ctx.reply("Thread focus cleared.");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const sessionKey = parts.length > 1 && parts[1] && !parts[1].startsWith("/") ? parts.slice(1).join(" ").trim() : generateSessionKey({
|
|
23
|
+
source: "telegram",
|
|
24
|
+
chatId,
|
|
25
|
+
senderId,
|
|
26
|
+
isGroup,
|
|
27
|
+
threadId: threadId != null ? String(threadId) : void 0,
|
|
28
|
+
accountId
|
|
29
|
+
});
|
|
30
|
+
setTelegramThreadBinding({
|
|
31
|
+
sessionKey,
|
|
32
|
+
chatId,
|
|
33
|
+
threadId: threadId != null ? String(threadId) : void 0,
|
|
34
|
+
createdAtMs: Date.now(),
|
|
35
|
+
lastActivityMs: Date.now()
|
|
36
|
+
});
|
|
37
|
+
log.info({
|
|
38
|
+
accountId,
|
|
39
|
+
chatId,
|
|
40
|
+
threadId,
|
|
41
|
+
sessionKey,
|
|
42
|
+
conversationId: buildTelegramConversationId(chatId, threadId)
|
|
43
|
+
}, "Telegram thread focus set");
|
|
44
|
+
await ctx.reply(`Focused on session:\n${sessionKey}`);
|
|
45
|
+
}
|
|
46
|
+
function resolveTelegramFocusedSessionKey(params) {
|
|
47
|
+
const binding = getTelegramThreadBinding(params.chatId, params.threadId);
|
|
48
|
+
if (!binding) return params.defaultSessionKey;
|
|
49
|
+
binding.lastActivityMs = Date.now();
|
|
50
|
+
return binding.sessionKey;
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { handleTelegramFocusCommand, resolveTelegramFocusedSessionKey };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=focus-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-handler.js","names":[],"sources":["../../../../extensions/telegram/src/focus-handler.ts"],"sourcesContent":["import type { Context } from 'grammy';\nimport type { Config } from '@xopcai/xopc/config/index.js';\nimport { generateSessionKey } from '@xopcai/xopc/chat-commands/session-key.js';\nimport { createLogger } from '@xopcai/xopc/utils/logger.js';\nimport {\n clearTelegramThreadBinding,\n getTelegramThreadBinding,\n setTelegramThreadBinding,\n} from './thread-bindings.js';\nimport { buildTelegramConversationId } from './conversation-id.js';\n\nconst log = createLogger('TelegramFocus');\n\nexport async function handleTelegramFocusCommand(params: {\n ctx: Context;\n accountId: string;\n config: Config;\n}): Promise<void> {\n const { ctx, accountId } = params;\n const chatId = String(ctx.chat?.id ?? '');\n const senderId = String(ctx.from?.id ?? '');\n const isGroup = ctx.chat?.type === 'group' || ctx.chat?.type === 'supergroup';\n const threadId = (ctx.message as { message_thread_id?: number } | undefined)?.message_thread_id;\n const text = ctx.message?.text?.trim() ?? '';\n const parts = text.split(/\\s+/);\n const sub = parts[1]?.toLowerCase();\n\n if (sub === 'off' || sub === 'clear') {\n clearTelegramThreadBinding(chatId, threadId != null ? String(threadId) : undefined);\n await ctx.reply('Thread focus cleared.');\n return;\n }\n\n const sessionKey =\n parts.length > 1 && parts[1] && !parts[1].startsWith('/')\n ? parts.slice(1).join(' ').trim()\n : generateSessionKey({\n source: 'telegram',\n chatId,\n senderId,\n isGroup,\n threadId: threadId != null ? String(threadId) : undefined,\n accountId,\n });\n\n setTelegramThreadBinding({\n sessionKey,\n chatId,\n threadId: threadId != null ? String(threadId) : undefined,\n createdAtMs: Date.now(),\n lastActivityMs: Date.now(),\n });\n\n log.info(\n { accountId, chatId, threadId, sessionKey, conversationId: buildTelegramConversationId(chatId, threadId) },\n 'Telegram thread focus set',\n );\n\n await ctx.reply(`Focused on session:\\n${sessionKey}`);\n}\n\nexport function resolveTelegramFocusedSessionKey(params: {\n chatId: string;\n threadId?: string;\n defaultSessionKey: string;\n}): string {\n const binding = getTelegramThreadBinding(params.chatId, params.threadId);\n if (!binding) {\n return params.defaultSessionKey;\n }\n binding.lastActivityMs = Date.now();\n return binding.sessionKey;\n}\n"],"mappings":";;;;;;aAG4D;AAQ5D,MAAM,MAAM,aAAa,gBAAgB;AAEzC,eAAsB,2BAA2B,QAI/B;CAChB,MAAM,EAAE,KAAK,cAAc;CAC3B,MAAM,SAAS,OAAO,IAAI,MAAM,MAAM,GAAG;CACzC,MAAM,WAAW,OAAO,IAAI,MAAM,MAAM,GAAG;CAC3C,MAAM,UAAU,IAAI,MAAM,SAAS,WAAW,IAAI,MAAM,SAAS;CACjE,MAAM,WAAY,IAAI,SAAwD;CAE9E,MAAM,SADO,IAAI,SAAS,MAAM,MAAM,IAAI,IACvB,MAAM,MAAM;CAC/B,MAAM,MAAM,MAAM,IAAI,aAAa;AAEnC,KAAI,QAAQ,SAAS,QAAQ,SAAS;AACpC,6BAA2B,QAAQ,YAAY,OAAO,OAAO,SAAS,GAAG,KAAA,EAAU;AACnF,QAAM,IAAI,MAAM,wBAAwB;AACxC;;CAGF,MAAM,aACJ,MAAM,SAAS,KAAK,MAAM,MAAM,CAAC,MAAM,GAAG,WAAW,IAAI,GACrD,MAAM,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC,MAAM,GAC/B,mBAAmB;EACjB,QAAQ;EACR;EACA;EACA;EACA,UAAU,YAAY,OAAO,OAAO,SAAS,GAAG,KAAA;EAChD;EACD,CAAC;AAER,0BAAyB;EACvB;EACA;EACA,UAAU,YAAY,OAAO,OAAO,SAAS,GAAG,KAAA;EAChD,aAAa,KAAK,KAAK;EACvB,gBAAgB,KAAK,KAAK;EAC3B,CAAC;AAEF,KAAI,KACF;EAAE;EAAW;EAAQ;EAAU;EAAY,gBAAgB,4BAA4B,QAAQ,SAAS;EAAE,EAC1G,4BACD;AAED,OAAM,IAAI,MAAM,wBAAwB,aAAa;;AAGvD,SAAgB,iCAAiC,QAItC;CACT,MAAM,UAAU,yBAAyB,OAAO,QAAQ,OAAO,SAAS;AACxE,KAAI,CAAC,QACH,QAAO,OAAO;AAEhB,SAAQ,iBAAiB,KAAK,KAAK;AACnC,QAAO,QAAQ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TelegramAccountConfig, TelegramGroupConfig, TelegramTopicConfig } from '@xopcai/xopc/channels/channel-domain.js';
|
|
2
|
+
export interface ResolvedTelegramGroupContext {
|
|
3
|
+
groupConfig?: TelegramGroupConfig;
|
|
4
|
+
topicConfig?: TelegramTopicConfig;
|
|
5
|
+
systemPrompt?: string;
|
|
6
|
+
agentId?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveTelegramGroupContext(params: {
|
|
9
|
+
account: TelegramAccountConfig;
|
|
10
|
+
chatId: string;
|
|
11
|
+
threadId?: string | number;
|
|
12
|
+
}): ResolvedTelegramGroupContext;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region extensions/telegram/src/group-config-resolver.ts
|
|
2
|
+
function resolveTelegramGroupContext(params) {
|
|
3
|
+
const chatKey = params.chatId;
|
|
4
|
+
const threadKey = params.threadId != null ? String(params.threadId) : void 0;
|
|
5
|
+
const groupConfig = params.account.groups?.[chatKey];
|
|
6
|
+
const topicConfig = threadKey ? groupConfig?.topics?.[threadKey] : void 0;
|
|
7
|
+
return {
|
|
8
|
+
groupConfig,
|
|
9
|
+
topicConfig,
|
|
10
|
+
systemPrompt: topicConfig?.systemPrompt?.trim() || groupConfig?.systemPrompt?.trim() || void 0,
|
|
11
|
+
agentId: topicConfig?.agentId?.trim() || groupConfig?.agentId?.trim() || void 0
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { resolveTelegramGroupContext };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=group-config-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-config-resolver.js","names":[],"sources":["../../../../extensions/telegram/src/group-config-resolver.ts"],"sourcesContent":["import type { TelegramAccountConfig, TelegramGroupConfig, TelegramTopicConfig } from '@xopcai/xopc/channels/channel-domain.js';\n\nexport interface ResolvedTelegramGroupContext {\n groupConfig?: TelegramGroupConfig;\n topicConfig?: TelegramTopicConfig;\n systemPrompt?: string;\n agentId?: string;\n}\n\nexport function resolveTelegramGroupContext(params: {\n account: TelegramAccountConfig;\n chatId: string;\n threadId?: string | number;\n}): ResolvedTelegramGroupContext {\n const chatKey = params.chatId;\n const threadKey = params.threadId != null ? String(params.threadId) : undefined;\n const groupConfig = params.account.groups?.[chatKey];\n const topicConfig = threadKey ? groupConfig?.topics?.[threadKey] : undefined;\n\n const systemPrompt = topicConfig?.systemPrompt?.trim() || groupConfig?.systemPrompt?.trim() || undefined;\n const agentId = topicConfig?.agentId?.trim() || groupConfig?.agentId?.trim() || undefined;\n\n return { groupConfig, topicConfig, systemPrompt, agentId };\n}\n"],"mappings":";AASA,SAAgB,4BAA4B,QAIX;CAC/B,MAAM,UAAU,OAAO;CACvB,MAAM,YAAY,OAAO,YAAY,OAAO,OAAO,OAAO,SAAS,GAAG,KAAA;CACtE,MAAM,cAAc,OAAO,QAAQ,SAAS;CAC5C,MAAM,cAAc,YAAY,aAAa,SAAS,aAAa,KAAA;AAKnE,QAAO;EAAE;EAAa;EAAa,cAHd,aAAa,cAAc,MAAM,IAAI,aAAa,cAAc,MAAM,IAAI,KAAA;EAG9C,SAFjC,aAAa,SAAS,MAAM,IAAI,aAAa,SAAS,MAAM,IAAI,KAAA;EAEtB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Context } from 'grammy';
|
|
2
|
+
import type { Message } from '@grammyjs/types';
|
|
3
|
+
export type TelegramCoalescedInbound = {
|
|
4
|
+
ctx: Context;
|
|
5
|
+
accountId: string;
|
|
6
|
+
messages: Message[];
|
|
7
|
+
};
|
|
8
|
+
export declare function createTelegramInboundCoalescer(): {
|
|
9
|
+
enqueue(params: {
|
|
10
|
+
ctx: Context;
|
|
11
|
+
accountId: string;
|
|
12
|
+
message: Message;
|
|
13
|
+
onReady: (batch: TelegramCoalescedInbound) => Promise<void>;
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
//#region extensions/telegram/src/inbound-coalescer.ts
|
|
2
|
+
const TEXT_FRAGMENT_GAP_MS = 500;
|
|
3
|
+
const MEDIA_GROUP_GAP_MS = 800;
|
|
4
|
+
const MAX_TEXT_FRAGMENTS = 12;
|
|
5
|
+
const MAX_TEXT_FRAGMENT_CHARS = 5e4;
|
|
6
|
+
function createTelegramInboundCoalescer() {
|
|
7
|
+
const textFragments = /* @__PURE__ */ new Map();
|
|
8
|
+
const mediaGroups = /* @__PURE__ */ new Map();
|
|
9
|
+
return { async enqueue(params) {
|
|
10
|
+
const { ctx, accountId, message, onReady } = params;
|
|
11
|
+
const mediaGroupId = message.media_group_id;
|
|
12
|
+
if (mediaGroupId) {
|
|
13
|
+
await enqueueMediaGroup({
|
|
14
|
+
key: `${accountId}:${ctx.chat?.id}:${mediaGroupId}`,
|
|
15
|
+
ctx,
|
|
16
|
+
accountId,
|
|
17
|
+
message,
|
|
18
|
+
onReady,
|
|
19
|
+
mediaGroups
|
|
20
|
+
});
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (message.text && message.message_id) {
|
|
24
|
+
await enqueueTextFragment({
|
|
25
|
+
key: `${accountId}:${ctx.chat?.id}:${ctx.from?.id}:${message.message_id}`,
|
|
26
|
+
ctx,
|
|
27
|
+
accountId,
|
|
28
|
+
message,
|
|
29
|
+
onReady,
|
|
30
|
+
textFragments
|
|
31
|
+
});
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
await onReady({
|
|
35
|
+
ctx,
|
|
36
|
+
accountId,
|
|
37
|
+
messages: [message]
|
|
38
|
+
});
|
|
39
|
+
} };
|
|
40
|
+
}
|
|
41
|
+
async function enqueueMediaGroup(params) {
|
|
42
|
+
const entry = params.mediaGroups.get(params.key) ?? {
|
|
43
|
+
key: params.key,
|
|
44
|
+
messages: []
|
|
45
|
+
};
|
|
46
|
+
entry.messages.push(params.message);
|
|
47
|
+
if (entry.timer) clearTimeout(entry.timer);
|
|
48
|
+
entry.timer = setTimeout(async () => {
|
|
49
|
+
params.mediaGroups.delete(params.key);
|
|
50
|
+
await params.onReady({
|
|
51
|
+
ctx: params.ctx,
|
|
52
|
+
accountId: params.accountId,
|
|
53
|
+
messages: entry.messages
|
|
54
|
+
});
|
|
55
|
+
}, MEDIA_GROUP_GAP_MS);
|
|
56
|
+
entry.timer.unref?.();
|
|
57
|
+
params.mediaGroups.set(params.key, entry);
|
|
58
|
+
}
|
|
59
|
+
async function enqueueTextFragment(params) {
|
|
60
|
+
if (!((params.message.text ?? "").length >= 3500)) {
|
|
61
|
+
await params.onReady({
|
|
62
|
+
ctx: params.ctx,
|
|
63
|
+
accountId: params.accountId,
|
|
64
|
+
messages: [params.message]
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const baseKey = `${params.accountId}:${params.ctx.chat?.id}:${params.ctx.from?.id}`;
|
|
69
|
+
const entry = [...params.textFragments.values()].find((e) => e.key.startsWith(baseKey)) ?? {
|
|
70
|
+
key: `${baseKey}:${params.message.message_id}`,
|
|
71
|
+
messages: []
|
|
72
|
+
};
|
|
73
|
+
if (entry.messages.length >= MAX_TEXT_FRAGMENTS) {
|
|
74
|
+
await flushTextFragment(entry, params);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
entry.messages.push(params.message);
|
|
78
|
+
if (entry.messages.reduce((n, m) => n + (m.text?.length ?? 0), 0) > MAX_TEXT_FRAGMENT_CHARS) {
|
|
79
|
+
await flushTextFragment(entry, params);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (entry.timer) clearTimeout(entry.timer);
|
|
83
|
+
entry.timer = setTimeout(async () => {
|
|
84
|
+
await flushTextFragment(entry, params);
|
|
85
|
+
}, TEXT_FRAGMENT_GAP_MS);
|
|
86
|
+
entry.timer.unref?.();
|
|
87
|
+
params.textFragments.set(entry.key, entry);
|
|
88
|
+
}
|
|
89
|
+
async function flushTextFragment(entry, params) {
|
|
90
|
+
params.textFragments.delete(entry.key);
|
|
91
|
+
if (entry.timer) clearTimeout(entry.timer);
|
|
92
|
+
if (entry.messages.length === 0) return;
|
|
93
|
+
const mergedText = entry.messages.map((m) => m.text ?? "").join("");
|
|
94
|
+
const merged = {
|
|
95
|
+
...entry.messages[entry.messages.length - 1],
|
|
96
|
+
text: mergedText
|
|
97
|
+
};
|
|
98
|
+
await params.onReady({
|
|
99
|
+
ctx: params.ctx,
|
|
100
|
+
accountId: params.accountId,
|
|
101
|
+
messages: [merged]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
export { createTelegramInboundCoalescer };
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=inbound-coalescer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbound-coalescer.js","names":[],"sources":["../../../../extensions/telegram/src/inbound-coalescer.ts"],"sourcesContent":["import type { Context } from 'grammy';\nimport type { Message } from '@grammyjs/types';\n\nconst TEXT_FRAGMENT_GAP_MS = 500;\nconst MEDIA_GROUP_GAP_MS = 800;\nconst MAX_TEXT_FRAGMENTS = 12;\nconst MAX_TEXT_FRAGMENT_CHARS = 50_000;\n\ntype PendingTextFragment = {\n key: string;\n messages: Message[];\n timer?: ReturnType<typeof setTimeout>;\n};\n\ntype PendingMediaGroup = {\n key: string;\n messages: Message[];\n timer?: ReturnType<typeof setTimeout>;\n};\n\nexport type TelegramCoalescedInbound = {\n ctx: Context;\n accountId: string;\n messages: Message[];\n};\n\nexport function createTelegramInboundCoalescer() {\n const textFragments = new Map<string, PendingTextFragment>();\n const mediaGroups = new Map<string, PendingMediaGroup>();\n\n return {\n async enqueue(params: {\n ctx: Context;\n accountId: string;\n message: Message;\n onReady: (batch: TelegramCoalescedInbound) => Promise<void>;\n }): Promise<void> {\n const { ctx, accountId, message, onReady } = params;\n const mediaGroupId = message.media_group_id;\n if (mediaGroupId) {\n await enqueueMediaGroup({\n key: `${accountId}:${ctx.chat?.id}:${mediaGroupId}`,\n ctx,\n accountId,\n message,\n onReady,\n mediaGroups,\n });\n return;\n }\n\n if (message.text && message.message_id) {\n await enqueueTextFragment({\n key: `${accountId}:${ctx.chat?.id}:${ctx.from?.id}:${message.message_id}`,\n ctx,\n accountId,\n message,\n onReady,\n textFragments,\n });\n return;\n }\n\n await onReady({ ctx, accountId, messages: [message] });\n },\n };\n}\n\nasync function enqueueMediaGroup(params: {\n key: string;\n ctx: Context;\n accountId: string;\n message: Message;\n onReady: (batch: TelegramCoalescedInbound) => Promise<void>;\n mediaGroups: Map<string, PendingMediaGroup>;\n}): Promise<void> {\n const existing = params.mediaGroups.get(params.key);\n const entry = existing ?? { key: params.key, messages: [] };\n entry.messages.push(params.message);\n if (entry.timer) clearTimeout(entry.timer);\n entry.timer = setTimeout(async () => {\n params.mediaGroups.delete(params.key);\n await params.onReady({\n ctx: params.ctx,\n accountId: params.accountId,\n messages: entry.messages,\n });\n }, MEDIA_GROUP_GAP_MS);\n entry.timer.unref?.();\n params.mediaGroups.set(params.key, entry);\n}\n\nasync function enqueueTextFragment(params: {\n key: string;\n ctx: Context;\n accountId: string;\n message: Message;\n onReady: (batch: TelegramCoalescedInbound) => Promise<void>;\n textFragments: Map<string, PendingTextFragment>;\n}): Promise<void> {\n const text = params.message.text ?? '';\n const isFragmentCandidate = text.length >= 3500;\n if (!isFragmentCandidate) {\n await params.onReady({ ctx: params.ctx, accountId: params.accountId, messages: [params.message] });\n return;\n }\n\n const baseKey = `${params.accountId}:${params.ctx.chat?.id}:${params.ctx.from?.id}`;\n const existing = [...params.textFragments.values()].find((e) => e.key.startsWith(baseKey));\n const entry = existing ?? { key: `${baseKey}:${params.message.message_id}`, messages: [] };\n\n if (entry.messages.length >= MAX_TEXT_FRAGMENTS) {\n await flushTextFragment(entry, params);\n return;\n }\n\n entry.messages.push(params.message);\n const combinedLen = entry.messages.reduce((n, m) => n + (m.text?.length ?? 0), 0);\n if (combinedLen > MAX_TEXT_FRAGMENT_CHARS) {\n await flushTextFragment(entry, params);\n return;\n }\n\n if (entry.timer) clearTimeout(entry.timer);\n entry.timer = setTimeout(async () => {\n await flushTextFragment(entry, params);\n }, TEXT_FRAGMENT_GAP_MS);\n entry.timer.unref?.();\n params.textFragments.set(entry.key, entry);\n}\n\nasync function flushTextFragment(\n entry: PendingTextFragment,\n params: {\n ctx: Context;\n accountId: string;\n onReady: (batch: TelegramCoalescedInbound) => Promise<void>;\n textFragments: Map<string, PendingTextFragment>;\n },\n): Promise<void> {\n params.textFragments.delete(entry.key);\n if (entry.timer) clearTimeout(entry.timer);\n if (entry.messages.length === 0) return;\n const mergedText = entry.messages.map((m) => m.text ?? '').join('');\n const base = entry.messages[entry.messages.length - 1]!;\n const merged: Message = { ...base, text: mergedText };\n await params.onReady({ ctx: params.ctx, accountId: params.accountId, messages: [merged] });\n}\n"],"mappings":"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"}
|