@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
|
@@ -12,6 +12,7 @@ export { createWebSearchTool, createWebFetchTool } from './web.js';
|
|
|
12
12
|
export { createWebExtractTool, stripHtmlBoilerplate, DEFAULT_WEB_EXTRACT_MAX_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, } from './web-extract.js';
|
|
13
13
|
export { createMessageTool } from './communication.js';
|
|
14
14
|
export { createSendMediaTool } from './send-media.js';
|
|
15
|
+
export { createReadMediaTool } from './media-read-tool.js';
|
|
15
16
|
export { createCreateShareTool, isShareToolAvailable, type CreateShareToolDeps, } from './create-share-tool.js';
|
|
16
17
|
export { createTodoTool, TodoStore, type TodoItem, type TodoStatus } from './todo-tool.js';
|
|
17
18
|
export { createSessionStatusTool } from './session-status-tool.js';
|
|
@@ -14,6 +14,7 @@ import { createWebFetchTool, createWebSearchTool } from "./web.js";
|
|
|
14
14
|
import { DEFAULT_WEB_EXTRACT_MAX_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, createWebExtractTool, stripHtmlBoilerplate } from "./web-extract.js";
|
|
15
15
|
import { createMessageTool } from "./communication.js";
|
|
16
16
|
import { createSendMediaTool } from "./send-media.js";
|
|
17
|
+
import { createReadMediaTool } from "./media-read-tool.js";
|
|
17
18
|
import { createCreateShareTool, isShareToolAvailable } from "./create-share-tool.js";
|
|
18
19
|
import { TodoStore, createTodoTool } from "./todo-tool.js";
|
|
19
20
|
import { createSessionStatusTool } from "./session-status-tool.js";
|
|
@@ -31,4 +32,4 @@ import { createSkillManageTool } from "./skill-manage-tool.js";
|
|
|
31
32
|
import { resolveImageModelConfigForTool } from "../image/tool-model-config.js";
|
|
32
33
|
import { createImageTool } from "./image-tool.js";
|
|
33
34
|
import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
|
|
34
|
-
export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, assertBrowserUrlAllowed, buildSandboxToolMap, createClarifyTool, createCreateShareTool, createCronjobTool, createCuratedMemoryTool, createDelegateTool, createDreamingTool, createEditFileTool, createExecuteCodeTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createShellTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, editFileTool, findTool, formatSize, fuzzyFindText, generateDiffString, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, restoreLineEndings, scanCronPrompt, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
|
|
35
|
+
export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, assertBrowserUrlAllowed, buildSandboxToolMap, createClarifyTool, createCreateShareTool, createCronjobTool, createCuratedMemoryTool, createDelegateTool, createDreamingTool, createEditFileTool, createExecuteCodeTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createShellTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, editFileTool, findTool, formatSize, fuzzyFindText, generateDiffString, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, restoreLineEndings, scanCronPrompt, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { mimeTypeFromMediaPath } from "../../media/store.js";
|
|
2
|
+
import { readMediaReference } from "../../media/media-reference.js";
|
|
3
|
+
import { Type } from "@sinclair/typebox";
|
|
4
|
+
//#region src/agent/tools/media-read-tool.ts
|
|
5
|
+
const DEFAULT_MAX_BYTES = 1024 * 1024;
|
|
6
|
+
const HARD_MAX_BYTES = 5 * 1024 * 1024;
|
|
7
|
+
const ReadMediaSchema = Type.Object({
|
|
8
|
+
uri: Type.String({ description: "The media:// URI from an xopc-media-uri line in the user message." }),
|
|
9
|
+
maxBytes: Type.Optional(Type.Number({ description: "Maximum bytes to read, capped at 5 MiB." }))
|
|
10
|
+
});
|
|
11
|
+
function isLikelyText(mimeType) {
|
|
12
|
+
return mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/xml" || mimeType === "application/javascript" || mimeType === "application/typescript";
|
|
13
|
+
}
|
|
14
|
+
function clampMaxBytes(raw) {
|
|
15
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return DEFAULT_MAX_BYTES;
|
|
16
|
+
return Math.min(Math.floor(raw), HARD_MAX_BYTES);
|
|
17
|
+
}
|
|
18
|
+
function createReadMediaTool() {
|
|
19
|
+
return {
|
|
20
|
+
name: "read_media",
|
|
21
|
+
label: "Read Media Attachment",
|
|
22
|
+
description: "Read an attachment by media:// URI. Use this for xopc-media-uri attachments in user messages.",
|
|
23
|
+
parameters: ReadMediaSchema,
|
|
24
|
+
async execute(_toolCallId, params, _signal) {
|
|
25
|
+
const uri = typeof params.uri === "string" ? params.uri.trim() : "";
|
|
26
|
+
if (!uri) return {
|
|
27
|
+
content: [{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: "Missing media URI."
|
|
30
|
+
}],
|
|
31
|
+
details: {
|
|
32
|
+
ok: false,
|
|
33
|
+
error: "missing_uri"
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
try {
|
|
37
|
+
const { buffer, path } = await readMediaReference(uri, clampMaxBytes(params.maxBytes));
|
|
38
|
+
const mimeType = mimeTypeFromMediaPath(path);
|
|
39
|
+
const metadata = {
|
|
40
|
+
ok: true,
|
|
41
|
+
uri,
|
|
42
|
+
mimeType,
|
|
43
|
+
size: buffer.byteLength,
|
|
44
|
+
path
|
|
45
|
+
};
|
|
46
|
+
if (isLikelyText(mimeType)) return {
|
|
47
|
+
content: [{
|
|
48
|
+
type: "text",
|
|
49
|
+
text: buffer.toString("utf8")
|
|
50
|
+
}],
|
|
51
|
+
details: {
|
|
52
|
+
...metadata,
|
|
53
|
+
kind: "text"
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
content: [{
|
|
58
|
+
type: "text",
|
|
59
|
+
text: JSON.stringify({
|
|
60
|
+
...metadata,
|
|
61
|
+
kind: "binary",
|
|
62
|
+
base64: buffer.toString("base64")
|
|
63
|
+
}, null, 2)
|
|
64
|
+
}],
|
|
65
|
+
details: {
|
|
66
|
+
...metadata,
|
|
67
|
+
kind: "binary"
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
} catch (err) {
|
|
71
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
72
|
+
return {
|
|
73
|
+
content: [{
|
|
74
|
+
type: "text",
|
|
75
|
+
text: `Media read error: ${message}`
|
|
76
|
+
}],
|
|
77
|
+
details: {
|
|
78
|
+
ok: false,
|
|
79
|
+
error: message
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { createReadMediaTool };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=media-read-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-read-tool.js","names":[],"sources":["../../../../src/agent/tools/media-read-tool.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\n\nimport { readMediaReference } from '../../media/media-reference.js';\nimport { mimeTypeFromMediaPath } from '../../media/store.js';\n\nconst DEFAULT_MAX_BYTES = 1024 * 1024;\nconst HARD_MAX_BYTES = 5 * 1024 * 1024;\n\nconst ReadMediaSchema = Type.Object({\n uri: Type.String({\n description: 'The media:// URI from an xopc-media-uri line in the user message.',\n }),\n maxBytes: Type.Optional(Type.Number({\n description: 'Maximum bytes to read, capped at 5 MiB.',\n })),\n});\n\nfunction isLikelyText(mimeType: string): boolean {\n return (\n mimeType.startsWith('text/') ||\n mimeType === 'application/json' ||\n mimeType === 'application/xml' ||\n mimeType === 'application/javascript' ||\n mimeType === 'application/typescript'\n );\n}\n\nfunction clampMaxBytes(raw: unknown): number {\n if (typeof raw !== 'number' || !Number.isFinite(raw) || raw <= 0) {\n return DEFAULT_MAX_BYTES;\n }\n return Math.min(Math.floor(raw), HARD_MAX_BYTES);\n}\n\nexport function createReadMediaTool(): AgentTool {\n return {\n name: 'read_media',\n label: 'Read Media Attachment',\n description:\n 'Read an attachment by media:// URI. Use this for xopc-media-uri attachments in user messages.',\n parameters: ReadMediaSchema,\n\n async execute(\n _toolCallId: string,\n params: { uri?: string; maxBytes?: number },\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<Record<string, unknown>>> {\n const uri = typeof params.uri === 'string' ? params.uri.trim() : '';\n if (!uri) {\n return {\n content: [{ type: 'text', text: 'Missing media URI.' }],\n details: { ok: false, error: 'missing_uri' },\n };\n }\n\n try {\n const maxBytes = clampMaxBytes(params.maxBytes);\n const { buffer, path } = await readMediaReference(uri, maxBytes);\n const mimeType = mimeTypeFromMediaPath(path);\n const metadata = {\n ok: true,\n uri,\n mimeType,\n size: buffer.byteLength,\n path,\n };\n\n if (isLikelyText(mimeType)) {\n const text = buffer.toString('utf8');\n return {\n content: [{ type: 'text', text }],\n details: { ...metadata, kind: 'text' },\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n ...metadata,\n kind: 'binary',\n base64: buffer.toString('base64'),\n }, null, 2),\n },\n ],\n details: { ...metadata, kind: 'binary' },\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: 'text', text: `Media read error: ${message}` }],\n details: { ok: false, error: message },\n };\n }\n },\n } as AgentTool;\n}\n"],"mappings":";;;;AAMA,MAAM,oBAAoB,OAAO;AACjC,MAAM,iBAAiB,IAAI,OAAO;AAElC,MAAM,kBAAkB,KAAK,OAAO;CAClC,KAAK,KAAK,OAAO,EACf,aAAa,qEACd,CAAC;CACF,UAAU,KAAK,SAAS,KAAK,OAAO,EAClC,aAAa,2CACd,CAAC,CAAC;CACJ,CAAC;AAEF,SAAS,aAAa,UAA2B;AAC/C,QACE,SAAS,WAAW,QAAQ,IAC5B,aAAa,sBACb,aAAa,qBACb,aAAa,4BACb,aAAa;;AAIjB,SAAS,cAAc,KAAsB;AAC3C,KAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,SAAS,IAAI,IAAI,OAAO,EAC7D,QAAO;AAET,QAAO,KAAK,IAAI,KAAK,MAAM,IAAI,EAAE,eAAe;;AAGlD,SAAgB,sBAAiC;AAC/C,QAAO;EACL,MAAM;EACN,OAAO;EACP,aACE;EACF,YAAY;EAEZ,MAAM,QACJ,aACA,QACA,SACmD;GACnD,MAAM,MAAM,OAAO,OAAO,QAAQ,WAAW,OAAO,IAAI,MAAM,GAAG;AACjE,OAAI,CAAC,IACH,QAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAsB,CAAC;IACvD,SAAS;KAAE,IAAI;KAAO,OAAO;KAAe;IAC7C;AAGH,OAAI;IAEF,MAAM,EAAE,QAAQ,SAAS,MAAM,mBAAmB,KADjC,cAAc,OAAO,SACyB,CAAC;IAChE,MAAM,WAAW,sBAAsB,KAAK;IAC5C,MAAM,WAAW;KACf,IAAI;KACJ;KACA;KACA,MAAM,OAAO;KACb;KACD;AAED,QAAI,aAAa,SAAS,CAExB,QAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAFf,OAAO,SAAS,OAEG;MAAE,CAAC;KACjC,SAAS;MAAE,GAAG;MAAU,MAAM;MAAQ;KACvC;AAGH,WAAO;KACL,SAAS,CACP;MACE,MAAM;MACN,MAAM,KAAK,UAAU;OACnB,GAAG;OACH,MAAM;OACN,QAAQ,OAAO,SAAS,SAAS;OAClC,EAAE,MAAM,EAAE;MACZ,CACF;KACD,SAAS;MAAE,GAAG;MAAU,MAAM;MAAU;KACzC;YACM,KAAK;IACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAChE,WAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,qBAAqB;MAAW,CAAC;KACjE,SAAS;MAAE,IAAI;MAAO,OAAO;MAAS;KACvC;;;EAGN"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/channels/attachments/attachment-classifiers.ts
|
|
2
|
+
function isImageInboundAttachment(att) {
|
|
3
|
+
return att.type === "image" || att.type === "photo" || att.mimeType?.startsWith("image/") === true;
|
|
4
|
+
}
|
|
5
|
+
function isVoiceInboundAttachment(att) {
|
|
6
|
+
return att.type === "voice" || att.type === "audio" || att.mimeType?.startsWith("audio/") === true;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { isImageInboundAttachment, isVoiceInboundAttachment };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=attachment-classifiers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-classifiers.js","names":[],"sources":["../../../../src/channels/attachments/attachment-classifiers.ts"],"sourcesContent":["export function isImageInboundAttachment(att: {\n type?: string;\n mimeType?: string;\n}): boolean {\n return (\n att.type === 'image' ||\n att.type === 'photo' ||\n att.mimeType?.startsWith('image/') === true\n );\n}\n\nexport function isVoiceInboundAttachment(att: { type?: string; mimeType?: string }): boolean {\n return (\n att.type === 'voice' ||\n att.type === 'audio' ||\n att.mimeType?.startsWith('audio/') === true\n );\n}\n"],"mappings":";AAAA,SAAgB,yBAAyB,KAG7B;AACV,QACE,IAAI,SAAS,WACb,IAAI,SAAS,WACb,IAAI,UAAU,WAAW,SAAS,KAAK;;AAI3C,SAAgB,yBAAyB,KAAoD;AAC3F,QACE,IAAI,SAAS,WACb,IAAI,SAAS,WACb,IAAI,UAAU,WAAW,SAAS,KAAK"}
|
|
@@ -1,39 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Persist inbound
|
|
3
|
-
* workspace stays user-visible; session transcripts reference stable relative paths.
|
|
2
|
+
* Persist inbound uploads to the global media store (`{stateDir}/media/inbound/`).
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
data?: string;
|
|
11
|
-
name?: string;
|
|
12
|
-
size?: number;
|
|
13
|
-
/** Set after persist (relative to agent home). */
|
|
14
|
-
workspaceRelativePath?: string;
|
|
15
|
-
}
|
|
16
|
-
export type InternalAttachmentRoots = {
|
|
17
|
-
/** `…/agents/<id>/` — primary storage */
|
|
18
|
-
agentHome: string;
|
|
19
|
-
};
|
|
20
|
-
/** Decode base64 or data-URL payload for inbound attachments (also used by voice STT). */
|
|
4
|
+
import type { InboundAttachmentInput, MediaRef } from '../../media/types.js';
|
|
5
|
+
export type { InboundAttachmentInput, MediaRef } from '../../media/types.js';
|
|
6
|
+
export { isImageInboundAttachment, isVoiceInboundAttachment } from './attachment-classifiers.js';
|
|
7
|
+
export { toMediaRef, mediaRefFromUri } from './inbound-types.js';
|
|
8
|
+
/** Decode base64 or data-URL payload (composer wire + voice STT). */
|
|
21
9
|
export declare function decodeInboundAttachmentBase64(data: string): Buffer;
|
|
22
10
|
/**
|
|
23
|
-
* Write
|
|
24
|
-
* of each attachment with `workspaceRelativePath` set (POSIX-style, `/` separators).
|
|
11
|
+
* Write attachments with binary `data` to the media store; returns metadata-only refs.
|
|
25
12
|
*/
|
|
26
|
-
export declare function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
*/
|
|
30
|
-
export declare function
|
|
31
|
-
|
|
32
|
-
* Remove inbound file transcript blocks from a string (e.g. auto session titles).
|
|
33
|
-
* Matches Web UI `stripInboundFileMachineText`, plus bare `[File: …]` lines when paths are absent.
|
|
34
|
-
*/
|
|
35
|
-
export declare function stripInboundFileMetadataFromText(text: string): string;
|
|
36
|
-
/**
|
|
37
|
-
* Resolve a stored relative path under `inbound/`.
|
|
38
|
-
*/
|
|
39
|
-
export declare function resolveSafeInboundFilePath(roots: InternalAttachmentRoots, relRaw: string): string | null;
|
|
13
|
+
export declare function persistInboundAttachments(attachments: InboundAttachmentInput[] | undefined, opts?: {
|
|
14
|
+
maxBytes?: number;
|
|
15
|
+
}): Promise<MediaRef[] | undefined>;
|
|
16
|
+
/** Read attachment bytes by media URI (voice STT, tools). */
|
|
17
|
+
export declare function readInboundAttachmentBuffer(uri: string): Promise<Buffer>;
|
|
18
|
+
export declare function assertMediaUri(uri: string): void;
|
|
@@ -1,125 +1,57 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { parseMediaUri } from "../../media/uri.js";
|
|
4
|
+
import { saveMediaBuffer } from "../../media/store.js";
|
|
5
|
+
import { readMediaReference, resolveMediaReference } from "../../media/media-reference.js";
|
|
6
|
+
import { isImageInboundAttachment, isVoiceInboundAttachment } from "./attachment-classifiers.js";
|
|
7
|
+
import { mediaRefFromUri, toMediaRef } from "./inbound-types.js";
|
|
6
8
|
//#region src/channels/attachments/inbound-persist.ts
|
|
7
|
-
/**
|
|
8
|
-
* Persist inbound channel / Web UI uploads under the agent home dir so the markdown
|
|
9
|
-
* workspace stays user-visible; session transcripts reference stable relative paths.
|
|
10
|
-
*/
|
|
11
9
|
init_logger();
|
|
12
10
|
const log = createLogger("InboundPersist");
|
|
13
|
-
/**
|
|
14
|
-
const INBOUND_REL_ROOT = "inbound";
|
|
15
|
-
function sanitizeSessionSegment(sessionKey) {
|
|
16
|
-
return sessionKey.replace(/[^a-zA-Z0-9_.-]+/g, "_").slice(0, 180) || "session";
|
|
17
|
-
}
|
|
18
|
-
function sanitizeFilename(name) {
|
|
19
|
-
return (name.replace(/[/\\?%*:|"<>]/g, "_").trim() || "file").slice(0, 200);
|
|
20
|
-
}
|
|
21
|
-
function isImageAttachment(att) {
|
|
22
|
-
return att.type === "image" || att.type === "photo" || att.mimeType?.startsWith("image/") === true;
|
|
23
|
-
}
|
|
24
|
-
/** Decode base64 or data-URL payload for inbound attachments (also used by voice STT). */
|
|
11
|
+
/** Decode base64 or data-URL payload (composer wire + voice STT). */
|
|
25
12
|
function decodeInboundAttachmentBase64(data) {
|
|
26
13
|
const trimmed = data.trim();
|
|
27
14
|
const b64 = trimmed.startsWith("data:") ? trimmed.split(/base64,/)[1] ?? trimmed : trimmed;
|
|
28
15
|
return Buffer.from(b64.replace(/\s/g, ""), "base64");
|
|
29
16
|
}
|
|
30
|
-
function resolveUnderRoot(root, rel, requiredPrefix) {
|
|
31
|
-
const normalized = rel.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
32
|
-
if (normalized.includes("..") || !normalized.startsWith(requiredPrefix)) return null;
|
|
33
|
-
const abs = resolve(root, ...normalized.split("/"));
|
|
34
|
-
const rootResolved = resolve(root);
|
|
35
|
-
if (!abs.startsWith(rootResolved)) return null;
|
|
36
|
-
return abs;
|
|
37
|
-
}
|
|
38
17
|
/**
|
|
39
|
-
* Write
|
|
40
|
-
* of each attachment with `workspaceRelativePath` set (POSIX-style, `/` separators).
|
|
18
|
+
* Write attachments with binary `data` to the media store; returns metadata-only refs.
|
|
41
19
|
*/
|
|
42
|
-
async function
|
|
43
|
-
if (!attachments?.length) return
|
|
44
|
-
const
|
|
45
|
-
const inboundAbs = resolve(agentHomeRoot, INBOUND_REL_ROOT, sessionSeg);
|
|
46
|
-
await mkdir(inboundAbs, { recursive: true });
|
|
20
|
+
async function persistInboundAttachments(attachments, opts) {
|
|
21
|
+
if (!attachments?.length) return void 0;
|
|
22
|
+
const maxBytes = opts?.maxBytes ?? 5242880;
|
|
47
23
|
const out = [];
|
|
48
24
|
for (const att of attachments) {
|
|
49
|
-
if (att.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
if (isImageAttachment(att)) {
|
|
54
|
-
out.push({ ...att });
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
if (!att.data || att.data.length === 0) {
|
|
58
|
-
out.push({ ...att });
|
|
25
|
+
if (att.uri?.trim()) {
|
|
26
|
+
const resolved = await resolveMediaReference(att.uri.trim());
|
|
27
|
+
out.push(mediaRefFromUri(att, resolved.uri, resolved.path, resolved.bucket, resolved.id));
|
|
59
28
|
continue;
|
|
60
29
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}, "Inbound file persisted");
|
|
75
|
-
out.push({
|
|
76
|
-
...att,
|
|
77
|
-
workspaceRelativePath,
|
|
78
|
-
size: att.size ?? buf.length
|
|
79
|
-
});
|
|
80
|
-
} catch (err) {
|
|
81
|
-
log.warn({
|
|
82
|
-
err,
|
|
83
|
-
sessionKey,
|
|
84
|
-
name: att.name
|
|
85
|
-
}, "Failed to persist inbound attachment");
|
|
86
|
-
out.push({ ...att });
|
|
87
|
-
}
|
|
30
|
+
if (!att.data || att.data.length === 0) throw new Error(`Inbound attachment "${att.name ?? "file"}" is missing data and uri`);
|
|
31
|
+
const saved = await saveMediaBuffer(decodeInboundAttachmentBase64(att.data), {
|
|
32
|
+
contentType: att.mimeType,
|
|
33
|
+
bucket: "inbound",
|
|
34
|
+
maxBytes,
|
|
35
|
+
originalFilename: att.name
|
|
36
|
+
});
|
|
37
|
+
log.debug({
|
|
38
|
+
uri: saved.uri,
|
|
39
|
+
bytes: saved.size,
|
|
40
|
+
name: att.name
|
|
41
|
+
}, "Inbound attachment persisted");
|
|
42
|
+
out.push(toMediaRef(att, saved));
|
|
88
43
|
}
|
|
89
|
-
return out;
|
|
44
|
+
return out.length ? out : void 0;
|
|
90
45
|
}
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const head = `[File: ${att.name || "unknown"} (${att.mimeType || "unknown type"}, ${att.size ?? 0} bytes)]`;
|
|
96
|
-
if (!att.workspaceRelativePath) return head;
|
|
97
|
-
const rel = att.workspaceRelativePath.replace(/\\/g, "/");
|
|
98
|
-
return `${head}\nxopc-path:rel:${rel}\nxopc-path:abs:${resolve(storageRootAbs, ...rel.split("/").filter(Boolean))}`;
|
|
46
|
+
/** Read attachment bytes by media URI (voice STT, tools). */
|
|
47
|
+
async function readInboundAttachmentBuffer(uri) {
|
|
48
|
+
const { buffer } = await readMediaReference(uri);
|
|
49
|
+
return buffer;
|
|
99
50
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
* Matches Web UI `stripInboundFileMachineText`, plus bare `[File: …]` lines when paths are absent.
|
|
103
|
-
*/
|
|
104
|
-
function stripInboundFileMetadataFromText(text) {
|
|
105
|
-
if (!text.includes("[File:") && !text.includes("xopc-path:")) return text;
|
|
106
|
-
let out = text;
|
|
107
|
-
out = out.replace(/\s*\[File:[^\]]+\]\s*\r?\nxopc-path:rel:[^\r\n]+\r?\n\s*xopc-path:abs:[^\r\n]+/g, "");
|
|
108
|
-
out = out.replace(/\s*\[File:[^\]]+\]\s+xopc-path:rel:\S+\s+xopc-path:abs:\S+/g, "");
|
|
109
|
-
out = out.replace(/\s*\[File:[^\]]+\]\s*xopc-path:rel:\S+\s*xopc-path:abs:\S+/g, "");
|
|
110
|
-
out = out.replace(/\s*\[File:[^\]]+\]\s*/g, " ");
|
|
111
|
-
return out.replace(/\n{3,}/g, "\n\n").replace(/\s{2,}/g, " ").trim();
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Resolve a stored relative path under `inbound/`.
|
|
115
|
-
*/
|
|
116
|
-
function resolveSafeInboundFilePath(roots, relRaw) {
|
|
117
|
-
const rel = relRaw.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
118
|
-
if (rel.includes("..")) return null;
|
|
119
|
-
if (rel.startsWith(`inbound/`)) return resolveUnderRoot(roots.agentHome, rel, `${INBOUND_REL_ROOT}/`);
|
|
120
|
-
return null;
|
|
51
|
+
function assertMediaUri(uri) {
|
|
52
|
+
parseMediaUri(uri);
|
|
121
53
|
}
|
|
122
54
|
//#endregion
|
|
123
|
-
export {
|
|
55
|
+
export { assertMediaUri, decodeInboundAttachmentBase64, isImageInboundAttachment, isVoiceInboundAttachment, mediaRefFromUri, persistInboundAttachments, readInboundAttachmentBuffer, toMediaRef };
|
|
124
56
|
|
|
125
57
|
//# sourceMappingURL=inbound-persist.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbound-persist.js","names":[],"sources":["../../../../src/channels/attachments/inbound-persist.ts"],"sourcesContent":["/**\n * Persist inbound
|
|
1
|
+
{"version":3,"file":"inbound-persist.js","names":[],"sources":["../../../../src/channels/attachments/inbound-persist.ts"],"sourcesContent":["/**\n * Persist inbound uploads to the global media store (`{stateDir}/media/inbound/`).\n */\n\nimport { createLogger } from '../../utils/logger.js';\nimport {\n MEDIA_MAX_BYTES,\n parseMediaUri,\n readMediaReference,\n resolveMediaReference,\n saveMediaBuffer,\n} from '../../media/index.js';\nimport type { InboundAttachmentInput, MediaRef } from '../../media/types.js';\nimport { mediaRefFromUri, toMediaRef } from './inbound-types.js';\n\nconst log = createLogger('InboundPersist');\n\nexport type { InboundAttachmentInput, MediaRef } from '../../media/types.js';\nexport { isImageInboundAttachment, isVoiceInboundAttachment } from './attachment-classifiers.js';\nexport { toMediaRef, mediaRefFromUri } from './inbound-types.js';\n\n/** Decode base64 or data-URL payload (composer wire + voice STT). */\nexport function decodeInboundAttachmentBase64(data: string): Buffer {\n const trimmed = data.trim();\n const b64 = trimmed.startsWith('data:') ? (trimmed.split(/base64,/)[1] ?? trimmed) : trimmed;\n return Buffer.from(b64.replace(/\\s/g, ''), 'base64');\n}\n\n/**\n * Write attachments with binary `data` to the media store; returns metadata-only refs.\n */\nexport async function persistInboundAttachments(\n attachments: InboundAttachmentInput[] | undefined,\n opts?: { maxBytes?: number },\n): Promise<MediaRef[] | undefined> {\n if (!attachments?.length) return undefined;\n\n const maxBytes = opts?.maxBytes ?? MEDIA_MAX_BYTES;\n const out: MediaRef[] = [];\n\n for (const att of attachments) {\n if (att.uri?.trim()) {\n const resolved = await resolveMediaReference(att.uri.trim());\n out.push(\n mediaRefFromUri(att, resolved.uri, resolved.path, resolved.bucket, resolved.id),\n );\n continue;\n }\n\n if (!att.data || att.data.length === 0) {\n throw new Error(`Inbound attachment \"${att.name ?? 'file'}\" is missing data and uri`);\n }\n\n const buf = decodeInboundAttachmentBase64(att.data);\n const saved = await saveMediaBuffer(buf, {\n contentType: att.mimeType,\n bucket: 'inbound',\n maxBytes,\n originalFilename: att.name,\n });\n\n log.debug({ uri: saved.uri, bytes: saved.size, name: att.name }, 'Inbound attachment persisted');\n\n out.push(toMediaRef(att, saved));\n }\n\n return out.length ? out : undefined;\n}\n\n/** Read attachment bytes by media URI (voice STT, tools). */\nexport async function readInboundAttachmentBuffer(uri: string): Promise<Buffer> {\n const { buffer } = await readMediaReference(uri);\n return buffer;\n}\n\nexport function assertMediaUri(uri: string): void {\n parseMediaUri(uri);\n}\n"],"mappings":";;;;;;;;aAIqD;AAWrD,MAAM,MAAM,aAAa,iBAAiB;;AAO1C,SAAgB,8BAA8B,MAAsB;CAClE,MAAM,UAAU,KAAK,MAAM;CAC3B,MAAM,MAAM,QAAQ,WAAW,QAAQ,GAAI,QAAQ,MAAM,UAAU,CAAC,MAAM,UAAW;AACrF,QAAO,OAAO,KAAK,IAAI,QAAQ,OAAO,GAAG,EAAE,SAAS;;;;;AAMtD,eAAsB,0BACpB,aACA,MACiC;AACjC,KAAI,CAAC,aAAa,OAAQ,QAAO,KAAA;CAEjC,MAAM,WAAW,MAAM,YAAA;CACvB,MAAM,MAAkB,EAAE;AAE1B,MAAK,MAAM,OAAO,aAAa;AAC7B,MAAI,IAAI,KAAK,MAAM,EAAE;GACnB,MAAM,WAAW,MAAM,sBAAsB,IAAI,IAAI,MAAM,CAAC;AAC5D,OAAI,KACF,gBAAgB,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,QAAQ,SAAS,GAAG,CAChF;AACD;;AAGF,MAAI,CAAC,IAAI,QAAQ,IAAI,KAAK,WAAW,EACnC,OAAM,IAAI,MAAM,uBAAuB,IAAI,QAAQ,OAAO,2BAA2B;EAIvF,MAAM,QAAQ,MAAM,gBADR,8BAA8B,IAAI,KACP,EAAE;GACvC,aAAa,IAAI;GACjB,QAAQ;GACR;GACA,kBAAkB,IAAI;GACvB,CAAC;AAEF,MAAI,MAAM;GAAE,KAAK,MAAM;GAAK,OAAO,MAAM;GAAM,MAAM,IAAI;GAAM,EAAE,+BAA+B;AAEhG,MAAI,KAAK,WAAW,KAAK,MAAM,CAAC;;AAGlC,QAAO,IAAI,SAAS,MAAM,KAAA;;;AAI5B,eAAsB,4BAA4B,KAA8B;CAC9E,MAAM,EAAE,WAAW,MAAM,mBAAmB,IAAI;AAChD,QAAO;;AAGT,SAAgB,eAAe,KAAmB;AAChD,eAAc,IAAI"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { InboundAttachmentInput, MediaRef } from '../../media/types.js';
|
|
2
|
+
import { isImageInboundAttachment, isVoiceInboundAttachment } from './attachment-classifiers.js';
|
|
3
|
+
export type { InboundAttachmentInput, MediaRef } from '../../media/types.js';
|
|
4
|
+
export { isImageInboundAttachment, isVoiceInboundAttachment };
|
|
5
|
+
export declare function toMediaRef(att: InboundAttachmentInput, saved: {
|
|
6
|
+
id: string;
|
|
7
|
+
bucket: MediaRef['bucket'];
|
|
8
|
+
uri: string;
|
|
9
|
+
path: string;
|
|
10
|
+
size: number;
|
|
11
|
+
contentType: string;
|
|
12
|
+
}): MediaRef;
|
|
13
|
+
export declare function mediaRefFromUri(att: InboundAttachmentInput, uri: string, path: string, bucket: MediaRef['bucket'], id: string): MediaRef;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { isImageInboundAttachment, isVoiceInboundAttachment } from "./attachment-classifiers.js";
|
|
2
|
+
//#region src/channels/attachments/inbound-types.ts
|
|
3
|
+
function toMediaRef(att, saved) {
|
|
4
|
+
return {
|
|
5
|
+
id: saved.id,
|
|
6
|
+
bucket: saved.bucket,
|
|
7
|
+
type: att.type,
|
|
8
|
+
mimeType: att.mimeType?.trim() || saved.contentType,
|
|
9
|
+
name: att.name?.trim() || "file",
|
|
10
|
+
size: att.size ?? saved.size,
|
|
11
|
+
uri: saved.uri,
|
|
12
|
+
path: saved.path
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function mediaRefFromUri(att, uri, path, bucket, id) {
|
|
16
|
+
return {
|
|
17
|
+
id,
|
|
18
|
+
bucket,
|
|
19
|
+
type: att.type,
|
|
20
|
+
mimeType: att.mimeType?.trim() || "application/octet-stream",
|
|
21
|
+
name: att.name?.trim() || "file",
|
|
22
|
+
size: att.size ?? 0,
|
|
23
|
+
uri,
|
|
24
|
+
path
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { isImageInboundAttachment, isVoiceInboundAttachment, mediaRefFromUri, toMediaRef };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=inbound-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbound-types.js","names":[],"sources":["../../../../src/channels/attachments/inbound-types.ts"],"sourcesContent":["import type { InboundAttachmentInput, MediaRef } from '../../media/types.js';\nimport {\n isImageInboundAttachment,\n isVoiceInboundAttachment,\n} from './attachment-classifiers.js';\n\nexport type { InboundAttachmentInput, MediaRef } from '../../media/types.js';\nexport { isImageInboundAttachment, isVoiceInboundAttachment };\n\nexport function toMediaRef(\n att: InboundAttachmentInput,\n saved: { id: string; bucket: MediaRef['bucket']; uri: string; path: string; size: number; contentType: string },\n): MediaRef {\n return {\n id: saved.id,\n bucket: saved.bucket,\n type: att.type,\n mimeType: att.mimeType?.trim() || saved.contentType,\n name: att.name?.trim() || 'file',\n size: att.size ?? saved.size,\n uri: saved.uri,\n path: saved.path,\n };\n}\n\nexport function mediaRefFromUri(\n att: InboundAttachmentInput,\n uri: string,\n path: string,\n bucket: MediaRef['bucket'],\n id: string,\n): MediaRef {\n return {\n id,\n bucket,\n type: att.type,\n mimeType: att.mimeType?.trim() || 'application/octet-stream',\n name: att.name?.trim() || 'file',\n size: att.size ?? 0,\n uri,\n path,\n };\n}\n"],"mappings":";;AASA,SAAgB,WACd,KACA,OACU;AACV,QAAO;EACL,IAAI,MAAM;EACV,QAAQ,MAAM;EACd,MAAM,IAAI;EACV,UAAU,IAAI,UAAU,MAAM,IAAI,MAAM;EACxC,MAAM,IAAI,MAAM,MAAM,IAAI;EAC1B,MAAM,IAAI,QAAQ,MAAM;EACxB,KAAK,MAAM;EACX,MAAM,MAAM;EACb;;AAGH,SAAgB,gBACd,KACA,KACA,MACA,QACA,IACU;AACV,QAAO;EACL;EACA;EACA,MAAM,IAAI;EACV,UAAU,IAAI,UAAU,MAAM,IAAI;EAClC,MAAM,IAAI,MAAM,MAAM,IAAI;EAC1B,MAAM,IAAI,QAAQ;EAClB;EACA;EACD"}
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Persist outbound TTS audio
|
|
2
|
+
* Persist outbound TTS audio to `{stateDir}/media/tts/`.
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
export declare
|
|
6
|
-
export declare function persistOutboundTtsAudio(agentHomeRoot: string, sessionKey: string, audioBuffer: Buffer, format: string): Promise<{
|
|
7
|
-
workspaceRelativePath: string;
|
|
8
|
-
name: string;
|
|
9
|
-
size: number;
|
|
10
|
-
}>;
|
|
11
|
-
/**
|
|
12
|
-
* Resolve a stored relative path under `tts/`.
|
|
13
|
-
*/
|
|
14
|
-
export declare function resolveSafeTtsFilePath(roots: InternalAttachmentRoots, relRaw: string): string | null;
|
|
4
|
+
import type { MediaRef } from '../../media/types.js';
|
|
5
|
+
export declare function persistOutboundTtsAudio(audioBuffer: Buffer, format: string): Promise<MediaRef>;
|
|
@@ -1,66 +1,46 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import {
|
|
4
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
5
|
-
import { randomBytes } from "crypto";
|
|
3
|
+
import { saveMediaBuffer } from "../../media/store.js";
|
|
6
4
|
//#region src/channels/attachments/outbound-tts-persist.ts
|
|
7
|
-
/**
|
|
8
|
-
* Persist outbound TTS audio under `<agentHome>/tts/<session>/`.
|
|
9
|
-
*/
|
|
10
5
|
init_logger();
|
|
11
6
|
const log = createLogger("OutboundTtsPersist");
|
|
12
|
-
const TTS_REL_ROOT = "tts";
|
|
13
|
-
function sanitizeSessionSegment(sessionKey) {
|
|
14
|
-
return sessionKey.replace(/[^a-zA-Z0-9_.-]+/g, "_").slice(0, 180) || "session";
|
|
15
|
-
}
|
|
16
7
|
function extForFormat(format) {
|
|
17
8
|
const f = format.toLowerCase();
|
|
18
|
-
if (f === "opus" || f === "ogg") return "ogg";
|
|
19
|
-
if (f === "mp3" || f === "mpeg") return "mp3";
|
|
20
|
-
if (f === "wav") return "wav";
|
|
21
|
-
return "bin";
|
|
9
|
+
if (f === "opus" || f === "ogg") return ".ogg";
|
|
10
|
+
if (f === "mp3" || f === "mpeg") return ".mp3";
|
|
11
|
+
if (f === "wav") return ".wav";
|
|
12
|
+
return ".bin";
|
|
22
13
|
}
|
|
23
|
-
function
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return abs;
|
|
14
|
+
function mimeForFormat(format) {
|
|
15
|
+
const f = format.toLowerCase();
|
|
16
|
+
if (f === "opus" || f === "ogg") return "audio/ogg";
|
|
17
|
+
if (f === "mp3" || f === "mpeg") return "audio/mpeg";
|
|
18
|
+
if (f === "wav") return "audio/wav";
|
|
19
|
+
return "application/octet-stream";
|
|
30
20
|
}
|
|
31
|
-
async function persistOutboundTtsAudio(
|
|
32
|
-
const sessionSeg = sanitizeSessionSegment(sessionKey);
|
|
33
|
-
const dirAbs = resolve(agentHomeRoot, "tts", sessionSeg);
|
|
34
|
-
await mkdir(dirAbs, { recursive: true });
|
|
21
|
+
async function persistOutboundTtsAudio(audioBuffer, format) {
|
|
35
22
|
const ext = extForFormat(format);
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
fname
|
|
42
|
-
].join("/");
|
|
23
|
+
const saved = await saveMediaBuffer(audioBuffer, {
|
|
24
|
+
contentType: mimeForFormat(format),
|
|
25
|
+
bucket: "tts",
|
|
26
|
+
originalFilename: `assist${ext}`
|
|
27
|
+
});
|
|
43
28
|
log.debug({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
bytes: audioBuffer.length
|
|
29
|
+
uri: saved.uri,
|
|
30
|
+
bytes: saved.size
|
|
47
31
|
}, "TTS audio persisted");
|
|
48
32
|
return {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
33
|
+
id: saved.id,
|
|
34
|
+
bucket: "tts",
|
|
35
|
+
type: "voice",
|
|
36
|
+
mimeType: saved.contentType,
|
|
37
|
+
name: saved.id,
|
|
38
|
+
size: saved.size,
|
|
39
|
+
uri: saved.uri,
|
|
40
|
+
path: saved.path
|
|
52
41
|
};
|
|
53
42
|
}
|
|
54
|
-
/**
|
|
55
|
-
* Resolve a stored relative path under `tts/`.
|
|
56
|
-
*/
|
|
57
|
-
function resolveSafeTtsFilePath(roots, relRaw) {
|
|
58
|
-
const rel = relRaw.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
59
|
-
if (rel.includes("..")) return null;
|
|
60
|
-
if (rel.startsWith(`tts/`)) return resolveUnderRoot(roots.agentHome, rel, `tts/`);
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
43
|
//#endregion
|
|
64
|
-
export {
|
|
44
|
+
export { persistOutboundTtsAudio };
|
|
65
45
|
|
|
66
46
|
//# sourceMappingURL=outbound-tts-persist.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbound-tts-persist.js","names":[],"sources":["../../../../src/channels/attachments/outbound-tts-persist.ts"],"sourcesContent":["/**\n * Persist outbound TTS audio
|
|
1
|
+
{"version":3,"file":"outbound-tts-persist.js","names":[],"sources":["../../../../src/channels/attachments/outbound-tts-persist.ts"],"sourcesContent":["/**\n * Persist outbound TTS audio to `{stateDir}/media/tts/`.\n */\n\nimport { createLogger } from '../../utils/logger.js';\nimport { saveMediaBuffer } from '../../media/index.js';\nimport type { MediaRef } from '../../media/types.js';\n\nconst log = createLogger('OutboundTtsPersist');\n\nfunction extForFormat(format: string): string {\n const f = format.toLowerCase();\n if (f === 'opus' || f === 'ogg') return '.ogg';\n if (f === 'mp3' || f === 'mpeg') return '.mp3';\n if (f === 'wav') return '.wav';\n return '.bin';\n}\n\nfunction mimeForFormat(format: string): string {\n const f = format.toLowerCase();\n if (f === 'opus' || f === 'ogg') return 'audio/ogg';\n if (f === 'mp3' || f === 'mpeg') return 'audio/mpeg';\n if (f === 'wav') return 'audio/wav';\n return 'application/octet-stream';\n}\n\nexport async function persistOutboundTtsAudio(\n audioBuffer: Buffer,\n format: string,\n): Promise<MediaRef> {\n const ext = extForFormat(format);\n const saved = await saveMediaBuffer(audioBuffer, {\n contentType: mimeForFormat(format),\n bucket: 'tts',\n originalFilename: `assist${ext}`,\n });\n\n log.debug({ uri: saved.uri, bytes: saved.size }, 'TTS audio persisted');\n\n return {\n id: saved.id,\n bucket: 'tts',\n type: 'voice',\n mimeType: saved.contentType,\n name: saved.id,\n size: saved.size,\n uri: saved.uri,\n path: saved.path,\n };\n}\n"],"mappings":";;;;aAIqD;AAIrD,MAAM,MAAM,aAAa,qBAAqB;AAE9C,SAAS,aAAa,QAAwB;CAC5C,MAAM,IAAI,OAAO,aAAa;AAC9B,KAAI,MAAM,UAAU,MAAM,MAAO,QAAO;AACxC,KAAI,MAAM,SAAS,MAAM,OAAQ,QAAO;AACxC,KAAI,MAAM,MAAO,QAAO;AACxB,QAAO;;AAGT,SAAS,cAAc,QAAwB;CAC7C,MAAM,IAAI,OAAO,aAAa;AAC9B,KAAI,MAAM,UAAU,MAAM,MAAO,QAAO;AACxC,KAAI,MAAM,SAAS,MAAM,OAAQ,QAAO;AACxC,KAAI,MAAM,MAAO,QAAO;AACxB,QAAO;;AAGT,eAAsB,wBACpB,aACA,QACmB;CACnB,MAAM,MAAM,aAAa,OAAO;CAChC,MAAM,QAAQ,MAAM,gBAAgB,aAAa;EAC/C,aAAa,cAAc,OAAO;EAClC,QAAQ;EACR,kBAAkB,SAAS;EAC5B,CAAC;AAEF,KAAI,MAAM;EAAE,KAAK,MAAM;EAAK,OAAO,MAAM;EAAM,EAAE,sBAAsB;AAEvE,QAAO;EACL,IAAI,MAAM;EACV,QAAQ;EACR,MAAM;EACN,UAAU,MAAM;EAChB,MAAM,MAAM;EACZ,MAAM,MAAM;EACZ,KAAK,MAAM;EACX,MAAM,MAAM;EACb"}
|