@xopcai/xopc 0.0.103 → 0.0.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/README.zh-CN.md +7 -4
- package/dist/_virtual/_rolldown/runtime.js +2 -3
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/adapters/cli-login.d.ts +1 -1
- package/dist/extensions/feishu/src/adapters/cli-login.js +1 -1
- package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
- package/dist/extensions/feishu/src/adapters/gateway-setup.d.ts +2 -0
- package/dist/extensions/feishu/src/adapters/gateway-setup.js +225 -0
- package/dist/extensions/feishu/src/adapters/gateway-setup.js.map +1 -0
- package/dist/extensions/feishu/src/index.d.ts +8 -1
- package/dist/extensions/feishu/src/index.js +14 -1
- package/dist/extensions/feishu/src/index.js.map +1 -0
- package/dist/extensions/feishu/src/outbound/outbound-adapter.js +1 -1
- package/dist/extensions/feishu/src/plugin.d.ts +2 -1
- package/dist/extensions/feishu/src/plugin.js +2 -0
- package/dist/extensions/feishu/src/plugin.js.map +1 -1
- package/dist/extensions/feishu/src/streaming/streaming-adapter.js +1 -1
- package/dist/extensions/feishu/src/transport/webhook/monitor.js +1 -1
- package/dist/extensions/feishu/xopc.extension.json +66 -1
- package/dist/extensions/telegram/src/adapters/gateway-setup.d.ts +2 -0
- package/dist/extensions/telegram/src/adapters/gateway-setup.js +146 -0
- package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -0
- package/dist/extensions/telegram/src/adapters/security-adapter.js +1 -1
- package/dist/extensions/telegram/src/command-handler.js +1 -2
- package/dist/extensions/telegram/src/command-handler.js.map +1 -1
- package/dist/extensions/telegram/src/config-schema.js +2 -2
- package/dist/extensions/telegram/src/config-schema.js.map +1 -1
- package/dist/extensions/telegram/src/doctor.d.ts +1 -0
- package/dist/extensions/telegram/src/doctor.js +68 -0
- package/dist/extensions/telegram/src/doctor.js.map +1 -1
- package/dist/extensions/telegram/src/index.d.ts +8 -1
- package/dist/extensions/telegram/src/index.js +15 -2
- package/dist/extensions/telegram/src/index.js.map +1 -0
- package/dist/extensions/telegram/src/plugin.d.ts +13 -5
- package/dist/extensions/telegram/src/plugin.js +32 -12
- package/dist/extensions/telegram/src/plugin.js.map +1 -1
- package/dist/extensions/telegram/src/proxy-fetch.js +22 -5
- package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -1
- package/dist/extensions/telegram/xopc.extension.json +412 -5
- package/dist/extensions/weixin/src/adapters/onboard-cli.js +2 -2
- package/dist/extensions/weixin/src/adapters/onboard-cli.js.map +1 -1
- package/dist/extensions/weixin/src/api/api.js +1 -1
- package/dist/extensions/weixin/src/index.d.ts +8 -0
- package/dist/extensions/weixin/src/index.js +12 -1
- package/dist/extensions/weixin/src/index.js.map +1 -0
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.d.ts +2 -1
- package/dist/extensions/weixin/src/plugin.js +77 -2
- package/dist/extensions/weixin/src/plugin.js.map +1 -1
- package/dist/extensions/weixin/xopc.extension.json +52 -0
- package/dist/gateway/static/root/assets/agents-CvsBrBfi.js +396 -0
- package/dist/gateway/static/root/assets/{apps-page-C5RmwmTT.js → apps-page-L-IwQTe0.js} +1 -1
- package/dist/gateway/static/root/assets/browser-BLJWD7WI.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-D95KuPeP.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-CfkWXDAI.js +1 -0
- package/dist/gateway/static/root/assets/{dist-CWm8hTXZ.js → dist-C6vclgEL.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BzYgTkS9.js → extension-debug-page-D4JYAbsX.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BmTZH6gL.js → extension-page-_T62gi6e.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CkJbjyM-.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-CMoWY2Si.js → fetch-B5aiIguv.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-startup-retry-DqmLXhs6.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-config-api-HwJV1K_Y.js +1 -0
- package/dist/gateway/static/root/assets/index-BPYKW7FB.css +1 -0
- package/dist/gateway/static/root/assets/index-DvTb6wNR.js +4845 -0
- package/dist/gateway/static/root/assets/{logs-page-BjdQjHwk.js → logs-page-DsjtTjBy.js} +2 -2
- package/dist/gateway/static/root/assets/{note-detail-page-8Er4197b.js → note-detail-page-B2V7RhgD.js} +43 -43
- package/dist/gateway/static/root/assets/{note-time-CF3vf1jm.js → note-time-BG8GCTr4.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-xrcVBQ6Z.js +1 -0
- package/dist/gateway/static/root/assets/schema-form-S-QUvhul.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-CrQer6Au.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DujQl9c7.js +2 -0
- package/dist/gateway/static/root/assets/{settings-form-section-C7qA7y0J.js → settings-form-section-r1V7dRV6.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-C9nrONQ2.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Tvr5Mtq5.js → share-preview-page-DOFy0FNt.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-DmTsrs_a.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-HTvJlFLL.js → theme-store-Bo3j5Ovv.js} +1 -1
- package/dist/gateway/static/root/assets/url-WgQIjFZu.js +3 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-AjmUAlEQ.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-page.utils-CeBkAjP7.js → workflow-page.utils-DLEJ92gK.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-BnjjKrM1.js +27 -0
- package/dist/gateway/static/root/index.html +6 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +18 -6
- package/dist/src/agent/agent-manager.js +60 -35
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/builtin-agent-ids.d.ts +2 -0
- package/dist/src/agent/builtin-agent-ids.js +17 -0
- package/dist/src/agent/builtin-agent-ids.js.map +1 -0
- package/dist/src/agent/child-agent-factory.d.ts +4 -0
- package/dist/src/agent/child-agent-factory.js +28 -8
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/context/workspace-seed.js +1 -1
- package/dist/src/agent/context/workspace-templates/AGENTS.md +23 -184
- package/dist/src/agent/embedded/run-turn.js +8 -2
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
- package/dist/src/agent/embedded/subscribe-session.js +33 -51
- package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
- package/dist/src/agent/embedded/types.d.ts +36 -35
- package/dist/src/agent/fallback/candidates.js +1 -1
- package/dist/src/agent/fallback/candidates.js.map +1 -1
- package/dist/src/agent/inbound/inbound-loop.js +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +24 -5
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/models/manager.d.ts +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/models/manager.js.map +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +4 -0
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
- package/dist/src/agent/service/direct-turn-helpers.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
- package/dist/src/agent/service/process-direct-streaming.js +35 -18
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service-inbound-utils.d.ts +0 -1
- package/dist/src/agent/service-inbound-utils.js +1 -17
- package/dist/src/agent/service-inbound-utils.js.map +1 -1
- package/dist/src/agent/service.d.ts +4 -4
- package/dist/src/agent/service.js +27 -15
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-config-service.d.ts +1 -0
- package/dist/src/agent/session/session-config-service.js +9 -1
- package/dist/src/agent/session/session-config-service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.d.ts +2 -1
- package/dist/src/agent/session/session-inspector.js +4 -0
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/skills/config.js +1 -3
- package/dist/src/agent/skills/config.js.map +1 -1
- package/dist/src/agent/skills/format-skills-prompt.d.ts +1 -0
- package/dist/src/agent/skills/format-skills-prompt.js +3 -2
- package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
- package/dist/src/agent/skills/hub-pull.js +1 -1
- package/dist/src/agent/skills/index.js +20 -5
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/installer.js +14 -27
- package/dist/src/agent/skills/installer.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +18 -4
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +11 -2
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +2 -2
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
- package/dist/src/agent/skills/skill-manager.d.ts +4 -1
- package/dist/src/agent/skills/skill-manager.js +3 -3
- package/dist/src/agent/skills/skill-manager.js.map +1 -1
- package/dist/src/agent/skills/skill-view-path.d.ts +1 -17
- package/dist/src/agent/skills/skill-view-path.js +3 -66
- package/dist/src/agent/skills/skill-view-path.js.map +1 -1
- package/dist/src/agent/skills/test-framework.js +2 -3
- package/dist/src/agent/skills/test-framework.js.map +1 -1
- package/dist/src/agent/streaming/reasoning-visibility-sse.js +1 -0
- package/dist/src/agent/streaming/reasoning-visibility-sse.js.map +1 -1
- package/dist/src/agent/tool-manuals/browser.d.ts +1 -0
- package/{skills/browser/SKILL.md → dist/src/agent/tool-manuals/browser.js} +51 -54
- package/dist/src/agent/tool-manuals/browser.js.map +1 -0
- package/dist/src/agent/tool-manuals/index.d.ts +10 -0
- package/dist/src/agent/tool-manuals/index.js +28 -0
- package/dist/src/agent/tool-manuals/index.js.map +1 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.js +7 -5
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +5 -4
- package/dist/src/agent/tools/session-search-tool.js +1 -1
- package/dist/src/agent/tools/shell.js +1 -1
- package/dist/src/agent/tools/skills-tools.js +37 -8
- package/dist/src/agent/tools/skills-tools.js.map +1 -1
- package/dist/src/agent/tools/tool-manual-tool.d.ts +6 -0
- package/dist/src/agent/tools/tool-manual-tool.js +34 -0
- package/dist/src/agent/tools/tool-manual-tool.js.map +1 -0
- package/dist/src/agent/tools/web-extract.js +2 -2
- package/dist/src/agent/tools/web.js +1 -1
- package/dist/src/agent/workflow/catalog.d.ts +7 -2
- package/dist/src/agent/workflow/catalog.js +66 -25
- package/dist/src/agent/workflow/catalog.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.d.ts +3 -0
- package/dist/src/agent/workflow/subagent-runner.js +50 -4
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +10 -0
- package/dist/src/auth/credentials.js +10 -5
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/browser/actions/extension-registry-bridge.js +1 -1
- package/dist/src/browser/actions/registry.js +2 -2
- package/dist/src/browser/cdp-local-launcher.js +1 -1
- package/dist/src/browser/index.js +3 -3
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +1 -1
- package/dist/src/channels/catalog/channel-catalog-service.d.ts +11 -0
- package/dist/src/channels/catalog/channel-catalog-service.js +168 -0
- package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -0
- package/dist/src/channels/catalog/channel-catalog-types.d.ts +22 -0
- package/dist/src/channels/catalog/channel-catalog-types.js +1 -0
- package/dist/src/channels/dock.d.ts +0 -7
- package/dist/src/channels/dock.js +1 -21
- package/dist/src/channels/index.d.ts +1 -3
- package/dist/src/channels/index.js +1 -5
- package/dist/src/channels/lifecycle-supervisor.d.ts +1 -0
- package/dist/src/channels/lifecycle-supervisor.js +11 -0
- package/dist/src/channels/lifecycle-supervisor.js.map +1 -1
- package/dist/src/channels/manager.d.ts +1 -0
- package/dist/src/channels/manager.js +3 -0
- package/dist/src/channels/manager.js.map +1 -1
- package/dist/src/channels/pairing/pairing-channel.d.ts +2 -3
- package/dist/src/channels/pairing/pairing-messages.js +1 -1
- package/dist/src/channels/pairing/pairing-messages.js.map +1 -1
- package/dist/src/channels/pairing/pairing-service.d.ts +1 -1
- package/dist/src/channels/pairing/pairing-service.js +8 -27
- package/dist/src/channels/pairing/pairing-service.js.map +1 -1
- package/dist/src/channels/plugin-types.d.ts +3 -1
- package/dist/src/channels/plugins/types.adapters.d.ts +55 -2
- package/dist/src/channels/telegram/index.js +1 -1
- package/dist/src/chat-commands/builtins/config.js +4 -4
- package/dist/src/chat-commands/builtins/config.js.map +1 -1
- package/dist/src/chat-commands/config-paths.js +1 -1
- package/dist/src/chat-commands/config-paths.js.map +1 -1
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/cli/bin.js +1 -1
- package/dist/src/cli/command-manifest.js +1 -1
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/agents.js +2 -4
- package/dist/src/cli/commands/agents.js.map +1 -1
- package/dist/src/cli/commands/auth.js +1 -1
- package/dist/src/cli/commands/browser-cli-helpers.js +1 -1
- package/dist/src/cli/commands/channels.d.ts +1 -5
- package/dist/src/cli/commands/channels.js +115 -281
- package/dist/src/cli/commands/channels.js.map +1 -1
- package/dist/src/cli/commands/config.js +2 -2
- package/dist/src/cli/commands/config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js +16 -69
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js +6 -4
- package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-plugins.js +2 -2
- package/dist/src/cli/commands/doctor/checks/channel-plugins.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +13 -9
- package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -1
- package/dist/src/cli/commands/extension-dev.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +2 -1
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.js +2 -1
- package/dist/src/cli/commands/extension-pack.js.map +1 -1
- package/dist/src/cli/commands/models.js +7 -4
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/channels/index.js +1 -1
- package/dist/src/cli/commands/onboard/channels/index.js.map +1 -1
- package/dist/src/cli/commands/onboard/channels/registry.d.ts +2 -1
- package/dist/src/cli/commands/onboard/channels/registry.js +32 -8
- package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
- package/dist/src/cli/commands/onboard/model.js +8 -5
- package/dist/src/cli/commands/onboard/model.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +4 -6
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/setup-shared/runner.d.ts +1 -1
- package/dist/src/cli/commands/setup-shared/runner.js.map +1 -1
- package/dist/src/cli/commands/setup-shared/types.d.ts +1 -1
- package/dist/src/cli/commands/setup-shared/types.js.map +1 -1
- package/dist/src/cli/commands/tui.js +13 -5
- package/dist/src/cli/commands/tui.js.map +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/commands/agents.config.d.ts +3 -3
- package/dist/src/commands/agents.config.js +7 -7
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.d.ts +1 -1
- package/dist/src/config/agent-profile.js +6 -2
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/agent-typed-models.d.ts +2 -2
- package/dist/src/config/agent-typed-models.js +13 -2
- package/dist/src/config/agent-typed-models.js.map +1 -1
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/integration.d.ts +1 -1
- package/dist/src/config/loader.d.ts +0 -1
- package/dist/src/config/loader.js +4 -9
- package/dist/src/config/loader.js.map +1 -1
- package/dist/src/config/models-json.d.ts +6 -6
- package/dist/src/config/rules.js +2 -12
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/config/schema.d.ts +74 -47
- package/dist/src/config/schema.js +28 -66
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/validate-channel-configs.d.ts +0 -3
- package/dist/src/config/validate-channel-configs.js +29 -10
- package/dist/src/config/validate-channel-configs.js.map +1 -1
- package/dist/src/cron/executor.js +1 -4
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/extensions/activation-context.js +3 -1
- package/dist/src/extensions/activation-context.js.map +1 -1
- package/dist/src/extensions/activation-planner.js +12 -0
- package/dist/src/extensions/activation-planner.js.map +1 -1
- package/dist/src/extensions/api.d.ts +5 -1
- package/dist/src/extensions/api.js +12 -0
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/discover-extensions.js +17 -13
- package/dist/src/extensions/discover-extensions.js.map +1 -1
- package/dist/src/extensions/extension-metadata-snapshot.js +11 -5
- package/dist/src/extensions/extension-metadata-snapshot.js.map +1 -1
- package/dist/src/extensions/index.js +12 -4
- package/dist/src/extensions/index.js.map +1 -0
- package/dist/src/extensions/loader.d.ts +5 -1
- package/dist/src/extensions/loader.js +12 -11
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/manifest-registry.js +98 -93
- package/dist/src/extensions/manifest-registry.js.map +1 -1
- package/dist/src/extensions/normalize-manifest.js +91 -15
- package/dist/src/extensions/normalize-manifest.js.map +1 -1
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/extensions/sdk/testing.js +4 -0
- package/dist/src/extensions/sdk/testing.js.map +1 -1
- package/dist/src/extensions/types/core.d.ts +32 -1
- package/dist/src/extensions/types/manifest.d.ts +60 -0
- package/dist/src/extensions/types/tui.d.ts +414 -5
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +16 -0
- package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
- package/dist/src/gateway/agent-run-relay.d.ts +2 -3
- package/dist/src/gateway/agent-run-relay.js +10 -3
- package/dist/src/gateway/agent-run-relay.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +32 -19
- package/dist/src/gateway/agents-admin.js +113 -93
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/chat-stream/mapper.d.ts +34 -0
- package/dist/src/gateway/chat-stream/mapper.js +244 -0
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -0
- package/dist/src/gateway/chat-stream/protocol.d.ts +100 -0
- package/dist/src/gateway/chat-stream/protocol.js +1 -0
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/agent-model.d.ts +4 -4
- package/dist/src/gateway/hono/lib/agent-model.js +13 -11
- package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +19 -7
- package/dist/src/gateway/hono/lib/config-payload.js +16 -15
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +83 -48
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/channels.js +134 -214
- package/dist/src/gateway/hono/routes/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/commands-skills.js +10 -4
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +26 -13
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +1 -11
- package/dist/src/gateway/hono/routes/config-patch/channels.js +18 -165
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/config.js +5 -2
- 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/lazy-bundles.js +13 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/public-gateway.js +2 -4
- package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +179 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/tui.d.ts +3 -0
- package/dist/src/gateway/hono/routes/tui.js +16 -0
- package/dist/src/gateway/hono/routes/tui.js.map +1 -0
- package/dist/src/gateway/hono/routes/workflows.js +25 -1
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/sse.d.ts +5 -7
- package/dist/src/gateway/hono/sse.js +21 -38
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/protocol.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +2 -4
- package/dist/src/gateway/service/agent-runner.js +1 -1
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +4 -3
- package/dist/src/gateway/service/marketplace-service.js +7 -4
- package/dist/src/gateway/service/marketplace-service.js.map +1 -1
- package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -6
- package/dist/src/gateway/service/run-gateway-agent.js +63 -36
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +19 -0
- package/dist/src/gateway/service/sessions-api.js +12 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +6 -0
- package/dist/src/gateway/service.js +73 -57
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/project-trust/trust-store.d.ts +30 -0
- package/dist/src/project-trust/trust-store.js +194 -0
- package/dist/src/project-trust/trust-store.js.map +1 -0
- package/dist/src/providers/index.d.ts +1 -1
- package/dist/src/providers/index.js +18 -7
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/routing/resolve-route.d.ts +0 -3
- package/dist/src/routing/resolve-route.js.map +1 -1
- package/dist/src/routing/resolve-tui-session-key.d.ts +2 -0
- package/dist/src/routing/resolve-tui-session-key.js +8 -3
- package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
- package/dist/src/session/client-history.d.ts +32 -0
- package/dist/src/session/client-history.js +232 -1
- package/dist/src/session/client-history.js.map +1 -1
- package/dist/src/session/manager.d.ts +37 -4
- package/dist/src/session/manager.js +39 -15
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/session-context-for-llm.d.ts +93 -1
- package/dist/src/session/session-context-for-llm.js +105 -2
- package/dist/src/session/session-context-for-llm.js.map +1 -1
- package/dist/src/session/store.d.ts +37 -0
- package/dist/src/session/store.js +127 -2
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/stored-rows-to-file-entries.js +37 -1
- package/dist/src/session/stored-rows-to-file-entries.js.map +1 -1
- package/dist/src/session/types.d.ts +14 -1
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/share/share-thumbnail.js +1 -1
- package/dist/src/storage/sqlite/migrations/004_add_session_type_metadata.sql +15 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/row-mappers.d.ts +14 -1
- package/dist/src/storage/sqlite/row-mappers.js +14 -1
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/session-metadata.js +1 -0
- package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
- package/dist/src/storage/sqlite/session-repository.js +52 -25
- package/dist/src/storage/sqlite/session-repository.js.map +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +53 -4
- package/dist/src/tui/backends/embedded-backend.js +227 -39
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +59 -3
- package/dist/src/tui/backends/gateway-sse-backend.js +416 -26
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/chat-history.d.ts +5 -1
- package/dist/src/tui/chat-history.js +78 -8
- package/dist/src/tui/chat-history.js.map +1 -1
- package/dist/src/tui/clipboard-text.d.ts +5 -0
- package/dist/src/tui/clipboard-text.js +46 -0
- package/dist/src/tui/clipboard-text.js.map +1 -0
- package/dist/src/tui/components/assistant-message.d.ts +19 -3
- package/dist/src/tui/components/assistant-message.js +115 -9
- package/dist/src/tui/components/assistant-message.js.map +1 -1
- package/dist/src/tui/components/bash-execution.d.ts +3 -2
- package/dist/src/tui/components/bash-execution.js +31 -3
- package/dist/src/tui/components/bash-execution.js.map +1 -1
- package/dist/src/tui/components/bash-summary.d.ts +23 -0
- package/dist/src/tui/components/bash-summary.js +87 -0
- package/dist/src/tui/components/bash-summary.js.map +1 -0
- package/dist/src/tui/components/branch-message-summary.d.ts +17 -0
- package/dist/src/tui/components/branch-message-summary.js +43 -0
- package/dist/src/tui/components/branch-message-summary.js.map +1 -0
- package/dist/src/tui/components/branch-summary.d.ts +13 -0
- package/dist/src/tui/components/branch-summary.js +51 -0
- package/dist/src/tui/components/branch-summary.js.map +1 -0
- package/dist/src/tui/components/chat-log.d.ts +46 -6
- package/dist/src/tui/components/chat-log.js +183 -21
- package/dist/src/tui/components/chat-log.js.map +1 -1
- package/dist/src/tui/components/compaction-summary.d.ts +13 -0
- package/dist/src/tui/components/compaction-summary.js +46 -0
- package/dist/src/tui/components/compaction-summary.js.map +1 -0
- package/dist/src/tui/components/custom-editor.d.ts +1 -0
- package/dist/src/tui/components/custom-editor.js +2 -0
- package/dist/src/tui/components/custom-editor.js.map +1 -1
- package/dist/src/tui/components/custom-message.d.ts +23 -0
- package/dist/src/tui/components/custom-message.js +65 -0
- package/dist/src/tui/components/custom-message.js.map +1 -0
- package/dist/src/tui/components/extension-dialog.d.ts +42 -0
- package/dist/src/tui/components/extension-dialog.js +127 -0
- package/dist/src/tui/components/extension-dialog.js.map +1 -0
- package/dist/src/tui/components/scoped-models-selector.d.ts +7 -2
- package/dist/src/tui/components/scoped-models-selector.js +89 -16
- package/dist/src/tui/components/scoped-models-selector.js.map +1 -1
- package/dist/src/tui/components/searchable-select-list.d.ts +30 -3
- package/dist/src/tui/components/searchable-select-list.js +82 -10
- package/dist/src/tui/components/searchable-select-list.js.map +1 -1
- package/dist/src/tui/components/session-selector.d.ts +18 -4
- package/dist/src/tui/components/session-selector.js +207 -40
- package/dist/src/tui/components/session-selector.js.map +1 -1
- package/dist/src/tui/components/settings-selector.d.ts +6 -2
- package/dist/src/tui/components/settings-selector.js +126 -7
- package/dist/src/tui/components/settings-selector.js.map +1 -1
- package/dist/src/tui/components/thinking-selector.d.ts +12 -0
- package/dist/src/tui/components/thinking-selector.js +48 -0
- package/dist/src/tui/components/thinking-selector.js.map +1 -0
- package/dist/src/tui/components/tool-execution.d.ts +57 -3
- package/dist/src/tui/components/tool-execution.js +378 -28
- package/dist/src/tui/components/tool-execution.js.map +1 -1
- package/dist/src/tui/components/tui-bottom-bar.d.ts +9 -1
- package/dist/src/tui/components/tui-bottom-bar.js +56 -11
- package/dist/src/tui/components/tui-bottom-bar.js.map +1 -1
- package/dist/src/tui/components/tui-header.d.ts +9 -2
- package/dist/src/tui/components/tui-header.js +25 -5
- package/dist/src/tui/components/tui-header.js.map +1 -1
- package/dist/src/tui/components/user-message.d.ts +4 -2
- package/dist/src/tui/components/user-message.js +42 -9
- package/dist/src/tui/components/user-message.js.map +1 -1
- package/dist/src/tui/components/visual-truncate.d.ts +11 -0
- package/dist/src/tui/components/visual-truncate.js +27 -0
- package/dist/src/tui/components/visual-truncate.js.map +1 -0
- package/dist/src/tui/extension-host/autocomplete.d.ts +43 -0
- package/dist/src/tui/extension-host/autocomplete.js +116 -0
- package/dist/src/tui/extension-host/autocomplete.js.map +1 -0
- package/dist/src/tui/extension-host/host.d.ts +31 -1
- package/dist/src/tui/extension-host/host.js +123 -6
- package/dist/src/tui/extension-host/host.js.map +1 -1
- package/dist/src/tui/extension-host/load-extensions.d.ts +6 -1
- package/dist/src/tui/extension-host/load-extensions.js +4 -3
- package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
- package/dist/src/tui/extension-host/runtime-context.d.ts +21 -0
- package/dist/src/tui/extension-host/runtime-context.js +152 -0
- package/dist/src/tui/extension-host/runtime-context.js.map +1 -0
- package/dist/src/tui/extension-host/runtime.d.ts +52 -4
- package/dist/src/tui/extension-host/runtime.js +547 -85
- package/dist/src/tui/extension-host/runtime.js.map +1 -1
- package/dist/src/tui/extension-host/surface.d.ts +20 -0
- package/dist/src/tui/extension-host/surface.js +30 -6
- package/dist/src/tui/extension-host/surface.js.map +1 -1
- package/dist/src/tui/extension-host/tool-renderers.d.ts +6 -3
- package/dist/src/tui/extension-host/tool-renderers.js +43 -5
- package/dist/src/tui/extension-host/tool-renderers.js.map +1 -1
- package/dist/src/tui/format-tui-hotkeys.d.ts +12 -2
- package/dist/src/tui/format-tui-hotkeys.js +22 -5
- package/dist/src/tui/format-tui-hotkeys.js.map +1 -1
- package/dist/src/tui/tui-agent-events.d.ts +8 -6
- package/dist/src/tui/tui-agent-events.js +200 -59
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +169 -3
- package/dist/src/tui/tui-command-formatters.d.ts +76 -0
- package/dist/src/tui/tui-command-formatters.js +594 -0
- package/dist/src/tui/tui-command-formatters.js.map +1 -0
- package/dist/src/tui/tui-commands.d.ts +57 -7
- package/dist/src/tui/tui-commands.js +639 -43
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-context-usage.d.ts +1 -1
- package/dist/src/tui/tui-context-usage.js +9 -1
- package/dist/src/tui/tui-context-usage.js.map +1 -1
- package/dist/src/tui/tui-extension-user-message.d.ts +8 -0
- package/dist/src/tui/tui-extension-user-message.js +32 -0
- package/dist/src/tui/tui-extension-user-message.js.map +1 -0
- package/dist/src/tui/tui-follow-up-queue.d.ts +9 -0
- package/dist/src/tui/tui-follow-up-queue.js +18 -0
- package/dist/src/tui/tui-follow-up-queue.js.map +1 -0
- package/dist/src/tui/tui-local-shell.d.ts +11 -1
- package/dist/src/tui/tui-local-shell.js +50 -8
- package/dist/src/tui/tui-local-shell.js.map +1 -1
- package/dist/src/tui/tui-model-picker.d.ts +26 -0
- package/dist/src/tui/tui-model-picker.js +152 -0
- package/dist/src/tui/tui-model-picker.js.map +1 -0
- package/dist/src/tui/tui-oauth-login.d.ts +16 -0
- package/dist/src/tui/tui-oauth-login.js +189 -0
- package/dist/src/tui/tui-oauth-login.js.map +1 -0
- package/dist/src/tui/tui-overlays.d.ts +3 -3
- package/dist/src/tui/tui-overlays.js +6 -7
- package/dist/src/tui/tui-overlays.js.map +1 -1
- package/dist/src/tui/tui-picker-overlay.d.ts +27 -32
- package/dist/src/tui/tui-picker-overlay.js +340 -30
- package/dist/src/tui/tui-picker-overlay.js.map +1 -1
- package/dist/src/tui/tui-picker-services.d.ts +41 -0
- package/dist/src/tui/tui-picker-services.js +1 -0
- package/dist/src/tui/tui-run-state.d.ts +11 -0
- package/dist/src/tui/tui-run-state.js +114 -0
- package/dist/src/tui/tui-run-state.js.map +1 -0
- package/dist/src/tui/tui-runtime-hints.d.ts +4 -0
- package/dist/src/tui/tui-runtime-hints.js +18 -0
- package/dist/src/tui/tui-runtime-hints.js.map +1 -0
- package/dist/src/tui/tui-scoped-models.d.ts +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-scoped-models.js.map +1 -1
- package/dist/src/tui/tui-session-actions.d.ts +5 -3
- package/dist/src/tui/tui-session-actions.js +21 -9
- package/dist/src/tui/tui-session-actions.js.map +1 -1
- package/dist/src/tui/tui-session-format.d.ts +4 -1
- package/dist/src/tui/tui-session-format.js +17 -3
- package/dist/src/tui/tui-session-format.js.map +1 -1
- package/dist/src/tui/tui-session-snapshot.d.ts +82 -0
- package/dist/src/tui/tui-session-snapshot.js +184 -0
- package/dist/src/tui/tui-session-snapshot.js.map +1 -0
- package/dist/src/tui/tui-session-stats.d.ts +3 -0
- package/dist/src/tui/tui-session-stats.js +59 -0
- package/dist/src/tui/tui-session-stats.js.map +1 -0
- package/dist/src/tui/tui-settings.d.ts +21 -0
- package/dist/src/tui/tui-settings.js +28 -1
- package/dist/src/tui/tui-settings.js.map +1 -1
- package/dist/src/tui/tui-skills-autocomplete.js +1 -1
- package/dist/src/tui/tui-skills-autocomplete.js.map +1 -1
- package/dist/src/tui/tui-startup-resources.d.ts +3 -0
- package/dist/src/tui/tui-startup-resources.js +39 -0
- package/dist/src/tui/tui-startup-resources.js.map +1 -0
- package/dist/src/tui/tui-startup-text.d.ts +10 -0
- package/dist/src/tui/tui-startup-text.js +58 -0
- package/dist/src/tui/tui-startup-text.js.map +1 -0
- package/dist/src/tui/tui-stdio-filter.d.ts +1 -0
- package/dist/src/tui/tui-stdio-filter.js +11 -7
- package/dist/src/tui/tui-stdio-filter.js.map +1 -1
- package/dist/src/tui/tui-submit.d.ts +2 -0
- package/dist/src/tui/tui-submit.js +2 -1
- package/dist/src/tui/tui-submit.js.map +1 -1
- package/dist/src/tui/tui-tool-diff.js +61 -7
- package/dist/src/tui/tui-tool-diff.js.map +1 -1
- package/dist/src/tui/tui-tool-result.d.ts +17 -0
- package/dist/src/tui/tui-tool-result.js +74 -0
- package/dist/src/tui/tui-tool-result.js.map +1 -0
- package/dist/src/tui/tui-transcript-tree-picker.d.ts +57 -0
- package/dist/src/tui/tui-transcript-tree-picker.js +604 -0
- package/dist/src/tui/tui-transcript-tree-picker.js.map +1 -0
- package/dist/src/tui/tui-transcript-tree.d.ts +7 -0
- package/dist/src/tui/tui-transcript-tree.js +316 -0
- package/dist/src/tui/tui-transcript-tree.js.map +1 -0
- package/dist/src/tui/tui-types.d.ts +25 -34
- package/dist/src/tui/tui-types.js +12 -0
- package/dist/src/tui/tui-types.js.map +1 -1
- package/dist/src/tui/tui.js +1288 -112
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tui/xopc-tui-keybindings.d.ts +127 -2
- package/dist/src/tui/xopc-tui-keybindings.js +127 -2
- package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
- package/dist/src/workflows/domain/definition-utils.d.ts +2 -1
- package/dist/src/workflows/domain/definition-utils.js +18 -8
- package/dist/src/workflows/domain/definition-utils.js.map +1 -1
- package/dist/src/workflows/domain/definition.d.ts +25 -0
- package/dist/src/workflows/domain/event.d.ts +1 -0
- package/dist/src/workflows/domain/result.d.ts +15 -0
- package/dist/src/workflows/domain/run.d.ts +2 -0
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/engine/projector.js +4 -0
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +37 -1
- package/dist/src/workflows/engine/workflow-engine.js +75 -11
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.d.ts +1 -0
- package/dist/src/workflows/index.js +4 -1
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.d.ts +9 -0
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +40 -0
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -0
- package/dist/src/workflows/registry/index.d.ts +2 -0
- package/dist/src/workflows/registry/index.js +2 -0
- package/dist/src/workflows/registry/workflow-definition-registry.d.ts +15 -0
- package/dist/src/workflows/registry/workflow-definition-registry.js +1 -0
- package/dist/src/workflows/runtime/index.d.ts +2 -0
- package/dist/src/workflows/runtime/index.js +2 -1
- package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +5 -0
- package/dist/src/workflows/runtime/script-workflow-runtime.js +15 -0
- package/dist/src/workflows/runtime/script-workflow-runtime.js.map +1 -0
- package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +16 -0
- package/dist/src/workflows/runtime/workflow-runtime-port.js +1 -0
- package/dist/src/workflows/service/run-view-to-snapshot.js +3 -0
- package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.d.ts +3 -0
- package/dist/src/workflows/service/workflow-run-service.js +10 -15
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +4 -1
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/package.json +21 -15
- package/skills/creative/frontend-design/SKILL.md +1 -1
- package/skills/creative/theme-factory/SKILL.md +1 -1
- package/skills/documents/xlsx/SKILL.md +1 -1
- package/skills/engineering/diagnose/SKILL.md +2 -2
- package/skills/engineering/tdd/SKILL.md +1 -1
- package/skills/tools/github/SKILL.md +6 -1
- package/skills/tools/webapp-testing/SKILL.md +4 -1
- package/dist/extensions/telegram/src/adapters/config-surface.d.ts +0 -2
- package/dist/extensions/telegram/src/adapters/config-surface.js +0 -26
- package/dist/extensions/telegram/src/adapters/config-surface.js.map +0 -1
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +0 -158
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +0 -1
- package/dist/gateway/static/root/assets/agents-BwXkia_W.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-tlOTdaXw.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-D4XjqwqC.js +0 -8
- package/dist/gateway/static/root/assets/cron-api-DcmfGuj0.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-CijJ4G6F.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CyJk_G64.js +0 -1
- package/dist/gateway/static/root/assets/field-primitives-C4GpxsDo.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-config-api-CLD0Gpi3.js +0 -1
- package/dist/gateway/static/root/assets/index-0HmunJW9.js +0 -4845
- package/dist/gateway/static/root/assets/index-Bk75Phrd.css +0 -1
- package/dist/gateway/static/root/assets/notes-page-BBnTh0uI.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-B0riYK7j.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DiP_WHu_.js +0 -2
- package/dist/gateway/static/root/assets/settings-page-1ZPhcCZ9.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-BQ1hllKD.js +0 -2
- package/dist/gateway/static/root/assets/url-F3_D_6zZ.js +0 -3
- package/dist/gateway/static/root/assets/utils-CPr3FBh2.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BkbDl6dH.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-D059ysoF.js +0 -27
- package/dist/src/agent/embedded/map-stream-events.d.ts +0 -9
- package/dist/src/agent/embedded/map-stream-events.js +0 -63
- package/dist/src/agent/embedded/map-stream-events.js.map +0 -1
- package/dist/src/channels/dock.js.map +0 -1
- package/dist/src/channels/plugins/bundled.d.ts +0 -11
- package/dist/src/channels/plugins/bundled.js +0 -10
- package/dist/src/channels/plugins/bundled.js.map +0 -1
- package/dist/src/channels/registry.d.ts +0 -25
- package/dist/src/channels/registry.js +0 -82
- package/dist/src/channels/registry.js.map +0 -1
- package/dist/src/config/localized-text.d.ts +0 -6
- package/dist/src/config/localized-text.js +0 -42
- package/dist/src/config/localized-text.js.map +0 -1
- package/dist/src/generated/bundled-channel-plugins.d.ts +0 -10
- package/dist/src/generated/bundled-channel-plugins.js +0 -16
- package/dist/src/generated/bundled-channel-plugins.js.map +0 -1
- package/dist/src/tui/stream-assembler.d.ts +0 -22
- package/dist/src/tui/stream-assembler.js +0 -63
- package/dist/src/tui/stream-assembler.js.map +0 -1
- package/skills/browser/SKILL-zh.md +0 -188
- package/skills/business/company-values/SKILL-zh.md +0 -80
- package/skills/business/company-values/SKILL.md +0 -80
- package/skills/business/find-community/SKILL-zh.md +0 -50
- package/skills/business/find-community/SKILL.md +0 -50
- package/skills/business/first-customers/SKILL-zh.md +0 -76
- package/skills/business/first-customers/SKILL.md +0 -76
- package/skills/business/grow-sustainably/SKILL-zh.md +0 -92
- package/skills/business/grow-sustainably/SKILL.md +0 -92
- package/skills/business/marketing-plan/SKILL-zh.md +0 -100
- package/skills/business/marketing-plan/SKILL.md +0 -100
- package/skills/business/minimalist-review/SKILL-zh.md +0 -82
- package/skills/business/minimalist-review/SKILL.md +0 -82
- package/skills/business/mvp/SKILL-zh.md +0 -81
- package/skills/business/mvp/SKILL.md +0 -81
- package/skills/business/pricing/SKILL-zh.md +0 -64
- package/skills/business/pricing/SKILL.md +0 -64
- package/skills/business/processize/SKILL-zh.md +0 -91
- package/skills/business/processize/SKILL.md +0 -91
- package/skills/business/validate-idea/SKILL-zh.md +0 -68
- package/skills/business/validate-idea/SKILL.md +0 -68
- package/skills/creative/algorithmic-art/LICENSE.txt +0 -202
- package/skills/creative/algorithmic-art/SKILL-zh.md +0 -405
- package/skills/creative/algorithmic-art/SKILL.md +0 -405
- package/skills/creative/algorithmic-art/templates/generator_template.js +0 -223
- package/skills/creative/algorithmic-art/templates/viewer.html +0 -599
- package/skills/creative/frontend-design/SKILL-zh.md +0 -42
- package/skills/creative/theme-factory/SKILL-zh.md +0 -59
- package/skills/creative/web-artifacts-builder/LICENSE.txt +0 -202
- package/skills/creative/web-artifacts-builder/SKILL-zh.md +0 -74
- package/skills/creative/web-artifacts-builder/SKILL.md +0 -74
- package/skills/creative/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
- package/skills/creative/web-artifacts-builder/scripts/init-artifact.sh +0 -322
- package/skills/creative/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/documents/doc-coauthoring/SKILL-zh.md +0 -375
- package/skills/documents/doc-coauthoring/SKILL.md +0 -375
- package/skills/documents/docx/LICENSE.txt +0 -30
- package/skills/documents/docx/SKILL-zh.md +0 -590
- package/skills/documents/docx/SKILL.md +0 -590
- package/skills/documents/docx/scripts/__init__.py +0 -1
- package/skills/documents/docx/scripts/accept_changes.py +0 -135
- package/skills/documents/docx/scripts/comment.py +0 -318
- package/skills/documents/docx/scripts/office/helpers/__init__.py +0 -0
- package/skills/documents/docx/scripts/office/helpers/merge_runs.py +0 -199
- package/skills/documents/docx/scripts/office/helpers/simplify_redlines.py +0 -197
- package/skills/documents/docx/scripts/office/pack.py +0 -159
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/documents/docx/scripts/office/schemas/mce/mc.xsd +0 -75
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/documents/docx/scripts/office/soffice.py +0 -183
- package/skills/documents/docx/scripts/office/unpack.py +0 -132
- package/skills/documents/docx/scripts/office/validate.py +0 -111
- package/skills/documents/docx/scripts/office/validators/__init__.py +0 -15
- package/skills/documents/docx/scripts/office/validators/base.py +0 -847
- package/skills/documents/docx/scripts/office/validators/docx.py +0 -446
- package/skills/documents/docx/scripts/office/validators/pptx.py +0 -275
- package/skills/documents/docx/scripts/office/validators/redlining.py +0 -247
- package/skills/documents/docx/scripts/templates/comments.xml +0 -3
- package/skills/documents/docx/scripts/templates/commentsExtended.xml +0 -3
- package/skills/documents/docx/scripts/templates/commentsExtensible.xml +0 -3
- package/skills/documents/docx/scripts/templates/commentsIds.xml +0 -3
- package/skills/documents/docx/scripts/templates/people.xml +0 -3
- package/skills/documents/pdf/LICENSE.txt +0 -30
- package/skills/documents/pdf/SKILL-zh.md +0 -314
- package/skills/documents/pdf/SKILL.md +0 -314
- package/skills/documents/pdf/forms.md +0 -294
- package/skills/documents/pdf/reference.md +0 -612
- package/skills/documents/pdf/scripts/check_bounding_boxes.py +0 -65
- package/skills/documents/pdf/scripts/check_fillable_fields.py +0 -11
- package/skills/documents/pdf/scripts/convert_pdf_to_images.py +0 -33
- package/skills/documents/pdf/scripts/create_validation_image.py +0 -37
- package/skills/documents/pdf/scripts/extract_form_field_info.py +0 -122
- package/skills/documents/pdf/scripts/extract_form_structure.py +0 -115
- package/skills/documents/pdf/scripts/fill_fillable_fields.py +0 -98
- package/skills/documents/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
- package/skills/documents/pptx/LICENSE.txt +0 -30
- package/skills/documents/pptx/SKILL-zh.md +0 -232
- package/skills/documents/pptx/SKILL.md +0 -232
- package/skills/documents/pptx/editing.md +0 -205
- package/skills/documents/pptx/pptxgenjs.md +0 -420
- package/skills/documents/pptx/scripts/__init__.py +0 -0
- package/skills/documents/pptx/scripts/add_slide.py +0 -195
- package/skills/documents/pptx/scripts/clean.py +0 -286
- package/skills/documents/pptx/scripts/office/helpers/__init__.py +0 -0
- package/skills/documents/pptx/scripts/office/helpers/merge_runs.py +0 -199
- package/skills/documents/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
- package/skills/documents/pptx/scripts/office/pack.py +0 -159
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/documents/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/documents/pptx/scripts/office/soffice.py +0 -183
- package/skills/documents/pptx/scripts/office/unpack.py +0 -132
- package/skills/documents/pptx/scripts/office/validate.py +0 -111
- package/skills/documents/pptx/scripts/office/validators/__init__.py +0 -15
- package/skills/documents/pptx/scripts/office/validators/base.py +0 -847
- package/skills/documents/pptx/scripts/office/validators/docx.py +0 -446
- package/skills/documents/pptx/scripts/office/validators/pptx.py +0 -275
- package/skills/documents/pptx/scripts/office/validators/redlining.py +0 -247
- package/skills/documents/pptx/scripts/thumbnail.py +0 -289
- package/skills/documents/xlsx/SKILL-zh.md +0 -292
- package/skills/engineering/diagnose/SKILL-zh.md +0 -117
- package/skills/engineering/grill-with-docs/ADR-FORMAT.md +0 -47
- package/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md +0 -77
- package/skills/engineering/grill-with-docs/SKILL-zh.md +0 -88
- package/skills/engineering/grill-with-docs/SKILL.md +0 -88
- package/skills/engineering/improve-codebase-architecture/DEEPENING.md +0 -37
- package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +0 -44
- package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +0 -53
- package/skills/engineering/improve-codebase-architecture/SKILL-zh.md +0 -71
- package/skills/engineering/improve-codebase-architecture/SKILL.md +0 -71
- package/skills/engineering/tdd/SKILL-zh.md +0 -109
- package/skills/engineering/to-issues/SKILL-zh.md +0 -81
- package/skills/engineering/to-issues/SKILL.md +0 -81
- package/skills/engineering/to-prd/SKILL-zh.md +0 -76
- package/skills/engineering/to-prd/SKILL.md +0 -74
- package/skills/engineering/zoom-out/SKILL-zh.md +0 -7
- package/skills/engineering/zoom-out/SKILL.md +0 -7
- package/skills/tools/find-skills/SKILL-zh.md +0 -440
- package/skills/tools/github/SKILL-zh.md +0 -48
- package/skills/tools/internal-comms/LICENSE.txt +0 -202
- package/skills/tools/internal-comms/SKILL-zh.md +0 -32
- package/skills/tools/internal-comms/SKILL.md +0 -32
- package/skills/tools/internal-comms/examples/3p-updates.md +0 -47
- package/skills/tools/internal-comms/examples/company-newsletter.md +0 -65
- package/skills/tools/internal-comms/examples/faq-answers.md +0 -30
- package/skills/tools/internal-comms/examples/general-comms.md +0 -16
- package/skills/tools/skill-creator/LICENSE.txt +0 -202
- package/skills/tools/skill-creator/SKILL-zh.md +0 -483
- package/skills/tools/skill-creator/SKILL.md +0 -485
- package/skills/tools/skill-creator/agents/analyzer.md +0 -274
- package/skills/tools/skill-creator/agents/comparator.md +0 -202
- package/skills/tools/skill-creator/agents/grader.md +0 -223
- package/skills/tools/skill-creator/assets/eval_review.html +0 -146
- package/skills/tools/skill-creator/eval-viewer/generate_review.py +0 -471
- package/skills/tools/skill-creator/eval-viewer/viewer.html +0 -1325
- package/skills/tools/skill-creator/references/schemas.md +0 -430
- package/skills/tools/skill-creator/scripts/__init__.py +0 -0
- package/skills/tools/skill-creator/scripts/aggregate_benchmark.py +0 -401
- package/skills/tools/skill-creator/scripts/generate_report.py +0 -326
- package/skills/tools/skill-creator/scripts/improve_description.py +0 -247
- package/skills/tools/skill-creator/scripts/package_skill.py +0 -136
- package/skills/tools/skill-creator/scripts/quick_validate.py +0 -103
- package/skills/tools/skill-creator/scripts/run_eval.py +0 -310
- package/skills/tools/skill-creator/scripts/run_loop.py +0 -328
- package/skills/tools/skill-creator/scripts/utils.py +0 -47
- package/skills/tools/summarize/SKILL-zh.md +0 -47
- package/skills/tools/weather/SKILL-zh.md +0 -46
- package/skills/tools/weather/SKILL.md +0 -46
- package/skills/tools/webapp-testing/SKILL-zh.md +0 -96
|
@@ -27,7 +27,8 @@ var TurnDispatcher = class {
|
|
|
27
27
|
sessionKey,
|
|
28
28
|
attachments,
|
|
29
29
|
thinking,
|
|
30
|
-
signal: options?.signal
|
|
30
|
+
signal: options?.signal,
|
|
31
|
+
runId: options?.runId
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
/** Push an out-of-band event into the live webchat stream for a session. */
|
|
@@ -38,10 +39,28 @@ var TurnDispatcher = class {
|
|
|
38
39
|
/** Stream assistant text to live webchat session + notify transcript listeners. */
|
|
39
40
|
notifyWebchatTranscriptAppend(sessionKey, assistantText) {
|
|
40
41
|
const trimmed = assistantText.trim();
|
|
41
|
-
if (trimmed)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
if (trimmed) {
|
|
43
|
+
const message = {
|
|
44
|
+
role: "assistant",
|
|
45
|
+
content: [{
|
|
46
|
+
type: "text",
|
|
47
|
+
text: trimmed
|
|
48
|
+
}],
|
|
49
|
+
timestamp: Date.now()
|
|
50
|
+
};
|
|
51
|
+
this.enqueueWebchatSseEvent(sessionKey, {
|
|
52
|
+
type: "message_start",
|
|
53
|
+
message
|
|
54
|
+
});
|
|
55
|
+
this.enqueueWebchatSseEvent(sessionKey, {
|
|
56
|
+
type: "message_update",
|
|
57
|
+
message
|
|
58
|
+
});
|
|
59
|
+
this.enqueueWebchatSseEvent(sessionKey, {
|
|
60
|
+
type: "message_end",
|
|
61
|
+
message
|
|
62
|
+
});
|
|
63
|
+
}
|
|
45
64
|
this.cfg.onSessionTranscriptUpdated?.(sessionKey);
|
|
46
65
|
}
|
|
47
66
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn-dispatcher.js","names":[],"sources":["../../../../src/agent/inbound/turn-dispatcher.ts"],"sourcesContent":["/**\n * TurnDispatcher — single entry point for direct (non-bus) agent turns.\n *\n * Wraps the two existing direct-turn runners (one-shot and streaming) so the\n * parent `AgentService` no longer carries a pair of huge `createXxxDeps()`\n * factories. The public surface — `processDirect`, `processDirectStreaming`,\n * `steerWebchatSession`, `enqueueWebchatSseEvent`,\n * `notifyWebchatTranscriptAppend` — matches what `AgentService` exposed\n * previously, so callers (gateway, CLI) are unchanged.\n *\n * Like `OutboundCoordinator` and `InboundLoop`, this class accepts a wide\n * dependency bag in its constructor (the direct-turn pipeline touches almost\n * every other subsystem). The win is that AgentService becomes the only place\n * that wires those dependencies together; individual responsibilities now live\n * in their own classes and are unit-testable.\n */\n\nimport type { Config } from '../../config/schema.js';\nimport type { ContextualLogger } from '../../utils/logger/types.js';\n\nimport type { AgentManager } from '../agent-manager.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionConfigStore } from '../../session/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type {\n SessionContext,\n SessionHydrator,\n SessionStateBag,\n} from '../session/index.js';\nimport { queueEmbeddedSteer } from '../embedded/runs.js';\nimport type {\n InboundAttachmentInput,\n MediaRef,\n} from '../../channels/attachments/inbound-persist.js';\nimport {\n buildDirectUserMessageContent,\n} from '../service/build-direct-message-content.js';\nimport {\n runProcessDirectStreaming,\n type ProcessDirectStreamingDeps,\n type ProcessDirectStreamingSseEvent,\n} from '../service/process-direct-streaming.js';\nimport {\n runProcessDirect,\n type RunProcessDirectDeps,\n} from '../service/process-direct-one-shot.js';\nimport { maybeEmitWebchatTts } from '../service/webchat-tts.js';\n\nexport interface TurnDispatcherConfig {\n log: ContextualLogger;\n agentManager: AgentManager;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n sessionConfigStore: SessionConfigStore;\n sessionState: SessionStateBag;\n commandHandler: CommandHandler;\n getConfig: () => Config | undefined;\n /** Strict accessor — required for direct-turn paths that must have a config. */\n requireConfig: () => Config;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n /** Establish per-session context (also creates the Agent + subscribes to events). */\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => SessionContext;\n /** Per-session config hydration: workspace, model, thinking. */\n sessionHydrator: SessionHydrator;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: InboundAttachmentInput[],\n ) => Promise<MediaRef[] | undefined>;\n enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;\n endDirectRequestContext: () => void;\n /** Gateway hook fired after assistant text lands on disk (UI refetch). */\n onSessionTranscriptUpdated?: (sessionKey: string) => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n}\n\nexport type DirectAttachment = InboundAttachmentInput;\n\nexport class TurnDispatcher {\n private readonly cfg: TurnDispatcherConfig;\n private readonly log: ContextualLogger;\n\n constructor(cfg: TurnDispatcherConfig) {\n this.cfg = cfg;\n this.log = cfg.log;\n }\n\n /** One-shot direct turn (CLI / embedded TUI). */\n processDirect(\n content: string,\n sessionKey = 'agent:main:main',\n attachments?: DirectAttachment[],\n thinking?: string,\n ): Promise<string> {\n return runProcessDirect(this.buildOneShotDeps(), {\n content,\n sessionKey,\n attachments,\n thinking,\n });\n }\n\n /** Streaming direct turn (webchat SSE / CLI streaming). */\n async *processDirectStreaming(\n content: string,\n sessionKey = 'agent:main:main',\n attachments?: DirectAttachment[],\n thinking?: string,\n options?: { signal?: AbortSignal },\n ): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n yield* runProcessDirectStreaming(this.buildStreamingDeps(), {\n content,\n sessionKey,\n attachments,\n thinking,\n signal: options?.signal,\n });\n }\n\n /** Push an out-of-band event into the live webchat stream for a session. */\n enqueueWebchatSseEvent(\n sessionKey: string,\n event: { type: string; [key: string]: unknown },\n ): void {\n const pub = this.cfg.sessionState.getWebchatPublisher(sessionKey);\n if (pub) {\n pub(event);\n }\n }\n\n /** Stream assistant text to live webchat session + notify transcript listeners. */\n notifyWebchatTranscriptAppend(sessionKey: string, assistantText: string): void {\n const trimmed = assistantText.trim();\n if (trimmed) {\n this.enqueueWebchatSseEvent(sessionKey, { type: 'token', content: trimmed });\n }\n this.cfg.onSessionTranscriptUpdated?.(sessionKey);\n }\n\n /**\n * Queue a steering user message into pi-agent's in-flight run (delivered\n * after current tool work, before the next LLM call). See `Agent.steer`\n * in `@earendil-works/pi-agent-core`.\n */\n async steerWebchatSession(sessionKey: string, text: string): Promise<boolean> {\n const trimmed = text.trim();\n if (!trimmed) return false;\n try {\n return await queueEmbeddedSteer(sessionKey, trimmed);\n } catch (err) {\n this.log.warn({ err, sessionKey }, 'steerWebchatSession failed');\n return false;\n }\n }\n\n private buildStreamingDeps(): ProcessDirectStreamingDeps {\n const c = this.cfg;\n return {\n log: this.log,\n parseSessionKey: c.parseSessionKey,\n initDirectStreamingSession: c.initSessionContext,\n registerWebchatSsePublisher: (sk, publisher) =>\n c.sessionState.registerWebchatPublisher(sk, publisher),\n unregisterWebchatSsePublisher: (sk) => c.sessionState.unregisterWebchatPublisher(sk),\n agentManager: c.agentManager,\n hydrateSessionWorkspaceFromStore: (sk) => c.sessionHydrator.workspace(sk),\n hydrateSessionModelFromStore: (sk) => c.sessionHydrator.model(sk),\n sessionStore: c.sessionStore,\n modelManager: c.modelManager,\n applyResolvedThinkingLevel: (sk, t) => c.sessionHydrator.thinking(sk, t),\n getConfig: c.getConfig,\n sessionConfigStore: c.sessionConfigStore,\n commandHandler: c.commandHandler,\n prepareInboundAttachments: c.prepareInboundAttachments,\n buildTranscriptUserMessage: async (text, prepared, sk) =>\n buildDirectUserMessageContent({\n content: text,\n attachments: prepared,\n sessionKey: sk,\n config: c.requireConfig(),\n agentManager: c.agentManager,\n modelManager: c.modelManager,\n }),\n recordPersistentGoalStreamOutcome: (sk, o) =>\n c.sessionState.recordPersistentGoalStreamOutcome(sk, o),\n enqueueProvisionalSessionTitle: (sk, userText) => {\n c.enqueueProvisionalSessionTitle?.(sk, userText);\n },\n onTurnComplete: (sk, text) => {\n if (text) {\n c.sessionState.setLastAssistantText(sk, text);\n }\n c.enqueueMaybeAutoTitleAfterPersist(sk);\n },\n reloadWebchatTranscript: (sk) => {\n c.onSessionTranscriptUpdated?.(sk);\n },\n maybeEmitWebchatTts: (sk, hadVoice) =>\n maybeEmitWebchatTts(\n {\n config: c.getConfig(),\n sessionStore: c.sessionStore,\n getLastAssistantPlainText: (sessionKey) =>\n c.sessionState.getLastAssistantText(sessionKey) ??\n c.agentManager.getLastAssistantContent(sessionKey) ??\n '',\n log: this.log,\n },\n sk,\n hadVoice,\n ),\n endDirectRequestContext: c.endDirectRequestContext,\n resetSession: c.resetSession,\n };\n }\n\n private buildOneShotDeps(): RunProcessDirectDeps {\n const c = this.cfg;\n const cfg = c.requireConfig();\n return {\n log: this.log,\n config: cfg,\n parseSessionKey: c.parseSessionKey,\n initSessionContext: (sk, channel, chatId) => {\n void c.initSessionContext(sk, channel, chatId);\n },\n hydrateSessionWorkspaceFromStore: (sk) => c.sessionHydrator.workspace(sk),\n hydrateSessionModelFromStore: (sk) => c.sessionHydrator.model(sk),\n agentManager: c.agentManager,\n sessionStore: c.sessionStore,\n modelManager: c.modelManager,\n applyResolvedThinkingLevel: (sk, t) => c.sessionHydrator.thinking(sk, t),\n prepareInboundAttachments: c.prepareInboundAttachments,\n commandHandler: c.commandHandler,\n onTurnComplete: (sk, text) => {\n if (text) {\n c.sessionState.setLastAssistantText(sk, text);\n }\n c.enqueueMaybeAutoTitleAfterPersist(sk);\n },\n endDirectRequestContext: c.endDirectRequestContext,\n resetSession: c.resetSession,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"turn-dispatcher.js","names":[],"sources":["../../../../src/agent/inbound/turn-dispatcher.ts"],"sourcesContent":["/**\n * TurnDispatcher — single entry point for direct (non-bus) agent turns.\n *\n * Wraps the two existing direct-turn runners (one-shot and streaming) so the\n * parent `AgentService` no longer carries a pair of huge `createXxxDeps()`\n * factories. The public surface — `processDirect`, `processDirectStreaming`,\n * `steerWebchatSession`, `enqueueWebchatSseEvent`,\n * `notifyWebchatTranscriptAppend` — matches what `AgentService` exposed\n * previously, so callers (gateway, CLI) are unchanged.\n *\n * Like `OutboundCoordinator` and `InboundLoop`, this class accepts a wide\n * dependency bag in its constructor (the direct-turn pipeline touches almost\n * every other subsystem). The win is that AgentService becomes the only place\n * that wires those dependencies together; individual responsibilities now live\n * in their own classes and are unit-testable.\n */\n\nimport type { Config } from '../../config/schema.js';\nimport type { ContextualLogger } from '../../utils/logger/types.js';\n\nimport type { AgentManager } from '../agent-manager.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionConfigStore } from '../../session/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type {\n SessionContext,\n SessionHydrator,\n SessionStateBag,\n} from '../session/index.js';\nimport { queueEmbeddedSteer } from '../embedded/runs.js';\nimport type {\n InboundAttachmentInput,\n MediaRef,\n} from '../../channels/attachments/inbound-persist.js';\nimport {\n buildDirectUserMessageContent,\n} from '../service/build-direct-message-content.js';\nimport {\n runProcessDirectStreaming,\n type ProcessDirectStreamingDeps,\n type ProcessDirectStreamingSseEvent,\n} from '../service/process-direct-streaming.js';\nimport {\n runProcessDirect,\n type RunProcessDirectDeps,\n} from '../service/process-direct-one-shot.js';\nimport { maybeEmitWebchatTts } from '../service/webchat-tts.js';\n\nexport interface TurnDispatcherConfig {\n log: ContextualLogger;\n agentManager: AgentManager;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n sessionConfigStore: SessionConfigStore;\n sessionState: SessionStateBag;\n commandHandler: CommandHandler;\n getConfig: () => Config | undefined;\n /** Strict accessor — required for direct-turn paths that must have a config. */\n requireConfig: () => Config;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n /** Establish per-session context (also creates the Agent + subscribes to events). */\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => SessionContext;\n /** Per-session config hydration: workspace, model, thinking. */\n sessionHydrator: SessionHydrator;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: InboundAttachmentInput[],\n ) => Promise<MediaRef[] | undefined>;\n enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;\n endDirectRequestContext: () => void;\n /** Gateway hook fired after assistant text lands on disk (UI refetch). */\n onSessionTranscriptUpdated?: (sessionKey: string) => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n}\n\nexport type DirectAttachment = InboundAttachmentInput;\n\nexport class TurnDispatcher {\n private readonly cfg: TurnDispatcherConfig;\n private readonly log: ContextualLogger;\n\n constructor(cfg: TurnDispatcherConfig) {\n this.cfg = cfg;\n this.log = cfg.log;\n }\n\n /** One-shot direct turn (CLI / embedded TUI). */\n processDirect(\n content: string,\n sessionKey = 'agent:main:main',\n attachments?: DirectAttachment[],\n thinking?: string,\n ): Promise<string> {\n return runProcessDirect(this.buildOneShotDeps(), {\n content,\n sessionKey,\n attachments,\n thinking,\n });\n }\n\n /** Streaming direct turn (webchat SSE / CLI streaming). */\n async *processDirectStreaming(\n content: string,\n sessionKey = 'agent:main:main',\n attachments?: DirectAttachment[],\n thinking?: string,\n options?: { signal?: AbortSignal; runId?: string },\n ): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n yield* runProcessDirectStreaming(this.buildStreamingDeps(), {\n content,\n sessionKey,\n attachments,\n thinking,\n signal: options?.signal,\n runId: options?.runId,\n });\n }\n\n /** Push an out-of-band event into the live webchat stream for a session. */\n enqueueWebchatSseEvent(\n sessionKey: string,\n event: { type: string; [key: string]: unknown },\n ): void {\n const pub = this.cfg.sessionState.getWebchatPublisher(sessionKey);\n if (pub) {\n pub(event);\n }\n }\n\n /** Stream assistant text to live webchat session + notify transcript listeners. */\n notifyWebchatTranscriptAppend(sessionKey: string, assistantText: string): void {\n const trimmed = assistantText.trim();\n if (trimmed) {\n const message = {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n };\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_start', message });\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_update', message });\n this.enqueueWebchatSseEvent(sessionKey, { type: 'message_end', message });\n }\n this.cfg.onSessionTranscriptUpdated?.(sessionKey);\n }\n\n /**\n * Queue a steering user message into pi-agent's in-flight run (delivered\n * after current tool work, before the next LLM call). See `Agent.steer`\n * in `@earendil-works/pi-agent-core`.\n */\n async steerWebchatSession(sessionKey: string, text: string): Promise<boolean> {\n const trimmed = text.trim();\n if (!trimmed) return false;\n try {\n return await queueEmbeddedSteer(sessionKey, trimmed);\n } catch (err) {\n this.log.warn({ err, sessionKey }, 'steerWebchatSession failed');\n return false;\n }\n }\n\n private buildStreamingDeps(): ProcessDirectStreamingDeps {\n const c = this.cfg;\n return {\n log: this.log,\n parseSessionKey: c.parseSessionKey,\n initDirectStreamingSession: c.initSessionContext,\n registerWebchatSsePublisher: (sk, publisher) =>\n c.sessionState.registerWebchatPublisher(sk, publisher),\n unregisterWebchatSsePublisher: (sk) => c.sessionState.unregisterWebchatPublisher(sk),\n agentManager: c.agentManager,\n hydrateSessionWorkspaceFromStore: (sk) => c.sessionHydrator.workspace(sk),\n hydrateSessionModelFromStore: (sk) => c.sessionHydrator.model(sk),\n sessionStore: c.sessionStore,\n modelManager: c.modelManager,\n applyResolvedThinkingLevel: (sk, t) => c.sessionHydrator.thinking(sk, t),\n getConfig: c.getConfig,\n sessionConfigStore: c.sessionConfigStore,\n commandHandler: c.commandHandler,\n prepareInboundAttachments: c.prepareInboundAttachments,\n buildTranscriptUserMessage: async (text, prepared, sk) =>\n buildDirectUserMessageContent({\n content: text,\n attachments: prepared,\n sessionKey: sk,\n config: c.requireConfig(),\n agentManager: c.agentManager,\n modelManager: c.modelManager,\n }),\n recordPersistentGoalStreamOutcome: (sk, o) =>\n c.sessionState.recordPersistentGoalStreamOutcome(sk, o),\n enqueueProvisionalSessionTitle: (sk, userText) => {\n c.enqueueProvisionalSessionTitle?.(sk, userText);\n },\n onTurnComplete: (sk, text) => {\n if (text) {\n c.sessionState.setLastAssistantText(sk, text);\n }\n c.enqueueMaybeAutoTitleAfterPersist(sk);\n },\n reloadWebchatTranscript: (sk) => {\n c.onSessionTranscriptUpdated?.(sk);\n },\n maybeEmitWebchatTts: (sk, hadVoice) =>\n maybeEmitWebchatTts(\n {\n config: c.getConfig(),\n sessionStore: c.sessionStore,\n getLastAssistantPlainText: (sessionKey) =>\n c.sessionState.getLastAssistantText(sessionKey) ??\n c.agentManager.getLastAssistantContent(sessionKey) ??\n '',\n log: this.log,\n },\n sk,\n hadVoice,\n ),\n endDirectRequestContext: c.endDirectRequestContext,\n resetSession: c.resetSession,\n };\n }\n\n private buildOneShotDeps(): RunProcessDirectDeps {\n const c = this.cfg;\n const cfg = c.requireConfig();\n return {\n log: this.log,\n config: cfg,\n parseSessionKey: c.parseSessionKey,\n initSessionContext: (sk, channel, chatId) => {\n void c.initSessionContext(sk, channel, chatId);\n },\n hydrateSessionWorkspaceFromStore: (sk) => c.sessionHydrator.workspace(sk),\n hydrateSessionModelFromStore: (sk) => c.sessionHydrator.model(sk),\n agentManager: c.agentManager,\n sessionStore: c.sessionStore,\n modelManager: c.modelManager,\n applyResolvedThinkingLevel: (sk, t) => c.sessionHydrator.thinking(sk, t),\n prepareInboundAttachments: c.prepareInboundAttachments,\n commandHandler: c.commandHandler,\n onTurnComplete: (sk, text) => {\n if (text) {\n c.sessionState.setLastAssistantText(sk, text);\n }\n c.enqueueMaybeAutoTitleAfterPersist(sk);\n },\n endDirectRequestContext: c.endDirectRequestContext,\n resetSession: c.resetSession,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -71,7 +71,7 @@ export declare class ModelManager {
|
|
|
71
71
|
*/
|
|
72
72
|
applyModelForSession(agent: Agent, sessionKey: string): Promise<void>;
|
|
73
73
|
/**
|
|
74
|
-
* Ordered model candidates for the session (primary + `agents.defaults.
|
|
74
|
+
* Ordered model candidates for the session (primary + `agents.defaults.models.chat.fallbacks`).
|
|
75
75
|
*/
|
|
76
76
|
getFallbackCandidatesForSession(sessionKey: string): ModelCandidate[];
|
|
77
77
|
/**
|
|
@@ -148,7 +148,7 @@ var ModelManager = class {
|
|
|
148
148
|
}, "Applied model for session");
|
|
149
149
|
}
|
|
150
150
|
/**
|
|
151
|
-
* Ordered model candidates for the session (primary + `agents.defaults.
|
|
151
|
+
* Ordered model candidates for the session (primary + `agents.defaults.models.chat.fallbacks`).
|
|
152
152
|
*/
|
|
153
153
|
getFallbackCandidatesForSession(sessionKey) {
|
|
154
154
|
const parsed = parseModelRef(this.getModelForSession(sessionKey));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","names":["getAllModelsFromProviders"],"sources":["../../../../src/agent/models/manager.ts"],"sourcesContent":["/**\n * Model management module\n * \n * Handles model selection, switching, and automatic fallback\n * when a provider fails.\n */\n\nimport { Agent, type AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport { type Config, getAgentDefaultModelRef } from '../../config/schema.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { resolveModel, getAllModels as getAllModelsFromProviders, getDefaultModelSync } from '../../providers/index.js';\nimport {\n isFailoverError,\n describeFailoverError,\n resolveFallbackCandidates,\n type ModelCandidate,\n} from '../fallback/index.js';\nimport { parseModelRef } from './selection.js';\nimport {\n isAssistantTurnAborted,\n isAssistantTurnFailed,\n maybeRetryTurnAfterTransientLlmFailure,\n} from '../orchestration/llm-turn-retry.js';\nimport {\n resolveAgentTurnTimeoutMs,\n runAgentTurnWithTimeout,\n} from '../orchestration/run-agent-turn-with-timeout.js';\n\nconst log = createLogger('ModelManager');\n\nexport interface ModelManagerConfig {\n defaultModel?: string;\n config?: Config;\n}\n\nexport interface RunResult {\n content: string | null;\n usage?: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n };\n}\n\n/**\n * Get the last assistant content from agent messages\n */\nfunction getLastAssistantContent(agent: Agent): string | null {\n const messages = agent.state.messages;\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'assistant') {\n return msg.content\n .filter((c) => c.type === 'text')\n .map((c) => c.text || '')\n .join('');\n }\n }\n return null;\n}\n\nexport class ModelManager {\n private defaultModel: string;\n private config?: Config;\n private currentModelName: string;\n private currentProvider: string;\n private sessionModels: Map<string, string> = new Map();\n /** Baseline model from `agents.list` / defaults merge when the session agent is created. */\n private sessionProfileDefaults: Map<string, string> = new Map();\n private channelManager?: any;\n\n constructor(config: ModelManagerConfig = {}) {\n this.config = config.config;\n this.defaultModel = config.defaultModel || getDefaultModelSync(config.config);\n this.currentModelName = this.defaultModel;\n this.currentProvider = this.defaultModel.split('/')[0] || 'anthropic';\n }\n\n /**\n * Set channel manager reference for accessing session-specific settings\n */\n setChannelManager(channelManager: any): void {\n this.channelManager = channelManager;\n }\n\n /**\n * Apply updated config so default model and failover metadata match disk/runtime config.\n */\n updateFromConfig(config: Config): void {\n this.config = config;\n const ref = getAgentDefaultModelRef(config);\n this.defaultModel = ref ? ref : getDefaultModelSync(config);\n this.sessionProfileDefaults.clear();\n }\n\n /**\n * Set the config-derived default model for a session (from effective agent profile).\n * Cleared by {@link updateFromConfig} or {@link clearSessionProfileDefault}.\n */\n setSessionProfileDefault(sessionKey: string, modelRef: string): void {\n this.sessionProfileDefaults.set(sessionKey, modelRef);\n }\n\n clearSessionProfileDefault(sessionKey: string): void {\n this.sessionProfileDefaults.delete(sessionKey);\n }\n\n /**\n * Get current model name\n */\n getCurrentModel(): string {\n return this.currentModelName;\n }\n\n /**\n * Get current provider\n */\n getCurrentProvider(): string {\n return this.currentProvider;\n }\n\n /**\n * Switch model for a specific session\n */\n async switchModelForSession(sessionKey: string, modelId: string): Promise<boolean> {\n try {\n resolveModel(modelId);\n this.sessionModels.set(sessionKey, modelId);\n log.info({ sessionKey, modelId }, 'Model switched for session');\n return true;\n } catch (err) {\n log.error({ err, sessionKey, modelId }, 'Failed to switch model');\n return false;\n }\n }\n\n /** Drop in-memory session override so the global default is used again. */\n clearSessionModelOverride(sessionKey: string): void {\n this.sessionModels.delete(sessionKey);\n }\n\n /**\n * Resolved pi-ai model for session (for transcript policy, tools, etc.)\n */\n getResolvedModelForSession(sessionKey: string): Model<Api> {\n return resolveModel(this.getModelForSession(sessionKey));\n }\n\n /**\n * Get model for session, checking session override first\n */\n getModelForSession(sessionKey: string): string {\n const sessionModel = this.sessionModels.get(sessionKey);\n if (sessionModel) {\n return sessionModel;\n }\n\n const profileDefault = this.sessionProfileDefaults.get(sessionKey);\n if (profileDefault) {\n return profileDefault;\n }\n\n return this.defaultModel;\n }\n\n /**\n * Apply model to agent if different from current\n */\n async applyModelForSession(agent: Agent, sessionKey: string): Promise<void> {\n const targetModelId = this.getModelForSession(sessionKey);\n\n let found: Model<Api>;\n try {\n found = resolveModel(targetModelId);\n } catch (err) {\n log.error({ err, sessionKey, modelId: targetModelId }, 'Failed to apply model');\n return;\n }\n\n const sm = agent.state.model as Model<Api> | undefined;\n if (sm && sm.provider === found.provider && sm.id === found.id) {\n this.currentModelName = targetModelId;\n this.currentProvider = found.provider || 'unknown';\n return;\n }\n\n agent.state.model = found;\n this.currentModelName = targetModelId;\n this.currentProvider = found.provider || 'unknown';\n\n log.info({ sessionKey, modelId: targetModelId }, 'Applied model for session');\n }\n\n /**\n * Ordered model candidates for the session (primary + `agents.defaults.model.fallbacks`).\n */\n getFallbackCandidatesForSession(sessionKey: string): ModelCandidate[] {\n const ref = this.getModelForSession(sessionKey);\n const parsed = parseModelRef(ref);\n if (!parsed) {\n return [];\n }\n return resolveFallbackCandidates({\n cfg: this.config,\n provider: parsed.provider,\n model: parsed.model,\n });\n }\n\n /**\n * Apply a resolved pi-ai model and sync {@link currentModelName} / {@link currentProvider}.\n */\n applyResolvedModel(agent: Agent, model: Model<Api>, modelRef: string): void {\n agent.state.model = model;\n this.currentModelName = modelRef;\n this.currentProvider = model.provider || 'unknown';\n }\n\n /**\n * Run the agent with automatic model fallback on failure.\n */\n async runWithFallback(\n agent: Agent,\n sessionKey: string,\n userMessage: AgentMessage,\n provider: string,\n model: string\n ): Promise<RunResult> {\n const candidates = resolveFallbackCandidates({\n cfg: this.config ?? undefined,\n provider,\n model,\n });\n\n let lastError: unknown;\n\n for (let i = 0; i < candidates.length; i++) {\n const candidate = candidates[i];\n const modelRef = `${candidate.provider}/${candidate.model}`;\n\n let candidateModel: Model<Api>;\n try {\n candidateModel = resolveModel(modelRef);\n } catch {\n log.warn({ provider: candidate.provider, model: candidate.model }, 'Fallback model not found');\n continue;\n }\n\n log.info(\n { attempt: i + 1, total: candidates.length, provider: candidate.provider, model: candidate.model },\n 'Attempting model',\n );\n\n const beforeLen = agent.state.messages.length;\n\n try {\n this.applyResolvedModel(agent, candidateModel, modelRef);\n\n const runTurn = async () => {\n await agent.prompt(userMessage);\n await agent.waitForIdle();\n await maybeRetryTurnAfterTransientLlmFailure(agent, { sessionKey, log });\n };\n\n await runAgentTurnWithTimeout(agent, runTurn, resolveAgentTurnTimeoutMs(this.config));\n\n if (isAssistantTurnAborted(agent)) {\n const usage = (agent.state as { lastUsage?: RunResult['usage'] }).lastUsage;\n return { content: getLastAssistantContent(agent), usage };\n }\n\n if (!isAssistantTurnFailed(agent)) {\n const usage = (agent.state as { lastUsage?: RunResult['usage'] }).lastUsage;\n log.info(\n { provider: candidate.provider, model: candidate.model, success: true },\n 'Model call completed',\n );\n return { content: getLastAssistantContent(agent), usage };\n }\n\n lastError = new Error(`Assistant turn failed: ${modelRef}`);\n log.warn(\n { attempt: i + 1, sessionKey, modelRef },\n 'Model turn failed after retries, trying fallback',\n );\n } catch (err) {\n lastError = err;\n if (err instanceof DOMException && err.name === 'AbortError') {\n log.info({ sessionKey }, 'User aborted model call');\n throw err;\n }\n\n const errorDetails = {\n attempt: i + 1,\n provider: candidate.provider,\n model: candidate.model,\n errorMessage: err instanceof Error ? err.message : String(err),\n };\n\n if (isFailoverError(err)) {\n const described = describeFailoverError(err);\n log.warn({ ...errorDetails, ...described }, 'Model call failed, trying fallback');\n } else {\n log.warn(errorDetails, 'Model call failed, trying fallback');\n }\n }\n\n agent.state.messages = agent.state.messages.slice(0, beforeLen);\n }\n\n if (lastError) {\n const em = lastError instanceof Error ? lastError.message : String(lastError);\n const attemptedModelRefs = candidates.map((c) => `${c.provider}/${c.model}`);\n log.error(\n {\n err: lastError instanceof Error ? lastError : undefined,\n errorMessage: em,\n attemptedCandidates: candidates.length,\n attemptedModelRefs,\n sessionKey,\n },\n `All model candidates failed (${candidates.length} refs): ${em}`,\n );\n throw lastError instanceof Error ? lastError : new Error(String(lastError));\n }\n\n return { content: null };\n }\n\n /**\n * Find model by reference (provider/modelId)\n */\n findByRef(ref: string): Model<Api> | undefined {\n try {\n return resolveModel(ref);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Find model by provider and ID\n */\n find(provider: string, modelId: string): Model<Api> | undefined {\n try {\n return resolveModel(`${provider}/${modelId}`);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Get all available models\n */\n getAllModels(): readonly Model<Api>[] {\n return getAllModelsFromProviders();\n }\n\n /**\n * Get models grouped by provider\n */\n getModelsByProvider(): Map<string, Model<Api>[]> {\n const all = this.getAllModels();\n const grouped = new Map<string, Model<Api>[]>();\n for (const model of all) {\n const list = grouped.get(model.provider) ?? [];\n list.push(model);\n grouped.set(model.provider, list);\n }\n return grouped;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manager.js","names":["getAllModelsFromProviders"],"sources":["../../../../src/agent/models/manager.ts"],"sourcesContent":["/**\n * Model management module\n * \n * Handles model selection, switching, and automatic fallback\n * when a provider fails.\n */\n\nimport { Agent, type AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport { type Config, getAgentDefaultModelRef } from '../../config/schema.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { resolveModel, getAllModels as getAllModelsFromProviders, getDefaultModelSync } from '../../providers/index.js';\nimport {\n isFailoverError,\n describeFailoverError,\n resolveFallbackCandidates,\n type ModelCandidate,\n} from '../fallback/index.js';\nimport { parseModelRef } from './selection.js';\nimport {\n isAssistantTurnAborted,\n isAssistantTurnFailed,\n maybeRetryTurnAfterTransientLlmFailure,\n} from '../orchestration/llm-turn-retry.js';\nimport {\n resolveAgentTurnTimeoutMs,\n runAgentTurnWithTimeout,\n} from '../orchestration/run-agent-turn-with-timeout.js';\n\nconst log = createLogger('ModelManager');\n\nexport interface ModelManagerConfig {\n defaultModel?: string;\n config?: Config;\n}\n\nexport interface RunResult {\n content: string | null;\n usage?: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n };\n}\n\n/**\n * Get the last assistant content from agent messages\n */\nfunction getLastAssistantContent(agent: Agent): string | null {\n const messages = agent.state.messages;\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'assistant') {\n return msg.content\n .filter((c) => c.type === 'text')\n .map((c) => c.text || '')\n .join('');\n }\n }\n return null;\n}\n\nexport class ModelManager {\n private defaultModel: string;\n private config?: Config;\n private currentModelName: string;\n private currentProvider: string;\n private sessionModels: Map<string, string> = new Map();\n /** Baseline model from `agents.list` / defaults merge when the session agent is created. */\n private sessionProfileDefaults: Map<string, string> = new Map();\n private channelManager?: any;\n\n constructor(config: ModelManagerConfig = {}) {\n this.config = config.config;\n this.defaultModel = config.defaultModel || getDefaultModelSync(config.config);\n this.currentModelName = this.defaultModel;\n this.currentProvider = this.defaultModel.split('/')[0] || 'anthropic';\n }\n\n /**\n * Set channel manager reference for accessing session-specific settings\n */\n setChannelManager(channelManager: any): void {\n this.channelManager = channelManager;\n }\n\n /**\n * Apply updated config so default model and failover metadata match disk/runtime config.\n */\n updateFromConfig(config: Config): void {\n this.config = config;\n const ref = getAgentDefaultModelRef(config);\n this.defaultModel = ref ? ref : getDefaultModelSync(config);\n this.sessionProfileDefaults.clear();\n }\n\n /**\n * Set the config-derived default model for a session (from effective agent profile).\n * Cleared by {@link updateFromConfig} or {@link clearSessionProfileDefault}.\n */\n setSessionProfileDefault(sessionKey: string, modelRef: string): void {\n this.sessionProfileDefaults.set(sessionKey, modelRef);\n }\n\n clearSessionProfileDefault(sessionKey: string): void {\n this.sessionProfileDefaults.delete(sessionKey);\n }\n\n /**\n * Get current model name\n */\n getCurrentModel(): string {\n return this.currentModelName;\n }\n\n /**\n * Get current provider\n */\n getCurrentProvider(): string {\n return this.currentProvider;\n }\n\n /**\n * Switch model for a specific session\n */\n async switchModelForSession(sessionKey: string, modelId: string): Promise<boolean> {\n try {\n resolveModel(modelId);\n this.sessionModels.set(sessionKey, modelId);\n log.info({ sessionKey, modelId }, 'Model switched for session');\n return true;\n } catch (err) {\n log.error({ err, sessionKey, modelId }, 'Failed to switch model');\n return false;\n }\n }\n\n /** Drop in-memory session override so the global default is used again. */\n clearSessionModelOverride(sessionKey: string): void {\n this.sessionModels.delete(sessionKey);\n }\n\n /**\n * Resolved pi-ai model for session (for transcript policy, tools, etc.)\n */\n getResolvedModelForSession(sessionKey: string): Model<Api> {\n return resolveModel(this.getModelForSession(sessionKey));\n }\n\n /**\n * Get model for session, checking session override first\n */\n getModelForSession(sessionKey: string): string {\n const sessionModel = this.sessionModels.get(sessionKey);\n if (sessionModel) {\n return sessionModel;\n }\n\n const profileDefault = this.sessionProfileDefaults.get(sessionKey);\n if (profileDefault) {\n return profileDefault;\n }\n\n return this.defaultModel;\n }\n\n /**\n * Apply model to agent if different from current\n */\n async applyModelForSession(agent: Agent, sessionKey: string): Promise<void> {\n const targetModelId = this.getModelForSession(sessionKey);\n\n let found: Model<Api>;\n try {\n found = resolveModel(targetModelId);\n } catch (err) {\n log.error({ err, sessionKey, modelId: targetModelId }, 'Failed to apply model');\n return;\n }\n\n const sm = agent.state.model as Model<Api> | undefined;\n if (sm && sm.provider === found.provider && sm.id === found.id) {\n this.currentModelName = targetModelId;\n this.currentProvider = found.provider || 'unknown';\n return;\n }\n\n agent.state.model = found;\n this.currentModelName = targetModelId;\n this.currentProvider = found.provider || 'unknown';\n\n log.info({ sessionKey, modelId: targetModelId }, 'Applied model for session');\n }\n\n /**\n * Ordered model candidates for the session (primary + `agents.defaults.models.chat.fallbacks`).\n */\n getFallbackCandidatesForSession(sessionKey: string): ModelCandidate[] {\n const ref = this.getModelForSession(sessionKey);\n const parsed = parseModelRef(ref);\n if (!parsed) {\n return [];\n }\n return resolveFallbackCandidates({\n cfg: this.config,\n provider: parsed.provider,\n model: parsed.model,\n });\n }\n\n /**\n * Apply a resolved pi-ai model and sync {@link currentModelName} / {@link currentProvider}.\n */\n applyResolvedModel(agent: Agent, model: Model<Api>, modelRef: string): void {\n agent.state.model = model;\n this.currentModelName = modelRef;\n this.currentProvider = model.provider || 'unknown';\n }\n\n /**\n * Run the agent with automatic model fallback on failure.\n */\n async runWithFallback(\n agent: Agent,\n sessionKey: string,\n userMessage: AgentMessage,\n provider: string,\n model: string\n ): Promise<RunResult> {\n const candidates = resolveFallbackCandidates({\n cfg: this.config ?? undefined,\n provider,\n model,\n });\n\n let lastError: unknown;\n\n for (let i = 0; i < candidates.length; i++) {\n const candidate = candidates[i];\n const modelRef = `${candidate.provider}/${candidate.model}`;\n\n let candidateModel: Model<Api>;\n try {\n candidateModel = resolveModel(modelRef);\n } catch {\n log.warn({ provider: candidate.provider, model: candidate.model }, 'Fallback model not found');\n continue;\n }\n\n log.info(\n { attempt: i + 1, total: candidates.length, provider: candidate.provider, model: candidate.model },\n 'Attempting model',\n );\n\n const beforeLen = agent.state.messages.length;\n\n try {\n this.applyResolvedModel(agent, candidateModel, modelRef);\n\n const runTurn = async () => {\n await agent.prompt(userMessage);\n await agent.waitForIdle();\n await maybeRetryTurnAfterTransientLlmFailure(agent, { sessionKey, log });\n };\n\n await runAgentTurnWithTimeout(agent, runTurn, resolveAgentTurnTimeoutMs(this.config));\n\n if (isAssistantTurnAborted(agent)) {\n const usage = (agent.state as { lastUsage?: RunResult['usage'] }).lastUsage;\n return { content: getLastAssistantContent(agent), usage };\n }\n\n if (!isAssistantTurnFailed(agent)) {\n const usage = (agent.state as { lastUsage?: RunResult['usage'] }).lastUsage;\n log.info(\n { provider: candidate.provider, model: candidate.model, success: true },\n 'Model call completed',\n );\n return { content: getLastAssistantContent(agent), usage };\n }\n\n lastError = new Error(`Assistant turn failed: ${modelRef}`);\n log.warn(\n { attempt: i + 1, sessionKey, modelRef },\n 'Model turn failed after retries, trying fallback',\n );\n } catch (err) {\n lastError = err;\n if (err instanceof DOMException && err.name === 'AbortError') {\n log.info({ sessionKey }, 'User aborted model call');\n throw err;\n }\n\n const errorDetails = {\n attempt: i + 1,\n provider: candidate.provider,\n model: candidate.model,\n errorMessage: err instanceof Error ? err.message : String(err),\n };\n\n if (isFailoverError(err)) {\n const described = describeFailoverError(err);\n log.warn({ ...errorDetails, ...described }, 'Model call failed, trying fallback');\n } else {\n log.warn(errorDetails, 'Model call failed, trying fallback');\n }\n }\n\n agent.state.messages = agent.state.messages.slice(0, beforeLen);\n }\n\n if (lastError) {\n const em = lastError instanceof Error ? lastError.message : String(lastError);\n const attemptedModelRefs = candidates.map((c) => `${c.provider}/${c.model}`);\n log.error(\n {\n err: lastError instanceof Error ? lastError : undefined,\n errorMessage: em,\n attemptedCandidates: candidates.length,\n attemptedModelRefs,\n sessionKey,\n },\n `All model candidates failed (${candidates.length} refs): ${em}`,\n );\n throw lastError instanceof Error ? lastError : new Error(String(lastError));\n }\n\n return { content: null };\n }\n\n /**\n * Find model by reference (provider/modelId)\n */\n findByRef(ref: string): Model<Api> | undefined {\n try {\n return resolveModel(ref);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Find model by provider and ID\n */\n find(provider: string, modelId: string): Model<Api> | undefined {\n try {\n return resolveModel(`${provider}/${modelId}`);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Get all available models\n */\n getAllModels(): readonly Model<Api>[] {\n return getAllModelsFromProviders();\n }\n\n /**\n * Get models grouped by provider\n */\n getModelsByProvider(): Map<string, Model<Api>[]> {\n const all = this.getAllModels();\n const grouped = new Map<string, Model<Api>[]>();\n for (const model of all) {\n const list = grouped.get(model.provider) ?? [];\n list.push(model);\n grouped.set(model.provider, list);\n }\n return grouped;\n }\n}\n"],"mappings":";;;;;;;;;;;aAS8E;aACzB;gBACmE;AAkBxH,MAAM,MAAM,aAAa,eAAe;;;;AAmBxC,SAAS,wBAAwB,OAA6B;CAC5D,MAAM,WAAW,MAAM,MAAM;AAC7B,MAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;EAC7C,MAAM,MAAM,SAAS;AACrB,MAAI,IAAI,SAAS,YACf,QAAO,IAAI,QACR,QAAQ,MAAM,EAAE,SAAS,OAAO,CAChC,KAAK,MAAM,EAAE,QAAQ,GAAG,CACxB,KAAK,GAAG;;AAGf,QAAO;;AAGT,IAAa,eAAb,MAA0B;CACxB;CACA;CACA;CACA;CACA,gCAA6C,IAAI,KAAK;;CAEtD,yCAAsD,IAAI,KAAK;CAC/D;CAEA,YAAY,SAA6B,EAAE,EAAE;AAC3C,OAAK,SAAS,OAAO;AACrB,OAAK,eAAe,OAAO,gBAAgB,oBAAoB,OAAO,OAAO;AAC7E,OAAK,mBAAmB,KAAK;AAC7B,OAAK,kBAAkB,KAAK,aAAa,MAAM,IAAI,CAAC,MAAM;;;;;CAM5D,kBAAkB,gBAA2B;AAC3C,OAAK,iBAAiB;;;;;CAMxB,iBAAiB,QAAsB;AACrC,OAAK,SAAS;EACd,MAAM,MAAM,wBAAwB,OAAO;AAC3C,OAAK,eAAe,MAAM,MAAM,oBAAoB,OAAO;AAC3D,OAAK,uBAAuB,OAAO;;;;;;CAOrC,yBAAyB,YAAoB,UAAwB;AACnE,OAAK,uBAAuB,IAAI,YAAY,SAAS;;CAGvD,2BAA2B,YAA0B;AACnD,OAAK,uBAAuB,OAAO,WAAW;;;;;CAMhD,kBAA0B;AACxB,SAAO,KAAK;;;;;CAMd,qBAA6B;AAC3B,SAAO,KAAK;;;;;CAMd,MAAM,sBAAsB,YAAoB,SAAmC;AACjF,MAAI;AACF,gBAAa,QAAQ;AACrB,QAAK,cAAc,IAAI,YAAY,QAAQ;AAC3C,OAAI,KAAK;IAAE;IAAY;IAAS,EAAE,6BAA6B;AAC/D,UAAO;WACA,KAAK;AACZ,OAAI,MAAM;IAAE;IAAK;IAAY;IAAS,EAAE,yBAAyB;AACjE,UAAO;;;;CAKX,0BAA0B,YAA0B;AAClD,OAAK,cAAc,OAAO,WAAW;;;;;CAMvC,2BAA2B,YAAgC;AACzD,SAAO,aAAa,KAAK,mBAAmB,WAAW,CAAC;;;;;CAM1D,mBAAmB,YAA4B;EAC7C,MAAM,eAAe,KAAK,cAAc,IAAI,WAAW;AACvD,MAAI,aACF,QAAO;EAGT,MAAM,iBAAiB,KAAK,uBAAuB,IAAI,WAAW;AAClE,MAAI,eACF,QAAO;AAGT,SAAO,KAAK;;;;;CAMd,MAAM,qBAAqB,OAAc,YAAmC;EAC1E,MAAM,gBAAgB,KAAK,mBAAmB,WAAW;EAEzD,IAAI;AACJ,MAAI;AACF,WAAQ,aAAa,cAAc;WAC5B,KAAK;AACZ,OAAI,MAAM;IAAE;IAAK;IAAY,SAAS;IAAe,EAAE,wBAAwB;AAC/E;;EAGF,MAAM,KAAK,MAAM,MAAM;AACvB,MAAI,MAAM,GAAG,aAAa,MAAM,YAAY,GAAG,OAAO,MAAM,IAAI;AAC9D,QAAK,mBAAmB;AACxB,QAAK,kBAAkB,MAAM,YAAY;AACzC;;AAGF,QAAM,MAAM,QAAQ;AACpB,OAAK,mBAAmB;AACxB,OAAK,kBAAkB,MAAM,YAAY;AAEzC,MAAI,KAAK;GAAE;GAAY,SAAS;GAAe,EAAE,4BAA4B;;;;;CAM/E,gCAAgC,YAAsC;EAEpE,MAAM,SAAS,cADH,KAAK,mBAAmB,WACJ,CAAC;AACjC,MAAI,CAAC,OACH,QAAO,EAAE;AAEX,SAAO,0BAA0B;GAC/B,KAAK,KAAK;GACV,UAAU,OAAO;GACjB,OAAO,OAAO;GACf,CAAC;;;;;CAMJ,mBAAmB,OAAc,OAAmB,UAAwB;AAC1E,QAAM,MAAM,QAAQ;AACpB,OAAK,mBAAmB;AACxB,OAAK,kBAAkB,MAAM,YAAY;;;;;CAM3C,MAAM,gBACJ,OACA,YACA,aACA,UACA,OACoB;EACpB,MAAM,aAAa,0BAA0B;GAC3C,KAAK,KAAK,UAAU,KAAA;GACpB;GACA;GACD,CAAC;EAEF,IAAI;AAEJ,OAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;GAC1C,MAAM,YAAY,WAAW;GAC7B,MAAM,WAAW,GAAG,UAAU,SAAS,GAAG,UAAU;GAEpD,IAAI;AACJ,OAAI;AACF,qBAAiB,aAAa,SAAS;WACjC;AACN,QAAI,KAAK;KAAE,UAAU,UAAU;KAAU,OAAO,UAAU;KAAO,EAAE,2BAA2B;AAC9F;;AAGF,OAAI,KACF;IAAE,SAAS,IAAI;IAAG,OAAO,WAAW;IAAQ,UAAU,UAAU;IAAU,OAAO,UAAU;IAAO,EAClG,mBACD;GAED,MAAM,YAAY,MAAM,MAAM,SAAS;AAEvC,OAAI;AACF,SAAK,mBAAmB,OAAO,gBAAgB,SAAS;IAExD,MAAM,UAAU,YAAY;AAC1B,WAAM,MAAM,OAAO,YAAY;AAC/B,WAAM,MAAM,aAAa;AACzB,WAAM,uCAAuC,OAAO;MAAE;MAAY;MAAK,CAAC;;AAG1E,UAAM,wBAAwB,OAAO,SAAS,0BAA0B,KAAK,OAAO,CAAC;AAErF,QAAI,uBAAuB,MAAM,EAAE;KACjC,MAAM,QAAS,MAAM,MAA6C;AAClE,YAAO;MAAE,SAAS,wBAAwB,MAAM;MAAE;MAAO;;AAG3D,QAAI,CAAC,sBAAsB,MAAM,EAAE;KACjC,MAAM,QAAS,MAAM,MAA6C;AAClE,SAAI,KACF;MAAE,UAAU,UAAU;MAAU,OAAO,UAAU;MAAO,SAAS;MAAM,EACvE,uBACD;AACD,YAAO;MAAE,SAAS,wBAAwB,MAAM;MAAE;MAAO;;AAG3D,gCAAY,IAAI,MAAM,0BAA0B,WAAW;AAC3D,QAAI,KACF;KAAE,SAAS,IAAI;KAAG;KAAY;KAAU,EACxC,mDACD;YACM,KAAK;AACZ,gBAAY;AACZ,QAAI,eAAe,gBAAgB,IAAI,SAAS,cAAc;AAC5D,SAAI,KAAK,EAAE,YAAY,EAAE,0BAA0B;AACnD,WAAM;;IAGR,MAAM,eAAe;KACnB,SAAS,IAAI;KACb,UAAU,UAAU;KACpB,OAAO,UAAU;KACjB,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;KAC/D;AAED,QAAI,gBAAgB,IAAI,EAAE;KACxB,MAAM,YAAY,sBAAsB,IAAI;AAC5C,SAAI,KAAK;MAAE,GAAG;MAAc,GAAG;MAAW,EAAE,qCAAqC;UAEjF,KAAI,KAAK,cAAc,qCAAqC;;AAIhE,SAAM,MAAM,WAAW,MAAM,MAAM,SAAS,MAAM,GAAG,UAAU;;AAGjE,MAAI,WAAW;GACb,MAAM,KAAK,qBAAqB,QAAQ,UAAU,UAAU,OAAO,UAAU;GAC7E,MAAM,qBAAqB,WAAW,KAAK,MAAM,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ;AAC5E,OAAI,MACF;IACE,KAAK,qBAAqB,QAAQ,YAAY,KAAA;IAC9C,cAAc;IACd,qBAAqB,WAAW;IAChC;IACA;IACD,EACD,gCAAgC,WAAW,OAAO,UAAU,KAC7D;AACD,SAAM,qBAAqB,QAAQ,YAAY,IAAI,MAAM,OAAO,UAAU,CAAC;;AAG7E,SAAO,EAAE,SAAS,MAAM;;;;;CAM1B,UAAU,KAAqC;AAC7C,MAAI;AACF,UAAO,aAAa,IAAI;UAClB;AACN;;;;;;CAOJ,KAAK,UAAkB,SAAyC;AAC9D,MAAI;AACF,UAAO,aAAa,GAAG,SAAS,GAAG,UAAU;UACvC;AACN;;;;;;CAOJ,eAAsC;AACpC,SAAOA,cAA2B;;;;;CAMpC,sBAAiD;EAC/C,MAAM,MAAM,KAAK,cAAc;EAC/B,MAAM,0BAAU,IAAI,KAA2B;AAC/C,OAAK,MAAM,SAAS,KAAK;GACvB,MAAM,OAAO,QAAQ,IAAI,MAAM,SAAS,IAAI,EAAE;AAC9C,QAAK,KAAK,MAAM;AAChB,WAAQ,IAAI,MAAM,UAAU,KAAK;;AAEnC,SAAO"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Primary chat model + `agents.defaults.
|
|
2
|
+
* Primary chat model + `agents.defaults.models.chat.fallbacks`: one user turn with rollback on failure.
|
|
3
3
|
* Used by channel orchestrator, gateway webchat stream, and direct CLI-style turns.
|
|
4
4
|
*/
|
|
5
5
|
import type { Agent, AgentMessage } from '@earendil-works/pi-agent-core';
|
|
@@ -9,7 +9,7 @@ async function runAgentTurnWithModelFallbacks(params) {
|
|
|
9
9
|
const beforeUserPrompt = params.beforeUserPrompt ?? (async () => {});
|
|
10
10
|
const afterUserPrompt = params.afterUserPrompt ?? (async () => {});
|
|
11
11
|
const candidates = modelManager.getFallbackCandidatesForSession(sessionKey);
|
|
12
|
-
if (candidates.length === 0) throw new Error("No model candidates available. Configure agents.defaults.
|
|
12
|
+
if (candidates.length === 0) throw new Error("No model candidates available. Configure agents.defaults.models.chat and provider API keys.");
|
|
13
13
|
let lastError;
|
|
14
14
|
for (let i = 0; i < candidates.length; i++) {
|
|
15
15
|
const candidate = candidates[i];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-agent-turn-with-fallbacks.js","names":[],"sources":["../../../../src/agent/orchestration/run-agent-turn-with-fallbacks.ts"],"sourcesContent":["/**\n * Primary chat model + `agents.defaults.
|
|
1
|
+
{"version":3,"file":"run-agent-turn-with-fallbacks.js","names":[],"sources":["../../../../src/agent/orchestration/run-agent-turn-with-fallbacks.ts"],"sourcesContent":["/**\n * Primary chat model + `agents.defaults.models.chat.fallbacks`: one user turn with rollback on failure.\n * Used by channel orchestrator, gateway webchat stream, and direct CLI-style turns.\n */\n\nimport type { Agent, AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\n\nimport type { Config } from '../../config/schema.js';\nimport { resolveModel } from '../../providers/index.js';\nimport type { ModelManager } from '../models/index.js';\nimport {\n isAssistantTurnAborted,\n isAssistantTurnFailed,\n maybeRetryTurnAfterTransientLlmFailure,\n} from './llm-turn-retry.js';\nimport { resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from './run-agent-turn-with-timeout.js';\n\nexport { resolveAgentTurnTimeoutMs };\n\ntype FallbackLog = {\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 async function runAgentTurnWithModelFallbacks(params: {\n agent: Agent;\n sessionKey: string;\n modelManager: ModelManager;\n userMessage: AgentMessage;\n log: FallbackLog;\n /** Before `prompt` adds the user message (e.g. background-review nudge counters). */\n beforeUserPrompt?: () => void | Promise<void>;\n /** After `prompt` adds the user message; before `waitForIdle`. */\n afterUserPrompt?: () => Promise<void>;\n /** Overrides {@link resolveAgentTurnTimeoutMs} when set. */\n timeoutMs?: number;\n /** Supplies `agents.defaults.maxTaskDurationMs` for the default turn limit. */\n getConfig?: () => Config | undefined;\n}): Promise<void> {\n const { agent, sessionKey, modelManager, userMessage, log } = params;\n const timeoutMs = params.timeoutMs ?? resolveAgentTurnTimeoutMs(params.getConfig?.());\n const beforeUserPrompt = params.beforeUserPrompt ?? (async () => {});\n const afterUserPrompt = params.afterUserPrompt ?? (async () => {});\n\n const candidates = modelManager.getFallbackCandidatesForSession(sessionKey);\n if (candidates.length === 0) {\n throw new Error(\n 'No model candidates available. Configure agents.defaults.models.chat and provider API keys.',\n );\n }\n\n let lastError: unknown;\n\n for (let i = 0; i < candidates.length; i++) {\n const candidate = candidates[i];\n const modelRef = `${candidate.provider}/${candidate.model}`;\n\n let resolved: Model<Api>;\n try {\n resolved = resolveModel(modelRef);\n } catch (err) {\n lastError = err;\n log.warn({ err, modelRef, attempt: i + 1 }, 'Skipping model candidate (resolve failed)');\n continue;\n }\n\n const beforeLen = agent.state.messages.length;\n\n try {\n modelManager.applyResolvedModel(agent, resolved, modelRef);\n\n log.info(\n { attempt: i + 1, total: candidates.length, provider: candidate.provider, model: candidate.model },\n 'Running agent turn',\n );\n\n const runTurn = async () => {\n await beforeUserPrompt();\n await agent.prompt(userMessage);\n await afterUserPrompt();\n await agent.waitForIdle();\n await maybeRetryTurnAfterTransientLlmFailure(agent, { sessionKey, log });\n };\n\n await runAgentTurnWithTimeout(agent, runTurn, timeoutMs);\n\n if (isAssistantTurnAborted(agent)) {\n return;\n }\n\n if (!isAssistantTurnFailed(agent)) {\n return;\n }\n\n lastError = new Error(`Assistant turn failed: ${modelRef}`);\n log.warn(\n { sessionKey, attempt: i + 1, total: candidates.length, modelRef },\n 'Model turn failed after retries, trying fallback',\n );\n } catch (err) {\n lastError = err;\n if (err instanceof DOMException && err.name === 'AbortError') {\n throw err;\n }\n log.warn({ err, sessionKey, attempt: i + 1, modelRef }, 'Model call threw, trying fallback');\n }\n\n agent.state.messages = agent.state.messages.slice(0, beforeLen);\n }\n\n if (lastError instanceof Error) {\n throw lastError;\n }\n throw new Error(lastError != null ? String(lastError) : 'All model candidates failed');\n}\n"],"mappings":";;;;gBASwD;AAiBxD,eAAsB,+BAA+B,QAcnC;CAChB,MAAM,EAAE,OAAO,YAAY,cAAc,aAAa,QAAQ;CAC9D,MAAM,YAAY,OAAO,aAAa,0BAA0B,OAAO,aAAa,CAAC;CACrF,MAAM,mBAAmB,OAAO,qBAAqB,YAAY;CACjE,MAAM,kBAAkB,OAAO,oBAAoB,YAAY;CAE/D,MAAM,aAAa,aAAa,gCAAgC,WAAW;AAC3E,KAAI,WAAW,WAAW,EACxB,OAAM,IAAI,MACR,8FACD;CAGH,IAAI;AAEJ,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;EAC1C,MAAM,YAAY,WAAW;EAC7B,MAAM,WAAW,GAAG,UAAU,SAAS,GAAG,UAAU;EAEpD,IAAI;AACJ,MAAI;AACF,cAAW,aAAa,SAAS;WAC1B,KAAK;AACZ,eAAY;AACZ,OAAI,KAAK;IAAE;IAAK;IAAU,SAAS,IAAI;IAAG,EAAE,4CAA4C;AACxF;;EAGF,MAAM,YAAY,MAAM,MAAM,SAAS;AAEvC,MAAI;AACF,gBAAa,mBAAmB,OAAO,UAAU,SAAS;AAE1D,OAAI,KACF;IAAE,SAAS,IAAI;IAAG,OAAO,WAAW;IAAQ,UAAU,UAAU;IAAU,OAAO,UAAU;IAAO,EAClG,qBACD;GAED,MAAM,UAAU,YAAY;AAC1B,UAAM,kBAAkB;AACxB,UAAM,MAAM,OAAO,YAAY;AAC/B,UAAM,iBAAiB;AACvB,UAAM,MAAM,aAAa;AACzB,UAAM,uCAAuC,OAAO;KAAE;KAAY;KAAK,CAAC;;AAG1E,SAAM,wBAAwB,OAAO,SAAS,UAAU;AAExD,OAAI,uBAAuB,MAAM,CAC/B;AAGF,OAAI,CAAC,sBAAsB,MAAM,CAC/B;AAGF,+BAAY,IAAI,MAAM,0BAA0B,WAAW;AAC3D,OAAI,KACF;IAAE;IAAY,SAAS,IAAI;IAAG,OAAO,WAAW;IAAQ;IAAU,EAClE,mDACD;WACM,KAAK;AACZ,eAAY;AACZ,OAAI,eAAe,gBAAgB,IAAI,SAAS,aAC9C,OAAM;AAER,OAAI,KAAK;IAAE;IAAK;IAAY,SAAS,IAAI;IAAG;IAAU,EAAE,oCAAoC;;AAG9F,QAAM,MAAM,WAAW,MAAM,MAAM,SAAS,MAAM,GAAG,UAAU;;AAGjE,KAAI,qBAAqB,MACvB,OAAM;AAER,OAAM,IAAI,MAAM,aAAa,OAAO,OAAO,UAAU,GAAG,8BAA8B"}
|
|
@@ -18,6 +18,7 @@ const CORE_TOOL_ORDER = [
|
|
|
18
18
|
"session_search",
|
|
19
19
|
"curated_memory",
|
|
20
20
|
"session_status",
|
|
21
|
+
"tool_manual",
|
|
21
22
|
"delegate_task",
|
|
22
23
|
"workflow",
|
|
23
24
|
"cronjob",
|
|
@@ -51,6 +52,7 @@ const CORE_TOOL_SUMMARIES = {
|
|
|
51
52
|
session_search: "Search other chat sessions or list recent sessions",
|
|
52
53
|
curated_memory: "Read/write structured notes under agent home memories/",
|
|
53
54
|
session_status: "Show session usage/time/model state",
|
|
55
|
+
tool_manual: "Load built-in usage manuals for complex tools",
|
|
54
56
|
delegate_task: "Spawn an isolated sub-agent for a delegated task",
|
|
55
57
|
workflow: "Start a persisted multi-phase workflow run",
|
|
56
58
|
cronjob: "Manage scheduled cron jobs",
|
|
@@ -95,6 +97,7 @@ function buildToolingSection(params) {
|
|
|
95
97
|
const shellToolName = resolveToolName("shell");
|
|
96
98
|
const hasDelegate = availableTools.has("delegate_task");
|
|
97
99
|
const hasWorkflow = availableTools.has("workflow");
|
|
100
|
+
const hasToolManual = availableTools.has("tool_manual");
|
|
98
101
|
const orchestrationLines = [];
|
|
99
102
|
if (hasDelegate) orchestrationLines.push("- Sub-agent delegation → use `delegate_task(goal, context?, toolset?)` for focused parallel work; results return to you automatically.");
|
|
100
103
|
if (hasWorkflow) orchestrationLines.push("- Multi-phase workflows → use `workflow` to start persisted runs with subagents when a script defines phases.");
|
|
@@ -104,6 +107,7 @@ function buildToolingSection(params) {
|
|
|
104
107
|
"Tool names are case-sensitive. Call tools exactly as listed.",
|
|
105
108
|
toolLines.length > 0 ? toolLines.join("\n") : "- No tools are registered for this session.",
|
|
106
109
|
`For long waits, avoid rapid poll loops: use \`${shellToolName}\` with enough yieldMs or poll in reasonable intervals.`,
|
|
110
|
+
hasToolManual ? "Some complex tools have built-in manuals. Use `tool_manual(tool)` before non-trivial use." : "",
|
|
107
111
|
hasDelegate ? "If a task is complex or long-running, delegate it. Completion is push-based: the sub-agent result returns when done." : "",
|
|
108
112
|
...orchestrationLines,
|
|
109
113
|
"Do not poll delegate/workflow status in a tight loop; check on-demand or wait for completion."
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooling.js","names":[],"sources":["../../../../../src/agent/prompt/sections/tooling.ts"],"sourcesContent":["const CORE_TOOL_ORDER = [\n 'read_file',\n 'write_file',\n 'edit_file',\n 'grep',\n 'find',\n 'list_dir',\n 'shell',\n 'web_search',\n 'web_fetch',\n 'web_extract',\n 'browser_use',\n 'send_message',\n 'send_media',\n 'memory_search',\n 'memory_get',\n 'session_search',\n 'curated_memory',\n 'session_status',\n 'delegate_task',\n 'workflow',\n 'cronjob',\n 'skills_list',\n 'skill_view',\n 'skill_manage',\n 'todo',\n 'clarify',\n 'text_to_speech',\n 'image',\n 'image_generate',\n 'create_share',\n 'execute_code',\n] as const;\n\nconst CORE_TOOL_SUMMARIES: Record<string, string> = {\n read_file: 'Read file contents',\n write_file: 'Create or overwrite files',\n edit_file: 'Make precise edits to files',\n grep: 'Search file contents for patterns',\n find: 'Find files by glob pattern',\n list_dir: 'List directory contents',\n shell: 'Run shell commands (supports background via yieldMs/background)',\n web_search: 'Search the web',\n web_fetch: 'Fetch and extract readable content from a URL',\n web_extract: 'Extract structured content from a URL',\n browser_use: 'Control the configured browser',\n send_message: 'Send messages to the current channel',\n send_media: 'Send media attachments to the current channel',\n memory_search: 'Semantic search over workspace and profile memory files',\n memory_get: 'Read specific lines from memory files',\n session_search: 'Search other chat sessions or list recent sessions',\n curated_memory: 'Read/write structured notes under agent home memories/',\n session_status: 'Show session usage/time/model state',\n delegate_task: 'Spawn an isolated sub-agent for a delegated task',\n workflow: 'Start a persisted multi-phase workflow run',\n cronjob: 'Manage scheduled cron jobs',\n skills_list: 'List available skills',\n skill_view: 'Load a skill SKILL.md or sub-documents',\n skill_manage: 'Create or update skills on disk',\n todo: 'Manage in-session todo items',\n clarify: 'Ask the user a blocking clarification question',\n text_to_speech: 'Send a standalone voice message',\n image: 'Analyze an image with the configured vision model',\n image_generate: 'Generate images with the configured image model',\n create_share: 'Create a shareable link for workspace files',\n execute_code: 'Run code in a sandbox with a restricted tool subset',\n};\n\nexport function buildToolingSection(params: {\n toolNames?: string[];\n toolSummaries?: Record<string, string>;\n}): string {\n const rawToolNames = (params.toolNames ?? []).map((tool) => tool.trim()).filter(Boolean);\n const canonicalByNormalized = new Map<string, string>();\n for (const name of rawToolNames) {\n const normalized = name.toLowerCase();\n if (!canonicalByNormalized.has(normalized)) {\n canonicalByNormalized.set(normalized, name);\n }\n }\n const resolveToolName = (normalized: string) =>\n canonicalByNormalized.get(normalized) ?? normalized;\n\n const normalizedTools = rawToolNames.map((tool) => tool.toLowerCase());\n const availableTools = new Set(normalizedTools);\n\n const externalToolSummaries = new Map<string, string>();\n for (const [key, value] of Object.entries(params.toolSummaries ?? {})) {\n const normalized = key.trim().toLowerCase();\n if (!normalized || !value?.trim()) {\n continue;\n }\n externalToolSummaries.set(normalized, value.trim());\n }\n\n const extraTools = Array.from(\n new Set(normalizedTools.filter((tool) => !CORE_TOOL_ORDER.includes(tool as (typeof CORE_TOOL_ORDER)[number]))),\n );\n const enabledTools = CORE_TOOL_ORDER.filter((tool) => availableTools.has(tool));\n const toolLines = enabledTools.map((tool) => {\n const summary = CORE_TOOL_SUMMARIES[tool] ?? externalToolSummaries.get(tool);\n const name = resolveToolName(tool);\n return summary ? `- ${name}: ${summary}` : `- ${name}`;\n });\n for (const tool of extraTools.toSorted()) {\n const summary = CORE_TOOL_SUMMARIES[tool] ?? externalToolSummaries.get(tool);\n const name = resolveToolName(tool);\n toolLines.push(summary ? `- ${name}: ${summary}` : `- ${name}`);\n }\n\n const shellToolName = resolveToolName('shell');\n const hasDelegate = availableTools.has('delegate_task');\n const hasWorkflow = availableTools.has('workflow');\n\n const orchestrationLines: string[] = [];\n if (hasDelegate) {\n orchestrationLines.push(\n '- Sub-agent delegation → use `delegate_task(goal, context?, toolset?)` for focused parallel work; results return to you automatically.',\n );\n }\n if (hasWorkflow) {\n orchestrationLines.push(\n '- Multi-phase workflows → use `workflow` to start persisted runs with subagents when a script defines phases.',\n );\n }\n\n return [\n '## Tooling',\n 'Tool availability (filtered by policy):',\n 'Tool names are case-sensitive. Call tools exactly as listed.',\n toolLines.length > 0\n ? toolLines.join('\\n')\n : '- No tools are registered for this session.',\n `For long waits, avoid rapid poll loops: use \\`${shellToolName}\\` with enough yieldMs or poll in reasonable intervals.`,\n hasDelegate\n ? 'If a task is complex or long-running, delegate it. Completion is push-based: the sub-agent result returns when done.'\n : '',\n ...orchestrationLines,\n 'Do not poll delegate/workflow status in a tight loop; check on-demand or wait for completion.',\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nexport function hasSkillsTools(toolNames: string[]): boolean {\n const normalized = new Set(toolNames.map((t) => t.toLowerCase()));\n return normalized.has('skills_list') || normalized.has('skill_view');\n}\n"],"mappings":";AAAA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAM,sBAA8C;CAClD,WAAW;CACX,YAAY;CACZ,WAAW;CACX,MAAM;CACN,MAAM;CACN,UAAU;CACV,OAAO;CACP,YAAY;CACZ,WAAW;CACX,aAAa;CACb,aAAa;CACb,cAAc;CACd,YAAY;CACZ,eAAe;CACf,YAAY;CACZ,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAChB,eAAe;CACf,UAAU;CACV,SAAS;CACT,aAAa;CACb,YAAY;CACZ,cAAc;CACd,MAAM;CACN,SAAS;CACT,gBAAgB;CAChB,OAAO;CACP,gBAAgB;CAChB,cAAc;CACd,cAAc;CACf;AAED,SAAgB,oBAAoB,QAGzB;CACT,MAAM,gBAAgB,OAAO,aAAa,EAAE,EAAE,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC,OAAO,QAAQ;CACxF,MAAM,wCAAwB,IAAI,KAAqB;AACvD,MAAK,MAAM,QAAQ,cAAc;EAC/B,MAAM,aAAa,KAAK,aAAa;AACrC,MAAI,CAAC,sBAAsB,IAAI,WAAW,CACxC,uBAAsB,IAAI,YAAY,KAAK;;CAG/C,MAAM,mBAAmB,eACvB,sBAAsB,IAAI,WAAW,IAAI;CAE3C,MAAM,kBAAkB,aAAa,KAAK,SAAS,KAAK,aAAa,CAAC;CACtE,MAAM,iBAAiB,IAAI,IAAI,gBAAgB;CAE/C,MAAM,wCAAwB,IAAI,KAAqB;AACvD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,iBAAiB,EAAE,CAAC,EAAE;EACrE,MAAM,aAAa,IAAI,MAAM,CAAC,aAAa;AAC3C,MAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAC/B;AAEF,wBAAsB,IAAI,YAAY,MAAM,MAAM,CAAC;;CAGrD,MAAM,aAAa,MAAM,KACvB,IAAI,IAAI,gBAAgB,QAAQ,SAAS,CAAC,gBAAgB,SAAS,KAAyC,CAAC,CAAC,CAC/G;CAED,MAAM,YADe,gBAAgB,QAAQ,SAAS,eAAe,IAAI,KAAK,CAChD,CAAC,KAAK,SAAS;EAC3C,MAAM,UAAU,oBAAoB,SAAS,sBAAsB,IAAI,KAAK;EAC5E,MAAM,OAAO,gBAAgB,KAAK;AAClC,SAAO,UAAU,KAAK,KAAK,IAAI,YAAY,KAAK;GAChD;AACF,MAAK,MAAM,QAAQ,WAAW,UAAU,EAAE;EACxC,MAAM,UAAU,oBAAoB,SAAS,sBAAsB,IAAI,KAAK;EAC5E,MAAM,OAAO,gBAAgB,KAAK;AAClC,YAAU,KAAK,UAAU,KAAK,KAAK,IAAI,YAAY,KAAK,OAAO;;CAGjE,MAAM,gBAAgB,gBAAgB,QAAQ;CAC9C,MAAM,cAAc,eAAe,IAAI,gBAAgB;CACvD,MAAM,cAAc,eAAe,IAAI,WAAW;
|
|
1
|
+
{"version":3,"file":"tooling.js","names":[],"sources":["../../../../../src/agent/prompt/sections/tooling.ts"],"sourcesContent":["const CORE_TOOL_ORDER = [\n 'read_file',\n 'write_file',\n 'edit_file',\n 'grep',\n 'find',\n 'list_dir',\n 'shell',\n 'web_search',\n 'web_fetch',\n 'web_extract',\n 'browser_use',\n 'send_message',\n 'send_media',\n 'memory_search',\n 'memory_get',\n 'session_search',\n 'curated_memory',\n 'session_status',\n 'tool_manual',\n 'delegate_task',\n 'workflow',\n 'cronjob',\n 'skills_list',\n 'skill_view',\n 'skill_manage',\n 'todo',\n 'clarify',\n 'text_to_speech',\n 'image',\n 'image_generate',\n 'create_share',\n 'execute_code',\n] as const;\n\nconst CORE_TOOL_SUMMARIES: Record<string, string> = {\n read_file: 'Read file contents',\n write_file: 'Create or overwrite files',\n edit_file: 'Make precise edits to files',\n grep: 'Search file contents for patterns',\n find: 'Find files by glob pattern',\n list_dir: 'List directory contents',\n shell: 'Run shell commands (supports background via yieldMs/background)',\n web_search: 'Search the web',\n web_fetch: 'Fetch and extract readable content from a URL',\n web_extract: 'Extract structured content from a URL',\n browser_use: 'Control the configured browser',\n send_message: 'Send messages to the current channel',\n send_media: 'Send media attachments to the current channel',\n memory_search: 'Semantic search over workspace and profile memory files',\n memory_get: 'Read specific lines from memory files',\n session_search: 'Search other chat sessions or list recent sessions',\n curated_memory: 'Read/write structured notes under agent home memories/',\n session_status: 'Show session usage/time/model state',\n tool_manual: 'Load built-in usage manuals for complex tools',\n delegate_task: 'Spawn an isolated sub-agent for a delegated task',\n workflow: 'Start a persisted multi-phase workflow run',\n cronjob: 'Manage scheduled cron jobs',\n skills_list: 'List available skills',\n skill_view: 'Load a skill SKILL.md or sub-documents',\n skill_manage: 'Create or update skills on disk',\n todo: 'Manage in-session todo items',\n clarify: 'Ask the user a blocking clarification question',\n text_to_speech: 'Send a standalone voice message',\n image: 'Analyze an image with the configured vision model',\n image_generate: 'Generate images with the configured image model',\n create_share: 'Create a shareable link for workspace files',\n execute_code: 'Run code in a sandbox with a restricted tool subset',\n};\n\nexport function buildToolingSection(params: {\n toolNames?: string[];\n toolSummaries?: Record<string, string>;\n}): string {\n const rawToolNames = (params.toolNames ?? []).map((tool) => tool.trim()).filter(Boolean);\n const canonicalByNormalized = new Map<string, string>();\n for (const name of rawToolNames) {\n const normalized = name.toLowerCase();\n if (!canonicalByNormalized.has(normalized)) {\n canonicalByNormalized.set(normalized, name);\n }\n }\n const resolveToolName = (normalized: string) =>\n canonicalByNormalized.get(normalized) ?? normalized;\n\n const normalizedTools = rawToolNames.map((tool) => tool.toLowerCase());\n const availableTools = new Set(normalizedTools);\n\n const externalToolSummaries = new Map<string, string>();\n for (const [key, value] of Object.entries(params.toolSummaries ?? {})) {\n const normalized = key.trim().toLowerCase();\n if (!normalized || !value?.trim()) {\n continue;\n }\n externalToolSummaries.set(normalized, value.trim());\n }\n\n const extraTools = Array.from(\n new Set(normalizedTools.filter((tool) => !CORE_TOOL_ORDER.includes(tool as (typeof CORE_TOOL_ORDER)[number]))),\n );\n const enabledTools = CORE_TOOL_ORDER.filter((tool) => availableTools.has(tool));\n const toolLines = enabledTools.map((tool) => {\n const summary = CORE_TOOL_SUMMARIES[tool] ?? externalToolSummaries.get(tool);\n const name = resolveToolName(tool);\n return summary ? `- ${name}: ${summary}` : `- ${name}`;\n });\n for (const tool of extraTools.toSorted()) {\n const summary = CORE_TOOL_SUMMARIES[tool] ?? externalToolSummaries.get(tool);\n const name = resolveToolName(tool);\n toolLines.push(summary ? `- ${name}: ${summary}` : `- ${name}`);\n }\n\n const shellToolName = resolveToolName('shell');\n const hasDelegate = availableTools.has('delegate_task');\n const hasWorkflow = availableTools.has('workflow');\n const hasToolManual = availableTools.has('tool_manual');\n\n const orchestrationLines: string[] = [];\n if (hasDelegate) {\n orchestrationLines.push(\n '- Sub-agent delegation → use `delegate_task(goal, context?, toolset?)` for focused parallel work; results return to you automatically.',\n );\n }\n if (hasWorkflow) {\n orchestrationLines.push(\n '- Multi-phase workflows → use `workflow` to start persisted runs with subagents when a script defines phases.',\n );\n }\n\n return [\n '## Tooling',\n 'Tool availability (filtered by policy):',\n 'Tool names are case-sensitive. Call tools exactly as listed.',\n toolLines.length > 0\n ? toolLines.join('\\n')\n : '- No tools are registered for this session.',\n `For long waits, avoid rapid poll loops: use \\`${shellToolName}\\` with enough yieldMs or poll in reasonable intervals.`,\n hasToolManual\n ? 'Some complex tools have built-in manuals. Use `tool_manual(tool)` before non-trivial use.'\n : '',\n hasDelegate\n ? 'If a task is complex or long-running, delegate it. Completion is push-based: the sub-agent result returns when done.'\n : '',\n ...orchestrationLines,\n 'Do not poll delegate/workflow status in a tight loop; check on-demand or wait for completion.',\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nexport function hasSkillsTools(toolNames: string[]): boolean {\n const normalized = new Set(toolNames.map((t) => t.toLowerCase()));\n return normalized.has('skills_list') || normalized.has('skill_view');\n}\n"],"mappings":"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"}
|
|
@@ -81,7 +81,7 @@ async function runDirectAgentTurn(deps, input) {
|
|
|
81
81
|
})).images;
|
|
82
82
|
const result = await runEmbeddedTurnForSession({
|
|
83
83
|
sessionKey: input.sessionKey,
|
|
84
|
-
runId: crypto.randomUUID(),
|
|
84
|
+
runId: input.runId ?? crypto.randomUUID(),
|
|
85
85
|
userMessage: userMessageForModel,
|
|
86
86
|
llmImages,
|
|
87
87
|
sessionStore: deps.sessionStore,
|
|
@@ -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 type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport { commandRegistry } from '../../chat-commands/index.js';\nimport { parseSlashCommand } from '../../chat-commands/command-parse.js';\nimport { shouldSkipResetOverlapCommand } from '../../session/reset-triggers.js';\nimport { hydrateUserTurnForLlm, type TranscriptUserMessage } from '../inbound/attachment-pipeline.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';\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 modelRef = deps.modelManager.getModelForSession(input.sessionKey);\n const llmTurn = await hydrateUserTurnForLlm({\n message: input.userMessage as TranscriptUserMessage,\n modelRef,\n });\n const llmImages = llmTurn.images;\n\n const result = await runEmbeddedTurnForSession({\n sessionKey: input.sessionKey,\n runId: crypto.randomUUID(),\n userMessage: userMessageForModel,\n llmImages,\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":";;;;;;;;;;;;;;;;;AAgCA,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;;;;;;;
|
|
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 type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport { commandRegistry } from '../../chat-commands/index.js';\nimport { parseSlashCommand } from '../../chat-commands/command-parse.js';\nimport { shouldSkipResetOverlapCommand } from '../../session/reset-triggers.js';\nimport { hydrateUserTurnForLlm, type TranscriptUserMessage } from '../inbound/attachment-pipeline.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';\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 runId?: 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 modelRef = deps.modelManager.getModelForSession(input.sessionKey);\n const llmTurn = await hydrateUserTurnForLlm({\n message: input.userMessage as TranscriptUserMessage,\n modelRef,\n });\n const llmImages = llmTurn.images;\n\n const result = await runEmbeddedTurnForSession({\n sessionKey: input.sessionKey,\n runId: input.runId ?? crypto.randomUUID(),\n userMessage: userMessageForModel,\n llmImages,\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":";;;;;;;;;;;;;;;;;AAgCA,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;;;;;;;AA6B7F,eAAsB,mBACpB,MACA,OACmC;CACnC,MAAM,YAAY,0BAA0B,MAAM,YAAY;CAC9D,MAAM,sBAAsB,MAAM,KAAK,aAAa,iCAClD,MAAM,aACN,MAAM,WACP;CAED,MAAM,WAAW,KAAK,aAAa,mBAAmB,MAAM,WAAW;CAKvE,MAAM,aAAY,MAJI,sBAAsB;EAC1C,SAAS,MAAM;EACf;EACD,CAAC,EACwB;CAE1B,MAAM,SAAS,MAAM,0BAA0B;EAC7C,YAAY,MAAM;EAClB,OAAO,MAAM,SAAS,OAAO,YAAY;EACzC,aAAa;EACb;EACA,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"}
|
|
@@ -6,11 +6,38 @@ import { initSessionTurn } from "../../session/init-session-turn.js";
|
|
|
6
6
|
import "../../session/index.js";
|
|
7
7
|
import { isVoiceLikeAttachment, mergeSttConfigFromAppConfig, mergeVoiceTranscriptsIntoUserText } from "../../channels/attachments/voice-stt-webchat.js";
|
|
8
8
|
import { abortEmbeddedRun } from "../embedded/runs.js";
|
|
9
|
-
import { mapEmbeddedEventToGatewaySse } from "../embedded/map-stream-events.js";
|
|
10
9
|
import { applyReasoningVisibilityToSseEvent } from "../streaming/reasoning-visibility-sse.js";
|
|
11
10
|
import { AsyncQueue } from "./async-queue.js";
|
|
12
11
|
import { hydratePerTurnState, runDirectAgentTurn, tryRunSlashCommand } from "./direct-turn-helpers.js";
|
|
13
12
|
//#region src/agent/service/process-direct-streaming.ts
|
|
13
|
+
function makeAssistantReceiptMessage(text) {
|
|
14
|
+
return {
|
|
15
|
+
role: "assistant",
|
|
16
|
+
content: [{
|
|
17
|
+
type: "text",
|
|
18
|
+
text
|
|
19
|
+
}],
|
|
20
|
+
timestamp: Date.now()
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function pushAssistantReceipt(queue, text, runId) {
|
|
24
|
+
const message = makeAssistantReceiptMessage(text);
|
|
25
|
+
queue.push({
|
|
26
|
+
type: "message_start",
|
|
27
|
+
runId,
|
|
28
|
+
message
|
|
29
|
+
});
|
|
30
|
+
queue.push({
|
|
31
|
+
type: "message_update",
|
|
32
|
+
runId,
|
|
33
|
+
message
|
|
34
|
+
});
|
|
35
|
+
queue.push({
|
|
36
|
+
type: "message_end",
|
|
37
|
+
runId,
|
|
38
|
+
message
|
|
39
|
+
});
|
|
40
|
+
}
|
|
14
41
|
async function* runProcessDirectStreaming(deps, input) {
|
|
15
42
|
const sessionKey = input.sessionKey ?? "agent:main:main";
|
|
16
43
|
const { channel, chatId } = deps.parseSessionKey(sessionKey);
|
|
@@ -57,10 +84,7 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
57
84
|
if (turn.bareReset && turn.ackMessage) {
|
|
58
85
|
ranSlashCommand = true;
|
|
59
86
|
webchatSlashReceipt = turn.ackMessage;
|
|
60
|
-
|
|
61
|
-
type: "token",
|
|
62
|
-
content: turn.ackMessage
|
|
63
|
-
});
|
|
87
|
+
pushAssistantReceipt(queue, turn.ackMessage, input.runId);
|
|
64
88
|
return;
|
|
65
89
|
}
|
|
66
90
|
turnBody = turn.bodyStripped;
|
|
@@ -122,16 +146,10 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
122
146
|
const text = slash.aggregatedText.trim();
|
|
123
147
|
if (text) {
|
|
124
148
|
webchatSlashReceipt = text;
|
|
125
|
-
|
|
126
|
-
type: "token",
|
|
127
|
-
content: text
|
|
128
|
-
});
|
|
149
|
+
pushAssistantReceipt(queue, text, input.runId);
|
|
129
150
|
} else if (channel === "webchat") {
|
|
130
151
|
webchatSlashReceipt = "Command finished with no assistant text. If you used `/goal`, a follow-up turn may still be scheduled automatically.";
|
|
131
|
-
|
|
132
|
-
type: "token",
|
|
133
|
-
content: webchatSlashReceipt
|
|
134
|
-
});
|
|
152
|
+
pushAssistantReceipt(queue, webchatSlashReceipt, input.runId);
|
|
135
153
|
}
|
|
136
154
|
return;
|
|
137
155
|
}
|
|
@@ -158,12 +176,11 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
158
176
|
sessionKey,
|
|
159
177
|
userMessage,
|
|
160
178
|
abortSignal: signal,
|
|
179
|
+
runId: input.runId,
|
|
161
180
|
onEvent: (embeddedEvent) => {
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
164
|
-
|
|
165
|
-
pushVisible(mapped);
|
|
166
|
-
}
|
|
181
|
+
const event = { ...embeddedEvent };
|
|
182
|
+
if (event.type === "error" && typeof event.content === "string") event.content = formatStreamError(event.content);
|
|
183
|
+
pushVisible(event);
|
|
167
184
|
}
|
|
168
185
|
});
|
|
169
186
|
if (result.lastAssistantText) deps.onTurnComplete?.(sessionKey, result.lastAssistantText);
|
|
@@ -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 { InboundAttachmentInput, MediaRef } from '../../channels/attachments/inbound-persist.js';\nimport { readAgentMessageContent } from '../memory/agent-message-access.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 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';\nimport {\n clearPendingTranscriptUserMessage,\n setPendingTranscriptUserMessage,\n type TranscriptUserMessage,\n} from '../inbound/attachment-pipeline.js';\n\nexport type DirectStreamInboundAttachment = InboundAttachmentInput;\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 commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectStreamInboundAttachment[],\n ) => Promise<MediaRef[] | undefined>;\n buildTranscriptUserMessage: (\n content: string,\n prepared: MediaRef[] | undefined,\n sessionKey: string,\n ) => Promise<TranscriptUserMessage>;\n recordPersistentGoalStreamOutcome?: (\n sessionKey: string,\n outcome: { skipPersistentGoalPostTurn: boolean },\n ) => void;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: 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'; uri: 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 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(prepared, turnBody, sttCfg);\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 voiceMedia = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({\n uri: att.uri,\n mimeType: att.mimeType,\n name: att.name,\n }));\n pushVisible({\n type: 'user_transcript',\n text: transcriptParts.join('\\n\\n'),\n media: voiceMedia,\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 {\n sessionKey,\n channel,\n chatId,\n senderId: context.senderId,\n isGroup: context.isGroup,\n inboundMetadata: context.metadata,\n },\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 userMessage = await deps.buildTranscriptUserMessage(textForAgent, prepared, sessionKey);\n\n if (channel === 'webchat') {\n pushVisible({\n type: 'user_message',\n timestamp: userMessage.timestamp ?? Date.now(),\n content: readAgentMessageContent(userMessage),\n media: userMessage.media,\n });\n if (textForAgent.trim()) {\n deps.enqueueProvisionalSessionTitle?.(sessionKey, textForAgent);\n }\n }\n\n const pendingUserMessage = userMessage as TranscriptUserMessage;\n setPendingTranscriptUserMessage(sessionKey, pendingUserMessage);\n\n try {\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 } finally {\n clearPendingTranscriptUserMessage(sessionKey, pendingUserMessage);\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;\n\n if (channel === 'webchat' && ranSlashCommand) {\n try {\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 deps.sessionStore.appendTranscriptMessage(sessionKey, userMsg);\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 deps.sessionStore.appendTranscriptMessage(sessionKey, assistantMsg);\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 { InboundAttachmentInput, MediaRef } from '../../channels/attachments/inbound-persist.js';\nimport { readAgentMessageContent } from '../memory/agent-message-access.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 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 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';\nimport {\n clearPendingTranscriptUserMessage,\n setPendingTranscriptUserMessage,\n type TranscriptUserMessage,\n} from '../inbound/attachment-pipeline.js';\n\nexport type DirectStreamInboundAttachment = InboundAttachmentInput;\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 commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectStreamInboundAttachment[],\n ) => Promise<MediaRef[] | undefined>;\n buildTranscriptUserMessage: (\n content: string,\n prepared: MediaRef[] | undefined,\n sessionKey: string,\n ) => Promise<TranscriptUserMessage>;\n recordPersistentGoalStreamOutcome?: (\n sessionKey: string,\n outcome: { skipPersistentGoalPostTurn: boolean },\n ) => void;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: 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'; uri: 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 runId?: string;\n}\n\nexport type ProcessDirectStreamingSseEvent = { type: string; [key: string]: unknown };\n\nfunction makeAssistantReceiptMessage(text: string): AgentMessage {\n return {\n role: 'assistant',\n content: [{ type: 'text', text }],\n timestamp: Date.now(),\n } as AgentMessage;\n}\n\nfunction pushAssistantReceipt(\n queue: AsyncQueue<ProcessDirectStreamingSseEvent>,\n text: string,\n runId?: string,\n): void {\n const message = makeAssistantReceiptMessage(text);\n queue.push({ type: 'message_start', runId, message });\n queue.push({ type: 'message_update', runId, message });\n queue.push({ type: 'message_end', runId, message });\n}\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 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 pushAssistantReceipt(queue, turn.ackMessage, input.runId);\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(prepared, turnBody, sttCfg);\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 voiceMedia = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({\n uri: att.uri,\n mimeType: att.mimeType,\n name: att.name,\n }));\n pushVisible({\n type: 'user_transcript',\n text: transcriptParts.join('\\n\\n'),\n media: voiceMedia,\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 {\n sessionKey,\n channel,\n chatId,\n senderId: context.senderId,\n isGroup: context.isGroup,\n inboundMetadata: context.metadata,\n },\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 pushAssistantReceipt(queue, text, input.runId);\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 pushAssistantReceipt(queue, webchatSlashReceipt, input.runId);\n }\n return;\n }\n\n const textForAgent = mergedUserText.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(mergedUserText)\n : mergedUserText;\n const userMessage = await deps.buildTranscriptUserMessage(textForAgent, prepared, sessionKey);\n\n if (channel === 'webchat') {\n pushVisible({\n type: 'user_message',\n timestamp: userMessage.timestamp ?? Date.now(),\n content: readAgentMessageContent(userMessage),\n media: userMessage.media,\n });\n if (textForAgent.trim()) {\n deps.enqueueProvisionalSessionTitle?.(sessionKey, textForAgent);\n }\n }\n\n const pendingUserMessage = userMessage as TranscriptUserMessage;\n setPendingTranscriptUserMessage(sessionKey, pendingUserMessage);\n\n try {\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 runId: input.runId,\n onEvent: (embeddedEvent) => {\n const event = { ...embeddedEvent };\n if (event.type === 'error' && typeof event.content === 'string') {\n event.content = formatStreamError(event.content);\n }\n pushVisible(event);\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 } finally {\n clearPendingTranscriptUserMessage(sessionKey, pendingUserMessage);\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;\n\n if (channel === 'webchat' && ranSlashCommand) {\n try {\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 deps.sessionStore.appendTranscriptMessage(sessionKey, userMsg);\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 deps.sessionStore.appendTranscriptMessage(sessionKey, assistantMsg);\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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"}
|
|
@@ -5,23 +5,7 @@ function inboundMessageLogRequestId(msg) {
|
|
|
5
5
|
if (typeof raw === "string" && raw.trim().length > 0) return raw.trim();
|
|
6
6
|
return randomUUID();
|
|
7
7
|
}
|
|
8
|
-
/** Cap tool result size in SSE `tool_end` events (pi-agent passes structured objects, not only strings). */
|
|
9
|
-
const SSE_TOOL_RESULT_MAX_CHARS = 1e5;
|
|
10
|
-
function serializeAgentToolResultForSse(result) {
|
|
11
|
-
if (result === void 0 || result === null) return void 0;
|
|
12
|
-
if (typeof result === "string") return result.length > SSE_TOOL_RESULT_MAX_CHARS ? `${result.slice(0, SSE_TOOL_RESULT_MAX_CHARS)}\n…(truncated)` : result;
|
|
13
|
-
try {
|
|
14
|
-
const s = JSON.stringify(result, null, 2);
|
|
15
|
-
return s.length > SSE_TOOL_RESULT_MAX_CHARS ? `${s.slice(0, SSE_TOOL_RESULT_MAX_CHARS)}\n…(truncated)` : s;
|
|
16
|
-
} catch {
|
|
17
|
-
try {
|
|
18
|
-
return String(result);
|
|
19
|
-
} catch {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
8
|
//#endregion
|
|
25
|
-
export { inboundMessageLogRequestId
|
|
9
|
+
export { inboundMessageLogRequestId };
|
|
26
10
|
|
|
27
11
|
//# sourceMappingURL=service-inbound-utils.js.map
|