@xopcai/xopc 0.0.82 → 0.0.84
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 +3 -1
- package/README.zh-CN.md +3 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +2 -3
- package/dist/extensions/feishu/src/outbound/media-load.js.map +1 -1
- package/dist/extensions/feishu/src/schema/config-schema.d.ts +6 -6
- package/dist/extensions/telegram/src/config-schema.d.ts +6 -6
- package/dist/extensions/telegram/src/plugin.d.ts +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +3 -3
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/gateway/static/root/assets/agents-tR-nNP04.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-pJ27dsqn.js → apps-page-BDw6SP-d.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DEFd-jj1.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-D1KYmOmi.js → channels-status-swr-DI5FHdGe.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-Y2wfSJVI.js → cron-api-BSqY8LwW.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-B97KU_RG.js → cron-page-D7lVDjcR.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-CboA_Css.js → dist-CqNMNhJM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DN_zNmpo.js → extension-debug-page-gf2L0kY_.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BUXtOzv5.js → extension-page-CQo2Xsmg.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-C2dX4KCW.js → extension-settings-page-CZf0WoZg.js} +1 -1
- package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +3 -0
- package/dist/gateway/static/root/assets/{field-primitives-B9rOLqdm.js → field-primitives-DTtlp-l8.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-DvfiRVrc.js → heartbeat-config-api-B0drdQEJ.js} +1 -1
- package/dist/gateway/static/root/assets/{index-DQuaMye9.js → index-0Gt3TG4j.js} +94 -85
- package/dist/gateway/static/root/assets/index-BuFldCsB.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-BQuBpHcc.js → logs-page-DMuORLfC.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-_UO8g6NN.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-2Yu-FASs.js → settings-form-section-DkmHkknc.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-Cz8FoW_A.js +3 -0
- package/dist/gateway/static/root/assets/skills-page-HrUOxF7H.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DnwYutiX.js → theme-store-D01dJt95.js} +1 -1
- package/dist/gateway/static/root/assets/{utils-D2Gn2qod.js → utils-BFwcR6pL.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-JF8-aqc5.js +1 -0
- package/dist/gateway/static/root/index.html +4 -4
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +50 -0
- package/dist/src/agent/agent-instance-gateway.js +1 -0
- package/dist/src/agent/agent-manager.d.ts +20 -14
- package/dist/src/agent/agent-manager.js +74 -186
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/background-review/coordinator.d.ts +61 -0
- package/dist/src/agent/background-review/coordinator.js +120 -0
- package/dist/src/agent/background-review/coordinator.js.map +1 -0
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +14 -0
- package/dist/src/agent/child-agent-factory.js +2 -8
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/context/workspace-seed.js +3 -3
- package/dist/src/agent/embedded/index.d.ts +1 -2
- package/dist/src/agent/embedded/index.js +2 -3
- package/dist/src/agent/embedded/run-for-session.d.ts +2 -2
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/embedded/runs.d.ts +32 -0
- package/dist/src/agent/embedded/runs.js +79 -19
- package/dist/src/agent/embedded/runs.js.map +1 -1
- package/dist/src/agent/embedded/session-manager-cache.d.ts +14 -0
- package/dist/src/agent/embedded/session-manager-cache.js +32 -11
- package/dist/src/agent/embedded/session-manager-cache.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.d.ts +37 -7
- package/dist/src/agent/embedded/session-runner.js +184 -153
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.d.ts +57 -9
- package/dist/src/agent/embedded/session-tool-result-guard.js +159 -67
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.d.ts +84 -0
- package/dist/src/agent/goals/persistent-goal-service.js +139 -0
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -0
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/goals/state.d.ts +1 -1
- package/dist/src/agent/goals/state.js.map +1 -1
- package/dist/src/agent/image/load-image-media.js +1 -1
- package/dist/src/agent/inbound/inbound-loop.d.ts +77 -0
- package/dist/src/agent/inbound/inbound-loop.js +226 -0
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +80 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +138 -0
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -0
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
- package/dist/src/agent/lifecycle/manager.d.ts +1 -1
- package/dist/src/agent/lifecycle/manager.js.map +1 -1
- package/dist/src/agent/lifecycle/types.d.ts +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.d.ts +12 -2
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js.map +1 -1
- package/dist/src/agent/memory/index.js +3 -3
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/memory/prefetch-coordinator.d.ts +37 -0
- package/dist/src/agent/memory/prefetch-coordinator.js +45 -0
- package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -0
- package/dist/src/agent/messaging/command-handler.d.ts +5 -1
- package/dist/src/agent/messaging/command-handler.js +24 -96
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/messaging/index.d.ts +1 -0
- package/dist/src/agent/messaging/index.js +2 -1
- package/dist/src/agent/messaging/message-router.d.ts +1 -1
- package/dist/src/agent/messaging/message-router.js.map +1 -1
- package/dist/src/agent/messaging/outbound-coordinator.d.ts +82 -0
- package/dist/src/agent/messaging/outbound-coordinator.js +123 -0
- package/dist/src/agent/messaging/outbound-coordinator.js.map +1 -0
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/agent-event-handler.d.ts +36 -33
- package/dist/src/agent/orchestration/agent-event-handler.js +212 -174
- package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +4 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +4 -8
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/orchestration/index.d.ts +1 -1
- package/dist/src/agent/orchestration/index.js +2 -2
- package/dist/src/agent/prompt/service-prompt-builder.js +4 -4
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +1 -1
- package/dist/src/agent/service/async-queue.d.ts +20 -0
- package/dist/src/agent/service/async-queue.js +53 -0
- package/dist/src/agent/service/async-queue.js.map +1 -0
- package/dist/src/agent/service/build-direct-message-content.d.ts +2 -2
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +70 -0
- package/dist/src/agent/service/direct-turn-helpers.js +90 -0
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -0
- package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -3
- package/dist/src/agent/service/process-direct-one-shot.js +17 -34
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
- package/dist/src/agent/service/process-direct-streaming.js +122 -168
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +2 -2
- package/dist/src/agent/service/webchat-tts.js +1 -1
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.d.ts +62 -167
- package/dist/src/agent/service.js +177 -786
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/index.d.ts +4 -0
- package/dist/src/agent/session/index.js +5 -1
- package/dist/src/agent/session/session-config-service.d.ts +68 -0
- package/dist/src/agent/session/session-config-service.js +172 -0
- package/dist/src/agent/session/session-config-service.js.map +1 -0
- package/dist/src/agent/session/session-context.d.ts +27 -19
- package/dist/src/agent/session/session-context.js +39 -24
- package/dist/src/agent/session/session-context.js.map +1 -1
- package/dist/src/agent/session/session-hydrator.d.ts +42 -0
- package/dist/src/agent/session/session-hydrator.js +66 -0
- package/dist/src/agent/session/session-hydrator.js.map +1 -0
- package/dist/src/agent/session/session-inspector.d.ts +80 -0
- package/dist/src/agent/session/session-inspector.js +119 -0
- package/dist/src/agent/session/session-inspector.js.map +1 -0
- package/dist/src/agent/session/session-state-bag.d.ts +83 -0
- package/dist/src/agent/session/session-state-bag.js +192 -0
- package/dist/src/agent/session/session-state-bag.js.map +1 -0
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.d.ts +0 -2
- package/dist/src/agent/skills/index.js +3 -5
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -6
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +35 -7
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +2 -2
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +7 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +37 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/delegate-tool.d.ts +7 -0
- package/dist/src/agent/tools/delegate-tool.js +2 -1
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/executor.d.ts +34 -15
- package/dist/src/agent/tools/executor.js +44 -79
- package/dist/src/agent/tools/executor.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +6 -0
- package/dist/src/agent/tools/factory.js +63 -4
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/skills-tools.js +1 -1
- package/dist/src/agent/tools/tts-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workspace-runtime/registry.d.ts +48 -0
- package/dist/src/agent/workspace-runtime/registry.js +59 -0
- package/dist/src/agent/workspace-runtime/registry.js.map +1 -0
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +4 -3
- package/dist/src/browser/cdp-local-launcher.js.map +1 -1
- package/dist/src/browser/index.d.ts +1 -0
- package/dist/src/browser/index.js +2 -1
- package/dist/src/browser/manager.js +3 -2
- package/dist/src/browser/manager.js.map +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +4 -4
- package/dist/src/browser/providers/browser-use.js +2 -1
- package/dist/src/browser/providers/browser-use.js.map +1 -1
- package/dist/src/browser/providers/browserbase.js +2 -1
- package/dist/src/browser/providers/browserbase.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +7 -6
- package/dist/src/browser/providers/cloakbrowser.js.map +1 -1
- package/dist/src/browser/providers/playwright-doctor.d.ts +2 -0
- package/dist/src/browser/providers/playwright-doctor.js +7 -3
- package/dist/src/browser/providers/playwright-doctor.js.map +1 -1
- package/dist/src/browser/readiness.d.ts +33 -0
- package/dist/src/browser/readiness.js +138 -0
- package/dist/src/browser/readiness.js.map +1 -0
- package/dist/src/browser/stealth.js +2 -2
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/channel-domain.d.ts +1 -1
- package/dist/src/channels/config-helpers.d.ts +1 -1
- package/dist/src/channels/config-helpers.js.map +1 -1
- package/dist/src/channels/heartbeat-scheduler.d.ts +40 -0
- package/dist/src/channels/heartbeat-scheduler.js +94 -0
- package/dist/src/channels/heartbeat-scheduler.js.map +1 -0
- package/dist/src/channels/lifecycle-supervisor.d.ts +81 -0
- package/dist/src/channels/lifecycle-supervisor.js +263 -0
- package/dist/src/channels/lifecycle-supervisor.js.map +1 -0
- package/dist/src/channels/manager.d.ts +34 -68
- package/dist/src/channels/manager.js +107 -477
- package/dist/src/channels/manager.js.map +1 -1
- package/dist/src/channels/outbound/deliver.d.ts +1 -1
- package/dist/src/channels/outbound/deliver.js.map +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/outbound-sender.d.ts +51 -0
- package/dist/src/channels/outbound-sender.js +125 -0
- package/dist/src/channels/outbound-sender.js.map +1 -0
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-service.d.ts +3 -10
- package/dist/src/channels/pairing/pairing-service.js.map +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/channels/pairing/pairing-types.d.ts +15 -0
- package/dist/src/channels/pairing/pairing-types.js +1 -0
- package/dist/src/channels/plugin-registry.d.ts +22 -0
- package/dist/src/channels/plugin-registry.js +44 -0
- package/dist/src/channels/plugin-registry.js.map +1 -0
- package/dist/src/channels/plugin-types.d.ts +1 -1
- package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
- package/dist/src/channels/security-helpers.d.ts +1 -1
- package/dist/src/channels/security-helpers.js.map +1 -1
- package/dist/src/channels/setup-wizard.d.ts +1 -1
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/command-catalog.js +110 -8
- package/dist/src/cli/command-catalog.js.map +1 -1
- package/dist/src/cli/command-loaders.js +2 -0
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +9 -1
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js.map +1 -1
- package/dist/src/cli/commands/agent.js +4 -4
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/browser-cli-helpers.js +2 -1
- package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
- package/dist/src/cli/commands/config.js +70 -19
- package/dist/src/cli/commands/config.js.map +1 -1
- package/dist/src/cli/commands/cron-cli.d.ts +2 -0
- package/dist/src/cli/commands/cron-cli.js +15 -0
- package/dist/src/cli/commands/cron-cli.js.map +1 -0
- package/dist/src/cli/commands/cron.d.ts +4 -1
- package/dist/src/cli/commands/cron.js +76 -41
- package/dist/src/cli/commands/cron.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +2 -2
- package/dist/src/cli/commands/doctor/checks/config-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/gateway-health.js +2 -2
- package/dist/src/cli/commands/doctor/checks/gateway-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/gateway-service.js +2 -2
- package/dist/src/cli/commands/doctor/checks/gateway-service.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +2 -2
- package/dist/src/cli/commands/doctor/checks/state-integrity.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +4 -4
- package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -2
- package/dist/src/cli/commands/extension-dev.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +2 -2
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/call.js +1 -1
- package/dist/src/cli/commands/gateway/call.js.map +1 -1
- package/dist/src/cli/commands/gateway/health.js +1 -1
- package/dist/src/cli/commands/gateway/health.js.map +1 -1
- package/dist/src/cli/commands/gateway/index.d.ts +1 -1
- package/dist/src/cli/commands/gateway/index.js +2 -2
- package/dist/src/cli/commands/gateway/lifecycle-core.d.ts +31 -12
- package/dist/src/cli/commands/gateway/lifecycle-core.js +167 -116
- package/dist/src/cli/commands/gateway/lifecycle-core.js.map +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.d.ts +11 -0
- package/dist/src/cli/commands/gateway/lifecycle.js +102 -0
- package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -0
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js.map +1 -1
- package/dist/src/cli/commands/gateway/probe.js +1 -1
- package/dist/src/cli/commands/gateway/probe.js.map +1 -1
- package/dist/src/cli/commands/gateway/restart-health.d.ts +12 -0
- package/dist/src/cli/commands/gateway/restart-health.js +45 -1
- package/dist/src/cli/commands/gateway/restart-health.js.map +1 -1
- package/dist/src/cli/commands/gateway/restart.js +3 -3
- package/dist/src/cli/commands/gateway/restart.js.map +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.d.ts +0 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +0 -35
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/gateway/service.d.ts +4 -0
- package/dist/src/cli/commands/gateway/service.js +18 -3
- package/dist/src/cli/commands/gateway/service.js.map +1 -1
- package/dist/src/cli/commands/gateway/shared.d.ts +3 -0
- package/dist/src/cli/commands/gateway/shared.js +54 -0
- package/dist/src/cli/commands/gateway/shared.js.map +1 -0
- package/dist/src/cli/commands/gateway/status.js +1 -1
- package/dist/src/cli/commands/gateway/status.js.map +1 -1
- package/dist/src/cli/commands/gateway/stop.js +2 -2
- package/dist/src/cli/commands/gateway/stop.js.map +1 -1
- package/dist/src/cli/commands/gateway/subcommands.js +1 -4
- package/dist/src/cli/commands/gateway/subcommands.js.map +1 -1
- package/dist/src/cli/commands/gateway/token.js +1 -1
- package/dist/src/cli/commands/gateway/token.js.map +1 -1
- package/dist/src/cli/commands/gateway.js +5 -5
- package/dist/src/cli/commands/gateway.js.map +1 -1
- package/dist/src/cli/commands/image.js +2 -2
- package/dist/src/cli/commands/image.js.map +1 -1
- package/dist/src/cli/commands/init.js +31 -4
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/models.d.ts +4 -1
- package/dist/src/cli/commands/models.js +87 -75
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/gateway.d.ts +0 -8
- package/dist/src/cli/commands/onboard/gateway.js +48 -49
- package/dist/src/cli/commands/onboard/gateway.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +11 -64
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/profile.d.ts +3 -5
- package/dist/src/cli/commands/profile.js +31 -31
- package/dist/src/cli/commands/profile.js.map +1 -1
- package/dist/src/cli/commands/session/utils.js +1 -1
- package/dist/src/cli/commands/session/utils.js.map +1 -1
- package/dist/src/cli/commands/setup.js +6 -1
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/commands/skills.js +1 -1
- package/dist/src/cli/commands/tailscale.js +1 -1
- package/dist/src/cli/commands/tailscale.js.map +1 -1
- package/dist/src/cli/context.d.ts +20 -0
- package/dist/src/cli/context.js +23 -0
- package/dist/src/cli/context.js.map +1 -0
- package/dist/src/cli/extension-cli-register.js +3 -3
- package/dist/src/cli/gateway-run-argv.js +16 -9
- package/dist/src/cli/gateway-run-argv.js.map +1 -1
- package/dist/src/cli/gateway-run-fast-path.js +1 -1
- package/dist/src/cli/gateway-run-fast-path.js.map +1 -1
- package/dist/src/cli/index.d.ts +1 -7
- package/dist/src/cli/index.js +4 -6
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/commands.flags.d.ts +3 -0
- package/dist/src/config/commands.flags.js +11 -0
- package/dist/src/config/commands.flags.js.map +1 -0
- package/dist/src/config/index.d.ts +1 -0
- package/dist/src/config/index.js +6 -5
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +11 -4
- package/dist/src/config/schema.js +13 -12
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path-helpers.d.ts +15 -0
- package/dist/src/config/workspace-path-helpers.js +14 -0
- package/dist/src/config/workspace-path-helpers.js.map +1 -0
- package/dist/src/cron/executor.js +4 -4
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/daemon/index.d.ts +0 -1
- package/dist/src/daemon/index.js +1 -2
- package/dist/src/daemon/install-plan.js +3 -2
- package/dist/src/daemon/install-plan.js.map +1 -1
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/daemon/types.d.ts +0 -6
- package/dist/src/extensions/api.d.ts +1 -1
- package/dist/src/extensions/api.js +2 -2
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/extension-registry-impl.d.ts +51 -0
- package/dist/src/extensions/extension-registry-impl.js +117 -0
- package/dist/src/extensions/extension-registry-impl.js.map +1 -0
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/index.js +3 -2
- package/dist/src/extensions/loader.d.ts +3 -43
- package/dist/src/extensions/loader.js +3 -110
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/sdk/index.js +2 -1
- package/dist/src/extensions/sdk/index.js.map +1 -1
- package/dist/src/extensions/types/events.d.ts +7 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +5 -53
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +1 -1
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.d.ts +5 -14
- package/dist/src/gateway/hono/middleware/auth.js +89 -126
- package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
- package/dist/src/gateway/hono/middleware/logger.js +1 -1
- package/dist/src/gateway/hono/middleware/logger.js.map +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +14 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +62 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js.map +1 -0
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +4 -4
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
- package/dist/src/gateway/hono/routes/browser.d.ts +20 -0
- package/dist/src/gateway/hono/routes/browser.js +626 -0
- package/dist/src/gateway/hono/routes/browser.js.map +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +13 -13
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/agents.js +418 -0
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +12 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.js +186 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +264 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/index.d.ts +9 -0
- package/dist/src/gateway/hono/routes/config-patch/index.js +6 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +23 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.js +139 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/result.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/result.js +13 -0
- package/dist/src/gateway/hono/routes/config-patch/result.js.map +1 -0
- package/dist/src/gateway/hono/routes/config.js +20 -1764
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +2 -3
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -5
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +1 -2
- package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +32 -32
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +4 -4
- package/dist/src/gateway/hono/routes/shares.js.map +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +6 -7
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.js +2 -2
- package/dist/src/gateway/index.d.ts +1 -1
- package/dist/src/gateway/index.js +4 -2
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/rate-limit/auth-policy.d.ts +34 -0
- package/dist/src/gateway/rate-limit/auth-policy.js +49 -0
- package/dist/src/gateway/rate-limit/auth-policy.js.map +1 -0
- package/dist/src/gateway/rate-limit/buckets.d.ts +63 -0
- package/dist/src/gateway/rate-limit/buckets.js +143 -0
- package/dist/src/gateway/rate-limit/buckets.js.map +1 -0
- package/dist/src/gateway/rate-limit/env-flags.d.ts +13 -0
- package/dist/src/gateway/rate-limit/env-flags.js +16 -0
- package/dist/src/gateway/rate-limit/env-flags.js.map +1 -0
- package/dist/src/gateway/rate-limit/index.d.ts +3 -0
- package/dist/src/gateway/rate-limit/index.js +4 -0
- package/dist/src/gateway/run-loop.d.ts +1 -1
- package/dist/src/gateway/run-loop.js +24 -4
- package/dist/src/gateway/run-loop.js.map +1 -1
- package/dist/src/gateway/runtime-config.js +2 -1
- package/dist/src/gateway/runtime-config.js.map +1 -1
- package/dist/src/gateway/security/audit.js +2 -1
- package/dist/src/gateway/security/audit.js.map +1 -1
- package/dist/src/gateway/security/index.d.ts +0 -1
- package/dist/src/gateway/security/index.js +1 -2
- package/dist/src/gateway/security/loopback.d.ts +13 -0
- package/dist/src/gateway/security/loopback.js +45 -0
- package/dist/src/gateway/security/loopback.js.map +1 -0
- package/dist/src/gateway/service/agent-runner.d.ts +108 -0
- package/dist/src/gateway/service/agent-runner.js +184 -0
- package/dist/src/gateway/service/agent-runner.js.map +1 -0
- package/dist/src/gateway/service/config-coordinator.d.ts +119 -0
- package/dist/src/gateway/service/config-coordinator.js +351 -0
- package/dist/src/gateway/service/config-coordinator.js.map +1 -0
- package/dist/src/gateway/service/marketplace-service.d.ts +85 -0
- package/dist/src/gateway/service/marketplace-service.js +239 -0
- package/dist/src/gateway/service/marketplace-service.js.map +1 -0
- package/dist/src/gateway/service/run-gateway-agent.js +5 -5
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +125 -0
- package/dist/src/gateway/service/sessions-api.js +135 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -0
- package/dist/src/gateway/service.d.ts +30 -360
- package/dist/src/gateway/service.js +122 -904
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/gateway/workspace-heartbeat-path.js +1 -2
- package/dist/src/gateway/workspace-heartbeat-path.js.map +1 -1
- package/dist/src/infra/gateway-process-argv.d.ts +4 -0
- package/dist/src/infra/gateway-process-argv.js +26 -0
- package/dist/src/infra/gateway-process-argv.js.map +1 -0
- package/dist/src/infra/gateway-processes.d.ts +5 -0
- package/dist/src/infra/gateway-processes.js +65 -0
- package/dist/src/infra/gateway-processes.js.map +1 -0
- package/dist/src/infra/rate-limit/failure-limiter.d.ts +50 -0
- package/dist/src/infra/rate-limit/failure-limiter.js +100 -0
- package/dist/src/infra/rate-limit/failure-limiter.js.map +1 -0
- package/dist/src/infra/rate-limit/index.d.ts +5 -0
- package/dist/src/infra/rate-limit/index.js +3 -0
- package/dist/src/infra/rate-limit/keyed-store.d.ts +34 -0
- package/dist/src/infra/rate-limit/keyed-store.js +44 -0
- package/dist/src/infra/rate-limit/keyed-store.js.map +1 -0
- package/dist/src/infra/rate-limit/rate-limiter.d.ts +39 -0
- package/dist/src/infra/rate-limit/rate-limiter.js +65 -0
- package/dist/src/infra/rate-limit/rate-limiter.js.map +1 -0
- package/dist/src/infra/restart.d.ts +21 -0
- package/dist/src/infra/restart.js +122 -0
- package/dist/src/infra/restart.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/mcp/channel-bridge.d.ts +0 -6
- package/dist/src/mcp/channel-bridge.js +1 -5
- package/dist/src/mcp/channel-bridge.js.map +1 -1
- package/dist/src/media-shared/http/ssrf-guard.js +1 -1
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file-read.d.ts +2 -1
- package/dist/src/session/parity/sessions-json-file-read.js.map +1 -1
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +1 -1
- package/dist/src/session/store.js +5 -5
- package/dist/src/share/share-rate-limit.d.ts +10 -2
- package/dist/src/share/share-rate-limit.js +33 -42
- package/dist/src/share/share-rate-limit.js.map +1 -1
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/tui/backends/embedded-backend.js +16 -12
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +2 -2
- package/dist/src/tui/extension-host/load-extensions.js +1 -1
- package/dist/src/tui/format-tui-hotkeys.js +1 -1
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +1 -1
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-skills-autocomplete.js +1 -1
- package/dist/src/tui/tui.js +1 -2
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tui/xopc-tui-keybindings.d.ts +0 -1
- package/dist/src/tui/xopc-tui-keybindings.js +1 -2
- package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
- package/dist/src/tunnel/frpc-binary.js +2 -2
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/pairing-rate-limit.d.ts +10 -2
- package/dist/src/tunnel/pairing-rate-limit.js +19 -15
- package/dist/src/tunnel/pairing-rate-limit.js.map +1 -1
- package/dist/src/tunnel/tunnel-rate-limit.d.ts +6 -3
- package/dist/src/tunnel/tunnel-rate-limit.js +11 -22
- package/dist/src/tunnel/tunnel-rate-limit.js.map +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/stats.d.ts +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/factory.js +1 -1
- package/dist/src/voice/tts/index.js +2 -2
- package/dist/src/voice/tts/merge-config.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +1 -1
- package/dist/src/voice/tts/service.js +1 -1
- package/dist/src/voice/tts/service.js.map +1 -1
- package/dist/src/voice/tts/speak-core.js +1 -1
- package/package.json +10 -5
- package/dist/gateway/static/root/assets/agents-Cqh1ts38.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-wTiWStg9.js +0 -1
- package/dist/gateway/static/root/assets/fetch-BAAh_kXG.js +0 -3
- package/dist/gateway/static/root/assets/index-C8yHX-AA.css +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BeiFm0Ms.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-RPAz_Wg_.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-Wu4aNWDx.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-BxIGhhEL.js +0 -1
- package/dist/src/agent/embedded/session-raw-append-message.d.ts +0 -11
- package/dist/src/agent/embedded/session-raw-append-message.js +0 -15
- package/dist/src/agent/embedded/session-raw-append-message.js.map +0 -1
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.d.ts +0 -15
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.js +0 -24
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.js.map +0 -1
- package/dist/src/agent/embedded/session-tool-result-state.d.ts +0 -17
- package/dist/src/agent/embedded/session-tool-result-state.js +0 -26
- package/dist/src/agent/embedded/session-tool-result-state.js.map +0 -1
- package/dist/src/daemon/launchd-restart-handoff.d.ts +0 -25
- package/dist/src/daemon/launchd-restart-handoff.js +0 -132
- package/dist/src/daemon/launchd-restart-handoff.js.map +0 -1
- package/dist/src/gateway/auth-rate-limit.d.ts +0 -71
- package/dist/src/gateway/auth-rate-limit.js +0 -192
- package/dist/src/gateway/auth-rate-limit.js.map +0 -1
- package/dist/src/gateway/restart-handler.d.ts +0 -14
- package/dist/src/gateway/restart-handler.js +0 -64
- package/dist/src/gateway/restart-handler.js.map +0 -1
- package/dist/src/gateway/security/flood-guard.d.ts +0 -28
- package/dist/src/gateway/security/flood-guard.js +0 -42
- package/dist/src/gateway/security/flood-guard.js.map +0 -1
- package/dist/src/infra/rate-limit.d.ts +0 -38
- package/dist/src/infra/rate-limit.js +0 -60
- package/dist/src/infra/rate-limit.js.map +0 -1
- package/dist/src/infra/restart-intent.d.ts +0 -13
- package/dist/src/infra/restart-intent.js +0 -40
- package/dist/src/infra/restart-intent.js.map +0 -1
- package/dist/src/infra/restart-sentinel.d.ts +0 -23
- package/dist/src/infra/restart-sentinel.js +0 -75
- package/dist/src/infra/restart-sentinel.js.map +0 -1
- package/skills/creative/canvas-design/LICENSE.txt +0 -202
- package/skills/creative/canvas-design/SKILL-zh.md +0 -130
- package/skills/creative/canvas-design/SKILL.md +0 -130
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-goal-service.js","names":["parseRoutingSessionKey"],"sources":["../../../../src/agent/goals/persistent-goal-service.ts"],"sourcesContent":["/**\n * PersistentGoalService — owns the \"/goal\" runtime: continuation scheduling,\n * the `PersistentGoalApis` bag that command handlers receive, and the post-turn\n * verdict hook called from `OutboundCoordinator`.\n *\n * Previously this logic was scattered across `AgentService`:\n * - `setPersistentGoalWebchatContinuationScheduler` + a private callback field\n * - `schedulePersistentGoalContinuation` (bus vs webchat fork)\n * - `getPersistentGoalApisForCommand` (~40-line API factory)\n * - `recordPersistentGoalStreamOutcome` / `takePersistentGoalStreamOutcome`\n * - the `/goal` half of `emitSessionTurnComplete` (delegated to\n * `handlePersistentGoalPostTurn`)\n *\n * Concentrating it here gives the rest of `AgentService` a cleaner surface\n * (one collaborator instead of five methods) and makes the goal runtime\n * unit-testable in isolation.\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type { SessionStateBag } from '../session/index.js';\nimport { parseSessionKey as parseRoutingSessionKey } from '../../routing/session-key.js';\nimport { appendPiTranscriptMessage } from '../../session/parity/jsonl-transcript-io.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { PersistentGoalApis } from './persistent-goal-apis.js';\nimport { handlePersistentGoalPostTurn } from './post-turn.js';\n\nconst log = createLogger('PersistentGoalService');\n\nexport interface PersistentGoalRouting {\n sessionKey: string;\n channel: string;\n chatId: string;\n inboundMetadata?: Record<string, unknown>;\n}\n\nexport interface SessionTurnCompletionForGoal {\n sessionKey: string;\n channel: string;\n chatId: string;\n assistantPlainText: string;\n aborted: boolean;\n streamError?: string;\n skipPersistentGoalPostTurn?: boolean;\n outboundMetadata?: Record<string, unknown>;\n}\n\nexport interface PersistentGoalServiceOptions {\n bus: MessageBus;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n sessionState: SessionStateBag;\n /** Effective config snapshot accessor. */\n getConfig: () => Config | undefined;\n /** Resolve the workspace directory for `appendAssistantReceipt` writes. */\n getResolvedWorkspaceForSession: (sessionKey: string) => string;\n /** Notify the gateway UI after a metadata change (replaces the in-bag emit). */\n onSessionMetadataUpdated?: (sessionKey: string) => void;\n /** Push an assistant token + transcript refresh into a live webchat stream. */\n notifyWebchatTranscriptAppend: (sessionKey: string, assistantText: string) => void;\n}\n\nexport class PersistentGoalService {\n private readonly opts: PersistentGoalServiceOptions;\n /** Gateway only: webchat continuations bypass the bus and reuse `runGatewayAgent`. */\n private webchatContinuationScheduler?: (sessionKey: string, message: string) => void;\n\n constructor(opts: PersistentGoalServiceOptions) {\n this.opts = opts;\n }\n\n /** Register the gateway-side webchat continuation hook (set from `web-agent` wiring). */\n setWebchatContinuationScheduler(\n fn: ((sessionKey: string, message: string) => void) | undefined,\n ): void {\n this.webchatContinuationScheduler = fn;\n }\n\n /**\n * Continue a session after `/goal` decides the previous turn needs follow-up.\n * Webchat sessions go through the scheduler; bus-driven channels re-publish the\n * follow-up message as an inbound bus event so the existing inbound loop picks it up.\n */\n scheduleContinuation(\n sessionKey: string,\n message: string,\n routing: { channel: string; chatId: string; inboundMetadata?: Record<string, unknown> },\n ): void {\n const parsed = parseRoutingSessionKey(sessionKey);\n if (parsed?.source === 'webchat' && this.webchatContinuationScheduler) {\n this.webchatContinuationScheduler(sessionKey, message);\n return;\n }\n queueMicrotask(() => {\n void this.opts.bus\n .publishInbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n sender_id: 'persistent-goal',\n content: message,\n metadata: { sessionKey, ...routing.inboundMetadata },\n })\n .catch((err) => {\n log.warn({ err, sessionKey }, 'Persistent goal: publishInbound failed');\n });\n });\n }\n\n /** Build the per-command `PersistentGoalApis` bag (transcript writers + scheduler closures). */\n buildApisForRouting(routing: PersistentGoalRouting): PersistentGoalApis {\n return {\n getSessionMetadata: (k) => this.opts.sessionStore.getMetadata(k),\n updateSessionMetadata: async (k, u) => {\n await this.opts.sessionStore.updateMetadata(k, u);\n this.opts.onSessionMetadataUpdated?.(k);\n },\n loadMessages: (k) => this.opts.sessionStore.loadMessages(k),\n saveMessages: (k, m) => this.opts.sessionStore.saveMessages(k, m),\n appendAssistantReceipt: async (k, text) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n const { absPath } = await this.opts.sessionStore.resolveTranscriptPath(k);\n const workspaceDir = this.opts.getResolvedWorkspaceForSession(k);\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n } as AgentMessage,\n sessionKey: k,\n });\n this.opts.notifyWebchatTranscriptAppend(k, trimmed);\n },\n scheduleContinuation: (sk, msg) => {\n this.scheduleContinuation(sk, msg, {\n channel: routing.channel,\n chatId: routing.chatId,\n inboundMetadata: routing.inboundMetadata,\n });\n },\n inboundConcurrentDepth: (sk) => this.opts.sessionState.getInboundTurnDepth(sk),\n };\n }\n\n recordStreamOutcome(sessionKey: string, outcome: { skipPersistentGoalPostTurn: boolean }): void {\n this.opts.sessionState.recordPersistentGoalStreamOutcome(sessionKey, outcome);\n }\n\n takeStreamOutcome(sessionKey: string): { skipPersistentGoalPostTurn: boolean } | undefined {\n return this.opts.sessionState.takePersistentGoalStreamOutcome(sessionKey);\n }\n\n /**\n * Run the `/goal` post-turn verdict for a completed user turn (called from\n * `OutboundCoordinator.emitSessionTurnComplete`).\n */\n async runPostTurn(payload: SessionTurnCompletionForGoal): Promise<void> {\n const apis = this.buildApisForRouting({\n sessionKey: payload.sessionKey,\n channel: payload.channel,\n chatId: payload.chatId,\n inboundMetadata: payload.outboundMetadata,\n });\n\n const src = parseRoutingSessionKey(payload.sessionKey)?.source;\n const isWebchat = src === 'webchat';\n const publishVerdict =\n !isWebchat && payload.channel !== 'cli'\n ? async (text: string) => {\n await this.opts.bus.publishOutbound({\n channel: payload.channel,\n chat_id: payload.chatId,\n content: text,\n type: 'message',\n metadata: {\n accountId: payload.outboundMetadata?.accountId,\n threadId: payload.outboundMetadata?.threadId,\n },\n });\n }\n : undefined;\n\n let runtimeSessionModelRef: string | undefined;\n try {\n runtimeSessionModelRef = this.opts.modelManager.getModelForSession(payload.sessionKey);\n } catch {\n runtimeSessionModelRef = undefined;\n }\n\n await handlePersistentGoalPostTurn({\n apis,\n sessionKey: payload.sessionKey,\n assistantPlainText: payload.assistantPlainText,\n aborted: payload.aborted,\n ...(payload.streamError !== undefined ? { streamError: payload.streamError } : {}),\n skipPersistentGoalPostTurn: payload.skipPersistentGoalPostTurn ?? false,\n config: this.opts.getConfig(),\n runtimeSessionModelRef,\n publishVerdictToChannel: publishVerdict,\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
2
|
-
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
3
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
4
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
4
|
+
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
5
5
|
import { PERSISTENT_GOAL_CUSTOM_KEY, mergeCustomDataPatch, readPersistentGoal, serializePersistentGoal } from "./state.js";
|
|
6
6
|
import { resolveGoalUiLocale } from "./goal-locale.js";
|
|
7
7
|
import { evaluateAfterTurnHermesLike } from "./evaluate-turn.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ChecklistItemStatus, type GoalChecklistItem } from './checklist-types.js';
|
|
2
|
-
import type { GoalUiLocale } from '
|
|
2
|
+
import type { ServerLocale as GoalUiLocale } from '../../i18n/locale.js';
|
|
3
3
|
/** Persisted under `SessionMetadata.customData.persistentGoal`. */
|
|
4
4
|
export declare const PERSISTENT_GOAL_CUSTOM_KEY = "persistentGoal";
|
|
5
5
|
export type PersistentGoalStatus = 'active' | 'paused' | 'done' | 'cleared';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","names":[],"sources":["../../../../src/agent/goals/state.ts"],"sourcesContent":["import {\n CHECKLIST_ITEM_PENDING,\n TERMINAL_CHECKLIST_STATUSES,\n type ChecklistItemAddedBy,\n type ChecklistItemStatus,\n type GoalChecklistItem,\n} from './checklist-types.js';\n\nimport type { GoalUiLocale } from './goal-locale.js';\n\n/** Persisted under `SessionMetadata.customData.persistentGoal`. */\nexport const PERSISTENT_GOAL_CUSTOM_KEY = 'persistentGoal';\n\nexport type PersistentGoalStatus = 'active' | 'paused' | 'done' | 'cleared';\n\nexport interface PersistentGoalState {\n goal: string;\n status: PersistentGoalStatus;\n turnsUsed: number;\n maxTurns: number;\n createdAt: number;\n lastTurnAt: number;\n lastVerdict?: 'done' | 'continue' | 'skipped' | 'decompose';\n lastReason?: string;\n pausedReason?: string;\n judgeModelRef?: string;\n /** Hermes-style: judge JSON parse failures in a row (API errors do not increment). */\n consecutiveParseFailures?: number;\n /** After first successful decomposition, checklist drives Phase-B judging. */\n decomposed?: boolean;\n checklist?: GoalChecklistItem[];\n /** Gateway console language: drives judge `reason` language and system messages. */\n uiLocale?: GoalUiLocale;\n}\n\nexport function defaultMaxTurns(cfg: { maxTurns?: number } | undefined): number {\n const n = cfg?.maxTurns;\n if (typeof n === 'number' && Number.isFinite(n)) {\n return Math.max(1, Math.min(500, Math.floor(n)));\n }\n return 20;\n}\n\nfunction coerceStatus(s: unknown): PersistentGoalStatus | undefined {\n if (s === 'active' || s === 'paused' || s === 'done' || s === 'cleared') return s;\n return undefined;\n}\n\nfunction coerceChecklistItem(raw: unknown): GoalChecklistItem | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const r = raw as Record<string, unknown>;\n const text = typeof r.text === 'string' ? r.text.trim() : '';\n if (!text) return null;\n const st = typeof r.status === 'string' ? r.status.trim().toLowerCase() : '';\n const status: ChecklistItemStatus =\n st === 'completed' || st === 'impossible' || st === 'pending' ? st : CHECKLIST_ITEM_PENDING;\n const ab = typeof r.addedBy === 'string' ? r.addedBy.trim().toLowerCase() : '';\n const addedBy: ChecklistItemAddedBy = ab === 'user' ? 'user' : 'judge';\n const addedAt =\n typeof r.addedAt === 'number' && Number.isFinite(r.addedAt) ? Math.floor(r.addedAt) : Date.now();\n const completedAt =\n typeof r.completedAt === 'number' && Number.isFinite(r.completedAt) ? Math.floor(r.completedAt) : undefined;\n const evidence = typeof r.evidence === 'string' ? r.evidence : undefined;\n return { text, status, addedBy, addedAt, completedAt, evidence };\n}\n\nexport function readPersistentGoal(customData: Record<string, unknown> | undefined): PersistentGoalState | null {\n if (!customData || typeof customData !== 'object') return null;\n\n const raw = customData[PERSISTENT_GOAL_CUSTOM_KEY];\n if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n const o = raw as Record<string, unknown>;\n const goal = typeof o.goal === 'string' ? o.goal.trim() : '';\n if (!goal) return null;\n const status = coerceStatus(o.status) ?? 'active';\n const maxTurns =\n typeof o.maxTurns === 'number' && Number.isFinite(o.maxTurns)\n ? Math.max(1, Math.min(500, Math.floor(o.maxTurns)))\n : 20;\n const turnsUsed =\n typeof o.turnsUsed === 'number' && Number.isFinite(o.turnsUsed)\n ? Math.max(0, Math.floor(o.turnsUsed))\n : 0;\n const createdAt =\n typeof o.createdAt === 'number' && Number.isFinite(o.createdAt) ? o.createdAt : Date.now();\n const lastTurnAt =\n typeof o.lastTurnAt === 'number' && Number.isFinite(o.lastTurnAt) ? o.lastTurnAt : 0;\n const lastVerdict =\n o.lastVerdict === 'done' ||\n o.lastVerdict === 'continue' ||\n o.lastVerdict === 'skipped' ||\n o.lastVerdict === 'decompose'\n ? o.lastVerdict\n : undefined;\n const lastReason = typeof o.lastReason === 'string' ? o.lastReason : undefined;\n const pausedReason = typeof o.pausedReason === 'string' ? o.pausedReason : undefined;\n const judgeModelRef = typeof o.judgeModelRef === 'string' ? o.judgeModelRef.trim() : undefined;\n const consecutiveParseFailures =\n typeof o.consecutiveParseFailures === 'number' && Number.isFinite(o.consecutiveParseFailures)\n ? Math.max(0, Math.floor(o.consecutiveParseFailures))\n : 0;\n const decomposed = Boolean(o.decomposed);\n const uiLocale = o.uiLocale === 'zh' || o.uiLocale === 'en' ? o.uiLocale : undefined;\n const checklistRaw = o.checklist;\n const checklist: GoalChecklistItem[] = [];\n if (Array.isArray(checklistRaw)) {\n for (const row of checklistRaw) {\n const it = coerceChecklistItem(row);\n if (it) checklist.push(it);\n }\n }\n return {\n goal,\n status,\n turnsUsed,\n maxTurns,\n createdAt,\n lastTurnAt,\n lastVerdict,\n lastReason,\n pausedReason,\n judgeModelRef: judgeModelRef || undefined,\n consecutiveParseFailures,\n decomposed: decomposed || undefined,\n checklist: checklist.length ? checklist : undefined,\n uiLocale,\n };\n }\n\n return null;\n}\n\nexport function serializePersistentGoal(s: PersistentGoalState): Record<string, unknown> {\n return {\n goal: s.goal,\n status: s.status,\n turnsUsed: s.turnsUsed,\n maxTurns: s.maxTurns,\n createdAt: s.createdAt,\n lastTurnAt: s.lastTurnAt,\n ...(s.lastVerdict ? { lastVerdict: s.lastVerdict } : {}),\n ...(s.lastReason ? { lastReason: s.lastReason } : {}),\n ...(s.pausedReason ? { pausedReason: s.pausedReason } : {}),\n ...(s.judgeModelRef ? { judgeModelRef: s.judgeModelRef } : {}),\n ...(s.consecutiveParseFailures ? { consecutiveParseFailures: s.consecutiveParseFailures } : {}),\n ...(s.decomposed ? { decomposed: true } : {}),\n ...(s.uiLocale ? { uiLocale: s.uiLocale } : {}),\n ...(s.checklist?.length\n ? {\n checklist: s.checklist.map((it) => ({\n text: it.text,\n status: it.status,\n addedBy: it.addedBy,\n addedAt: it.addedAt,\n ...(it.completedAt !== undefined ? { completedAt: it.completedAt } : {}),\n ...(it.evidence ? { evidence: it.evidence } : {}),\n })),\n }\n : {}),\n };\n}\n\n/** Render checklist for continuation prompt (Hermes-style, no numbers in body). */\nexport function renderChecklistPlain(items: GoalChecklistItem[]): string {\n if (!items.length) return '(empty)';\n const lines: string[] = [];\n for (const it of items) {\n const marker =\n it.status === 'completed' ? '[x]' : it.status === 'impossible' ? '[!]' : '[ ]';\n let line = `${marker} ${it.text}`;\n if (it.status === 'impossible' && it.evidence) line += ` (impossible: ${it.evidence})`;\n lines.push(line);\n }\n return lines.join('\\n');\n}\n\n/** Numbered checklist for judge user prompts (1-based indices). */\nexport function renderChecklistNumbered(items: GoalChecklistItem[]): string {\n if (!items.length) return '(empty)';\n const lines: string[] = [];\n for (let i = 0; i < items.length; i++) {\n const it = items[i]!;\n const n = i + 1;\n const marker =\n it.status === 'completed' ? '[x]' : it.status === 'impossible' ? '[!]' : '[ ]';\n let line = `${n}. ${marker} ${it.text}`;\n if (it.status === 'impossible' && it.evidence) line += ` (impossible: ${it.evidence})`;\n lines.push(line);\n }\n return lines.join('\\n');\n}\n\n/**\n * After LLM decomposition, keep existing checklist rows (e.g. user-added acceptance criteria)\n * and append judge-generated items, skipping duplicate text (case-insensitive trim).\n */\nexport function mergeDecomposedChecklistItems(\n existing: GoalChecklistItem[],\n decomposedTexts: { text: string }[],\n): GoalChecklistItem[] {\n const now = Date.now();\n const next = existing.map((it) => ({ ...it }));\n const seen = new Set(next.map((it) => it.text.trim().toLowerCase()));\n for (const row of decomposedTexts) {\n const t = row.text.trim();\n if (!t) continue;\n const key = t.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n next.push({\n text: t,\n status: CHECKLIST_ITEM_PENDING,\n addedBy: 'judge',\n addedAt: now,\n });\n }\n return next;\n}\n\nexport function applyJudgeChecklistUpdates(\n items: GoalChecklistItem[],\n parsed: {\n updates: { index: number; status: ChecklistItemStatus; evidence?: string | null }[];\n newItems: { text: string }[];\n },\n): GoalChecklistItem[] {\n const next = items.map((it) => ({ ...it }));\n const now = Date.now();\n for (const upd of parsed.updates) {\n const idx = upd.index;\n if (idx < 0 || idx >= next.length) continue;\n const item = next[idx]!;\n if (TERMINAL_CHECKLIST_STATUSES.has(item.status)) continue;\n if (!TERMINAL_CHECKLIST_STATUSES.has(upd.status)) continue;\n item.status = upd.status;\n item.completedAt = now;\n if (upd.evidence?.trim()) item.evidence = upd.evidence.trim();\n }\n for (const ni of parsed.newItems) {\n const t = ni.text.trim();\n if (!t) continue;\n next.push({\n text: t,\n status: CHECKLIST_ITEM_PENDING,\n addedBy: 'judge',\n addedAt: now,\n });\n }\n return next;\n}\n\n\nexport function mergeCustomDataPatch(\n existingCustom: Record<string, unknown> | undefined,\n patch: Record<string, unknown>,\n): Record<string, unknown> {\n return { ...(existingCustom ?? {}), ...patch };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"state.js","names":[],"sources":["../../../../src/agent/goals/state.ts"],"sourcesContent":["import {\n CHECKLIST_ITEM_PENDING,\n TERMINAL_CHECKLIST_STATUSES,\n type ChecklistItemAddedBy,\n type ChecklistItemStatus,\n type GoalChecklistItem,\n} from './checklist-types.js';\n\n// Direct import of the underlying locale type — `goal-locale.ts` aliases this as\n// `GoalUiLocale` AND imports values from `state.ts`, so going through `./goal-locale.js`\n// would create a circular module cycle.\nimport type { ServerLocale as GoalUiLocale } from '../../i18n/locale.js';\n\n/** Persisted under `SessionMetadata.customData.persistentGoal`. */\nexport const PERSISTENT_GOAL_CUSTOM_KEY = 'persistentGoal';\n\nexport type PersistentGoalStatus = 'active' | 'paused' | 'done' | 'cleared';\n\nexport interface PersistentGoalState {\n goal: string;\n status: PersistentGoalStatus;\n turnsUsed: number;\n maxTurns: number;\n createdAt: number;\n lastTurnAt: number;\n lastVerdict?: 'done' | 'continue' | 'skipped' | 'decompose';\n lastReason?: string;\n pausedReason?: string;\n judgeModelRef?: string;\n /** Hermes-style: judge JSON parse failures in a row (API errors do not increment). */\n consecutiveParseFailures?: number;\n /** After first successful decomposition, checklist drives Phase-B judging. */\n decomposed?: boolean;\n checklist?: GoalChecklistItem[];\n /** Gateway console language: drives judge `reason` language and system messages. */\n uiLocale?: GoalUiLocale;\n}\n\nexport function defaultMaxTurns(cfg: { maxTurns?: number } | undefined): number {\n const n = cfg?.maxTurns;\n if (typeof n === 'number' && Number.isFinite(n)) {\n return Math.max(1, Math.min(500, Math.floor(n)));\n }\n return 20;\n}\n\nfunction coerceStatus(s: unknown): PersistentGoalStatus | undefined {\n if (s === 'active' || s === 'paused' || s === 'done' || s === 'cleared') return s;\n return undefined;\n}\n\nfunction coerceChecklistItem(raw: unknown): GoalChecklistItem | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const r = raw as Record<string, unknown>;\n const text = typeof r.text === 'string' ? r.text.trim() : '';\n if (!text) return null;\n const st = typeof r.status === 'string' ? r.status.trim().toLowerCase() : '';\n const status: ChecklistItemStatus =\n st === 'completed' || st === 'impossible' || st === 'pending' ? st : CHECKLIST_ITEM_PENDING;\n const ab = typeof r.addedBy === 'string' ? r.addedBy.trim().toLowerCase() : '';\n const addedBy: ChecklistItemAddedBy = ab === 'user' ? 'user' : 'judge';\n const addedAt =\n typeof r.addedAt === 'number' && Number.isFinite(r.addedAt) ? Math.floor(r.addedAt) : Date.now();\n const completedAt =\n typeof r.completedAt === 'number' && Number.isFinite(r.completedAt) ? Math.floor(r.completedAt) : undefined;\n const evidence = typeof r.evidence === 'string' ? r.evidence : undefined;\n return { text, status, addedBy, addedAt, completedAt, evidence };\n}\n\nexport function readPersistentGoal(customData: Record<string, unknown> | undefined): PersistentGoalState | null {\n if (!customData || typeof customData !== 'object') return null;\n\n const raw = customData[PERSISTENT_GOAL_CUSTOM_KEY];\n if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n const o = raw as Record<string, unknown>;\n const goal = typeof o.goal === 'string' ? o.goal.trim() : '';\n if (!goal) return null;\n const status = coerceStatus(o.status) ?? 'active';\n const maxTurns =\n typeof o.maxTurns === 'number' && Number.isFinite(o.maxTurns)\n ? Math.max(1, Math.min(500, Math.floor(o.maxTurns)))\n : 20;\n const turnsUsed =\n typeof o.turnsUsed === 'number' && Number.isFinite(o.turnsUsed)\n ? Math.max(0, Math.floor(o.turnsUsed))\n : 0;\n const createdAt =\n typeof o.createdAt === 'number' && Number.isFinite(o.createdAt) ? o.createdAt : Date.now();\n const lastTurnAt =\n typeof o.lastTurnAt === 'number' && Number.isFinite(o.lastTurnAt) ? o.lastTurnAt : 0;\n const lastVerdict =\n o.lastVerdict === 'done' ||\n o.lastVerdict === 'continue' ||\n o.lastVerdict === 'skipped' ||\n o.lastVerdict === 'decompose'\n ? o.lastVerdict\n : undefined;\n const lastReason = typeof o.lastReason === 'string' ? o.lastReason : undefined;\n const pausedReason = typeof o.pausedReason === 'string' ? o.pausedReason : undefined;\n const judgeModelRef = typeof o.judgeModelRef === 'string' ? o.judgeModelRef.trim() : undefined;\n const consecutiveParseFailures =\n typeof o.consecutiveParseFailures === 'number' && Number.isFinite(o.consecutiveParseFailures)\n ? Math.max(0, Math.floor(o.consecutiveParseFailures))\n : 0;\n const decomposed = Boolean(o.decomposed);\n const uiLocale = o.uiLocale === 'zh' || o.uiLocale === 'en' ? o.uiLocale : undefined;\n const checklistRaw = o.checklist;\n const checklist: GoalChecklistItem[] = [];\n if (Array.isArray(checklistRaw)) {\n for (const row of checklistRaw) {\n const it = coerceChecklistItem(row);\n if (it) checklist.push(it);\n }\n }\n return {\n goal,\n status,\n turnsUsed,\n maxTurns,\n createdAt,\n lastTurnAt,\n lastVerdict,\n lastReason,\n pausedReason,\n judgeModelRef: judgeModelRef || undefined,\n consecutiveParseFailures,\n decomposed: decomposed || undefined,\n checklist: checklist.length ? checklist : undefined,\n uiLocale,\n };\n }\n\n return null;\n}\n\nexport function serializePersistentGoal(s: PersistentGoalState): Record<string, unknown> {\n return {\n goal: s.goal,\n status: s.status,\n turnsUsed: s.turnsUsed,\n maxTurns: s.maxTurns,\n createdAt: s.createdAt,\n lastTurnAt: s.lastTurnAt,\n ...(s.lastVerdict ? { lastVerdict: s.lastVerdict } : {}),\n ...(s.lastReason ? { lastReason: s.lastReason } : {}),\n ...(s.pausedReason ? { pausedReason: s.pausedReason } : {}),\n ...(s.judgeModelRef ? { judgeModelRef: s.judgeModelRef } : {}),\n ...(s.consecutiveParseFailures ? { consecutiveParseFailures: s.consecutiveParseFailures } : {}),\n ...(s.decomposed ? { decomposed: true } : {}),\n ...(s.uiLocale ? { uiLocale: s.uiLocale } : {}),\n ...(s.checklist?.length\n ? {\n checklist: s.checklist.map((it) => ({\n text: it.text,\n status: it.status,\n addedBy: it.addedBy,\n addedAt: it.addedAt,\n ...(it.completedAt !== undefined ? { completedAt: it.completedAt } : {}),\n ...(it.evidence ? { evidence: it.evidence } : {}),\n })),\n }\n : {}),\n };\n}\n\n/** Render checklist for continuation prompt (Hermes-style, no numbers in body). */\nexport function renderChecklistPlain(items: GoalChecklistItem[]): string {\n if (!items.length) return '(empty)';\n const lines: string[] = [];\n for (const it of items) {\n const marker =\n it.status === 'completed' ? '[x]' : it.status === 'impossible' ? '[!]' : '[ ]';\n let line = `${marker} ${it.text}`;\n if (it.status === 'impossible' && it.evidence) line += ` (impossible: ${it.evidence})`;\n lines.push(line);\n }\n return lines.join('\\n');\n}\n\n/** Numbered checklist for judge user prompts (1-based indices). */\nexport function renderChecklistNumbered(items: GoalChecklistItem[]): string {\n if (!items.length) return '(empty)';\n const lines: string[] = [];\n for (let i = 0; i < items.length; i++) {\n const it = items[i]!;\n const n = i + 1;\n const marker =\n it.status === 'completed' ? '[x]' : it.status === 'impossible' ? '[!]' : '[ ]';\n let line = `${n}. ${marker} ${it.text}`;\n if (it.status === 'impossible' && it.evidence) line += ` (impossible: ${it.evidence})`;\n lines.push(line);\n }\n return lines.join('\\n');\n}\n\n/**\n * After LLM decomposition, keep existing checklist rows (e.g. user-added acceptance criteria)\n * and append judge-generated items, skipping duplicate text (case-insensitive trim).\n */\nexport function mergeDecomposedChecklistItems(\n existing: GoalChecklistItem[],\n decomposedTexts: { text: string }[],\n): GoalChecklistItem[] {\n const now = Date.now();\n const next = existing.map((it) => ({ ...it }));\n const seen = new Set(next.map((it) => it.text.trim().toLowerCase()));\n for (const row of decomposedTexts) {\n const t = row.text.trim();\n if (!t) continue;\n const key = t.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n next.push({\n text: t,\n status: CHECKLIST_ITEM_PENDING,\n addedBy: 'judge',\n addedAt: now,\n });\n }\n return next;\n}\n\nexport function applyJudgeChecklistUpdates(\n items: GoalChecklistItem[],\n parsed: {\n updates: { index: number; status: ChecklistItemStatus; evidence?: string | null }[];\n newItems: { text: string }[];\n },\n): GoalChecklistItem[] {\n const next = items.map((it) => ({ ...it }));\n const now = Date.now();\n for (const upd of parsed.updates) {\n const idx = upd.index;\n if (idx < 0 || idx >= next.length) continue;\n const item = next[idx]!;\n if (TERMINAL_CHECKLIST_STATUSES.has(item.status)) continue;\n if (!TERMINAL_CHECKLIST_STATUSES.has(upd.status)) continue;\n item.status = upd.status;\n item.completedAt = now;\n if (upd.evidence?.trim()) item.evidence = upd.evidence.trim();\n }\n for (const ni of parsed.newItems) {\n const t = ni.text.trim();\n if (!t) continue;\n next.push({\n text: t,\n status: CHECKLIST_ITEM_PENDING,\n addedBy: 'judge',\n addedAt: now,\n });\n }\n return next;\n}\n\n\nexport function mergeCustomDataPatch(\n existingCustom: Record<string, unknown> | undefined,\n patch: Record<string, unknown>,\n): Record<string, unknown> {\n return { ...(existingCustom ?? {}), ...patch };\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { checkFileSafety } from "../prompt/safety.js";
|
|
2
2
|
import { decodeDataUrl } from "./image-helpers.js";
|
|
3
|
+
import { promises } from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { homedir } from "node:os";
|
|
5
|
-
import { promises } from "node:fs";
|
|
6
6
|
//#region src/agent/image/load-image-media.ts
|
|
7
7
|
function expandUser(p) {
|
|
8
8
|
if (p.startsWith("~/") || p === "~") return path.join(homedir(), p.slice(1));
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InboundLoop — owns the bus-driven inbound pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the previous `AgentService.start()` while-loop, `handleInboundMessage`,
|
|
5
|
+
* and `handleSystemMessage` methods. Everything that "a message arrives, run the
|
|
6
|
+
* agent turn, publish the reply" needs is concentrated here; the parent
|
|
7
|
+
* `AgentService` now just constructs the loop with collaborators and forwards
|
|
8
|
+
* start/stop to it.
|
|
9
|
+
*
|
|
10
|
+
* The constructor takes a fairly wide config because handling a single inbound
|
|
11
|
+
* message touches almost every subsystem (router, command handler, lifecycle
|
|
12
|
+
* manager, agent orchestrator, outbound coordinator, session state, etc.). All
|
|
13
|
+
* dependencies are injected so this class is unit-testable and the inbound
|
|
14
|
+
* pipeline can evolve without touching `AgentService`.
|
|
15
|
+
*/
|
|
16
|
+
import type { AgentMessage } from '@earendil-works/pi-agent-core';
|
|
17
|
+
import type { MessageBus } from '../../infra/bus/index.js';
|
|
18
|
+
import type { Config } from '../../config/schema.js';
|
|
19
|
+
import type { ChannelManager } from '../../channels/manager.js';
|
|
20
|
+
import type { ContextualLogger } from '../../utils/logger/types.js';
|
|
21
|
+
import type { AgentManager } from '../agent-manager.js';
|
|
22
|
+
import type { AgentOrchestrator } from '../orchestration/index.js';
|
|
23
|
+
import type { CommandHandler, OutboundCoordinator, StreamManager } from '../messaging/index.js';
|
|
24
|
+
import type { MessageRouter } from '../messaging/message-router.js';
|
|
25
|
+
import type { ModelManager } from '../models/index.js';
|
|
26
|
+
import type { SessionContextManager, SessionHydrator, SessionLifecycleManager, SessionStateBag } from '../session/index.js';
|
|
27
|
+
import type { FeedbackCoordinator } from '../feedback/index.js';
|
|
28
|
+
import type { HookHandler } from '../lifecycle/hook-handler.js';
|
|
29
|
+
import type { SessionStore } from '../../session/store.js';
|
|
30
|
+
import type { StreamHandle } from '../service.types.js';
|
|
31
|
+
export interface InboundLoopConfig {
|
|
32
|
+
log: ContextualLogger;
|
|
33
|
+
agentId: string;
|
|
34
|
+
bus: MessageBus;
|
|
35
|
+
hookHandler: HookHandler;
|
|
36
|
+
messageRouter: MessageRouter;
|
|
37
|
+
commandHandler: CommandHandler;
|
|
38
|
+
sessionContextManager: SessionContextManager;
|
|
39
|
+
feedbackCoordinator: FeedbackCoordinator;
|
|
40
|
+
agentManager: AgentManager;
|
|
41
|
+
sessionLifecycleManager: SessionLifecycleManager;
|
|
42
|
+
agentOrchestrator: AgentOrchestrator;
|
|
43
|
+
outboundCoordinator: OutboundCoordinator;
|
|
44
|
+
streamManager: StreamManager;
|
|
45
|
+
sessionState: SessionStateBag;
|
|
46
|
+
sessionStore: SessionStore;
|
|
47
|
+
modelManager: ModelManager;
|
|
48
|
+
/** Register a per-session agent-event subscription (idempotent). */
|
|
49
|
+
setupSessionEventHandling: (sessionKey: string) => void;
|
|
50
|
+
/** Per-session config hydration (workspace + model override) before a turn runs. */
|
|
51
|
+
sessionHydrator: SessionHydrator;
|
|
52
|
+
/** Returns the visible last assistant text used for outbound + persistent-goal hook. */
|
|
53
|
+
getLastAssistantPlainText: (sessionKey: string) => string;
|
|
54
|
+
/** Pre-turn auto-compaction (only used by system messages). */
|
|
55
|
+
checkAndCompact: (sessionKey: string, messages: AgentMessage[]) => Promise<void>;
|
|
56
|
+
/** Fire-and-forget auto-title (no-ops for cron/heartbeat keys). */
|
|
57
|
+
enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;
|
|
58
|
+
/** Effective merged config snapshot. */
|
|
59
|
+
getConfig: () => Config | undefined;
|
|
60
|
+
/** Connect a channel stream handle for partial assistant text rendering. */
|
|
61
|
+
setStreamHandle: (handle: StreamHandle) => void;
|
|
62
|
+
}
|
|
63
|
+
export declare class InboundLoop {
|
|
64
|
+
private readonly cfg;
|
|
65
|
+
private readonly log;
|
|
66
|
+
private running;
|
|
67
|
+
private channelManagerRef;
|
|
68
|
+
constructor(cfg: InboundLoopConfig);
|
|
69
|
+
setChannelManager(channelManager: ChannelManager | null): void;
|
|
70
|
+
isRunning(): boolean;
|
|
71
|
+
/** Begin consuming inbound messages from the bus until {@link stop} or shutdown. */
|
|
72
|
+
start(): Promise<void>;
|
|
73
|
+
/** Cooperatively stop the loop; the current message (if any) is allowed to finish. */
|
|
74
|
+
stop(): void;
|
|
75
|
+
private handleInboundMessage;
|
|
76
|
+
private handleSystemMessage;
|
|
77
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { runWithLogContext, updateAsyncLogContext } from "../../utils/logger/context.js";
|
|
2
|
+
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { MessageBusShutdownError } from "../../infra/bus/queue.js";
|
|
4
|
+
import "../../infra/bus/index.js";
|
|
5
|
+
import { inboundMessageLogRequestId } from "../service-inbound-utils.js";
|
|
6
|
+
import { runEmbeddedTurnForSession } from "../embedded/run-for-session.js";
|
|
7
|
+
//#region src/agent/inbound/inbound-loop.ts
|
|
8
|
+
init_logger();
|
|
9
|
+
/** Initial back-off when bus consume fails. Doubles each consecutive failure. */
|
|
10
|
+
const INBOUND_CONSUME_BASE_BACKOFF_MS = 1e3;
|
|
11
|
+
/** Hard cap on back-off so a long bus outage settles at one retry per 30s. */
|
|
12
|
+
const INBOUND_CONSUME_MAX_BACKOFF_MS = 3e4;
|
|
13
|
+
var InboundLoop = class {
|
|
14
|
+
cfg;
|
|
15
|
+
log;
|
|
16
|
+
running = false;
|
|
17
|
+
channelManagerRef = null;
|
|
18
|
+
constructor(cfg) {
|
|
19
|
+
this.cfg = cfg;
|
|
20
|
+
this.log = cfg.log;
|
|
21
|
+
}
|
|
22
|
+
setChannelManager(channelManager) {
|
|
23
|
+
this.channelManagerRef = channelManager;
|
|
24
|
+
}
|
|
25
|
+
isRunning() {
|
|
26
|
+
return this.running;
|
|
27
|
+
}
|
|
28
|
+
/** Begin consuming inbound messages from the bus until {@link stop} or shutdown. */
|
|
29
|
+
async start() {
|
|
30
|
+
this.running = true;
|
|
31
|
+
await this.cfg.hookHandler.trigger("session_start", { sessionId: this.cfg.agentId });
|
|
32
|
+
let consecutiveConsumeFailures = 0;
|
|
33
|
+
while (this.running) {
|
|
34
|
+
let msg;
|
|
35
|
+
try {
|
|
36
|
+
msg = await this.cfg.bus.consumeInbound();
|
|
37
|
+
consecutiveConsumeFailures = 0;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error instanceof MessageBusShutdownError) break;
|
|
40
|
+
consecutiveConsumeFailures += 1;
|
|
41
|
+
const delayMs = Math.min(INBOUND_CONSUME_MAX_BACKOFF_MS, INBOUND_CONSUME_BASE_BACKOFF_MS * 2 ** (consecutiveConsumeFailures - 1));
|
|
42
|
+
const em = error instanceof Error ? error.message : String(error);
|
|
43
|
+
this.log.error({
|
|
44
|
+
err: error,
|
|
45
|
+
errorMessage: em,
|
|
46
|
+
phase: "inbound_consume",
|
|
47
|
+
consecutiveFailures: consecutiveConsumeFailures,
|
|
48
|
+
backoffMs: delayMs
|
|
49
|
+
}, `Bus consume failed (backing off ${delayMs}ms): ${em}`);
|
|
50
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
await this.handleInboundMessage(msg);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
const em = error instanceof Error ? error.message : String(error);
|
|
57
|
+
this.log.error({
|
|
58
|
+
err: error,
|
|
59
|
+
errorMessage: em,
|
|
60
|
+
phase: "inbound_handle",
|
|
61
|
+
channel: msg.channel,
|
|
62
|
+
chatId: msg.chat_id
|
|
63
|
+
}, `Inbound message handler failed: ${em}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
await this.cfg.hookHandler.trigger("session_end", {
|
|
67
|
+
sessionId: this.cfg.agentId,
|
|
68
|
+
messageCount: 0
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** Cooperatively stop the loop; the current message (if any) is allowed to finish. */
|
|
72
|
+
stop() {
|
|
73
|
+
this.running = false;
|
|
74
|
+
}
|
|
75
|
+
async handleInboundMessage(msg) {
|
|
76
|
+
await runWithLogContext({ requestId: inboundMessageLogRequestId(msg) }, async () => {
|
|
77
|
+
const { context, isCommand, command, commandArgs } = await this.cfg.messageRouter.routeMessage(msg);
|
|
78
|
+
const sessionContext = {
|
|
79
|
+
sessionKey: context.sessionKey,
|
|
80
|
+
channel: context.channel,
|
|
81
|
+
chatId: context.chatId,
|
|
82
|
+
senderId: context.senderId || "",
|
|
83
|
+
isGroup: context.isGroup || false,
|
|
84
|
+
metadata: { transcribedVoice: msg.metadata?.transcribedVoice === true }
|
|
85
|
+
};
|
|
86
|
+
updateAsyncLogContext({ sessionId: sessionContext.sessionKey });
|
|
87
|
+
await this.cfg.sessionContextManager.runWith(sessionContext, async () => {
|
|
88
|
+
this.cfg.feedbackCoordinator.setContext(sessionContext);
|
|
89
|
+
this.cfg.agentManager.getOrCreateAgent(sessionContext.sessionKey);
|
|
90
|
+
this.cfg.setupSessionEventHandling(sessionContext.sessionKey);
|
|
91
|
+
await this.cfg.sessionLifecycleManager.startSession(sessionContext);
|
|
92
|
+
let typingController = null;
|
|
93
|
+
let inboundTurnArmed = false;
|
|
94
|
+
let busProcessFailed;
|
|
95
|
+
try {
|
|
96
|
+
if (msg.channel === "system") {
|
|
97
|
+
await this.handleSystemMessage(msg, sessionContext);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (this.channelManagerRef && msg.channel !== "cli") await this.channelManagerRef.dispatchInboundMessageAction(msg);
|
|
101
|
+
if (isCommand && command) {
|
|
102
|
+
if (await this.cfg.commandHandler.executeCommand(command, commandArgs || "", {
|
|
103
|
+
sessionKey: sessionContext.sessionKey,
|
|
104
|
+
channel: sessionContext.channel,
|
|
105
|
+
chatId: sessionContext.chatId,
|
|
106
|
+
senderId: sessionContext.senderId,
|
|
107
|
+
isGroup: sessionContext.isGroup,
|
|
108
|
+
inboundMetadata: msg.metadata
|
|
109
|
+
})) return;
|
|
110
|
+
}
|
|
111
|
+
typingController = this.cfg.outboundCoordinator.createTypingControllerForInbound(msg);
|
|
112
|
+
typingController?.start();
|
|
113
|
+
if (this.channelManagerRef && msg.channel !== "cli") {
|
|
114
|
+
const meta = msg.metadata;
|
|
115
|
+
const streamHandle = this.channelManagerRef.startStream(msg.channel, msg.chat_id, meta?.accountId, {
|
|
116
|
+
threadId: meta?.threadId,
|
|
117
|
+
replyToMessageId: meta?.messageId
|
|
118
|
+
});
|
|
119
|
+
if (streamHandle) this.cfg.setStreamHandle(streamHandle);
|
|
120
|
+
}
|
|
121
|
+
this.cfg.sessionState.beginInboundTurn(sessionContext.sessionKey);
|
|
122
|
+
inboundTurnArmed = true;
|
|
123
|
+
try {
|
|
124
|
+
await this.cfg.agentOrchestrator.process(msg, sessionContext);
|
|
125
|
+
} catch (procErr) {
|
|
126
|
+
busProcessFailed = procErr instanceof Error ? procErr.message : String(procErr);
|
|
127
|
+
throw procErr;
|
|
128
|
+
}
|
|
129
|
+
} finally {
|
|
130
|
+
await this.cfg.sessionLifecycleManager.endSession(sessionContext);
|
|
131
|
+
await this.cfg.streamManager.end();
|
|
132
|
+
try {
|
|
133
|
+
await this.cfg.outboundCoordinator.sendFinalResponse(msg, sessionContext);
|
|
134
|
+
} finally {
|
|
135
|
+
await typingController?.stop();
|
|
136
|
+
}
|
|
137
|
+
if (inboundTurnArmed) {
|
|
138
|
+
const meta = msg.metadata;
|
|
139
|
+
const assistantPlainText = this.cfg.getLastAssistantPlainText(sessionContext.sessionKey) ?? "";
|
|
140
|
+
try {
|
|
141
|
+
await this.cfg.outboundCoordinator.emitSessionTurnComplete({
|
|
142
|
+
sessionKey: sessionContext.sessionKey,
|
|
143
|
+
channel: sessionContext.channel,
|
|
144
|
+
chatId: sessionContext.chatId,
|
|
145
|
+
inboundUserText: msg.content,
|
|
146
|
+
assistantPlainText,
|
|
147
|
+
aborted: false,
|
|
148
|
+
...busProcessFailed !== void 0 ? { streamError: busProcessFailed } : {},
|
|
149
|
+
skipPersistentGoalPostTurn: false,
|
|
150
|
+
outboundMetadata: {
|
|
151
|
+
accountId: meta?.accountId,
|
|
152
|
+
threadId: meta?.threadId
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
} catch (turnErr) {
|
|
156
|
+
const em = turnErr instanceof Error ? turnErr.message : String(turnErr);
|
|
157
|
+
this.log.warn({
|
|
158
|
+
err: turnErr,
|
|
159
|
+
sessionKey: sessionContext.sessionKey
|
|
160
|
+
}, `Session turn complete failed: ${em}`);
|
|
161
|
+
}
|
|
162
|
+
this.cfg.sessionState.endInboundTurn(sessionContext.sessionKey);
|
|
163
|
+
}
|
|
164
|
+
this.cfg.feedbackCoordinator.endTask();
|
|
165
|
+
this.cfg.feedbackCoordinator.clearContext();
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async handleSystemMessage(msg, context) {
|
|
171
|
+
this.log.debug({ sessionKey: context.sessionKey }, "Processing system message");
|
|
172
|
+
await this.cfg.sessionHydrator.workspace(context.sessionKey);
|
|
173
|
+
await this.cfg.sessionHydrator.model(context.sessionKey);
|
|
174
|
+
const messages = await this.cfg.sessionStore.load(context.sessionKey);
|
|
175
|
+
await this.cfg.checkAndCompact(context.sessionKey, messages);
|
|
176
|
+
const systemMessage = {
|
|
177
|
+
role: "user",
|
|
178
|
+
content: [{
|
|
179
|
+
type: "text",
|
|
180
|
+
text: `[System: ${msg.sender_id}] ${msg.content}`
|
|
181
|
+
}],
|
|
182
|
+
timestamp: Date.now()
|
|
183
|
+
};
|
|
184
|
+
try {
|
|
185
|
+
const finalContent = (await runEmbeddedTurnForSession({
|
|
186
|
+
sessionKey: context.sessionKey,
|
|
187
|
+
userMessage: systemMessage,
|
|
188
|
+
sessionStore: this.cfg.sessionStore,
|
|
189
|
+
agentManager: this.cfg.agentManager,
|
|
190
|
+
modelManager: this.cfg.modelManager,
|
|
191
|
+
getConfig: this.cfg.getConfig
|
|
192
|
+
})).lastAssistantText ?? this.cfg.getLastAssistantPlainText(context.sessionKey);
|
|
193
|
+
if (finalContent) {
|
|
194
|
+
this.cfg.sessionState.setLastAssistantText(context.sessionKey, finalContent);
|
|
195
|
+
const hookResult = await this.cfg.hookHandler.runMessageSending(context.chatId, finalContent, context.channel);
|
|
196
|
+
if (hookResult.send) await this.cfg.bus.publishOutbound({
|
|
197
|
+
channel: context.channel,
|
|
198
|
+
chat_id: context.chatId,
|
|
199
|
+
content: hookResult.content || finalContent,
|
|
200
|
+
type: "message"
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
this.cfg.enqueueMaybeAutoTitleAfterPersist(context.sessionKey);
|
|
204
|
+
} catch (error) {
|
|
205
|
+
const em = error instanceof Error ? error.message : String(error);
|
|
206
|
+
this.log.error({
|
|
207
|
+
err: error,
|
|
208
|
+
errorMessage: em,
|
|
209
|
+
sessionKey: context.sessionKey,
|
|
210
|
+
channel: context.channel,
|
|
211
|
+
chatId: context.chatId,
|
|
212
|
+
senderId: msg.sender_id
|
|
213
|
+
}, `System message handling failed: ${em}`);
|
|
214
|
+
await this.cfg.bus.publishOutbound({
|
|
215
|
+
channel: context.channel,
|
|
216
|
+
chat_id: context.chatId,
|
|
217
|
+
content: "❌ An error occurred while processing the system message.",
|
|
218
|
+
type: "message"
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
//#endregion
|
|
224
|
+
export { InboundLoop };
|
|
225
|
+
|
|
226
|
+
//# sourceMappingURL=inbound-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbound-loop.js","names":[],"sources":["../../../../src/agent/inbound/inbound-loop.ts"],"sourcesContent":["/**\n * InboundLoop — owns the bus-driven inbound pipeline.\n *\n * Replaces the previous `AgentService.start()` while-loop, `handleInboundMessage`,\n * and `handleSystemMessage` methods. Everything that \"a message arrives, run the\n * agent turn, publish the reply\" needs is concentrated here; the parent\n * `AgentService` now just constructs the loop with collaborators and forwards\n * start/stop to it.\n *\n * The constructor takes a fairly wide config because handling a single inbound\n * message touches almost every subsystem (router, command handler, lifecycle\n * manager, agent orchestrator, outbound coordinator, session state, etc.). All\n * dependencies are injected so this class is unit-testable and the inbound\n * pipeline can evolve without touching `AgentService`.\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { MessageBus, InboundMessage } from '../../infra/bus/index.js';\nimport { MessageBusShutdownError } from '../../infra/bus/index.js';\nimport type { Config } from '../../config/schema.js';\nimport type { ChannelManager } from '../../channels/manager.js';\nimport { runWithLogContext, updateAsyncLogContext } from '../../utils/logger.js';\nimport type { ContextualLogger } from '../../utils/logger/types.js';\n\nimport type { AgentManager } from '../agent-manager.js';\nimport type { AgentOrchestrator } from '../orchestration/index.js';\nimport type { CommandHandler, OutboundCoordinator, StreamManager } from '../messaging/index.js';\nimport type { MessageRouter } from '../messaging/message-router.js';\nimport type { ModelManager } from '../models/index.js';\nimport type {\n SessionContext,\n SessionContextManager,\n SessionHydrator,\n SessionLifecycleManager,\n SessionStateBag,\n} from '../session/index.js';\nimport type { FeedbackCoordinator } from '../feedback/index.js';\nimport type { HookHandler } from '../lifecycle/hook-handler.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type { StreamHandle } from '../service.types.js';\nimport { runEmbeddedTurnForSession } from '../embedded/run-for-session.js';\nimport { inboundMessageLogRequestId } from '../service-inbound-utils.js';\n\n/** Initial back-off when bus consume fails. Doubles each consecutive failure. */\nconst INBOUND_CONSUME_BASE_BACKOFF_MS = 1_000;\n/** Hard cap on back-off so a long bus outage settles at one retry per 30s. */\nconst INBOUND_CONSUME_MAX_BACKOFF_MS = 30_000;\n\nexport interface InboundLoopConfig {\n log: ContextualLogger;\n agentId: string;\n bus: MessageBus;\n hookHandler: HookHandler;\n messageRouter: MessageRouter;\n commandHandler: CommandHandler;\n sessionContextManager: SessionContextManager;\n feedbackCoordinator: FeedbackCoordinator;\n agentManager: AgentManager;\n sessionLifecycleManager: SessionLifecycleManager;\n agentOrchestrator: AgentOrchestrator;\n outboundCoordinator: OutboundCoordinator;\n streamManager: StreamManager;\n sessionState: SessionStateBag;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n\n /** Register a per-session agent-event subscription (idempotent). */\n setupSessionEventHandling: (sessionKey: string) => void;\n /** Per-session config hydration (workspace + model override) before a turn runs. */\n sessionHydrator: SessionHydrator;\n /** Returns the visible last assistant text used for outbound + persistent-goal hook. */\n getLastAssistantPlainText: (sessionKey: string) => string;\n /** Pre-turn auto-compaction (only used by system messages). */\n checkAndCompact: (sessionKey: string, messages: AgentMessage[]) => Promise<void>;\n /** Fire-and-forget auto-title (no-ops for cron/heartbeat keys). */\n enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;\n /** Effective merged config snapshot. */\n getConfig: () => Config | undefined;\n /** Connect a channel stream handle for partial assistant text rendering. */\n setStreamHandle: (handle: StreamHandle) => void;\n}\n\nexport class InboundLoop {\n private readonly cfg: InboundLoopConfig;\n private readonly log: ContextualLogger;\n private running = false;\n private channelManagerRef: ChannelManager | null = null;\n\n constructor(cfg: InboundLoopConfig) {\n this.cfg = cfg;\n this.log = cfg.log;\n }\n\n setChannelManager(channelManager: ChannelManager | null): void {\n this.channelManagerRef = channelManager;\n }\n\n isRunning(): boolean {\n return this.running;\n }\n\n /** Begin consuming inbound messages from the bus until {@link stop} or shutdown. */\n async start(): Promise<void> {\n this.running = true;\n await this.cfg.hookHandler.trigger('session_start', { sessionId: this.cfg.agentId });\n\n // Errors fall into two buckets:\n // 1. `bus.consumeInbound()` itself threw → infrastructure problem; back off\n // exponentially so a flapping bus does not pin the CPU at 100%.\n // 2. `handleInboundMessage(msg)` threw → per-message handler bug. The\n // message is already lost; do NOT sleep, just log and move on so\n // legitimate traffic is not held hostage.\n // Shutdown (`MessageBusShutdownError`) is the only signal that breaks the loop.\n let consecutiveConsumeFailures = 0;\n\n while (this.running) {\n let msg: InboundMessage;\n try {\n msg = await this.cfg.bus.consumeInbound();\n consecutiveConsumeFailures = 0;\n } catch (error) {\n if (error instanceof MessageBusShutdownError) {\n break;\n }\n consecutiveConsumeFailures += 1;\n const delayMs = Math.min(\n INBOUND_CONSUME_MAX_BACKOFF_MS,\n INBOUND_CONSUME_BASE_BACKOFF_MS * 2 ** (consecutiveConsumeFailures - 1),\n );\n const em = error instanceof Error ? error.message : String(error);\n this.log.error(\n {\n err: error,\n errorMessage: em,\n phase: 'inbound_consume',\n consecutiveFailures: consecutiveConsumeFailures,\n backoffMs: delayMs,\n },\n `Bus consume failed (backing off ${delayMs}ms): ${em}`,\n );\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n continue;\n }\n\n try {\n await this.handleInboundMessage(msg);\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n this.log.error(\n {\n err: error,\n errorMessage: em,\n phase: 'inbound_handle',\n channel: msg.channel,\n chatId: msg.chat_id,\n },\n `Inbound message handler failed: ${em}`,\n );\n // Per-message failure: keep consuming. The next message is independent.\n }\n }\n\n await this.cfg.hookHandler.trigger('session_end', {\n sessionId: this.cfg.agentId,\n messageCount: 0,\n });\n }\n\n /** Cooperatively stop the loop; the current message (if any) is allowed to finish. */\n stop(): void {\n this.running = false;\n }\n\n private async handleInboundMessage(msg: InboundMessage): Promise<void> {\n const requestId = inboundMessageLogRequestId(msg);\n\n await runWithLogContext({ requestId }, async () => {\n const routing = await this.cfg.messageRouter.routeMessage(msg);\n const { context, isCommand, command, commandArgs } = routing;\n\n const sessionContext: SessionContext = {\n sessionKey: context.sessionKey,\n channel: context.channel,\n chatId: context.chatId,\n senderId: context.senderId || '',\n isGroup: context.isGroup || false,\n metadata: {\n transcribedVoice: msg.metadata?.transcribedVoice === true,\n },\n };\n\n updateAsyncLogContext({ sessionId: sessionContext.sessionKey });\n\n await this.cfg.sessionContextManager.runWith(sessionContext, async () => {\n this.cfg.feedbackCoordinator.setContext(sessionContext);\n\n // `subscribeToSession` requires an Agent instance; without this the first inbound never\n // registers `message_update` streaming (second turn behaved differently).\n this.cfg.agentManager.getOrCreateAgent(sessionContext.sessionKey);\n this.cfg.setupSessionEventHandling(sessionContext.sessionKey);\n\n await this.cfg.sessionLifecycleManager.startSession(sessionContext);\n\n let typingController: ReturnType<OutboundCoordinator['createTypingControllerForInbound']> = null;\n let inboundTurnArmed = false;\n let busProcessFailed: string | undefined;\n\n try {\n if (msg.channel === 'system') {\n await this.handleSystemMessage(msg, sessionContext);\n return;\n }\n\n if (this.channelManagerRef && msg.channel !== 'cli') {\n await this.channelManagerRef.dispatchInboundMessageAction(msg);\n }\n\n if (isCommand && command) {\n const handled = await this.cfg.commandHandler.executeCommand(command, commandArgs || '', {\n sessionKey: sessionContext.sessionKey,\n channel: sessionContext.channel,\n chatId: sessionContext.chatId,\n senderId: sessionContext.senderId,\n isGroup: sessionContext.isGroup,\n inboundMetadata: msg.metadata,\n });\n if (handled) {\n return;\n }\n }\n\n // Continuous typing indicator (renews every 5 seconds); stopped only AFTER outbound.\n typingController = this.cfg.outboundCoordinator.createTypingControllerForInbound(msg);\n typingController?.start();\n\n if (this.channelManagerRef && msg.channel !== 'cli') {\n const meta = msg.metadata as Record<string, unknown> | undefined;\n const streamHandle = this.channelManagerRef.startStream(\n msg.channel,\n msg.chat_id,\n meta?.accountId as string | undefined,\n {\n threadId: meta?.threadId as string | undefined,\n replyToMessageId: meta?.messageId as string | undefined,\n },\n );\n if (streamHandle) {\n this.cfg.setStreamHandle(streamHandle as StreamHandle);\n }\n }\n\n this.cfg.sessionState.beginInboundTurn(sessionContext.sessionKey);\n inboundTurnArmed = true;\n try {\n await this.cfg.agentOrchestrator.process(msg, sessionContext);\n } catch (procErr) {\n busProcessFailed = procErr instanceof Error ? procErr.message : String(procErr);\n throw procErr;\n }\n } finally {\n await this.cfg.sessionLifecycleManager.endSession(sessionContext);\n await this.cfg.streamManager.end();\n try {\n await this.cfg.outboundCoordinator.sendFinalResponse(msg, sessionContext);\n } finally {\n // Clear typing AFTER outbound (incl. TTS); otherwise Weixin shows typing_off before the message.\n await typingController?.stop();\n }\n if (inboundTurnArmed) {\n const meta = msg.metadata as Record<string, unknown> | undefined;\n const assistantPlainText = this.cfg.getLastAssistantPlainText(sessionContext.sessionKey) ?? '';\n try {\n await this.cfg.outboundCoordinator.emitSessionTurnComplete({\n sessionKey: sessionContext.sessionKey,\n channel: sessionContext.channel,\n chatId: sessionContext.chatId,\n inboundUserText: msg.content,\n assistantPlainText,\n aborted: false,\n ...(busProcessFailed !== undefined ? { streamError: busProcessFailed } : {}),\n skipPersistentGoalPostTurn: false,\n outboundMetadata: {\n accountId: meta?.accountId,\n threadId: meta?.threadId,\n },\n });\n } catch (turnErr) {\n const em = turnErr instanceof Error ? turnErr.message : String(turnErr);\n this.log.warn(\n { err: turnErr, sessionKey: sessionContext.sessionKey },\n `Session turn complete failed: ${em}`,\n );\n }\n this.cfg.sessionState.endInboundTurn(sessionContext.sessionKey);\n }\n this.cfg.feedbackCoordinator.endTask();\n this.cfg.feedbackCoordinator.clearContext();\n }\n });\n });\n }\n\n private async handleSystemMessage(msg: InboundMessage, context: SessionContext): Promise<void> {\n this.log.debug({ sessionKey: context.sessionKey }, 'Processing system message');\n\n await this.cfg.sessionHydrator.workspace(context.sessionKey);\n await this.cfg.sessionHydrator.model(context.sessionKey);\n\n const messages = await this.cfg.sessionStore.load(context.sessionKey);\n await this.cfg.checkAndCompact(context.sessionKey, messages);\n\n const systemMessage: AgentMessage = {\n role: 'user',\n content: [{ type: 'text', text: `[System: ${msg.sender_id}] ${msg.content}` }],\n timestamp: Date.now(),\n };\n\n try {\n const result = await runEmbeddedTurnForSession({\n sessionKey: context.sessionKey,\n userMessage: systemMessage,\n sessionStore: this.cfg.sessionStore,\n agentManager: this.cfg.agentManager,\n modelManager: this.cfg.modelManager,\n getConfig: this.cfg.getConfig,\n });\n\n const finalContent = result.lastAssistantText ?? this.cfg.getLastAssistantPlainText(context.sessionKey);\n if (finalContent) {\n this.cfg.sessionState.setLastAssistantText(context.sessionKey, finalContent);\n const hookResult = await this.cfg.hookHandler.runMessageSending(\n context.chatId,\n finalContent,\n context.channel,\n );\n if (hookResult.send) {\n await this.cfg.bus.publishOutbound({\n channel: context.channel,\n chat_id: context.chatId,\n content: hookResult.content || finalContent,\n type: 'message',\n });\n }\n }\n this.cfg.enqueueMaybeAutoTitleAfterPersist(context.sessionKey);\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n this.log.error(\n {\n err: error,\n errorMessage: em,\n sessionKey: context.sessionKey,\n channel: context.channel,\n chatId: context.chatId,\n senderId: msg.sender_id,\n },\n `System message handling failed: ${em}`,\n );\n await this.cfg.bus.publishOutbound({\n channel: context.channel,\n chat_id: context.chatId,\n content: '❌ An error occurred while processing the system message.',\n type: 'message',\n });\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurnDispatcher — single entry point for direct (non-bus) agent turns.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the two existing direct-turn runners (one-shot and streaming) so the
|
|
5
|
+
* parent `AgentService` no longer carries a pair of huge `createXxxDeps()`
|
|
6
|
+
* factories. The public surface — `processDirect`, `processDirectStreaming`,
|
|
7
|
+
* `steerWebchatSession`, `enqueueWebchatSseEvent`,
|
|
8
|
+
* `notifyWebchatTranscriptAppend` — matches what `AgentService` exposed
|
|
9
|
+
* previously, so callers (gateway, CLI) are unchanged.
|
|
10
|
+
*
|
|
11
|
+
* Like `OutboundCoordinator` and `InboundLoop`, this class accepts a wide
|
|
12
|
+
* dependency bag in its constructor (the direct-turn pipeline touches almost
|
|
13
|
+
* every other subsystem). The win is that AgentService becomes the only place
|
|
14
|
+
* that wires those dependencies together; individual responsibilities now live
|
|
15
|
+
* in their own classes and are unit-testable.
|
|
16
|
+
*/
|
|
17
|
+
import type { Config } from '../../config/schema.js';
|
|
18
|
+
import type { ContextualLogger } from '../../utils/logger/types.js';
|
|
19
|
+
import type { AgentManager } from '../agent-manager.js';
|
|
20
|
+
import type { CommandHandler } from '../messaging/command-handler.js';
|
|
21
|
+
import type { ModelManager } from '../models/index.js';
|
|
22
|
+
import type { SessionConfigStore } from '../../session/index.js';
|
|
23
|
+
import type { SessionStore } from '../../session/store.js';
|
|
24
|
+
import type { SessionContext, SessionHydrator, SessionStateBag } from '../session/index.js';
|
|
25
|
+
import type { InternalAttachmentRoots } from '../../channels/attachments/inbound-persist.js';
|
|
26
|
+
import { type DirectInboundAttachment } from '../service/build-direct-message-content.js';
|
|
27
|
+
import { type ProcessDirectStreamingSseEvent } from '../service/process-direct-streaming.js';
|
|
28
|
+
export interface TurnDispatcherConfig {
|
|
29
|
+
log: ContextualLogger;
|
|
30
|
+
agentManager: AgentManager;
|
|
31
|
+
sessionStore: SessionStore;
|
|
32
|
+
modelManager: ModelManager;
|
|
33
|
+
sessionConfigStore: SessionConfigStore;
|
|
34
|
+
sessionState: SessionStateBag;
|
|
35
|
+
commandHandler: CommandHandler;
|
|
36
|
+
getConfig: () => Config | undefined;
|
|
37
|
+
/** Strict accessor — required for direct-turn paths that must have a config. */
|
|
38
|
+
requireConfig: () => Config;
|
|
39
|
+
parseSessionKey: (sessionKey: string) => {
|
|
40
|
+
channel: string;
|
|
41
|
+
chatId: string;
|
|
42
|
+
};
|
|
43
|
+
/** Establish per-session context (also creates the Agent + subscribes to events). */
|
|
44
|
+
initSessionContext: (sessionKey: string, channel: string, chatId: string) => SessionContext;
|
|
45
|
+
/** Per-session config hydration: workspace, model, thinking. */
|
|
46
|
+
sessionHydrator: SessionHydrator;
|
|
47
|
+
attachmentRootsForSession: (sessionKey: string) => InternalAttachmentRoots;
|
|
48
|
+
prepareInboundAttachments: (sessionKey: string, attachments?: DirectInboundAttachment[]) => Promise<DirectInboundAttachment[] | undefined>;
|
|
49
|
+
enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;
|
|
50
|
+
endDirectRequestContext: () => void;
|
|
51
|
+
/** Gateway hook fired after assistant text lands on disk (UI refetch). */
|
|
52
|
+
onSessionTranscriptUpdated?: (sessionKey: string) => void;
|
|
53
|
+
}
|
|
54
|
+
export type DirectAttachment = DirectInboundAttachment;
|
|
55
|
+
export declare class TurnDispatcher {
|
|
56
|
+
private readonly cfg;
|
|
57
|
+
private readonly log;
|
|
58
|
+
constructor(cfg: TurnDispatcherConfig);
|
|
59
|
+
/** One-shot direct turn (CLI / embedded TUI). */
|
|
60
|
+
processDirect(content: string, sessionKey?: string, attachments?: DirectAttachment[], thinking?: string): Promise<string>;
|
|
61
|
+
/** Streaming direct turn (webchat SSE / CLI streaming). */
|
|
62
|
+
processDirectStreaming(content: string, sessionKey?: string, attachments?: DirectAttachment[], thinking?: string, options?: {
|
|
63
|
+
signal?: AbortSignal;
|
|
64
|
+
}): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown>;
|
|
65
|
+
/** Push an out-of-band event into the live webchat stream for a session. */
|
|
66
|
+
enqueueWebchatSseEvent(sessionKey: string, event: {
|
|
67
|
+
type: string;
|
|
68
|
+
[key: string]: unknown;
|
|
69
|
+
}): void;
|
|
70
|
+
/** Stream assistant text to live webchat session + notify transcript listeners. */
|
|
71
|
+
notifyWebchatTranscriptAppend(sessionKey: string, assistantText: string): void;
|
|
72
|
+
/**
|
|
73
|
+
* Queue a steering user message into pi-agent's in-flight run (delivered
|
|
74
|
+
* after current tool work, before the next LLM call). See `Agent.steer`
|
|
75
|
+
* in `@earendil-works/pi-agent-core`.
|
|
76
|
+
*/
|
|
77
|
+
steerWebchatSession(sessionKey: string, text: string): Promise<boolean>;
|
|
78
|
+
private buildStreamingDeps;
|
|
79
|
+
private buildOneShotDeps;
|
|
80
|
+
}
|