@xopcai/xopc 0.0.86 → 0.0.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/adapters/cli-login.js +3 -3
- package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/delivery-chat-id.d.ts +1 -1
- package/dist/extensions/telegram/src/delivery-chat-id.js +1 -1
- package/dist/extensions/telegram/src/delivery-chat-id.js.map +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +3 -2
- package/dist/extensions/telegram/src/routing-integration.js.map +1 -1
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +2 -2
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -1
- package/dist/extensions/weixin/src/api/api.js +3 -3
- package/dist/extensions/weixin/src/api/api.js.map +1 -1
- package/dist/extensions/weixin/src/auth/accounts.js +12 -12
- package/dist/extensions/weixin/src/auth/accounts.js.map +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/delivery-to.js +2 -2
- package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +5 -5
- package/dist/extensions/weixin/src/messaging/debug-mode.js.map +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +11 -11
- package/dist/extensions/weixin/src/messaging/inbound.js.map +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +4 -4
- package/dist/extensions/weixin/src/storage/sync-buf.js.map +1 -1
- package/dist/extensions/weixin/src/workflow-progress.d.ts +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js.map +1 -1
- package/dist/gateway/static/root/assets/agents-CRxETUZx.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-DrfytjOb.js → apps-page-wKWf3l57.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-Bs5kMCMI.js → channels-status-swr-DIsl75Y3.js} +1 -1
- package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +1 -0
- package/dist/gateway/static/root/assets/{cron-api-BuVcZ5zR.js → cron-api-N9hvuRrn.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-BMrloeFH.js → cron-page-tlNGNxhP.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-CKU1OOTf.js → dist-CJwfHYvT.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BdW_46sN.js → extension-debug-page-BVJohZoZ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DW47KI82.js → extension-page-BT2tmElC.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BSS47c2j.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-B2MYHbWg.js → fetch-BaFNUtkE.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-DPG-oJmx.js → field-primitives-QwYEq6Hz.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-C8dNts9i.js → heartbeat-config-api-BVSidEDJ.js} +1 -1
- package/dist/gateway/static/root/assets/index-CqZzHNEg.css +1 -0
- package/dist/gateway/static/root/assets/{index-BmVYculr.js → index-qNrVJp-y.js} +97 -95
- package/dist/gateway/static/root/assets/{logs-page-sTsVWz0X.js → logs-page-DDonPVLn.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-DuvRQW--.js → settings-form-section-B8N3A3Zo.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BtG2kLDh.js → share-preview-page-Q7KqkO-u.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DryYl3qD.js → theme-store-BbRc5ugR.js} +1 -1
- package/dist/gateway/static/root/assets/url-D6jvVYIA.js +7 -0
- package/dist/gateway/static/root/assets/{utils-BY7bU1DT.js → utils-CxDGduqK.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-CTyHz7L_.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +27 -0
- package/dist/gateway/static/root/index.html +6 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/agent-scope.d.ts +4 -0
- package/dist/src/agent/agent-scope.js +53 -10
- package/dist/src/agent/agent-scope.js.map +1 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js +2 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +15 -0
- package/dist/src/agent/child-agent-factory.js +35 -2
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/client-error-format.d.ts +20 -0
- package/dist/src/agent/client-error-format.js +97 -0
- package/dist/src/agent/client-error-format.js.map +1 -0
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/embedded/run-turn.js +23 -4
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +2 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/embedded/tool-result-truncation.js +2 -1
- package/dist/src/agent/embedded/tool-result-truncation.js.map +1 -1
- package/dist/src/agent/fallback/candidates.js +2 -2
- package/dist/src/agent/fallback/candidates.js.map +1 -1
- package/dist/src/agent/goals/goal-locale.d.ts +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-apis.d.ts +0 -2
- package/dist/src/agent/goals/persistent-goal-service.js +1 -2
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/generation/normalization.js +2 -12
- package/dist/src/agent/image/generation/normalization.js.map +1 -1
- package/dist/src/agent/image/generation/provider-registry.d.ts +4 -8
- package/dist/src/agent/image/generation/provider-registry.js.map +1 -1
- package/dist/src/agent/image/generation/runtime.d.ts +2 -2
- package/dist/src/agent/image/generation/runtime.js.map +1 -1
- package/dist/src/agent/image/generation/types.d.ts +0 -18
- package/dist/src/agent/image/image-helpers.js +6 -1
- package/dist/src/agent/image/image-helpers.js.map +1 -1
- package/dist/src/agent/image/index.d.ts +1 -1
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/inbound/inbound-loop.d.ts +5 -0
- package/dist/src/agent/inbound/inbound-loop.js +41 -10
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +4 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +7 -5
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-names.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-names.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +2 -1
- package/dist/src/agent/mcp/mcp-transport-config.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +2 -1
- package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
- package/dist/src/agent/media-generation/runtime-shared.js +2 -9
- package/dist/src/agent/media-generation/runtime-shared.js.map +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/messaging/command-handler.d.ts +6 -0
- package/dist/src/agent/messaging/command-handler.js +5 -0
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/llm-turn-retry.d.ts +2 -0
- package/dist/src/agent/orchestration/llm-turn-retry.js +9 -1
- package/dist/src/agent/orchestration/llm-turn-retry.js.map +1 -1
- package/dist/src/agent/prompt/safety.d.ts +0 -7
- package/dist/src/agent/prompt/safety.js +1 -20
- package/dist/src/agent/prompt/safety.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +3 -1
- package/dist/src/agent/service/direct-turn-helpers.js +6 -1
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
- package/dist/src/agent/service/process-direct-one-shot.d.ts +4 -0
- package/dist/src/agent/service/process-direct-one-shot.js +15 -2
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +4 -0
- package/dist/src/agent/service/process-direct-streaming.js +53 -7
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +1 -2
- package/dist/src/agent/service/webchat-tts.js +2 -2
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.d.ts +8 -0
- package/dist/src/agent/service.js +25 -5
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/create-share-tool.js +27 -20
- package/dist/src/agent/tools/create-share-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +2 -2
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/index.d.ts +0 -1
- package/dist/src/agent/tools/index.js +4 -5
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/shell.js +0 -13
- package/dist/src/agent/tools/shell.js.map +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.js +70 -16
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/agent-progress.d.ts +5 -0
- package/dist/src/agent/workflow/agent-progress.js +65 -0
- package/dist/src/agent/workflow/agent-progress.js.map +1 -0
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/audit-repo.js +14 -0
- package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.js +14 -0
- package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/implementation-plan.js +175 -0
- package/dist/src/agent/workflow/builtins/implementation-plan.js.map +1 -0
- package/dist/src/agent/workflow/builtins/index.d.ts +3 -1
- package/dist/src/agent/workflow/builtins/index.js +11 -1
- package/dist/src/agent/workflow/builtins/index.js.map +1 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js +14 -0
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.js +14 -0
- package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/release-check.d.ts +11 -0
- package/dist/src/agent/workflow/builtins/release-check.js +165 -0
- package/dist/src/agent/workflow/builtins/release-check.js.map +1 -0
- package/dist/src/agent/workflow/builtins/research.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/research.js +14 -0
- package/dist/src/agent/workflow/builtins/research.js.map +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/channel-capability.d.ts +3 -3
- package/dist/src/agent/workflow/index.d.ts +2 -1
- package/dist/src/agent/workflow/index.js +3 -2
- package/dist/src/agent/workflow/lint.d.ts +38 -0
- package/dist/src/agent/workflow/lint.js +74 -0
- package/dist/src/agent/workflow/lint.js.map +1 -0
- package/dist/src/agent/workflow/meta-locale.d.ts +12 -0
- package/dist/src/agent/workflow/meta-locale.js +62 -0
- package/dist/src/agent/workflow/meta-locale.js.map +1 -0
- package/dist/src/agent/workflow/parser.js +7 -1
- package/dist/src/agent/workflow/parser.js.map +1 -1
- package/dist/src/agent/workflow/runtime.d.ts +4 -1
- package/dist/src/agent/workflow/runtime.js +88 -8
- package/dist/src/agent/workflow/runtime.js.map +1 -1
- package/dist/src/agent/workflow/snapshot.js +2 -12
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/agent/workflow/step-labels.d.ts +8 -0
- package/dist/src/agent/workflow/step-labels.js +48 -0
- package/dist/src/agent/workflow/step-labels.js.map +1 -0
- package/dist/src/agent/workflow/subagent-runner.js +46 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +76 -1
- package/dist/src/auth/credentials.d.ts +5 -0
- package/dist/src/auth/credentials.js +12 -3
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/index.js +4 -4
- package/dist/src/browser/manager.d.ts +1 -3
- package/dist/src/browser/manager.js +0 -6
- package/dist/src/browser/manager.js.map +1 -1
- package/dist/src/browser/providers/browser-ext-install.d.ts +4 -4
- package/dist/src/browser/providers/browser-ext-install.js +41 -88
- package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.d.ts +0 -5
- package/dist/src/browser/providers/cloakbrowser.js +6 -59
- package/dist/src/browser/providers/cloakbrowser.js.map +1 -1
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/attachments/voice-stt-webchat.js +10 -8
- package/dist/src/channels/attachments/voice-stt-webchat.js.map +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +9 -9
- package/dist/src/channels/pairing/allow-from-file.js.map +1 -1
- package/dist/src/channels/pairing/pairing-store.js +7 -7
- package/dist/src/channels/pairing/pairing-store.js.map +1 -1
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/builtins/session.js +1 -1
- package/dist/src/chat-commands/builtins/session.js.map +1 -1
- package/dist/src/chat-commands/builtins/tts.js +2 -2
- package/dist/src/chat-commands/builtins/tts.js.map +1 -1
- package/dist/src/chat-commands/context.d.ts +3 -0
- package/dist/src/chat-commands/context.js +22 -4
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/session-key.d.ts +4 -37
- package/dist/src/chat-commands/session-key.js +49 -85
- package/dist/src/chat-commands/session-key.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +2 -0
- package/dist/src/cli/commands/agent/interactive.js +2 -2
- package/dist/src/cli/commands/agent/interactive.js.map +1 -1
- package/dist/src/cli/commands/agent/sessions.js +2 -2
- package/dist/src/cli/commands/agent/sessions.js.map +1 -1
- package/dist/src/cli/commands/agent.js +4 -5
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/channels.js +1 -5
- package/dist/src/cli/commands/channels.js.map +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle-core.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle-core.js.map +1 -1
- package/dist/src/cli/commands/gateway/logs.d.ts +9 -0
- package/dist/src/cli/commands/gateway/logs.js +50 -17
- package/dist/src/cli/commands/gateway/logs.js.map +1 -1
- package/dist/src/cli/commands/image.js +23 -22
- package/dist/src/cli/commands/image.js.map +1 -1
- package/dist/src/cli/commands/init.js +4 -4
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/session/utils.js +2 -2
- package/dist/src/cli/commands/session/utils.js.map +1 -1
- package/dist/src/cli/commands/update.js +26 -46
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/cli/utils/session.d.ts +0 -5
- package/dist/src/cli/utils/session.js +1 -6
- package/dist/src/cli/utils/session.js.map +1 -1
- package/dist/src/commands/agents.config.js +1 -1
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.js +6 -28
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/agent-typed-models.d.ts +18 -0
- package/dist/src/config/agent-typed-models.js +53 -0
- package/dist/src/config/agent-typed-models.js.map +1 -0
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +6 -6
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/model-input.js +2 -5
- package/dist/src/config/model-input.js.map +1 -1
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +253 -217
- package/dist/src/config/schema.js +91 -40
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/voice.d.ts +3 -28
- package/dist/src/config/voice.js +27 -261
- package/dist/src/config/voice.js.map +1 -1
- package/dist/src/config/workspace-path-helpers.d.ts +1 -2
- package/dist/src/config/workspace-path-helpers.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.js +2 -2
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +27 -3
- package/dist/src/daemon/install-plan.js.map +1 -1
- package/dist/src/daemon/launchd.d.ts +8 -0
- package/dist/src/daemon/launchd.js +7 -14
- package/dist/src/daemon/launchd.js.map +1 -1
- package/dist/src/daemon/schtasks.d.ts +25 -0
- package/dist/src/daemon/schtasks.js +168 -48
- package/dist/src/daemon/schtasks.js.map +1 -1
- package/dist/src/daemon/service.js +5 -4
- package/dist/src/daemon/service.js.map +1 -1
- package/dist/src/daemon/systemd.d.ts +6 -0
- package/dist/src/daemon/systemd.js +20 -5
- package/dist/src/daemon/systemd.js.map +1 -1
- package/dist/src/extensions/activation-context.js +0 -1
- package/dist/src/extensions/activation-context.js.map +1 -1
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/normalize-manifest.js +0 -1
- package/dist/src/extensions/normalize-manifest.js.map +1 -1
- package/dist/src/extensions/types/manifest.d.ts +0 -2
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +1 -0
- package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +9 -0
- package/dist/src/gateway/agents-admin.js +28 -4
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/config-tools-web.js +3 -2
- package/dist/src/gateway/config-tools-web.js.map +1 -1
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +2 -2
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +1 -1
- package/dist/src/gateway/hono/lib/agent-model.d.ts +25 -10
- package/dist/src/gateway/hono/lib/agent-model.js +60 -36
- package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +29 -6
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/mask-secret-length.d.ts +6 -0
- package/dist/src/gateway/hono/lib/mask-secret-length.js +16 -0
- package/dist/src/gateway/hono/lib/mask-secret-length.js.map +1 -0
- package/dist/src/gateway/hono/lib/safe-providers-config.d.ts +1 -1
- package/dist/src/gateway/hono/lib/safe-providers-config.js +2 -1
- package/dist/src/gateway/hono/lib/safe-providers-config.js.map +1 -1
- package/dist/src/gateway/hono/lib/safe-voice-config.js +16 -54
- package/dist/src/gateway/hono/lib/safe-voice-config.js.map +1 -1
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +2 -2
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +25 -7
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/channels.js +0 -11
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +3 -2
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +8 -3
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
- package/dist/src/gateway/hono/routes/config.js +59 -0
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/goals.js +1 -1
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +75 -12
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +28 -7
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +15 -13
- package/dist/src/gateway/hono/routes/shares.js.map +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +1 -1
- package/dist/src/gateway/hono/routes/update.js +4 -2
- package/dist/src/gateway/hono/routes/update.js.map +1 -1
- package/dist/src/gateway/hono/routes/voice.js +75 -0
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.d.ts +3 -0
- package/dist/src/gateway/hono/routes/workflows.js +347 -0
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -0
- package/dist/src/gateway/hono/routes/workspace.js +4 -4
- package/dist/src/gateway/hono/sse.js +16 -33
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/lock.js +11 -11
- package/dist/src/gateway/lock.js.map +1 -1
- package/dist/src/gateway/ports.js +6 -6
- package/dist/src/gateway/ports.js.map +1 -1
- package/dist/src/gateway/resolve-webchat-session-key.d.ts +19 -0
- package/dist/src/gateway/resolve-webchat-session-key.js +46 -0
- package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -0
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +9 -11
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +3 -0
- package/dist/src/gateway/service/sessions-api.js +8 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +3 -2
- package/dist/src/gateway/service.js +9 -8
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/session-reset-service.d.ts +20 -0
- package/dist/src/gateway/session-reset-service.js +54 -0
- package/dist/src/gateway/session-reset-service.js.map +1 -0
- package/dist/src/gateway/startup-readiness.d.ts +1 -1
- package/dist/src/gateway/startup-readiness.js +1 -0
- package/dist/src/gateway/startup-readiness.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/gateway-processes.js +2 -2
- package/dist/src/infra/gateway-processes.js.map +1 -1
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/run-command.d.ts +16 -0
- package/dist/src/infra/run-command.js +67 -0
- package/dist/src/infra/run-command.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.d.ts +45 -0
- package/dist/src/infra/update-global.js +224 -0
- package/dist/src/infra/update-global.js.map +1 -0
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/mcp/channel-shared.js +2 -1
- package/dist/src/mcp/channel-shared.js.map +1 -1
- package/dist/src/providers/auth-runtime/auth-profile-store.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js.map +1 -1
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -12
- package/dist/src/providers/auth-runtime/resolve-auth.js.map +1 -1
- package/dist/src/providers/auth-runtime/types.d.ts +6 -12
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/routing/agent-session-key.d.ts +58 -0
- package/dist/src/routing/agent-session-key.js +164 -0
- package/dist/src/routing/agent-session-key.js.map +1 -0
- package/dist/src/routing/index.d.ts +1 -1
- package/dist/src/routing/index.js +4 -2
- package/dist/src/routing/index.js.map +1 -1
- package/dist/src/routing/resolve-route.d.ts +15 -0
- package/dist/src/routing/resolve-route.js +41 -20
- package/dist/src/routing/resolve-route.js.map +1 -1
- package/dist/src/routing/resolve-tui-session-key.d.ts +25 -0
- package/dist/src/routing/resolve-tui-session-key.js +54 -0
- package/dist/src/routing/resolve-tui-session-key.js.map +1 -0
- package/dist/src/routing/session-key-utils.d.ts +24 -0
- package/dist/src/routing/session-key-utils.js +92 -0
- package/dist/src/routing/session-key-utils.js.map +1 -0
- package/dist/src/routing/session-key.d.ts +19 -49
- package/dist/src/routing/session-key.js +143 -116
- package/dist/src/routing/session-key.js.map +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/index.d.ts +6 -0
- package/dist/src/session/index.js +7 -1
- package/dist/src/session/init-session-turn.d.ts +30 -0
- package/dist/src/session/init-session-turn.js +102 -0
- package/dist/src/session/init-session-turn.js.map +1 -0
- package/dist/src/session/lifecycle-timestamps.d.ts +8 -0
- package/dist/src/session/lifecycle-timestamps.js +16 -0
- package/dist/src/session/lifecycle-timestamps.js.map +1 -0
- package/dist/src/session/manager.d.ts +7 -1
- package/dist/src/session/manager.js +8 -1
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +2 -2
- package/dist/src/session/parity/transcript-paths.js.map +1 -1
- package/dist/src/session/parity/xopc-session-disk-entry.d.ts +6 -0
- package/dist/src/session/reset-policy.d.ts +32 -0
- package/dist/src/session/reset-policy.js +65 -0
- package/dist/src/session/reset-policy.js.map +1 -0
- package/dist/src/session/reset-triggers.d.ts +20 -0
- package/dist/src/session/reset-triggers.js +63 -0
- package/dist/src/session/reset-triggers.js.map +1 -0
- package/dist/src/session/reset-type.d.ts +12 -0
- package/dist/src/session/reset-type.js +25 -0
- package/dist/src/session/reset-type.js.map +1 -0
- package/dist/src/session/resolve-session.d.ts +30 -0
- package/dist/src/session/resolve-session.js +93 -0
- package/dist/src/session/resolve-session.js.map +1 -0
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +3 -2
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/session/store.d.ts +11 -4
- package/dist/src/session/store.js +62 -11
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/transcript-events.js +2 -1
- package/dist/src/session/transcript-events.js.map +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-url.d.ts +33 -0
- package/dist/src/share/share-url.js +56 -14
- package/dist/src/share/share-url.js.map +1 -1
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/tui/backends/embedded-backend.js +4 -9
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/components/chat-log.js +3 -3
- package/dist/src/tui/components/chat-log.js.map +1 -1
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/theme.d.ts +0 -2
- package/dist/src/tui/theme.js +1 -3
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/tui-agent-events.js +2 -1
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/tui/tui-commands.d.ts +3 -0
- package/dist/src/tui/tui-commands.js +45 -10
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-keybindings-file.js +2 -22
- package/dist/src/tui/tui-keybindings-file.js.map +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-session-actions.d.ts +28 -0
- package/dist/src/tui/tui-session-actions.js +88 -0
- package/dist/src/tui/tui-session-actions.js.map +1 -0
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +54 -49
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/string-coerce.d.ts +2 -0
- package/dist/src/utils/string-coerce.js +10 -1
- package/dist/src/utils/string-coerce.js.map +1 -1
- package/dist/src/voice/metadata/builtin.d.ts +2 -0
- package/dist/src/voice/metadata/builtin.js +420 -0
- package/dist/src/voice/metadata/builtin.js.map +1 -0
- package/dist/src/voice/metadata/index.d.ts +4 -0
- package/dist/src/voice/metadata/index.js +3 -0
- package/dist/src/voice/metadata/registry.d.ts +5 -0
- package/dist/src/voice/metadata/registry.js +34 -0
- package/dist/src/voice/metadata/registry.js.map +1 -0
- package/dist/src/voice/metadata/types.d.ts +41 -0
- package/dist/src/voice/metadata/types.js +1 -0
- package/dist/src/voice/stt/config-slice.d.ts +2 -5
- package/dist/src/voice/stt/config-slice.js +5 -26
- package/dist/src/voice/stt/config-slice.js.map +1 -1
- package/dist/src/voice/stt/list-providers.d.ts +3 -3
- package/dist/src/voice/stt/list-providers.js +41 -6
- package/dist/src/voice/stt/list-providers.js.map +1 -1
- package/dist/src/voice/stt/types.d.ts +1 -18
- package/dist/src/voice/stt/types.js +4 -2
- package/dist/src/voice/stt/types.js.map +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/config-slice.d.ts +3 -7
- package/dist/src/voice/tts/config-slice.js +7 -38
- package/dist/src/voice/tts/config-slice.js.map +1 -1
- package/dist/src/voice/tts/list-providers.d.ts +3 -3
- package/dist/src/voice/tts/list-providers.js +41 -6
- package/dist/src/voice/tts/list-providers.js.map +1 -1
- package/dist/src/voice/tts/merge-config.js +2 -48
- package/dist/src/voice/tts/merge-config.js.map +1 -1
- package/dist/src/voice/tts/providers/alibaba-speech.js +1 -1
- package/dist/src/voice/tts/providers/alibaba-speech.js.map +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/voice/tts/types.d.ts +1 -29
- package/dist/src/voice/tts/types.js +19 -17
- package/dist/src/voice/tts/types.js.map +1 -1
- package/dist/src/workflows/domain/command.d.ts +18 -0
- package/dist/src/workflows/domain/command.js +1 -0
- package/dist/src/workflows/domain/definition.d.ts +62 -0
- package/dist/src/workflows/domain/definition.js +1 -0
- package/dist/src/workflows/domain/event.d.ts +67 -0
- package/dist/src/workflows/domain/event.js +1 -0
- package/dist/src/workflows/domain/index.d.ts +5 -0
- package/dist/src/workflows/domain/index.js +2 -0
- package/dist/src/workflows/domain/result.d.ts +65 -0
- package/dist/src/workflows/domain/result.js +1 -0
- package/dist/src/workflows/domain/run.d.ts +120 -0
- package/dist/src/workflows/domain/run.js +14 -0
- package/dist/src/workflows/domain/run.js.map +1 -0
- package/dist/src/workflows/engine/index.d.ts +2 -0
- package/dist/src/workflows/engine/index.js +3 -0
- package/dist/src/workflows/engine/projector.d.ts +3 -0
- package/dist/src/workflows/engine/projector.js +205 -0
- package/dist/src/workflows/engine/projector.js.map +1 -0
- package/dist/src/workflows/engine/workflow-engine.d.ts +31 -0
- package/dist/src/workflows/engine/workflow-engine.js +188 -0
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -0
- package/dist/src/workflows/index.d.ts +6 -0
- package/dist/src/workflows/index.js +11 -0
- package/dist/src/workflows/runtime/index.d.ts +1 -0
- package/dist/src/workflows/runtime/index.js +4 -0
- package/dist/src/workflows/runtime/script-runtime.d.ts +3 -0
- package/dist/src/workflows/runtime/script-runtime.js +3 -0
- package/dist/src/workflows/store/event-store.d.ts +17 -0
- package/dist/src/workflows/store/event-store.js +83 -0
- package/dist/src/workflows/store/event-store.js.map +1 -0
- package/dist/src/workflows/store/paths.d.ts +7 -0
- package/dist/src/workflows/store/paths.js +26 -0
- package/dist/src/workflows/store/paths.js.map +1 -0
- package/dist/src/workflows/store/run-store.d.ts +13 -0
- package/dist/src/workflows/store/run-store.js +68 -0
- package/dist/src/workflows/store/run-store.js.map +1 -0
- package/package.json +5 -8
- package/dist/gateway/static/root/assets/agents-mS3_HpRI.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-BG6b9KrW.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-B-W4x2xP.js +0 -1
- package/dist/gateway/static/root/assets/index-ew_2L2We.css +0 -1
- package/dist/gateway/static/root/assets/sessions-page-FaG_Vlkb.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-Bet1OerL.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-DhUO235y.js +0 -2
- package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +0 -3
- package/dist/gateway/static/root/assets/voice-api-key-field-CGEydndO.js +0 -1
- package/dist/src/agent/tools/browser-legacy-tools.d.ts +0 -17
- package/dist/src/agent/tools/browser-legacy-tools.js +0 -766
- package/dist/src/agent/tools/browser-legacy-tools.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-direct-message-content.js","names":[],"sources":["../../../../src/agent/service/build-direct-message-content.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { getDefaultModelSync } from '../../providers/index.js';\nimport { formatInboundFileTextBlock } from '../../channels/attachments/inbound-persist.js';\nimport { expandAtFileMentionsInPlainText } from '../context/expand-at-file-mentions.js';\nimport { resolveInboundImageContentParts } from '../image/inbound-image-handling.js';\nimport { resolveAgentHomeDir, resolveDefaultAgentId } from '../agent-scope.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\n\nexport type DirectInboundAttachment = {\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n};\n\nexport type DirectMessagePart =\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string };\n\n/**\n * Build user message parts (text + resolved images/files) for direct / webchat turns.\n */\nexport async function buildDirectUserMessageContent(opts: {\n content: string;\n attachments?: DirectInboundAttachment[];\n sessionKey?: string;\n config: Config;\n agentManager: AgentInstanceGateway;\n modelManager: ModelManager;\n}): Promise<DirectMessagePart[]> {\n const { content, attachments, sessionKey, config, agentManager, modelManager } = opts;\n const messageContent: DirectMessagePart[] = [];\n const sk = sessionKey ?? '';\n\n if (content.trim()) {\n let textPart = content;\n if (/@file:/.test(textPart)) {\n const wsKey = sk !== '' ? sk : '
|
|
1
|
+
{"version":3,"file":"build-direct-message-content.js","names":[],"sources":["../../../../src/agent/service/build-direct-message-content.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { getDefaultModelSync } from '../../providers/index.js';\nimport { formatInboundFileTextBlock } from '../../channels/attachments/inbound-persist.js';\nimport { expandAtFileMentionsInPlainText } from '../context/expand-at-file-mentions.js';\nimport { resolveInboundImageContentParts } from '../image/inbound-image-handling.js';\nimport { resolveAgentHomeDir, resolveDefaultAgentId } from '../agent-scope.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\n\nexport type DirectInboundAttachment = {\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n};\n\nexport type DirectMessagePart =\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string };\n\n/**\n * Build user message parts (text + resolved images/files) for direct / webchat turns.\n */\nexport async function buildDirectUserMessageContent(opts: {\n content: string;\n attachments?: DirectInboundAttachment[];\n sessionKey?: string;\n config: Config;\n agentManager: AgentInstanceGateway;\n modelManager: ModelManager;\n}): Promise<DirectMessagePart[]> {\n const { content, attachments, sessionKey, config, agentManager, modelManager } = opts;\n const messageContent: DirectMessagePart[] = [];\n const sk = sessionKey ?? '';\n\n if (content.trim()) {\n let textPart = content;\n if (/@file:/.test(textPart)) {\n const wsKey = sk !== '' ? sk : 'agent:main:main';\n const root = agentManager.getResolvedWorkspaceForSession(wsKey);\n textPart = await expandAtFileMentionsInPlainText(textPart, root);\n }\n messageContent.push({ type: 'text', text: textPart });\n }\n\n if (!attachments?.length) {\n return messageContent;\n }\n\n const modelRef =\n sk !== ''\n ? modelManager.getModelForSession(sk)\n : getAgentDefaultModelRef(config) ?? getDefaultModelSync(config);\n\n const storageRoot =\n sk !== ''\n ? resolveAgentHomeDir(config, extractProfileAgentId(sk, config))\n : resolveAgentHomeDir(config, resolveDefaultAgentId(config));\n\n let i = 0;\n while (i < attachments.length) {\n const att = attachments[i]!;\n const isImage =\n att.type === 'image' ||\n att.type === 'photo' ||\n Boolean(att.mimeType?.startsWith('image/'));\n\n if (isImage) {\n const group: Array<{ data: string; mimeType: string }> = [];\n while (i < attachments.length) {\n const a = attachments[i]!;\n const img = a.type === 'image' || a.type === 'photo' || Boolean(a.mimeType?.startsWith('image/'));\n if (!img) {\n break;\n }\n if (!a.data || a.data.length === 0) {\n i += 1;\n continue;\n }\n group.push({ data: a.data, mimeType: a.mimeType || 'image/png' });\n i += 1;\n }\n if (group.length > 0) {\n const parts = await resolveInboundImageContentParts({\n modelRef: modelRef || getDefaultModelSync(config),\n cfg: config,\n userTextForContext: content.trim() ? content : '',\n images: group,\n });\n messageContent.push(...parts);\n }\n } else {\n const fileBlock = formatInboundFileTextBlock(att, storageRoot);\n messageContent.push({ type: 'text', text: fileBlock });\n i += 1;\n }\n }\n\n return messageContent;\n}\n"],"mappings":";;;;;;;;aACiE;gBACF;kBAIgB;;;;AAqB/E,eAAsB,8BAA8B,MAOnB;CAC/B,MAAM,EAAE,SAAS,aAAa,YAAY,QAAQ,cAAc,iBAAiB;CACjF,MAAM,iBAAsC,EAAE;CAC9C,MAAM,KAAK,cAAc;AAEzB,KAAI,QAAQ,MAAM,EAAE;EAClB,IAAI,WAAW;AACf,MAAI,SAAS,KAAK,SAAS,EAAE;GAC3B,MAAM,QAAQ,OAAO,KAAK,KAAK;GAC/B,MAAM,OAAO,aAAa,+BAA+B,MAAM;AAC/D,cAAW,MAAM,gCAAgC,UAAU,KAAK;;AAElE,iBAAe,KAAK;GAAE,MAAM;GAAQ,MAAM;GAAU,CAAC;;AAGvD,KAAI,CAAC,aAAa,OAChB,QAAO;CAGT,MAAM,WACJ,OAAO,KACH,aAAa,mBAAmB,GAAG,GACnC,wBAAwB,OAAO,IAAI,oBAAoB,OAAO;CAEpE,MAAM,cACJ,OAAO,KACH,oBAAoB,QAAQ,sBAAsB,IAAI,OAAO,CAAC,GAC9D,oBAAoB,QAAQ,sBAAsB,OAAO,CAAC;CAEhE,IAAI,IAAI;AACR,QAAO,IAAI,YAAY,QAAQ;EAC7B,MAAM,MAAM,YAAY;AAMxB,MAJE,IAAI,SAAS,WACb,IAAI,SAAS,WACb,QAAQ,IAAI,UAAU,WAAW,SAAS,CAAC,EAEhC;GACX,MAAM,QAAmD,EAAE;AAC3D,UAAO,IAAI,YAAY,QAAQ;IAC7B,MAAM,IAAI,YAAY;AAEtB,QAAI,EADQ,EAAE,SAAS,WAAW,EAAE,SAAS,WAAW,QAAQ,EAAE,UAAU,WAAW,SAAS,CAAC,EAE/F;AAEF,QAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,WAAW,GAAG;AAClC,UAAK;AACL;;AAEF,UAAM,KAAK;KAAE,MAAM,EAAE;KAAM,UAAU,EAAE,YAAY;KAAa,CAAC;AACjE,SAAK;;AAEP,OAAI,MAAM,SAAS,GAAG;IACpB,MAAM,QAAQ,MAAM,gCAAgC;KAClD,UAAU,YAAY,oBAAoB,OAAO;KACjD,KAAK;KACL,oBAAoB,QAAQ,MAAM,GAAG,UAAU;KAC/C,QAAQ;KACT,CAAC;AACF,mBAAe,KAAK,GAAG,MAAM;;SAE1B;GACL,MAAM,YAAY,2BAA2B,KAAK,YAAY;AAC9D,kBAAe,KAAK;IAAE,MAAM;IAAQ,MAAM;IAAW,CAAC;AACtD,QAAK;;;AAIT,QAAO"}
|
|
@@ -45,7 +45,9 @@ export declare function tryRunSlashCommand(deps: TryRunSlashCommandDeps, ctx: {
|
|
|
45
45
|
senderId?: string;
|
|
46
46
|
isGroup?: boolean;
|
|
47
47
|
inboundMetadata?: Record<string, unknown>;
|
|
48
|
-
}, content: string
|
|
48
|
+
}, content: string, options?: {
|
|
49
|
+
skipResetCommands?: boolean;
|
|
50
|
+
}): Promise<SlashCommandOutcome>;
|
|
49
51
|
export interface RunDirectAgentTurnDeps {
|
|
50
52
|
sessionStore: SessionStore;
|
|
51
53
|
agentManager: AgentInstanceGateway;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { extractAgentUserPlainText } from "../memory/user-message-text.js";
|
|
2
|
+
import { shouldSkipResetOverlapCommand } from "../../session/reset-triggers.js";
|
|
2
3
|
import { parseSlashCommand } from "../../chat-commands/command-parse.js";
|
|
3
4
|
import { commandRegistry } from "../../chat-commands/registry.js";
|
|
4
5
|
import "../../chat-commands/index.js";
|
|
@@ -23,12 +24,16 @@ async function hydratePerTurnState(deps, sessionKey, thinking) {
|
|
|
23
24
|
* text. Errors thrown inside the command surface as `aggregatedText` so callers
|
|
24
25
|
* can persist the receipt or stream it as a token.
|
|
25
26
|
*/
|
|
26
|
-
async function tryRunSlashCommand(deps, ctx, content) {
|
|
27
|
+
async function tryRunSlashCommand(deps, ctx, content, options) {
|
|
27
28
|
const parsed = parseSlashCommand(content);
|
|
28
29
|
if (!parsed) return {
|
|
29
30
|
matched: false,
|
|
30
31
|
aggregatedText: ""
|
|
31
32
|
};
|
|
33
|
+
if (options?.skipResetCommands && shouldSkipResetOverlapCommand(parsed.command, true)) return {
|
|
34
|
+
matched: false,
|
|
35
|
+
aggregatedText: ""
|
|
36
|
+
};
|
|
32
37
|
if (!commandRegistry.has(parsed.command)) return {
|
|
33
38
|
matched: false,
|
|
34
39
|
aggregatedText: ""
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"direct-turn-helpers.js","names":[],"sources":["../../../../src/agent/service/direct-turn-helpers.ts"],"sourcesContent":["/**\n * Shared building blocks for the two direct-turn entry points (streaming\n * webchat SSE and one-shot CLI). Both flows do the same hydrate → maybe-slash\n * → run-embedded-turn → after-turn dance; this module captures that core so\n * the entry points only manage their I/O specifics (event sink, voice STT,\n * TTS, transcript persistence).\n */\n\nimport crypto from 'node:crypto';\n\nimport { commandRegistry } from '../../chat-commands/index.js';\nimport { parseSlashCommand } from '../../chat-commands/command-parse.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport { extractAgentUserPlainText } from '../memory/user-message-text.js';\nimport { runEmbeddedTurnForSession } from '../embedded/run-for-session.js';\nimport type { EmbeddedStreamEvent } from '../embedded/types.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nexport interface HydratePerTurnStateDeps {\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n}\n\n/** Workspace + model + thinking level — common prep before any direct turn. */\nexport async function hydratePerTurnState(\n deps: HydratePerTurnStateDeps,\n sessionKey: string,\n thinking?: string,\n): Promise<void> {\n await deps.hydrateSessionWorkspaceFromStore(sessionKey);\n await deps.hydrateSessionModelFromStore(sessionKey);\n await deps.applyResolvedThinkingLevel(sessionKey, thinking);\n}\n\nexport interface SlashCommandOutcome {\n /** True if the input parsed as a registered slash command (handled or not). */\n matched: boolean;\n /** Aggregated user-visible reply text (assistant view). */\n aggregatedText: string;\n /** The parsed command name when matched. */\n command?: string;\n}\n\nexport interface TryRunSlashCommandDeps {\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n log: { warn: (obj: Record<string, unknown>, msg: string) => void };\n}\n\n/**\n * Detect a slash command and, if registered, execute it and aggregate the reply\n * text. Errors thrown inside the command surface as `aggregatedText` so callers\n * can persist the receipt or stream it as a token.\n */\nexport async function tryRunSlashCommand(\n deps: TryRunSlashCommandDeps,\n ctx: {\n sessionKey: string;\n channel: string;\n chatId: string;\n senderId?: string;\n isGroup?: boolean;\n inboundMetadata?: Record<string, unknown>;\n },\n content: string,\n): Promise<SlashCommandOutcome> {\n const parsed = parseSlashCommand(content);\n if (!parsed) {\n return { matched: false, aggregatedText: '' };\n }\n if (!commandRegistry.has(parsed.command)) {\n return { matched: false, aggregatedText: '' };\n }\n try {\n const { aggregatedText } = await deps.commandHandler.executeCommandAndAggregateReply(\n parsed.command,\n parsed.args,\n {\n sessionKey: ctx.sessionKey,\n channel: ctx.channel,\n chatId: ctx.chatId,\n senderId: ctx.senderId ?? '',\n isGroup: ctx.isGroup ?? false,\n inboundMetadata: ctx.inboundMetadata ?? {},\n },\n );\n return { matched: true, aggregatedText: aggregatedText ?? '', command: parsed.command };\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n deps.log.warn(\n { err, sessionKey: ctx.sessionKey, command: parsed.command },\n `Slash command failed: ${em}`,\n );\n return { matched: true, aggregatedText: `Command error: ${em}`, command: parsed.command };\n }\n}\n\nexport interface RunDirectAgentTurnDeps {\n sessionStore: SessionStore;\n agentManager: AgentInstanceGateway;\n modelManager: ModelManager;\n config: Config | undefined;\n}\n\nexport interface RunDirectAgentTurnInput {\n sessionKey: string;\n userMessage: AgentMessage;\n abortSignal?: AbortSignal;\n onEvent?: (event: EmbeddedStreamEvent) => void;\n}\n\nexport interface RunDirectAgentTurnResult {\n ok: boolean;\n errorMessage?: string;\n lastAssistantText?: string;\n}\n\n/**\n * Convert a user message into an embedded turn, including the standard memory\n * prefetch + background-review nudge wiring used by every direct entry point.\n */\nexport async function runDirectAgentTurn(\n deps: RunDirectAgentTurnDeps,\n input: RunDirectAgentTurnInput,\n): Promise<RunDirectAgentTurnResult> {\n const userPlain = extractAgentUserPlainText(input.userMessage);\n const userMessageForModel = await deps.agentManager.applyMemoryPrefetchToUserMessage(\n input.userMessage,\n input.sessionKey,\n );\n\n const result = await runEmbeddedTurnForSession({\n sessionKey: input.sessionKey,\n runId: crypto.randomUUID(),\n userMessage: userMessageForModel,\n sessionStore: deps.sessionStore,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n getConfig: () => deps.config,\n abortSignal: input.abortSignal,\n beforeTurn: () => deps.agentManager.beginBackgroundReviewUserTurn(input.sessionKey),\n onEvent: input.onEvent,\n });\n\n deps.agentManager.afterAgentTurn(input.sessionKey, userPlain);\n deps.agentManager.scheduleBackgroundReviewAfterUserTurn(input.sessionKey);\n\n return result;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"direct-turn-helpers.js","names":[],"sources":["../../../../src/agent/service/direct-turn-helpers.ts"],"sourcesContent":["/**\n * Shared building blocks for the two direct-turn entry points (streaming\n * webchat SSE and one-shot CLI). Both flows do the same hydrate → maybe-slash\n * → run-embedded-turn → after-turn dance; this module captures that core so\n * the entry points only manage their I/O specifics (event sink, voice STT,\n * TTS, transcript persistence).\n */\n\nimport crypto from 'node:crypto';\n\nimport { commandRegistry } from '../../chat-commands/index.js';\nimport { parseSlashCommand } from '../../chat-commands/command-parse.js';\nimport { shouldSkipResetOverlapCommand } from '../../session/reset-triggers.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport { extractAgentUserPlainText } from '../memory/user-message-text.js';\nimport { runEmbeddedTurnForSession } from '../embedded/run-for-session.js';\nimport type { EmbeddedStreamEvent } from '../embedded/types.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nexport interface HydratePerTurnStateDeps {\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n}\n\n/** Workspace + model + thinking level — common prep before any direct turn. */\nexport async function hydratePerTurnState(\n deps: HydratePerTurnStateDeps,\n sessionKey: string,\n thinking?: string,\n): Promise<void> {\n await deps.hydrateSessionWorkspaceFromStore(sessionKey);\n await deps.hydrateSessionModelFromStore(sessionKey);\n await deps.applyResolvedThinkingLevel(sessionKey, thinking);\n}\n\nexport interface SlashCommandOutcome {\n /** True if the input parsed as a registered slash command (handled or not). */\n matched: boolean;\n /** Aggregated user-visible reply text (assistant view). */\n aggregatedText: string;\n /** The parsed command name when matched. */\n command?: string;\n}\n\nexport interface TryRunSlashCommandDeps {\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n log: { warn: (obj: Record<string, unknown>, msg: string) => void };\n}\n\n/**\n * Detect a slash command and, if registered, execute it and aggregate the reply\n * text. Errors thrown inside the command surface as `aggregatedText` so callers\n * can persist the receipt or stream it as a token.\n */\nexport async function tryRunSlashCommand(\n deps: TryRunSlashCommandDeps,\n ctx: {\n sessionKey: string;\n channel: string;\n chatId: string;\n senderId?: string;\n isGroup?: boolean;\n inboundMetadata?: Record<string, unknown>;\n },\n content: string,\n options?: { skipResetCommands?: boolean },\n): Promise<SlashCommandOutcome> {\n const parsed = parseSlashCommand(content);\n if (!parsed) {\n return { matched: false, aggregatedText: '' };\n }\n if (options?.skipResetCommands && shouldSkipResetOverlapCommand(parsed.command, true)) {\n return { matched: false, aggregatedText: '' };\n }\n if (!commandRegistry.has(parsed.command)) {\n return { matched: false, aggregatedText: '' };\n }\n try {\n const { aggregatedText } = await deps.commandHandler.executeCommandAndAggregateReply(\n parsed.command,\n parsed.args,\n {\n sessionKey: ctx.sessionKey,\n channel: ctx.channel,\n chatId: ctx.chatId,\n senderId: ctx.senderId ?? '',\n isGroup: ctx.isGroup ?? false,\n inboundMetadata: ctx.inboundMetadata ?? {},\n },\n );\n return { matched: true, aggregatedText: aggregatedText ?? '', command: parsed.command };\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n deps.log.warn(\n { err, sessionKey: ctx.sessionKey, command: parsed.command },\n `Slash command failed: ${em}`,\n );\n return { matched: true, aggregatedText: `Command error: ${em}`, command: parsed.command };\n }\n}\n\nexport interface RunDirectAgentTurnDeps {\n sessionStore: SessionStore;\n agentManager: AgentInstanceGateway;\n modelManager: ModelManager;\n config: Config | undefined;\n}\n\nexport interface RunDirectAgentTurnInput {\n sessionKey: string;\n userMessage: AgentMessage;\n abortSignal?: AbortSignal;\n onEvent?: (event: EmbeddedStreamEvent) => void;\n}\n\nexport interface RunDirectAgentTurnResult {\n ok: boolean;\n errorMessage?: string;\n lastAssistantText?: string;\n}\n\n/**\n * Convert a user message into an embedded turn, including the standard memory\n * prefetch + background-review nudge wiring used by every direct entry point.\n */\nexport async function runDirectAgentTurn(\n deps: RunDirectAgentTurnDeps,\n input: RunDirectAgentTurnInput,\n): Promise<RunDirectAgentTurnResult> {\n const userPlain = extractAgentUserPlainText(input.userMessage);\n const userMessageForModel = await deps.agentManager.applyMemoryPrefetchToUserMessage(\n input.userMessage,\n input.sessionKey,\n );\n\n const result = await runEmbeddedTurnForSession({\n sessionKey: input.sessionKey,\n runId: crypto.randomUUID(),\n userMessage: userMessageForModel,\n sessionStore: deps.sessionStore,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n getConfig: () => deps.config,\n abortSignal: input.abortSignal,\n beforeTurn: () => deps.agentManager.beginBackgroundReviewUserTurn(input.sessionKey),\n onEvent: input.onEvent,\n });\n\n deps.agentManager.afterAgentTurn(input.sessionKey, userPlain);\n deps.agentManager.scheduleBackgroundReviewAfterUserTurn(input.sessionKey);\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8BA,eAAsB,oBACpB,MACA,YACA,UACe;AACf,OAAM,KAAK,iCAAiC,WAAW;AACvD,OAAM,KAAK,6BAA6B,WAAW;AACnD,OAAM,KAAK,2BAA2B,YAAY,SAAS;;;;;;;AAsB7D,eAAsB,mBACpB,MACA,KAQA,SACA,SAC8B;CAC9B,MAAM,SAAS,kBAAkB,QAAQ;AACzC,KAAI,CAAC,OACH,QAAO;EAAE,SAAS;EAAO,gBAAgB;EAAI;AAE/C,KAAI,SAAS,qBAAqB,8BAA8B,OAAO,SAAS,KAAK,CACnF,QAAO;EAAE,SAAS;EAAO,gBAAgB;EAAI;AAE/C,KAAI,CAAC,gBAAgB,IAAI,OAAO,QAAQ,CACtC,QAAO;EAAE,SAAS;EAAO,gBAAgB;EAAI;AAE/C,KAAI;EACF,MAAM,EAAE,mBAAmB,MAAM,KAAK,eAAe,gCACnD,OAAO,SACP,OAAO,MACP;GACE,YAAY,IAAI;GAChB,SAAS,IAAI;GACb,QAAQ,IAAI;GACZ,UAAU,IAAI,YAAY;GAC1B,SAAS,IAAI,WAAW;GACxB,iBAAiB,IAAI,mBAAmB,EAAE;GAC3C,CACF;AACD,SAAO;GAAE,SAAS;GAAM,gBAAgB,kBAAkB;GAAI,SAAS,OAAO;GAAS;UAChF,KAAK;EACZ,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,OAAK,IAAI,KACP;GAAE;GAAK,YAAY,IAAI;GAAY,SAAS,OAAO;GAAS,EAC5D,yBAAyB,KAC1B;AACD,SAAO;GAAE,SAAS;GAAM,gBAAgB,kBAAkB;GAAM,SAAS,OAAO;GAAS;;;;;;;AA4B7F,eAAsB,mBACpB,MACA,OACmC;CACnC,MAAM,YAAY,0BAA0B,MAAM,YAAY;CAC9D,MAAM,sBAAsB,MAAM,KAAK,aAAa,iCAClD,MAAM,aACN,MAAM,WACP;CAED,MAAM,SAAS,MAAM,0BAA0B;EAC7C,YAAY,MAAM;EAClB,OAAO,OAAO,YAAY;EAC1B,aAAa;EACb,cAAc,KAAK;EACnB,cAAc,KAAK;EACnB,cAAc,KAAK;EACnB,iBAAiB,KAAK;EACtB,aAAa,MAAM;EACnB,kBAAkB,KAAK,aAAa,8BAA8B,MAAM,WAAW;EACnF,SAAS,MAAM;EAChB,CAAC;AAEF,MAAK,aAAa,eAAe,MAAM,YAAY,UAAU;AAC7D,MAAK,aAAa,sCAAsC,MAAM,WAAW;AAEzE,QAAO"}
|
|
@@ -23,6 +23,10 @@ export type RunProcessDirectDeps = {
|
|
|
23
23
|
commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;
|
|
24
24
|
onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;
|
|
25
25
|
endDirectRequestContext: () => void;
|
|
26
|
+
resetSession: (sessionKey: string) => Promise<{
|
|
27
|
+
sessionId: string;
|
|
28
|
+
previousSessionId: string;
|
|
29
|
+
} | null>;
|
|
26
30
|
};
|
|
27
31
|
export declare function runProcessDirect(deps: RunProcessDirectDeps, input: {
|
|
28
32
|
content: string;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { appendPiTranscriptMessage } from "../../session/parity/jsonl-transcript-io.js";
|
|
2
|
+
import { initSessionTurn } from "../../session/init-session-turn.js";
|
|
3
|
+
import "../../session/index.js";
|
|
2
4
|
import { buildDirectUserMessageContent } from "./build-direct-message-content.js";
|
|
3
5
|
import { hydratePerTurnState, runDirectAgentTurn, tryRunSlashCommand } from "./direct-turn-helpers.js";
|
|
4
6
|
//#region src/agent/service/process-direct-one-shot.ts
|
|
@@ -6,13 +8,24 @@ async function runProcessDirect(deps, input) {
|
|
|
6
8
|
const { channel, chatId } = deps.parseSessionKey(input.sessionKey);
|
|
7
9
|
deps.initSessionContext(input.sessionKey, channel, chatId);
|
|
8
10
|
try {
|
|
11
|
+
let turnBody = input.content;
|
|
12
|
+
let resetTriggeredAtInit = false;
|
|
13
|
+
const turn = await initSessionTurn({
|
|
14
|
+
cfg: deps.config,
|
|
15
|
+
sessionKey: input.sessionKey,
|
|
16
|
+
body: input.content,
|
|
17
|
+
resetSession: deps.resetSession
|
|
18
|
+
});
|
|
19
|
+
resetTriggeredAtInit = turn.resetTriggered;
|
|
20
|
+
if (turn.bareReset && turn.ackMessage) return turn.ackMessage;
|
|
21
|
+
turnBody = turn.bodyStripped;
|
|
9
22
|
await hydratePerTurnState(deps, input.sessionKey, input.thinking);
|
|
10
23
|
const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);
|
|
11
24
|
const slash = await tryRunSlashCommand(deps, {
|
|
12
25
|
sessionKey: input.sessionKey,
|
|
13
26
|
channel,
|
|
14
27
|
chatId
|
|
15
|
-
},
|
|
28
|
+
}, turnBody, { skipResetCommands: resetTriggeredAtInit });
|
|
16
29
|
if (slash.matched) {
|
|
17
30
|
const trimmed = slash.aggregatedText.trim();
|
|
18
31
|
if (trimmed) {
|
|
@@ -36,7 +49,7 @@ async function runProcessDirect(deps, input) {
|
|
|
36
49
|
const userMessage = {
|
|
37
50
|
role: "user",
|
|
38
51
|
content: await buildDirectUserMessageContent({
|
|
39
|
-
content:
|
|
52
|
+
content: turnBody.trimStart().startsWith("/skill:") ? deps.agentManager.expandSkillUserText(turnBody) : turnBody,
|
|
40
53
|
attachments: prepared,
|
|
41
54
|
sessionKey: input.sessionKey,
|
|
42
55
|
config: deps.config,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-direct-one-shot.js","names":[],"sources":["../../../../src/agent/service/process-direct-one-shot.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport { appendPiTranscriptMessage } from '../../session/parity/jsonl-transcript-io.js';\nimport { buildDirectUserMessageContent, type DirectInboundAttachment } from './build-direct-message-content.js';\nimport type { ProcessDirectStreamLog } from './process-direct-streaming.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\n\nexport type RunProcessDirectDeps = {\n log: ProcessDirectStreamLog;\n config: Config;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => void;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n agentManager: AgentInstanceGateway;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectInboundAttachment[],\n ) => Promise<DirectInboundAttachment[] | undefined>;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n endDirectRequestContext: () => void;\n};\n\nexport async function runProcessDirect(\n deps: RunProcessDirectDeps,\n input: {\n content: string;\n sessionKey: string;\n attachments?: DirectInboundAttachment[];\n thinking?: string;\n },\n): Promise<string> {\n const { channel, chatId } = deps.parseSessionKey(input.sessionKey);\n deps.initSessionContext(input.sessionKey, channel, chatId);\n\n try {\n await hydratePerTurnState(deps, input.sessionKey, input.thinking);\n const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey: input.sessionKey, channel, chatId },\n
|
|
1
|
+
{"version":3,"file":"process-direct-one-shot.js","names":[],"sources":["../../../../src/agent/service/process-direct-one-shot.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport { initSessionTurn } from '../../session/index.js';\nimport { appendPiTranscriptMessage } from '../../session/parity/jsonl-transcript-io.js';\nimport { buildDirectUserMessageContent, type DirectInboundAttachment } from './build-direct-message-content.js';\nimport type { ProcessDirectStreamLog } from './process-direct-streaming.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\n\nexport type RunProcessDirectDeps = {\n log: ProcessDirectStreamLog;\n config: Config;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => void;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n agentManager: AgentInstanceGateway;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectInboundAttachment[],\n ) => Promise<DirectInboundAttachment[] | undefined>;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n};\n\nexport async function runProcessDirect(\n deps: RunProcessDirectDeps,\n input: {\n content: string;\n sessionKey: string;\n attachments?: DirectInboundAttachment[];\n thinking?: string;\n },\n): Promise<string> {\n const { channel, chatId } = deps.parseSessionKey(input.sessionKey);\n deps.initSessionContext(input.sessionKey, channel, chatId);\n\n try {\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n const turn = await initSessionTurn({\n cfg: deps.config,\n sessionKey: input.sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n return turn.ackMessage;\n }\n turnBody = turn.bodyStripped;\n\n await hydratePerTurnState(deps, input.sessionKey, input.thinking);\n const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey: input.sessionKey, channel, chatId },\n turnBody,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n const trimmed = slash.aggregatedText.trim();\n if (trimmed) {\n const { absPath } = await deps.sessionStore.resolveTranscriptPath(input.sessionKey);\n const workspaceDir = deps.agentManager.getResolvedWorkspaceForSession(input.sessionKey);\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n } as AgentMessage,\n sessionKey: input.sessionKey,\n });\n }\n return slash.aggregatedText ?? '';\n }\n\n const textForDirect = turnBody.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(turnBody)\n : turnBody;\n const messageContent = await buildDirectUserMessageContent({\n content: textForDirect,\n attachments: prepared,\n sessionKey: input.sessionKey,\n config: deps.config,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n });\n\n const userMessage = {\n role: 'user' as const,\n content: messageContent,\n timestamp: Date.now(),\n };\n\n const result = await runDirectAgentTurn(\n { ...deps, config: deps.config },\n { sessionKey: input.sessionKey, userMessage },\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(input.sessionKey, result.lastAssistantText);\n }\n\n return result.lastAssistantText ?? '';\n } finally {\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":";;;;;;AAsCA,eAAsB,iBACpB,MACA,OAMiB;CACjB,MAAM,EAAE,SAAS,WAAW,KAAK,gBAAgB,MAAM,WAAW;AAClE,MAAK,mBAAmB,MAAM,YAAY,SAAS,OAAO;AAE1D,KAAI;EACF,IAAI,WAAW,MAAM;EACrB,IAAI,uBAAuB;EAC3B,MAAM,OAAO,MAAM,gBAAgB;GACjC,KAAK,KAAK;GACV,YAAY,MAAM;GAClB,MAAM,MAAM;GACZ,cAAc,KAAK;GACpB,CAAC;AACF,yBAAuB,KAAK;AAC5B,MAAI,KAAK,aAAa,KAAK,WACzB,QAAO,KAAK;AAEd,aAAW,KAAK;AAEhB,QAAM,oBAAoB,MAAM,MAAM,YAAY,MAAM,SAAS;EACjE,MAAM,WAAW,MAAM,KAAK,0BAA0B,MAAM,YAAY,MAAM,YAAY;EAE1F,MAAM,QAAQ,MAAM,mBAClB,MACA;GAAE,YAAY,MAAM;GAAY;GAAS;GAAQ,EACjD,UACA,EAAE,mBAAmB,sBAAsB,CAC5C;AACD,MAAI,MAAM,SAAS;GACjB,MAAM,UAAU,MAAM,eAAe,MAAM;AAC3C,OAAI,SAAS;IACX,MAAM,EAAE,YAAY,MAAM,KAAK,aAAa,sBAAsB,MAAM,WAAW;AAEnF,UAAM,0BAA0B;KAC9B;KACA,KAHmB,KAAK,aAAa,+BAA+B,MAAM,WAGzD;KACjB,SAAS;MACP,MAAM;MACN,SAAS,CAAC;OAAE,MAAM;OAAQ,MAAM;OAAS,CAAC;MAC1C,WAAW,KAAK,KAAK;MACtB;KACD,YAAY,MAAM;KACnB,CAAC;;AAEJ,UAAO,MAAM,kBAAkB;;EAejC,MAAM,cAAc;GAClB,MAAM;GACN,SAAS,MAXkB,8BAA8B;IACzD,SAJoB,SAAS,WAAW,CAAC,WAAW,UAAU,GAC5D,KAAK,aAAa,oBAAoB,SAAS,GAC/C;IAGF,aAAa;IACb,YAAY,MAAM;IAClB,QAAQ,KAAK;IACb,cAAc,KAAK;IACnB,cAAc,KAAK;IACpB,CAAC;GAKA,WAAW,KAAK,KAAK;GACtB;EAED,MAAM,SAAS,MAAM,mBACnB;GAAE,GAAG;GAAM,QAAQ,KAAK;GAAQ,EAChC;GAAE,YAAY,MAAM;GAAY;GAAa,CAC9C;AAED,MAAI,OAAO,kBACT,MAAK,iBAAiB,MAAM,YAAY,OAAO,kBAAkB;AAGnE,SAAO,OAAO,qBAAqB;WAC3B;AACR,OAAK,yBAAyB"}
|
|
@@ -62,6 +62,10 @@ export interface ProcessDirectStreamingDeps {
|
|
|
62
62
|
name: string;
|
|
63
63
|
} | null>;
|
|
64
64
|
endDirectRequestContext: () => void;
|
|
65
|
+
resetSession: (sessionKey: string) => Promise<{
|
|
66
|
+
sessionId: string;
|
|
67
|
+
previousSessionId: string;
|
|
68
|
+
} | null>;
|
|
65
69
|
}
|
|
66
70
|
export interface ProcessDirectStreamingInput {
|
|
67
71
|
content: string;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { appendPiTranscriptMessage } from "../../session/parity/jsonl-transcript-io.js";
|
|
2
|
+
import { formatAgentRunErrorForClient } from "../client-error-format.js";
|
|
2
3
|
import { resolveEffectiveReasoningLevel } from "../../session/thinking-resolve.js";
|
|
4
|
+
import { initSessionTurn } from "../../session/init-session-turn.js";
|
|
3
5
|
import "../../session/index.js";
|
|
4
6
|
import { isVoiceLikeAttachment, mergeSttConfigFromAppConfig, mergeVoiceTranscriptsIntoUserText } from "../../channels/attachments/voice-stt-webchat.js";
|
|
5
7
|
import { abortEmbeddedRun } from "../embedded/runs.js";
|
|
@@ -9,7 +11,7 @@ import { AsyncQueue } from "./async-queue.js";
|
|
|
9
11
|
import { hydratePerTurnState, runDirectAgentTurn, tryRunSlashCommand } from "./direct-turn-helpers.js";
|
|
10
12
|
//#region src/agent/service/process-direct-streaming.ts
|
|
11
13
|
async function* runProcessDirectStreaming(deps, input) {
|
|
12
|
-
const sessionKey = input.sessionKey ?? "
|
|
14
|
+
const sessionKey = input.sessionKey ?? "agent:main:main";
|
|
13
15
|
const { channel, chatId } = deps.parseSessionKey(sessionKey);
|
|
14
16
|
const context = deps.initDirectStreamingSession(sessionKey, channel, chatId);
|
|
15
17
|
const queue = new AsyncQueue();
|
|
@@ -18,6 +20,18 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
18
20
|
const visible = applyReasoningVisibilityToSseEvent(event, reasoningLevel);
|
|
19
21
|
if (visible !== null) queue.push(visible);
|
|
20
22
|
};
|
|
23
|
+
const formatStreamError = (raw) => {
|
|
24
|
+
let provider;
|
|
25
|
+
let modelRef;
|
|
26
|
+
try {
|
|
27
|
+
provider = deps.modelManager.getResolvedModelForSession(sessionKey).provider;
|
|
28
|
+
modelRef = deps.modelManager.getModelForSession(sessionKey);
|
|
29
|
+
} catch {}
|
|
30
|
+
return formatAgentRunErrorForClient(raw, {
|
|
31
|
+
provider,
|
|
32
|
+
modelRef
|
|
33
|
+
});
|
|
34
|
+
};
|
|
21
35
|
if (channel === "webchat") deps.registerWebchatSsePublisher(sessionKey, pushVisible);
|
|
22
36
|
const signal = input.signal;
|
|
23
37
|
let userAborted = false;
|
|
@@ -28,6 +42,35 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
28
42
|
let webchatSlashReceipt;
|
|
29
43
|
const taskPromise = (async () => {
|
|
30
44
|
try {
|
|
45
|
+
const cfg = deps.getConfig();
|
|
46
|
+
let turnBody = input.content;
|
|
47
|
+
let resetTriggeredAtInit = false;
|
|
48
|
+
if (cfg) {
|
|
49
|
+
const turn = await initSessionTurn({
|
|
50
|
+
cfg,
|
|
51
|
+
sessionKey,
|
|
52
|
+
body: input.content,
|
|
53
|
+
resetSession: deps.resetSession
|
|
54
|
+
});
|
|
55
|
+
resetTriggeredAtInit = turn.resetTriggered;
|
|
56
|
+
if (turn.bareReset && turn.ackMessage) {
|
|
57
|
+
ranSlashCommand = true;
|
|
58
|
+
webchatSlashReceipt = turn.ackMessage;
|
|
59
|
+
pushVisible({
|
|
60
|
+
type: "token",
|
|
61
|
+
content: turn.ackMessage
|
|
62
|
+
});
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
turnBody = turn.bodyStripped;
|
|
66
|
+
if (turn.isNewSession) deps.log.debug({
|
|
67
|
+
sessionKey,
|
|
68
|
+
sessionId: turn.sessionId,
|
|
69
|
+
previousSessionId: turn.previousSessionId,
|
|
70
|
+
resetTriggered: turn.resetTriggered,
|
|
71
|
+
staleRollover: turn.staleRollover
|
|
72
|
+
}, "Session reset boundary at direct turn start");
|
|
73
|
+
}
|
|
31
74
|
await hydratePerTurnState(deps, sessionKey, input.thinking);
|
|
32
75
|
{
|
|
33
76
|
const defReason = deps.getConfig()?.agents?.defaults?.reasoningDefault ?? "stream";
|
|
@@ -35,11 +78,11 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
35
78
|
}
|
|
36
79
|
const prepared = await deps.prepareInboundAttachments(sessionKey, input.attachments);
|
|
37
80
|
const sttCfg = mergeSttConfigFromAppConfig(deps.getConfig()?.tools?.media?.audio, deps.getConfig()?.tools?.media);
|
|
38
|
-
const voiceMerge = await mergeVoiceTranscriptsIntoUserText(deps.attachmentRootsForSession(sessionKey), prepared,
|
|
81
|
+
const voiceMerge = await mergeVoiceTranscriptsIntoUserText(deps.attachmentRootsForSession(sessionKey), prepared, turnBody, sttCfg);
|
|
39
82
|
mergedUserText = voiceMerge.text;
|
|
40
83
|
inboundVoice = voiceMerge.inboundVoice;
|
|
41
84
|
if (inboundVoice) {
|
|
42
|
-
const transcriptParts = [voiceMerge.voiceTranscripts.filter(Boolean).join("\n"),
|
|
85
|
+
const transcriptParts = [voiceMerge.voiceTranscripts.filter(Boolean).join("\n"), turnBody.trim()].filter(Boolean);
|
|
43
86
|
const voiceAttachments = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({
|
|
44
87
|
workspaceRelativePath: att.workspaceRelativePath,
|
|
45
88
|
mimeType: att.mimeType,
|
|
@@ -71,7 +114,7 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
71
114
|
chatId,
|
|
72
115
|
senderId: context.senderId,
|
|
73
116
|
isGroup: context.isGroup
|
|
74
|
-
}, mergedUserText);
|
|
117
|
+
}, mergedUserText, { skipResetCommands: resetTriggeredAtInit });
|
|
75
118
|
if (slash.matched) {
|
|
76
119
|
ranSlashCommand = true;
|
|
77
120
|
const text = slash.aggregatedText.trim();
|
|
@@ -119,18 +162,21 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
119
162
|
abortSignal: signal,
|
|
120
163
|
onEvent: (embeddedEvent) => {
|
|
121
164
|
const mapped = mapEmbeddedEventToGatewaySse(embeddedEvent);
|
|
122
|
-
if (mapped)
|
|
165
|
+
if (mapped) {
|
|
166
|
+
if (mapped.type === "error" && typeof mapped.content === "string") mapped.content = formatStreamError(mapped.content);
|
|
167
|
+
pushVisible(mapped);
|
|
168
|
+
}
|
|
123
169
|
}
|
|
124
170
|
});
|
|
125
171
|
if (result.lastAssistantText) deps.onTurnComplete?.(sessionKey, result.lastAssistantText);
|
|
126
172
|
if (!result.ok && result.errorMessage && !abortHandled) pushVisible({
|
|
127
173
|
type: "error",
|
|
128
|
-
content: result.errorMessage
|
|
174
|
+
content: formatStreamError(result.errorMessage)
|
|
129
175
|
});
|
|
130
176
|
} catch (err) {
|
|
131
177
|
if (!abortHandled) pushVisible({
|
|
132
178
|
type: "error",
|
|
133
|
-
content: err instanceof Error ? err.message : String(err)
|
|
179
|
+
content: formatStreamError(err instanceof Error ? err.message : String(err))
|
|
134
180
|
});
|
|
135
181
|
} finally {
|
|
136
182
|
queue.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-direct-streaming.js","names":[],"sources":["../../../../src/agent/service/process-direct-streaming.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { InternalAttachmentRoots } from '../../channels/attachments/inbound-persist.js';\nimport {\n isVoiceLikeAttachment,\n mergeVoiceTranscriptsIntoUserText,\n mergeSttConfigFromAppConfig,\n} from '../../channels/attachments/voice-stt-webchat.js';\nimport {\n resolveEffectiveReasoningLevel,\n type SessionConfigStore,\n type SessionStore,\n} from '../../session/index.js';\nimport { appendPiTranscriptMessage } from '../../session/parity/jsonl-transcript-io.js';\nimport type { SessionContext } from '../session/index.js';\nimport { applyReasoningVisibilityToSseEvent } from '../streaming/reasoning-visibility-sse.js';\nimport type { ReasoningLevel } from '../transcript/thinking-types.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport { mapEmbeddedEventToGatewaySse } from '../embedded/map-stream-events.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\n\nimport { AsyncQueue } from './async-queue.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\n\nexport type DirectStreamInboundAttachment = {\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n};\n\nexport type ProcessDirectStreamLog = {\n info: (obj: Record<string, unknown>, msg: string) => void;\n warn: (obj: Record<string, unknown>, msg: string) => void;\n debug?: (obj: Record<string, unknown>, msg: string) => void;\n};\n\nexport interface ProcessDirectStreamingDeps {\n log: ProcessDirectStreamLog;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initDirectStreamingSession: (\n sessionKey: string,\n channel: string,\n chatId: string,\n ) => SessionContext;\n registerWebchatSsePublisher: (\n sessionKey: string,\n publisher: (event: { type: string; [key: string]: unknown }) => void,\n ) => void;\n unregisterWebchatSsePublisher: (sessionKey: string) => void;\n agentManager: AgentInstanceGateway;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n getConfig: () => Config | undefined;\n sessionConfigStore: SessionConfigStore;\n attachmentRootsForSession: (sessionKey: string) => InternalAttachmentRoots;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectStreamInboundAttachment[],\n ) => Promise<DirectStreamInboundAttachment[] | undefined>;\n buildMessageContent: (\n content: string,\n attachments: DirectStreamInboundAttachment[] | undefined,\n sessionKey: string,\n ) => Promise<Array<{ type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string }>>;\n recordPersistentGoalStreamOutcome?: (\n sessionKey: string,\n outcome: { skipPersistentGoalPostTurn: boolean },\n ) => void;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n /** Disk-only transcript sync (slash receipt already streamed as tokens). */\n reloadWebchatTranscript?: (sessionKey: string) => void;\n maybeEmitWebchatTts: (\n sessionKey: string,\n hadInboundVoice: boolean,\n ) => Promise<{ type: 'tts_audio'; workspaceRelativePath: string; mimeType: string; name: string } | null>;\n endDirectRequestContext: () => void;\n}\n\nexport interface ProcessDirectStreamingInput {\n content: string;\n sessionKey?: string;\n attachments?: DirectStreamInboundAttachment[];\n thinking?: string;\n signal?: AbortSignal;\n}\n\nexport type ProcessDirectStreamingSseEvent = { type: string; [key: string]: unknown };\n\nexport async function* runProcessDirectStreaming(\n deps: ProcessDirectStreamingDeps,\n input: ProcessDirectStreamingInput,\n): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n const sessionKey = input.sessionKey ?? 'cli:direct';\n const { channel, chatId } = deps.parseSessionKey(sessionKey);\n const context = deps.initDirectStreamingSession(sessionKey, channel, chatId);\n\n const queue = new AsyncQueue<ProcessDirectStreamingSseEvent>();\n let reasoningLevel: ReasoningLevel = 'stream';\n\n const pushVisible = (event: ProcessDirectStreamingSseEvent) => {\n const visible = applyReasoningVisibilityToSseEvent(event, reasoningLevel);\n if (visible !== null) {\n queue.push(visible);\n }\n };\n\n if (channel === 'webchat') {\n deps.registerWebchatSsePublisher(sessionKey, pushVisible);\n }\n\n const signal = input.signal;\n let userAborted = false;\n let abortHandled = false;\n let inboundVoice = false;\n let ranSlashCommand = false;\n let mergedUserText = input.content;\n let webchatSlashReceipt: string | undefined;\n\n // Kick off the agent task in the background; events stream into `queue` as they happen\n // and the generator below drains `queue` until the task closes it.\n const taskPromise = (async () => {\n try {\n await hydratePerTurnState(deps, sessionKey, input.thinking);\n {\n const defReason = (deps.getConfig()?.agents?.defaults?.reasoningDefault ?? 'stream') as ReasoningLevel;\n reasoningLevel = await resolveEffectiveReasoningLevel(deps.sessionConfigStore, sessionKey, defReason);\n }\n\n const prepared = await deps.prepareInboundAttachments(sessionKey, input.attachments);\n\n const sttCfg = mergeSttConfigFromAppConfig(deps.getConfig()?.tools?.media?.audio, deps.getConfig()?.tools?.media);\n const voiceMerge = await mergeVoiceTranscriptsIntoUserText(\n deps.attachmentRootsForSession(sessionKey),\n prepared,\n input.content,\n sttCfg,\n );\n mergedUserText = voiceMerge.text;\n inboundVoice = voiceMerge.inboundVoice;\n\n if (inboundVoice) {\n const transcriptParts = [\n voiceMerge.voiceTranscripts.filter(Boolean).join('\\n'),\n input.content.trim(),\n ].filter(Boolean);\n const voiceAttachments = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({\n workspaceRelativePath: att.workspaceRelativePath,\n mimeType: att.mimeType,\n name: att.name,\n }));\n pushVisible({\n type: 'user_transcript',\n text: transcriptParts.join('\\n\\n'),\n attachments: voiceAttachments,\n });\n }\n\n const armAbort = () => {\n if (abortHandled) {\n return;\n }\n abortHandled = true;\n userAborted = true;\n void abortEmbeddedRun(sessionKey);\n queue.close();\n };\n if (signal) {\n if (signal.aborted) {\n armAbort();\n return;\n }\n signal.addEventListener('abort', armAbort, { once: true });\n }\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey, channel, chatId, senderId: context.senderId, isGroup: context.isGroup },\n mergedUserText,\n );\n if (slash.matched) {\n ranSlashCommand = true;\n const text = slash.aggregatedText.trim();\n if (text) {\n webchatSlashReceipt = text;\n pushVisible({ type: 'token', content: text });\n } else if (channel === 'webchat') {\n webchatSlashReceipt =\n 'Command finished with no assistant text. If you used `/goal`, a follow-up turn may still be scheduled automatically.';\n pushVisible({ type: 'token', content: webchatSlashReceipt });\n }\n return;\n }\n\n const textForAgent = mergedUserText.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(mergedUserText)\n : mergedUserText;\n const messageContent = await deps.buildMessageContent(textForAgent, prepared, sessionKey);\n\n const userMessage = {\n role: 'user' as const,\n content: messageContent,\n timestamp: Date.now(),\n };\n if (channel === 'webchat') {\n pushVisible({\n type: 'user_message',\n timestamp: userMessage.timestamp,\n content: userMessage.content,\n attachments: prepared?.map((att) => ({\n type: att.type,\n mimeType: att.mimeType,\n name: att.name,\n size: att.size,\n workspaceRelativePath: att.workspaceRelativePath,\n })),\n });\n }\n\n const result = await runDirectAgentTurn(\n {\n sessionStore: deps.sessionStore,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n config: deps.getConfig(),\n },\n {\n sessionKey,\n userMessage,\n abortSignal: signal,\n onEvent: (embeddedEvent) => {\n const mapped = mapEmbeddedEventToGatewaySse(embeddedEvent);\n if (mapped) {\n pushVisible(mapped);\n }\n },\n },\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(sessionKey, result.lastAssistantText);\n }\n if (!result.ok && result.errorMessage && !abortHandled) {\n pushVisible({ type: 'error', content: result.errorMessage });\n }\n } catch (err) {\n if (!abortHandled) {\n pushVisible({ type: 'error', content: err instanceof Error ? err.message : String(err) });\n }\n } finally {\n queue.close();\n }\n })();\n\n try {\n for await (const event of queue) {\n yield event;\n }\n await taskPromise; // surface unexpected throws\n\n if (channel === 'webchat' && ranSlashCommand) {\n try {\n const { absPath } = await deps.sessionStore.resolveTranscriptPath(sessionKey);\n const workspaceDir = deps.agentManager.getResolvedWorkspaceForSession(sessionKey);\n const userMsg = {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: mergedUserText }],\n timestamp: Date.now(),\n } as AgentMessage;\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: userMsg,\n sessionKey,\n });\n if (webchatSlashReceipt?.trim()) {\n const assistantMsg = {\n role: 'assistant' as const,\n content: [{ type: 'text' as const, text: webchatSlashReceipt.trim() }],\n timestamp: Date.now(),\n } as AgentMessage;\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: assistantMsg,\n sessionKey,\n });\n }\n deps.reloadWebchatTranscript?.(sessionKey);\n } catch (err) {\n deps.log.warn({ err, sessionKey }, 'Failed to persist webchat slash command receipt');\n }\n }\n\n if (!userAborted) {\n const ttsAudioEvent = await deps.maybeEmitWebchatTts(sessionKey, inboundVoice);\n if (ttsAudioEvent) {\n yield ttsAudioEvent;\n }\n }\n\n deps.recordPersistentGoalStreamOutcome?.(sessionKey, { skipPersistentGoalPostTurn: ranSlashCommand });\n } finally {\n if (channel === 'webchat') {\n deps.unregisterWebchatSsePublisher(sessionKey);\n }\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"process-direct-streaming.js","names":[],"sources":["../../../../src/agent/service/process-direct-streaming.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { InternalAttachmentRoots } from '../../channels/attachments/inbound-persist.js';\nimport {\n isVoiceLikeAttachment,\n mergeVoiceTranscriptsIntoUserText,\n mergeSttConfigFromAppConfig,\n} from '../../channels/attachments/voice-stt-webchat.js';\nimport {\n resolveEffectiveReasoningLevel,\n initSessionTurn,\n type SessionConfigStore,\n type SessionStore,\n} from '../../session/index.js';\nimport { appendPiTranscriptMessage } from '../../session/parity/jsonl-transcript-io.js';\nimport type { SessionContext } from '../session/index.js';\nimport { applyReasoningVisibilityToSseEvent } from '../streaming/reasoning-visibility-sse.js';\nimport type { ReasoningLevel } from '../transcript/thinking-types.js';\nimport { formatAgentRunErrorForClient } from '../client-error-format.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport { mapEmbeddedEventToGatewaySse } from '../embedded/map-stream-events.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\n\nimport { AsyncQueue } from './async-queue.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\n\nexport type DirectStreamInboundAttachment = {\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n};\n\nexport type ProcessDirectStreamLog = {\n info: (obj: Record<string, unknown>, msg: string) => void;\n warn: (obj: Record<string, unknown>, msg: string) => void;\n debug?: (obj: Record<string, unknown>, msg: string) => void;\n};\n\nexport interface ProcessDirectStreamingDeps {\n log: ProcessDirectStreamLog;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initDirectStreamingSession: (\n sessionKey: string,\n channel: string,\n chatId: string,\n ) => SessionContext;\n registerWebchatSsePublisher: (\n sessionKey: string,\n publisher: (event: { type: string; [key: string]: unknown }) => void,\n ) => void;\n unregisterWebchatSsePublisher: (sessionKey: string) => void;\n agentManager: AgentInstanceGateway;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n getConfig: () => Config | undefined;\n sessionConfigStore: SessionConfigStore;\n attachmentRootsForSession: (sessionKey: string) => InternalAttachmentRoots;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectStreamInboundAttachment[],\n ) => Promise<DirectStreamInboundAttachment[] | undefined>;\n buildMessageContent: (\n content: string,\n attachments: DirectStreamInboundAttachment[] | undefined,\n sessionKey: string,\n ) => Promise<Array<{ type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string }>>;\n recordPersistentGoalStreamOutcome?: (\n sessionKey: string,\n outcome: { skipPersistentGoalPostTurn: boolean },\n ) => void;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n /** Disk-only transcript sync (slash receipt already streamed as tokens). */\n reloadWebchatTranscript?: (sessionKey: string) => void;\n maybeEmitWebchatTts: (\n sessionKey: string,\n hadInboundVoice: boolean,\n ) => Promise<{ type: 'tts_audio'; workspaceRelativePath: string; mimeType: string; name: string } | null>;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n}\n\nexport interface ProcessDirectStreamingInput {\n content: string;\n sessionKey?: string;\n attachments?: DirectStreamInboundAttachment[];\n thinking?: string;\n signal?: AbortSignal;\n}\n\nexport type ProcessDirectStreamingSseEvent = { type: string; [key: string]: unknown };\n\nexport async function* runProcessDirectStreaming(\n deps: ProcessDirectStreamingDeps,\n input: ProcessDirectStreamingInput,\n): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n const sessionKey = input.sessionKey ?? 'agent:main:main';\n const { channel, chatId } = deps.parseSessionKey(sessionKey);\n const context = deps.initDirectStreamingSession(sessionKey, channel, chatId);\n\n const queue = new AsyncQueue<ProcessDirectStreamingSseEvent>();\n let reasoningLevel: ReasoningLevel = 'stream';\n\n const pushVisible = (event: ProcessDirectStreamingSseEvent) => {\n const visible = applyReasoningVisibilityToSseEvent(event, reasoningLevel);\n if (visible !== null) {\n queue.push(visible);\n }\n };\n\n const formatStreamError = (raw: string): string => {\n let provider: string | undefined;\n let modelRef: string | undefined;\n try {\n const resolved = deps.modelManager.getResolvedModelForSession(sessionKey);\n provider = resolved.provider;\n modelRef = deps.modelManager.getModelForSession(sessionKey);\n } catch {\n /* ignore — format without provider context */\n }\n return formatAgentRunErrorForClient(raw, { provider, modelRef });\n };\n\n if (channel === 'webchat') {\n deps.registerWebchatSsePublisher(sessionKey, pushVisible);\n }\n\n const signal = input.signal;\n let userAborted = false;\n let abortHandled = false;\n let inboundVoice = false;\n let ranSlashCommand = false;\n let mergedUserText = input.content;\n let webchatSlashReceipt: string | undefined;\n\n // Kick off the agent task in the background; events stream into `queue` as they happen\n // and the generator below drains `queue` until the task closes it.\n const taskPromise = (async () => {\n try {\n const cfg = deps.getConfig();\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n if (cfg) {\n const turn = await initSessionTurn({\n cfg,\n sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n ranSlashCommand = true;\n webchatSlashReceipt = turn.ackMessage;\n pushVisible({ type: 'token', content: turn.ackMessage });\n return;\n }\n turnBody = turn.bodyStripped;\n if (turn.isNewSession) {\n deps.log.debug(\n {\n sessionKey,\n sessionId: turn.sessionId,\n previousSessionId: turn.previousSessionId,\n resetTriggered: turn.resetTriggered,\n staleRollover: turn.staleRollover,\n },\n 'Session reset boundary at direct turn start',\n );\n }\n }\n\n await hydratePerTurnState(deps, sessionKey, input.thinking);\n {\n const defReason = (deps.getConfig()?.agents?.defaults?.reasoningDefault ?? 'stream') as ReasoningLevel;\n reasoningLevel = await resolveEffectiveReasoningLevel(deps.sessionConfigStore, sessionKey, defReason);\n }\n\n const prepared = await deps.prepareInboundAttachments(sessionKey, input.attachments);\n\n const sttCfg = mergeSttConfigFromAppConfig(deps.getConfig()?.tools?.media?.audio, deps.getConfig()?.tools?.media);\n const voiceMerge = await mergeVoiceTranscriptsIntoUserText(\n deps.attachmentRootsForSession(sessionKey),\n prepared,\n turnBody,\n sttCfg,\n );\n mergedUserText = voiceMerge.text;\n inboundVoice = voiceMerge.inboundVoice;\n\n if (inboundVoice) {\n const transcriptParts = [\n voiceMerge.voiceTranscripts.filter(Boolean).join('\\n'),\n turnBody.trim(),\n ].filter(Boolean);\n const voiceAttachments = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({\n workspaceRelativePath: att.workspaceRelativePath,\n mimeType: att.mimeType,\n name: att.name,\n }));\n pushVisible({\n type: 'user_transcript',\n text: transcriptParts.join('\\n\\n'),\n attachments: voiceAttachments,\n });\n }\n\n const armAbort = () => {\n if (abortHandled) {\n return;\n }\n abortHandled = true;\n userAborted = true;\n void abortEmbeddedRun(sessionKey);\n queue.close();\n };\n if (signal) {\n if (signal.aborted) {\n armAbort();\n return;\n }\n signal.addEventListener('abort', armAbort, { once: true });\n }\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey, channel, chatId, senderId: context.senderId, isGroup: context.isGroup },\n mergedUserText,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n ranSlashCommand = true;\n const text = slash.aggregatedText.trim();\n if (text) {\n webchatSlashReceipt = text;\n pushVisible({ type: 'token', content: text });\n } else if (channel === 'webchat') {\n webchatSlashReceipt =\n 'Command finished with no assistant text. If you used `/goal`, a follow-up turn may still be scheduled automatically.';\n pushVisible({ type: 'token', content: webchatSlashReceipt });\n }\n return;\n }\n\n const textForAgent = mergedUserText.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(mergedUserText)\n : mergedUserText;\n const messageContent = await deps.buildMessageContent(textForAgent, prepared, sessionKey);\n\n const userMessage = {\n role: 'user' as const,\n content: messageContent,\n timestamp: Date.now(),\n };\n if (channel === 'webchat') {\n pushVisible({\n type: 'user_message',\n timestamp: userMessage.timestamp,\n content: userMessage.content,\n attachments: prepared?.map((att) => ({\n type: att.type,\n mimeType: att.mimeType,\n name: att.name,\n size: att.size,\n workspaceRelativePath: att.workspaceRelativePath,\n })),\n });\n }\n\n const result = await runDirectAgentTurn(\n {\n sessionStore: deps.sessionStore,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n config: deps.getConfig(),\n },\n {\n sessionKey,\n userMessage,\n abortSignal: signal,\n onEvent: (embeddedEvent) => {\n const mapped = mapEmbeddedEventToGatewaySse(embeddedEvent);\n if (mapped) {\n if (mapped.type === 'error' && typeof mapped.content === 'string') {\n mapped.content = formatStreamError(mapped.content);\n }\n pushVisible(mapped);\n }\n },\n },\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(sessionKey, result.lastAssistantText);\n }\n if (!result.ok && result.errorMessage && !abortHandled) {\n pushVisible({ type: 'error', content: formatStreamError(result.errorMessage) });\n }\n } catch (err) {\n if (!abortHandled) {\n const em = err instanceof Error ? err.message : String(err);\n pushVisible({ type: 'error', content: formatStreamError(em) });\n }\n } finally {\n queue.close();\n }\n })();\n\n try {\n for await (const event of queue) {\n yield event;\n }\n await taskPromise; // surface unexpected throws\n\n if (channel === 'webchat' && ranSlashCommand) {\n try {\n const { absPath } = await deps.sessionStore.resolveTranscriptPath(sessionKey);\n const workspaceDir = deps.agentManager.getResolvedWorkspaceForSession(sessionKey);\n const userMsg = {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: mergedUserText }],\n timestamp: Date.now(),\n } as AgentMessage;\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: userMsg,\n sessionKey,\n });\n if (webchatSlashReceipt?.trim()) {\n const assistantMsg = {\n role: 'assistant' as const,\n content: [{ type: 'text' as const, text: webchatSlashReceipt.trim() }],\n timestamp: Date.now(),\n } as AgentMessage;\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: assistantMsg,\n sessionKey,\n });\n }\n deps.reloadWebchatTranscript?.(sessionKey);\n } catch (err) {\n deps.log.warn({ err, sessionKey }, 'Failed to persist webchat slash command receipt');\n }\n }\n\n if (!userAborted) {\n const ttsAudioEvent = await deps.maybeEmitWebchatTts(sessionKey, inboundVoice);\n if (ttsAudioEvent) {\n yield ttsAudioEvent;\n }\n }\n\n deps.recordPersistentGoalStreamOutcome?.(sessionKey, { skipPersistentGoalPostTurn: ranSlashCommand });\n } finally {\n if (channel === 'webchat') {\n deps.unregisterWebchatSsePublisher(sessionKey);\n }\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":";;;;;;;;;;;;AAyGA,gBAAuB,0BACrB,MACA,OAC+D;CAC/D,MAAM,aAAa,MAAM,cAAc;CACvC,MAAM,EAAE,SAAS,WAAW,KAAK,gBAAgB,WAAW;CAC5D,MAAM,UAAU,KAAK,2BAA2B,YAAY,SAAS,OAAO;CAE5E,MAAM,QAAQ,IAAI,YAA4C;CAC9D,IAAI,iBAAiC;CAErC,MAAM,eAAe,UAA0C;EAC7D,MAAM,UAAU,mCAAmC,OAAO,eAAe;AACzE,MAAI,YAAY,KACd,OAAM,KAAK,QAAQ;;CAIvB,MAAM,qBAAqB,QAAwB;EACjD,IAAI;EACJ,IAAI;AACJ,MAAI;AAEF,cADiB,KAAK,aAAa,2BAA2B,WAC3C,CAAC;AACpB,cAAW,KAAK,aAAa,mBAAmB,WAAW;UACrD;AAGR,SAAO,6BAA6B,KAAK;GAAE;GAAU;GAAU,CAAC;;AAGlE,KAAI,YAAY,UACd,MAAK,4BAA4B,YAAY,YAAY;CAG3D,MAAM,SAAS,MAAM;CACrB,IAAI,cAAc;CAClB,IAAI,eAAe;CACnB,IAAI,eAAe;CACnB,IAAI,kBAAkB;CACtB,IAAI,iBAAiB,MAAM;CAC3B,IAAI;CAIJ,MAAM,eAAe,YAAY;AAC/B,MAAI;GACF,MAAM,MAAM,KAAK,WAAW;GAC5B,IAAI,WAAW,MAAM;GACrB,IAAI,uBAAuB;AAC3B,OAAI,KAAK;IACP,MAAM,OAAO,MAAM,gBAAgB;KACjC;KACA;KACA,MAAM,MAAM;KACZ,cAAc,KAAK;KACpB,CAAC;AACF,2BAAuB,KAAK;AAC5B,QAAI,KAAK,aAAa,KAAK,YAAY;AACrC,uBAAkB;AAClB,2BAAsB,KAAK;AAC3B,iBAAY;MAAE,MAAM;MAAS,SAAS,KAAK;MAAY,CAAC;AACxD;;AAEF,eAAW,KAAK;AAChB,QAAI,KAAK,aACP,MAAK,IAAI,MACP;KACE;KACA,WAAW,KAAK;KAChB,mBAAmB,KAAK;KACxB,gBAAgB,KAAK;KACrB,eAAe,KAAK;KACrB,EACD,8CACD;;AAIL,SAAM,oBAAoB,MAAM,YAAY,MAAM,SAAS;GAC3D;IACE,MAAM,YAAa,KAAK,WAAW,EAAE,QAAQ,UAAU,oBAAoB;AAC3E,qBAAiB,MAAM,+BAA+B,KAAK,oBAAoB,YAAY,UAAU;;GAGvG,MAAM,WAAW,MAAM,KAAK,0BAA0B,YAAY,MAAM,YAAY;GAEpF,MAAM,SAAS,4BAA4B,KAAK,WAAW,EAAE,OAAO,OAAO,OAAO,KAAK,WAAW,EAAE,OAAO,MAAM;GACjH,MAAM,aAAa,MAAM,kCACvB,KAAK,0BAA0B,WAAW,EAC1C,UACA,UACA,OACD;AACD,oBAAiB,WAAW;AAC5B,kBAAe,WAAW;AAE1B,OAAI,cAAc;IAChB,MAAM,kBAAkB,CACtB,WAAW,iBAAiB,OAAO,QAAQ,CAAC,KAAK,KAAK,EACtD,SAAS,MAAM,CAChB,CAAC,OAAO,QAAQ;IACjB,MAAM,oBAAoB,YAAY,EAAE,EAAE,OAAO,sBAAsB,CAAC,KAAK,SAAS;KACpF,uBAAuB,IAAI;KAC3B,UAAU,IAAI;KACd,MAAM,IAAI;KACX,EAAE;AACH,gBAAY;KACV,MAAM;KACN,MAAM,gBAAgB,KAAK,OAAO;KAClC,aAAa;KACd,CAAC;;GAGJ,MAAM,iBAAiB;AACrB,QAAI,aACF;AAEF,mBAAe;AACf,kBAAc;AACT,qBAAiB,WAAW;AACjC,UAAM,OAAO;;AAEf,OAAI,QAAQ;AACV,QAAI,OAAO,SAAS;AAClB,eAAU;AACV;;AAEF,WAAO,iBAAiB,SAAS,UAAU,EAAE,MAAM,MAAM,CAAC;;GAG5D,MAAM,QAAQ,MAAM,mBAClB,MACA;IAAE;IAAY;IAAS;IAAQ,UAAU,QAAQ;IAAU,SAAS,QAAQ;IAAS,EACrF,gBACA,EAAE,mBAAmB,sBAAsB,CAC5C;AACD,OAAI,MAAM,SAAS;AACjB,sBAAkB;IAClB,MAAM,OAAO,MAAM,eAAe,MAAM;AACxC,QAAI,MAAM;AACR,2BAAsB;AACtB,iBAAY;MAAE,MAAM;MAAS,SAAS;MAAM,CAAC;eACpC,YAAY,WAAW;AAChC,2BACE;AACF,iBAAY;MAAE,MAAM;MAAS,SAAS;MAAqB,CAAC;;AAE9D;;GAGF,MAAM,eAAe,eAAe,WAAW,CAAC,WAAW,UAAU,GACjE,KAAK,aAAa,oBAAoB,eAAe,GACrD;GAGJ,MAAM,cAAc;IAClB,MAAM;IACN,SAAS,MAJkB,KAAK,oBAAoB,cAAc,UAAU,WAAW;IAKvF,WAAW,KAAK,KAAK;IACtB;AACD,OAAI,YAAY,UACd,aAAY;IACV,MAAM;IACN,WAAW,YAAY;IACvB,SAAS,YAAY;IACrB,aAAa,UAAU,KAAK,SAAS;KACnC,MAAM,IAAI;KACV,UAAU,IAAI;KACd,MAAM,IAAI;KACV,MAAM,IAAI;KACV,uBAAuB,IAAI;KAC5B,EAAE;IACJ,CAAC;GAGJ,MAAM,SAAS,MAAM,mBACnB;IACE,cAAc,KAAK;IACnB,cAAc,KAAK;IACnB,cAAc,KAAK;IACnB,QAAQ,KAAK,WAAW;IACzB,EACD;IACE;IACA;IACA,aAAa;IACb,UAAU,kBAAkB;KAC1B,MAAM,SAAS,6BAA6B,cAAc;AAC1D,SAAI,QAAQ;AACV,UAAI,OAAO,SAAS,WAAW,OAAO,OAAO,YAAY,SACvD,QAAO,UAAU,kBAAkB,OAAO,QAAQ;AAEpD,kBAAY,OAAO;;;IAGxB,CACF;AAED,OAAI,OAAO,kBACT,MAAK,iBAAiB,YAAY,OAAO,kBAAkB;AAE7D,OAAI,CAAC,OAAO,MAAM,OAAO,gBAAgB,CAAC,aACxC,aAAY;IAAE,MAAM;IAAS,SAAS,kBAAkB,OAAO,aAAa;IAAE,CAAC;WAE1E,KAAK;AACZ,OAAI,CAAC,aAEH,aAAY;IAAE,MAAM;IAAS,SAAS,kBAD3B,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CACA;IAAE,CAAC;YAExD;AACR,SAAM,OAAO;;KAEb;AAEJ,KAAI;AACF,aAAW,MAAM,SAAS,MACxB,OAAM;AAER,QAAM;AAEN,MAAI,YAAY,aAAa,gBAC3B,KAAI;GACF,MAAM,EAAE,YAAY,MAAM,KAAK,aAAa,sBAAsB,WAAW;GAC7E,MAAM,eAAe,KAAK,aAAa,+BAA+B,WAAW;AAMjF,SAAM,0BAA0B;IAC9B;IACA,KAAK;IACL,SAAS;KAPT,MAAM;KACN,SAAS,CAAC;MAAE,MAAM;MAAiB,MAAM;MAAgB,CAAC;KAC1D,WAAW,KAAK,KAAK;KAKL;IAChB;IACD,CAAC;AACF,OAAI,qBAAqB,MAAM,CAM7B,OAAM,0BAA0B;IAC9B;IACA,KAAK;IACL,SAAS;KAPT,MAAM;KACN,SAAS,CAAC;MAAE,MAAM;MAAiB,MAAM,oBAAoB,MAAM;MAAE,CAAC;KACtE,WAAW,KAAK,KAAK;KAKA;IACrB;IACD,CAAC;AAEJ,QAAK,0BAA0B,WAAW;WACnC,KAAK;AACZ,QAAK,IAAI,KAAK;IAAE;IAAK;IAAY,EAAE,kDAAkD;;AAIzF,MAAI,CAAC,aAAa;GAChB,MAAM,gBAAgB,MAAM,KAAK,oBAAoB,YAAY,aAAa;AAC9E,OAAI,cACF,OAAM;;AAIV,OAAK,oCAAoC,YAAY,EAAE,4BAA4B,iBAAiB,CAAC;WAC7F;AACR,MAAI,YAAY,UACd,MAAK,8BAA8B,WAAW;AAEhD,OAAK,yBAAyB"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Config } from '../../config/schema.js';
|
|
2
|
-
import type { AgentInstanceGateway } from '../agent-instance-gateway.js';
|
|
3
2
|
import type { SessionStore } from '../../session/index.js';
|
|
4
3
|
export type WebchatTtsResult = {
|
|
5
4
|
type: 'tts_audio';
|
|
@@ -9,8 +8,8 @@ export type WebchatTtsResult = {
|
|
|
9
8
|
};
|
|
10
9
|
export type WebchatTtsDeps = {
|
|
11
10
|
config: Config | undefined;
|
|
12
|
-
agentManager: AgentInstanceGateway;
|
|
13
11
|
sessionStore: SessionStore;
|
|
12
|
+
getLastAssistantPlainText: (sessionKey: string) => string;
|
|
14
13
|
log: {
|
|
15
14
|
warn: (obj: Record<string, unknown>, msg: string) => void;
|
|
16
15
|
};
|
|
@@ -16,7 +16,7 @@ async function maybeEmitWebchatTts(deps, sessionKey, hadInboundVoice) {
|
|
|
16
16
|
const ttsConfig = mergeTtsConfigFromAppConfig(deps.config?.messages?.tts);
|
|
17
17
|
if (!isTTSAvailable(ttsConfig)) return null;
|
|
18
18
|
if (!shouldUseTTS(ttsConfig, hadInboundVoice).useTTS) return null;
|
|
19
|
-
const text = deps.
|
|
19
|
+
const text = deps.getLastAssistantPlainText(sessionKey).trim();
|
|
20
20
|
if (!text) return null;
|
|
21
21
|
try {
|
|
22
22
|
const webOut = getChannelOutputFormat("webchat");
|
|
@@ -62,7 +62,7 @@ async function appendAttachmentToLastAssistant(sessionStore, sessionKey, att) {
|
|
|
62
62
|
...m,
|
|
63
63
|
attachments: next
|
|
64
64
|
};
|
|
65
|
-
await sessionStore.
|
|
65
|
+
await sessionStore.saveMessages(sessionKey, loaded);
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webchat-tts.js","names":[],"sources":["../../../../src/agent/service/webchat-tts.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { persistOutboundTtsAudio } from '../../channels/attachments/outbound-tts-persist.js';\nimport { compressAudio } from '../../voice/tts/audio.js';\nimport { speak } from '../../voice/tts/index.js';\nimport { mergeTtsConfigFromAppConfig } from '../../voice/tts/merge-config.js';\nimport { shouldUseTTS, getChannelOutputFormat } from '../../voice/tts/service.js';\nimport { isTTSAvailable } from '../../voice/tts/factory.js';\nimport { resolveAgentHomeDir } from '../agent-scope.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\nimport type {
|
|
1
|
+
{"version":3,"file":"webchat-tts.js","names":[],"sources":["../../../../src/agent/service/webchat-tts.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { persistOutboundTtsAudio } from '../../channels/attachments/outbound-tts-persist.js';\nimport { compressAudio } from '../../voice/tts/audio.js';\nimport { speak } from '../../voice/tts/index.js';\nimport { mergeTtsConfigFromAppConfig } from '../../voice/tts/merge-config.js';\nimport { shouldUseTTS, getChannelOutputFormat } from '../../voice/tts/service.js';\nimport { isTTSAvailable } from '../../voice/tts/factory.js';\nimport { resolveAgentHomeDir } from '../agent-scope.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nexport type WebchatTtsResult = {\n type: 'tts_audio';\n workspaceRelativePath: string;\n mimeType: string;\n name: string;\n};\n\nexport type WebchatTtsDeps = {\n config: Config | undefined;\n sessionStore: SessionStore;\n getLastAssistantPlainText: (sessionKey: string) => string;\n log: { warn: (obj: Record<string, unknown>, msg: string) => void };\n};\n\n/**\n * Generate TTS for webchat when config allows; persist under agent home `tts/`.\n */\nexport async function maybeEmitWebchatTts(\n deps: WebchatTtsDeps,\n sessionKey: string,\n hadInboundVoice: boolean,\n): Promise<WebchatTtsResult | null> {\n const ttsConfig = mergeTtsConfigFromAppConfig(deps.config?.messages?.tts);\n if (!isTTSAvailable(ttsConfig)) {\n return null;\n }\n const decision = shouldUseTTS(ttsConfig, hadInboundVoice);\n if (!decision.useTTS) {\n return null;\n }\n const text = deps.getLastAssistantPlainText(sessionKey).trim();\n if (!text) {\n return null;\n }\n try {\n const webOut = getChannelOutputFormat('webchat');\n const fmt = webOut.format as 'opus' | 'mp3' | 'wav';\n const ttsResult = await speak(text, ttsConfig, {\n appConfig: deps.config,\n tts: { format: fmt },\n });\n const { buffer, format } = await compressAudio(\n Buffer.from(ttsResult.audio),\n ttsResult.format,\n webOut.format === 'mp3' ? 'mp3' : 'opus',\n );\n const normalizedMime =\n format === 'opus' || format === 'ogg'\n ? 'audio/ogg'\n : format === 'mp3' || format === 'mpeg'\n ? 'audio/mpeg'\n : format === 'wav'\n ? 'audio/wav'\n : `audio/${format}`;\n const cfg = deps.config!;\n const persisted = await persistOutboundTtsAudio(\n resolveAgentHomeDir(cfg, extractProfileAgentId(sessionKey, cfg)),\n sessionKey,\n buffer,\n format,\n );\n await appendAttachmentToLastAssistant(deps.sessionStore, sessionKey, {\n type: 'audio',\n mimeType: normalizedMime,\n name: persisted.name,\n size: persisted.size,\n workspaceRelativePath: persisted.workspaceRelativePath,\n });\n return {\n type: 'tts_audio',\n workspaceRelativePath: persisted.workspaceRelativePath,\n mimeType: normalizedMime,\n name: persisted.name,\n };\n } catch (err) {\n deps.log.warn({ err, sessionKey }, 'Webchat TTS failed');\n return null;\n }\n}\n\nexport async function appendAttachmentToLastAssistant(\n sessionStore: SessionStore,\n sessionKey: string,\n att: {\n type: string;\n mimeType: string;\n name: string;\n size: number;\n workspaceRelativePath: string;\n },\n): Promise<void> {\n const loaded = await sessionStore.load(sessionKey);\n for (let i = loaded.length - 1; i >= 0; i--) {\n const m = loaded[i] as { role?: string; attachments?: unknown[] };\n if (m.role === 'assistant') {\n const prev = (m.attachments ?? []) as Array<{ workspaceRelativePath?: string }>;\n if (prev.some((x) => x.workspaceRelativePath === att.workspaceRelativePath)) {\n return;\n }\n const next = [...prev, att];\n loaded[i] = { ...m, attachments: next } as unknown as AgentMessage;\n await sessionStore.saveMessages(sessionKey, loaded);\n return;\n }\n }\n}\n"],"mappings":";;;;;;;;;;kBAOwD;;;;AAsBxD,eAAsB,oBACpB,MACA,YACA,iBACkC;CAClC,MAAM,YAAY,4BAA4B,KAAK,QAAQ,UAAU,IAAI;AACzE,KAAI,CAAC,eAAe,UAAU,CAC5B,QAAO;AAGT,KAAI,CADa,aAAa,WAAW,gBAC5B,CAAC,OACZ,QAAO;CAET,MAAM,OAAO,KAAK,0BAA0B,WAAW,CAAC,MAAM;AAC9D,KAAI,CAAC,KACH,QAAO;AAET,KAAI;EACF,MAAM,SAAS,uBAAuB,UAAU;EAChD,MAAM,MAAM,OAAO;EACnB,MAAM,YAAY,MAAM,MAAM,MAAM,WAAW;GAC7C,WAAW,KAAK;GAChB,KAAK,EAAE,QAAQ,KAAK;GACrB,CAAC;EACF,MAAM,EAAE,QAAQ,WAAW,MAAM,cAC/B,OAAO,KAAK,UAAU,MAAM,EAC5B,UAAU,QACV,OAAO,WAAW,QAAQ,QAAQ,OACnC;EACD,MAAM,iBACJ,WAAW,UAAU,WAAW,QAC5B,cACA,WAAW,SAAS,WAAW,SAC7B,eACA,WAAW,QACT,cACA,SAAS;EACnB,MAAM,MAAM,KAAK;EACjB,MAAM,YAAY,MAAM,wBACtB,oBAAoB,KAAK,sBAAsB,YAAY,IAAI,CAAC,EAChE,YACA,QACA,OACD;AACD,QAAM,gCAAgC,KAAK,cAAc,YAAY;GACnE,MAAM;GACN,UAAU;GACV,MAAM,UAAU;GAChB,MAAM,UAAU;GAChB,uBAAuB,UAAU;GAClC,CAAC;AACF,SAAO;GACL,MAAM;GACN,uBAAuB,UAAU;GACjC,UAAU;GACV,MAAM,UAAU;GACjB;UACM,KAAK;AACZ,OAAK,IAAI,KAAK;GAAE;GAAK;GAAY,EAAE,qBAAqB;AACxD,SAAO;;;AAIX,eAAsB,gCACpB,cACA,YACA,KAOe;CACf,MAAM,SAAS,MAAM,aAAa,KAAK,WAAW;AAClD,MAAK,IAAI,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;EAC3C,MAAM,IAAI,OAAO;AACjB,MAAI,EAAE,SAAS,aAAa;GAC1B,MAAM,OAAQ,EAAE,eAAe,EAAE;AACjC,OAAI,KAAK,MAAM,MAAM,EAAE,0BAA0B,IAAI,sBAAsB,CACzE;GAEF,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI;AAC3B,UAAO,KAAK;IAAE,GAAG;IAAG,aAAa;IAAM;AACvC,SAAM,aAAa,aAAa,YAAY,OAAO;AACnD"}
|
|
@@ -172,6 +172,14 @@ export declare class AgentService {
|
|
|
172
172
|
* `agentService.sessionStore.*` directly.
|
|
173
173
|
*/
|
|
174
174
|
clearSessionMessages(key: string): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Reset session transcript (archive + new session id) and evict in-memory agent state.
|
|
177
|
+
* Preserves the session key and persisted per-session overrides.
|
|
178
|
+
*/
|
|
179
|
+
resetSession(key: string): Promise<{
|
|
180
|
+
sessionId: string;
|
|
181
|
+
previousSessionId: string;
|
|
182
|
+
} | null>;
|
|
175
183
|
/**
|
|
176
184
|
* Drop in-memory agent so the next turn reloads transcript from disk (e.g. after checkpoint restore).
|
|
177
185
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { init_agent_scope, resolveAgentHomeDir, resolveAgentProfileDir, resolveDefaultAgentId } from "./agent-scope.js";
|
|
1
4
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
2
5
|
import { applyConfigOverrides } from "../config/runtime-overrides.js";
|
|
3
|
-
import { init_agent_scope, resolveAgentHomeDir, resolveAgentProfileDir, resolveDefaultAgentId } from "./agent-scope.js";
|
|
4
6
|
import { extractProfileAgentId, resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
5
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
6
|
-
import { init_logger } from "../utils/logger.js";
|
|
7
7
|
import { extractTextContent } from "./context/workspace.js";
|
|
8
8
|
import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
|
|
9
9
|
import { getWorkflowProgressBroker } from "./workflow/progress-broker.js";
|
|
@@ -59,8 +59,8 @@ import { reconcileManagedDreamingCronJobs } from "./service/reconcile-dreaming-c
|
|
|
59
59
|
import { parseOutboundSessionKey } from "./service/parse-outbound-session-key.js";
|
|
60
60
|
import { cleanTrailingErrors } from "./memory/message-sanitizer.js";
|
|
61
61
|
import { tryApplySessionTranscriptHygiene } from "./transcript/transcript-hygiene.js";
|
|
62
|
-
import { join } from "node:path";
|
|
63
62
|
import { existsSync, readFileSync } from "node:fs";
|
|
63
|
+
import { join } from "node:path";
|
|
64
64
|
//#region src/agent/service.ts
|
|
65
65
|
init_schema();
|
|
66
66
|
init_logger();
|
|
@@ -279,6 +279,7 @@ var AgentService = class {
|
|
|
279
279
|
invalidateAgentSession: (sessionKey) => {
|
|
280
280
|
this.agentManager.removeAgent(sessionKey);
|
|
281
281
|
},
|
|
282
|
+
resetSession: (sessionKey) => this.resetSession(sessionKey),
|
|
282
283
|
abortSessionTurn: async (sessionKey) => {
|
|
283
284
|
await this.streamManager.abort();
|
|
284
285
|
this.agentOrchestrator.abort(sessionKey);
|
|
@@ -343,7 +344,8 @@ var AgentService = class {
|
|
|
343
344
|
prepareInboundAttachments: (sk, att) => this.prepareInboundAttachments(sk, att),
|
|
344
345
|
enqueueMaybeAutoTitleAfterPersist: (sk) => this.enqueueMaybeAutoTitleAfterPersist(sk),
|
|
345
346
|
endDirectRequestContext: () => this.endDirectRequestContext(),
|
|
346
|
-
onSessionTranscriptUpdated: this.onSessionTranscriptUpdated
|
|
347
|
+
onSessionTranscriptUpdated: this.onSessionTranscriptUpdated,
|
|
348
|
+
resetSession: (sk) => this.resetSession(sk)
|
|
347
349
|
});
|
|
348
350
|
this.inboundLoop = new InboundLoop({
|
|
349
351
|
log,
|
|
@@ -368,6 +370,7 @@ var AgentService = class {
|
|
|
368
370
|
checkAndCompact: (sk, msgs) => this.checkAndCompact(sk, msgs),
|
|
369
371
|
enqueueMaybeAutoTitleAfterPersist: (sk) => this.enqueueMaybeAutoTitleAfterPersist(sk),
|
|
370
372
|
getConfig: () => this.effectiveAppConfig(),
|
|
373
|
+
resetSession: (sk) => this.resetSession(sk),
|
|
371
374
|
setStreamHandle: (handle) => this.setStreamHandle(handle)
|
|
372
375
|
});
|
|
373
376
|
if (!!!process.env.ELECTRON_RUN_AS_NODE) {
|
|
@@ -665,6 +668,23 @@ var AgentService = class {
|
|
|
665
668
|
this.agentManager.removeAgent(key);
|
|
666
669
|
}
|
|
667
670
|
/**
|
|
671
|
+
* Reset session transcript (archive + new session id) and evict in-memory agent state.
|
|
672
|
+
* Preserves the session key and persisted per-session overrides.
|
|
673
|
+
*/
|
|
674
|
+
async resetSession(key) {
|
|
675
|
+
const { abortEmbeddedRun } = await import("./embedded/runs.js");
|
|
676
|
+
const { retireSessionMcpRuntimeForSessionKey } = await import("./mcp/bundle-mcp-tools.js");
|
|
677
|
+
await abortEmbeddedRun(key);
|
|
678
|
+
const outcome = await this.sessionStore.reset(key);
|
|
679
|
+
if (!outcome) return null;
|
|
680
|
+
this.agentManager.removeAgent(key);
|
|
681
|
+
await retireSessionMcpRuntimeForSessionKey({
|
|
682
|
+
sessionKey: key,
|
|
683
|
+
reason: "session-reset"
|
|
684
|
+
});
|
|
685
|
+
return outcome;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
668
688
|
* Drop in-memory agent so the next turn reloads transcript from disk (e.g. after checkpoint restore).
|
|
669
689
|
*/
|
|
670
690
|
evictSessionAgent(sessionKey) {
|