@xopcai/xopc 0.0.384 → 0.0.386
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BSel9yf8.js → agent-avatar-dicebear-D-86VOlb.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-DgHMyhuY.js → agent-defaults-settings-panel-SmeUVHY8.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-BosuN4dO.js → agent-plugin-dialog-BVT3wXq5.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-B-pw5RKI.js → agents-D7rLQFhX.js} +3 -3
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DuOqKkfH.js → app-management-settings-panel-CUR7n5iP.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-8JF9rXFr.js → appearance-settings-BCotSGep.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-Cuclpk0A.js → apps-page-hk0bo9LT.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-D7NwNy2I.js → automations-page-CqxuUwox.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-CSxW4wX0.js → automations-workspace-11_Z69pr.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Dnb7CH_l.js → block-editor-eldB84Mj.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-GBgDe21o.js → browser-automations-page-D4TaUPYT.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-B2FXaO3n.js → browser-settings-page-BXRlxeGV.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-XFwwUNU3.js → capabilities-BkKgImWi.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-2Do3eKMM.js → capabilities-DVj9n65C.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-page-f2-MquJn.js → capabilities-page-CyYlueEd.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-D9F0mw16.js → capabilities-settings-panel-uVEgfvo0.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-header-actions-DVRxJPQP.js → capability-header-actions-BXv0xu56.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-CnDm5T1t.js → channels-fNb3SOzm.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BxSCDbK7.js → chat-terminal-dock-CnLtparQ.js} +1 -1
- package/dist/gateway/static/root/assets/{computer-settings-page-DVAB-kQw.js → computer-settings-page-xM0AnOlP.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-D2EeLXei.js → connector-service-page-CdG2WUb6.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-DK9n4hgZ.js → connectors-page-BRd08GH6.js} +1 -1
- package/dist/gateway/static/root/assets/constants-CpWu0oHS.js +1 -0
- package/dist/gateway/static/root/assets/{date-picker-Cl9KfFj8.js → date-picker-DIBbE-O8.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-Ei6aX5WM.js → dependency-picker-DDD8zokD.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-4Evl4RKX.js → desktop-pet-KlF390Xn.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DAD_OWcX.js → desktop-pet-settings-CgqQMKDC.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-BA21epMn.js → device-pairing-wizard-BR6isfG2.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-B_Zb5nNR.js → directory-picker-path-field-vPQsW05P.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DtHNy4TE.js → extension-debug-page-ZHLPrLbH.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-8gWSThWP.js → extension-page-DJ42KFRN.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-provider-nbgU7xBS.js → extension-provider-6IcsyNaV.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CunUbB09.js → extension-settings-page-D7-5v0V4.js} +1 -1
- package/dist/gateway/static/root/assets/{fallback-models-BSAfzXby.js → fallback-models-DnYn7qOV.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-CN-2229W.js → gateway-settings-Bwe3JWX-.js} +1 -1
- package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-DktBCtHF.js → highlighted-body-KQOG7T2V-DefTxF3q.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-CUJcNW3H.js → home-page-BtSy2hRV.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-DQm1MNNC.js → imports-page-CTdBYZib.js} +1 -1
- package/dist/gateway/static/root/assets/{index-BPNL54bv.js → index-B08iR7fT.js} +10 -10
- package/dist/gateway/static/root/assets/index-DBRwvWzm.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DaC5YjuJ.js → keyboard-shortcuts-settings-CXKp57O_.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DwQyyo7a.js → local-app-workbench-page-DzD_OzGY.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-CpZhivpf.js → local-apps-page-B0E0vttg.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-Db43nh1M.js → logs-page-eL4fYcMl.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-DrKejBEZ.js → management-settings-DSpjodMC.js} +1 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-BTrk2wWv.js +1 -0
- package/dist/gateway/static/root/assets/{note-detail-panel-a8NSwmmW.js → note-detail-panel-CsY5tQp5.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-page-BKRke43F.js → notes-page-D09LjNoj.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-capture-button-DUaMkmxv.js → page-context-capture-button-DO-aP3D9.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-page-BqF-HHw1.js → personal-page-E8F2aGNB.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-GrhtTQIz.js → product-open-page-aUoA-uPw.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-zdP7gN0y.js → product-preview-content-B-cz-pIV.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-9Vd_AqDW.js → project-detail-page-WhefAh8E.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-DGunhjoM.js → projects-page-CyqAs0tO.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-BoRsF3Lx.js → remote-access-hub-BwhRGL6m.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-W0HDm--J.js → runtime-tools-settings-panel-o26dmPNq.js} +1 -1
- package/dist/gateway/static/root/assets/{scenes-page-CYsFOfVJ.js → scenes-page-D_e19kv_.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-CBxEbBQq.js → schema-form-DLLdqUC3.js} +1 -1
- package/dist/gateway/static/root/assets/{send-session-input-BCAF-Ikt.js → send-session-input-2I-nFJcE.js} +1 -1
- package/dist/gateway/static/root/assets/session-manager-Co5ozD0l.js +16 -0
- package/dist/gateway/static/root/assets/{sessions-page-Dthfx_vc.js → sessions-page-DX6INsiS.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-C4_gW1vw.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-CFs-WP_2.js → settings-page-Bc_zxxRu.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-D2-9fXYL.js → setup-status-panel-FpF_cPPr.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-nJ2FWAEP.js → share-preview-page-BOCcPBqQ.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-DTb88RHD.js → shares-settings-CInxjxgJ.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-api-DJ8UBsxq.js → skill-api-Bjd8WAA4.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-DjbBOikT.js → skills-page-8CKS3Oo2.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-Dt5GkLhM.js → system-settings-panel-BgQdsrNw.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-BnG5ehZ6.js +2 -0
- package/dist/gateway/static/root/assets/task-expandable-content-BCuc70Vc.js +1 -0
- package/dist/gateway/static/root/assets/{tasks-DJIeIk9C.js → tasks-PuIUgF9L.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-JHttXi63.js → tunnel-api-CY7MoDGf.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-B3rUa0fW.js → usage-page-s8Sv_PIG.js} +1 -1
- package/dist/gateway/static/root/assets/{use-composer-attachments-BFP3k6oC.js → use-composer-attachments-D0S2iZF4.js} +1 -1
- package/dist/gateway/static/root/assets/{use-file-preview-expanded-B1BiTQNS.js → use-file-preview-expanded-BElqELib.js} +1 -1
- package/dist/gateway/static/root/assets/{user-model-page-Cq1VSsZw.js → user-model-page-CyWrEtHY.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BAtG_JHv.js → work-discovery-overlay-DmZXLs1v.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cw12NFgx.js → workflow-run-setup-panel-BdLOzHm4.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-kR5ouOuM.js → workflows-page-Cx3I3AV5.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-api-Xr3wz8T3.js → workspace-api-Du7-xJ0q.js} +2 -2
- package/dist/gateway/static/root/assets/{xopc-cloud-account-card-BTBVKpSg.js → xopc-cloud-account-card-D8B136vW.js} +1 -1
- package/dist/gateway/static/root/index.html +12 -12
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/index.js +2 -0
- package/dist/packages/gateway-contract/src/task-research-result.js +89 -0
- package/dist/packages/gateway-contract/src/tasks.js +7 -1
- package/dist/packages/gateway-contract/src/turn-outcome.js +3 -0
- package/dist/src/agent/child-agent-factory.d.ts +4 -1
- package/dist/src/agent/child-agent-factory.js +91 -11
- package/dist/src/agent/context/connection-objective-context.d.ts +1 -0
- package/dist/src/agent/context/connection-objective-context.js +33 -0
- package/dist/src/agent/data-acquisition/service.js +41 -6
- package/dist/src/agent/data-acquisition/types.d.ts +2 -0
- package/dist/src/agent/embedded/agent-profile-context.d.ts +7 -0
- package/dist/src/agent/embedded/agent-profile-context.js +92 -0
- package/dist/src/agent/embedded/execution-tool-policy.d.ts +1 -1
- package/dist/src/agent/embedded/execution-tool-policy.js +3 -2
- package/dist/src/agent/embedded/run-for-session.js +37 -14
- package/dist/src/agent/embedded/run-turn.js +123 -26
- package/dist/src/agent/embedded/runs.d.ts +9 -2
- package/dist/src/agent/embedded/runs.js +30 -7
- package/dist/src/agent/embedded/session-runner.js +14 -3
- package/dist/src/agent/embedded/types.d.ts +6 -1
- package/dist/src/agent/external-tools/cliProvider.d.ts +1 -0
- package/dist/src/agent/external-tools/cliProvider.js +1 -0
- package/dist/src/agent/external-tools/composio-provider.js +2 -0
- package/dist/src/agent/external-tools/gateway-tools.js +15 -5
- package/dist/src/agent/external-tools/service.d.ts +1 -0
- package/dist/src/agent/external-tools/service.js +3 -1
- package/dist/src/agent/external-tools/types.d.ts +4 -0
- package/dist/src/agent/orchestration/agent-run-supervisor.js +2 -1
- package/dist/src/agent/orchestration/agent-turn-policy.d.ts +1 -0
- package/dist/src/agent/orchestration/agent-turn-policy.js +5 -1
- package/dist/src/agent/orchestration/delegation-budget.d.ts +7 -1
- package/dist/src/agent/orchestration/delegation-budget.js +19 -10
- package/dist/src/agent/orchestration/llm-turn-retry.d.ts +5 -0
- package/dist/src/agent/orchestration/llm-turn-retry.js +15 -5
- package/dist/src/agent/orchestration/research-checkpoint.d.ts +56 -0
- package/dist/src/agent/orchestration/research-checkpoint.js +64 -0
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +3 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +15 -2
- package/dist/src/agent/orchestration/run-termination.d.ts +12 -0
- package/dist/src/agent/orchestration/run-termination.js +24 -0
- package/dist/src/agent/orchestration/turn-recovery.d.ts +9 -0
- package/dist/src/agent/orchestration/turn-recovery.js +45 -0
- package/dist/src/agent/prompt/sections/agent-identity.js +12 -7
- package/dist/src/agent/prompt/sections/messaging-runtime.js +1 -1
- package/dist/src/agent/prompt/sections/project-context.js +1 -1
- package/dist/src/agent/prompt/sections/response-language.d.ts +1 -1
- package/dist/src/agent/prompt/sections/response-language.js +6 -2
- package/dist/src/agent/prompt/subagent-context.js +1 -1
- package/dist/src/agent/prompt/system-prompt.js +4 -6
- package/dist/src/agent/service/direct-turn-helpers.js +6 -5
- package/dist/src/agent/service/process-direct-streaming.js +7 -1
- package/dist/src/agent/tasks/task-judge-service.js +30 -10
- package/dist/src/agent/tools/apply-patch.js +1 -1
- package/dist/src/agent/tools/delegate-tool.js +216 -121
- package/dist/src/agent/tools/delegation-policy.js +13 -1
- package/dist/src/agent/tools/factory.js +12 -1
- package/dist/src/agent/tools/index.d.ts +2 -0
- package/dist/src/agent/tools/index.js +3 -1
- package/dist/src/agent/tools/language-diagnostics.js +1 -1
- package/dist/src/agent/tools/personal-request-result-tool.js +20 -3
- package/dist/src/agent/tools/personal-request-tool.js +165 -23
- package/dist/src/agent/tools/personal-task-tool.d.ts +6 -3
- package/dist/src/agent/tools/personal-task-tool.js +146 -23
- package/dist/src/agent/tools/publish-artifacts.js +1 -1
- package/dist/src/agent/tools/research-checkpoint-tool.d.ts +3 -0
- package/dist/src/agent/tools/research-checkpoint-tool.js +28 -0
- package/dist/src/agent/tools/review-workspace.js +1 -1
- package/dist/src/agent/tools/search/cache.d.ts +20 -0
- package/dist/src/agent/tools/search/cache.js +19 -0
- package/dist/src/agent/tools/search/errors.d.ts +19 -0
- package/dist/src/agent/tools/search/errors.js +69 -0
- package/dist/src/agent/tools/search/providers/bing-api.js +2 -1
- package/dist/src/agent/tools/search/providers/bing-html.js +2 -1
- package/dist/src/agent/tools/search/providers/brave.js +2 -1
- package/dist/src/agent/tools/search/providers/duckduckgo-html.js +2 -1
- package/dist/src/agent/tools/search/providers/searxng.js +2 -1
- package/dist/src/agent/tools/search/providers/tavily.js +2 -1
- package/dist/src/agent/tools/search/providers/xopc-cloud.d.ts +1 -0
- package/dist/src/agent/tools/search/providers/xopc-cloud.js +7 -2
- package/dist/src/agent/tools/search/registry.d.ts +21 -5
- package/dist/src/agent/tools/search/registry.js +252 -25
- package/dist/src/agent/tools/search/types.d.ts +25 -0
- package/dist/src/agent/tools/task-collaboration-tool.d.ts +16 -0
- package/dist/src/agent/tools/task-collaboration-tool.js +153 -0
- package/dist/src/agent/tools/task-result-tool.d.ts +2 -0
- package/dist/src/agent/tools/task-result-tool.js +73 -0
- package/dist/src/agent/tools/web.d.ts +16 -2
- package/dist/src/agent/tools/web.js +74 -29
- package/dist/src/agent/tools/xopc-use-tool.js +3 -3
- package/dist/src/automations/capabilities/write.d.ts +4 -4
- package/dist/src/automations/domain/validation.d.ts +8 -8
- package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -2
- package/dist/src/browser/automations/schema.d.ts +2 -2
- package/dist/src/browser/automations/service.d.ts +2 -2
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/schema.d.ts +1 -0
- package/dist/src/config/schema.js +4 -1
- package/dist/src/connectors/connection-recovery-service.d.ts +9 -1
- package/dist/src/connectors/connection-recovery-service.js +213 -33
- package/dist/src/discussions/action-tasks.d.ts +2 -2
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/hono/routes/connection-waits.js +3 -1
- package/dist/src/gateway/hono/routes/projects.js +1 -1
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +16 -0
- package/dist/src/gateway/hono/routes/tasks.js +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +2 -0
- package/dist/src/gateway/service/agent-runner.js +30 -17
- package/dist/src/gateway/service/run-gateway-agent.js +21 -6
- package/dist/src/gateway/service/session-input-coordinator.d.ts +10 -1
- package/dist/src/gateway/service/session-input-coordinator.js +216 -27
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +6 -4
- package/dist/src/gateway/session-context-summary.js +1 -1
- package/dist/src/personal-agent/prompts.js +10 -3
- package/dist/src/personal-agent/reply-composer.d.ts +1 -0
- package/dist/src/personal-agent/reply-composer.js +91 -19
- package/dist/src/personal-agent/reply-style.d.ts +1 -1
- package/dist/src/personal-agent/reply-style.js +1 -0
- package/dist/src/personal-agent/repository.d.ts +1 -1
- package/dist/src/personal-agent/repository.js +1 -1
- package/dist/src/personal-agent/request-access.d.ts +3 -0
- package/dist/src/personal-agent/request-access.js +31 -0
- package/dist/src/personal-agent/request-delivery.js +9 -4
- package/dist/src/personal-agent/request-repository.d.ts +3 -0
- package/dist/src/personal-agent/request-service.d.ts +6 -0
- package/dist/src/personal-agent/request-service.js +121 -25
- package/dist/src/personal-agent/result-file-links.d.ts +3 -0
- package/dist/src/personal-agent/result-file-links.js +21 -0
- package/dist/src/personal-agent/task-cancel.js +85 -35
- package/dist/src/providers/model-response.js +13 -2
- package/dist/src/scenes/taskFollowUp/service.d.ts +15 -5
- package/dist/src/session/session-context-for-llm.js +2 -2
- package/dist/src/session/store.d.ts +3 -1
- package/dist/src/session/store.js +30 -7
- package/dist/src/storage/sqlite/connection-wait-repository.d.ts +7 -2
- package/dist/src/storage/sqlite/connection-wait-repository.js +124 -20
- package/dist/src/storage/sqlite/index.d.ts +1 -0
- package/dist/src/storage/sqlite/index.js +3 -1
- package/dist/src/storage/sqlite/migrations/250_research_checkpoints.sql +15 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/research-checkpoint-repository.d.ts +24 -0
- package/dist/src/storage/sqlite/research-checkpoint-repository.js +91 -0
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/session-creation-repository.js +3 -2
- package/dist/src/storage/sqlite/session-input-repository.d.ts +16 -0
- package/dist/src/storage/sqlite/session-input-repository.js +41 -7
- package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -0
- package/dist/src/storage/sqlite/transcript-repository.js +25 -1
- package/dist/src/tasks/capabilities/management.d.ts +2 -2
- package/dist/src/tasks/capabilities/relations.d.ts +7 -7
- package/dist/src/tasks/capabilities/write.d.ts +2 -2
- package/dist/src/tasks/index.js +1 -1
- package/dist/src/tasks/task-allocation-service.d.ts +2 -0
- package/dist/src/tasks/task-allocation-service.js +43 -2
- package/dist/src/tasks/task-application-service.js +3 -3
- package/dist/src/tasks/task-collaboration-delivery.js +4 -1
- package/dist/src/tasks/task-collaboration-repository.d.ts +3 -0
- package/dist/src/tasks/task-collaboration-repository.js +11 -1
- package/dist/src/tasks/task-context-assembler.js +19 -6
- package/dist/src/tasks/task-continuation.d.ts +6 -0
- package/dist/src/tasks/task-continuation.js +33 -0
- package/dist/src/tasks/task-contract-planner.d.ts +1 -0
- package/dist/src/tasks/task-contract-planner.js +22 -15
- package/dist/src/tasks/task-main-update-delivery.js +13 -8
- package/dist/src/tasks/task-model-call.d.ts +7 -0
- package/dist/src/tasks/task-model-call.js +35 -0
- package/dist/src/tasks/task-read-model-projector.js +1 -1
- package/dist/src/tasks/task-research-repair.d.ts +19 -0
- package/dist/src/tasks/task-research-repair.js +75 -0
- package/dist/src/tasks/task-research-result.d.ts +85 -0
- package/dist/src/tasks/task-research-result.js +394 -0
- package/dist/src/tasks/task-result-delivery-repository.js +13 -2
- package/dist/src/tasks/task-result-delivery-service.js +1 -1
- package/dist/src/tasks/task-run-coordinator.d.ts +1 -0
- package/dist/src/tasks/task-run-coordinator.js +80 -11
- package/dist/src/tasks/task-run-dispatcher.js +12 -0
- package/dist/src/tasks/task-run-repository.d.ts +13 -0
- package/dist/src/tasks/task-run-repository.js +120 -2
- package/package.json +7 -3
- package/dist/gateway/static/root/assets/constants-Dy8Gw0sF.js +0 -1
- package/dist/gateway/static/root/assets/index-yseLAt9D.css +0 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-C4VzqE9z.js +0 -1
- package/dist/gateway/static/root/assets/session-manager-_yy4bxhT.js +0 -16
- package/dist/gateway/static/root/assets/settings-advanced-gate-O_0Lk38S.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-88EShcbs.js +0 -2
- package/dist/gateway/static/root/assets/task-expandable-content-CF6Bj-Qa.js +0 -1
|
@@ -14,6 +14,8 @@ import type { AgentSourceContext, TurnContextRef } from '../../agent/source-cont
|
|
|
14
14
|
import { SessionInputCoordinator, type ReplaceLatestTurnInput, type SubmitSessionInput } from './session-input-coordinator.js';
|
|
15
15
|
export interface GatewayAgentRunnerOptions {
|
|
16
16
|
validateConnectionResume?: (input: import('../../storage/sqlite/session-input-repository.js').SessionInput) => Promise<boolean>;
|
|
17
|
+
continueConnection?: (wait: import('@xopcai/gateway-contract').ConnectionWait, idempotencyKey: string) => Promise<void>;
|
|
18
|
+
cancelConnection?: (wait: import('@xopcai/gateway-contract').ConnectionWait) => void;
|
|
17
19
|
bus: MessageBus;
|
|
18
20
|
sessionIndex: SessionIndex;
|
|
19
21
|
/** Resolved lazily — the runner is constructed before AgentService exists. */
|
|
@@ -6,9 +6,11 @@ import { TaskRepository, init_task_repository } from "../../tasks/task-repositor
|
|
|
6
6
|
import { createClarificationWait, getClarification, getClarificationSnapshot, init_clarification_wait_repository, resolveClarification, supersedeActiveClarification } from "../../storage/sqlite/clarification-wait-repository.js";
|
|
7
7
|
import { init_connection_wait_repository, onConnectionWaitChanged } from "../../storage/sqlite/connection-wait-repository.js";
|
|
8
8
|
import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
9
|
+
import { AgentRunCancelledError } from "../../agent/orchestration/run-termination.js";
|
|
9
10
|
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
10
11
|
import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
|
|
11
12
|
import { TaskCollaborationRepository } from "../../tasks/task-collaboration-repository.js";
|
|
13
|
+
import { reserveEmbeddedRunCancellation } from "../../agent/embedded/runs.js";
|
|
12
14
|
import { TaskApplicationService } from "../../tasks/task-application-service.js";
|
|
13
15
|
import { EphemeralClarificationWaiter } from "../ephemeral-clarification-waiter.js";
|
|
14
16
|
import { describeActiveExecution } from "./active-execution.js";
|
|
@@ -65,10 +67,12 @@ var GatewayAgentRunner = class {
|
|
|
65
67
|
});
|
|
66
68
|
this.inputs = new SessionInputCoordinator({
|
|
67
69
|
beforeExecute: opts.validateConnectionResume,
|
|
70
|
+
continueConnection: opts.continueConnection,
|
|
71
|
+
cancelConnection: opts.cancelConnection,
|
|
68
72
|
prioritizeInput: (input) => (input.origin.type !== "system" || input.origin.source === "cli") && isPersonalConversation(input.conversationId),
|
|
69
|
-
interrupt: async (conversationId, runId) => {
|
|
73
|
+
interrupt: async (conversationId, runId, reason) => {
|
|
70
74
|
const execution = this.activeExecutionBySession.get(conversationId);
|
|
71
|
-
if (execution && execution.kind !== "chat") return;
|
|
75
|
+
if (reason !== "connection_cancel" && execution && execution.kind !== "chat") return;
|
|
72
76
|
await this.abortAgentRun(runId);
|
|
73
77
|
},
|
|
74
78
|
sessionExists: async (conversationId) => Boolean(await opts.sessionIndex.getSessionMetadata(conversationId)),
|
|
@@ -187,29 +191,38 @@ var GatewayAgentRunner = class {
|
|
|
187
191
|
}
|
|
188
192
|
async *runAgent(message, channel, chatId, origin, attachments, thinking, runOptions) {
|
|
189
193
|
const trackedRunId = runOptions?.runId;
|
|
194
|
+
const cancellation = channel === "webchat" && trackedRunId ? reserveEmbeddedRunCancellation({
|
|
195
|
+
conversationId: chatId,
|
|
196
|
+
runId: trackedRunId
|
|
197
|
+
}) : void 0;
|
|
190
198
|
if (trackedRunId) {
|
|
199
|
+
if (channel === "webchat" && !this.runAbortControllers.has(trackedRunId)) this.runAbortControllers.set(trackedRunId, new AbortController());
|
|
191
200
|
let resolve = () => {};
|
|
192
201
|
this.runCompletions.set(trackedRunId, new Promise((done) => {
|
|
193
202
|
resolve = done;
|
|
194
203
|
}));
|
|
195
204
|
this.resolveRunCompletions.set(trackedRunId, resolve);
|
|
196
205
|
}
|
|
197
|
-
const iter = runGatewayAgent({
|
|
198
|
-
config: this.opts.getConfig(),
|
|
199
|
-
agentService: this.opts.getAgentService(),
|
|
200
|
-
bus: this.opts.bus,
|
|
201
|
-
runAbortControllers: this.runAbortControllers,
|
|
202
|
-
activeWebchatRunBySession: this.activeWebchatRunBySession,
|
|
203
|
-
activeExecutionBySession: this.activeExecutionBySession,
|
|
204
|
-
sessionIndex: this.opts.sessionIndex,
|
|
205
|
-
emit: this.opts.emit,
|
|
206
|
-
publishRealtime: this.opts.publishRealtime,
|
|
207
|
-
completeRealtimeTopic: this.opts.completeRealtimeTopic
|
|
208
|
-
}, message, channel, chatId, origin, attachments, thinking, runOptions);
|
|
209
206
|
try {
|
|
210
|
-
return yield*
|
|
207
|
+
return yield* runGatewayAgent({
|
|
208
|
+
config: this.opts.getConfig(),
|
|
209
|
+
agentService: this.opts.getAgentService(),
|
|
210
|
+
bus: this.opts.bus,
|
|
211
|
+
runAbortControllers: this.runAbortControllers,
|
|
212
|
+
activeWebchatRunBySession: this.activeWebchatRunBySession,
|
|
213
|
+
activeExecutionBySession: this.activeExecutionBySession,
|
|
214
|
+
sessionIndex: this.opts.sessionIndex,
|
|
215
|
+
emit: this.opts.emit,
|
|
216
|
+
publishRealtime: this.opts.publishRealtime,
|
|
217
|
+
completeRealtimeTopic: this.opts.completeRealtimeTopic
|
|
218
|
+
}, message, channel, chatId, origin, attachments, thinking, cancellation ? {
|
|
219
|
+
...runOptions,
|
|
220
|
+
signal: runOptions?.signal ? AbortSignal.any([runOptions.signal, cancellation.signal]) : cancellation.signal
|
|
221
|
+
} : runOptions);
|
|
211
222
|
} finally {
|
|
223
|
+
cancellation?.release();
|
|
212
224
|
if (trackedRunId) {
|
|
225
|
+
this.runAbortControllers.delete(trackedRunId);
|
|
213
226
|
this.resolveRunCompletions.get(trackedRunId)?.();
|
|
214
227
|
this.resolveRunCompletions.delete(trackedRunId);
|
|
215
228
|
this.runCompletions.delete(trackedRunId);
|
|
@@ -258,9 +271,9 @@ var GatewayAgentRunner = class {
|
|
|
258
271
|
data: { runId }
|
|
259
272
|
}).catch(() => {});
|
|
260
273
|
}
|
|
261
|
-
c.abort();
|
|
274
|
+
c.abort(new AgentRunCancelledError());
|
|
262
275
|
const { abortEmbeddedRun } = await import("../../agent/embedded/runs.js");
|
|
263
|
-
await Promise.all(keysToMark.map((conversationId) => abortEmbeddedRun(conversationId).catch(() => false)));
|
|
276
|
+
await Promise.all(keysToMark.map((conversationId) => abortEmbeddedRun(conversationId, "user_cancelled", runId).catch(() => false)));
|
|
264
277
|
await completion;
|
|
265
278
|
return {
|
|
266
279
|
aborted: true,
|
|
@@ -4,12 +4,14 @@ import { init_logger } from "../../utils/logger.js";
|
|
|
4
4
|
import { parseTurnOutcome } from "../../../packages/gateway-contract/src/turn-outcome.js";
|
|
5
5
|
import { init_src } from "../../../packages/gateway-contract/src/index.js";
|
|
6
6
|
import { init_session_input_repository, listTaskUpdateTriggers } from "../../storage/sqlite/session-input-repository.js";
|
|
7
|
+
import { TaskRunRepository, init_task_run_repository } from "../../tasks/task-run-repository.js";
|
|
7
8
|
import { init_clarification_wait_repository, isClarificationSuspended } from "../../storage/sqlite/clarification-wait-repository.js";
|
|
8
9
|
import { updateInteractionStateFromMessage } from "../../storage/sqlite/interaction-state-repository.js";
|
|
9
10
|
import { getConnectionResumeInput, init_connection_wait_repository, isConnectionSuspended } from "../../storage/sqlite/connection-wait-repository.js";
|
|
10
11
|
import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
11
12
|
import { getConversationRouting } from "../../storage/sqlite/conversation-repository.js";
|
|
12
13
|
import { init_session_key } from "../../routing/session-key.js";
|
|
14
|
+
import { resolveAgentTurnTimeoutMs } from "../../agent/orchestration/run-agent-turn-with-timeout.js";
|
|
13
15
|
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
14
16
|
import { resolveExecutionContext } from "../../tasks/execution-context.js";
|
|
15
17
|
import { TaskRunCoordinator } from "../../tasks/task-run-coordinator.js";
|
|
@@ -29,6 +31,7 @@ init_clarification_wait_repository();
|
|
|
29
31
|
init_src();
|
|
30
32
|
init_logger();
|
|
31
33
|
init_session_key();
|
|
34
|
+
init_task_run_repository();
|
|
32
35
|
init_sqlite();
|
|
33
36
|
init_session_input_repository();
|
|
34
37
|
const log = createLogger("Gateway:Service");
|
|
@@ -64,7 +67,15 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
64
67
|
if (!meta) throw new Error("Session not found; submit a start input command first");
|
|
65
68
|
webchatTranscriptId = meta?.transcriptId;
|
|
66
69
|
webchatMetadata = meta;
|
|
67
|
-
runAbortControllers.set(runId, new AbortController());
|
|
70
|
+
if (!runAbortControllers.has(runId)) runAbortControllers.set(runId, new AbortController());
|
|
71
|
+
if (runAbortControllers.get(runId).signal.aborted || runOptions?.signal?.aborted || runOptions?.taskRunId && new TaskRunRepository().get(runOptions.taskRunId)?.status === "cancelled") {
|
|
72
|
+
runAbortControllers.delete(runId);
|
|
73
|
+
completeRealtimeTopic(`run:${runId}`);
|
|
74
|
+
return {
|
|
75
|
+
status: "aborted",
|
|
76
|
+
summary: "Interrupted before startup"
|
|
77
|
+
};
|
|
78
|
+
}
|
|
68
79
|
}
|
|
69
80
|
const streamConversationId = webchatConversationId ?? chatId;
|
|
70
81
|
if (webchatConversationId) {
|
|
@@ -89,7 +100,8 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
89
100
|
taskRun = TaskRunCoordinator.start({
|
|
90
101
|
runId: runOptions?.taskRunId ?? runId,
|
|
91
102
|
context: executionContext,
|
|
92
|
-
fallbackObjective: message
|
|
103
|
+
fallbackObjective: message,
|
|
104
|
+
timeoutMs: executionContext.taskId ? resolveAgentTurnTimeoutMs(deps.config, webchatConversationId) : void 0
|
|
93
105
|
});
|
|
94
106
|
}
|
|
95
107
|
const mapper = new ChatStreamMapper({
|
|
@@ -156,6 +168,7 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
156
168
|
const prepared = await agentService.prepareInboundAttachments(conversationId, cappedAttachments);
|
|
157
169
|
const runAbort = runAbortControllers.get(runId);
|
|
158
170
|
if (!runAbort) throw new Error("run abort controller missing for webchat");
|
|
171
|
+
if (runOptions?.taskRunId && new TaskRunRepository().get(runOptions.taskRunId)?.status === "cancelled") runAbort.abort();
|
|
159
172
|
const mergedSignal = runOptions?.signal ? AbortSignal.any([runOptions.signal, runAbort.signal]) : runAbort.signal;
|
|
160
173
|
agentService.beginInboundTurn(conversationId);
|
|
161
174
|
if (!activeWebchatRunBySession.has(conversationId)) {
|
|
@@ -192,6 +205,8 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
192
205
|
});
|
|
193
206
|
const mappedEvents = (async function* () {
|
|
194
207
|
for await (const event of eventStream) {
|
|
208
|
+
if (event.type === "error") streamError ??= String(event.content ?? event.message ?? "Agent run failed");
|
|
209
|
+
if (event.type === "turn_outcome" && parseTurnOutcome(event.outcome)?.status === "failed") streamError = parseTurnOutcome(event.outcome)?.summary ?? streamError ?? "Agent run failed";
|
|
195
210
|
if (event.type === "turn_outcome" && parseTurnOutcome(event.outcome)?.summary === "aborted") embeddedAborted = true;
|
|
196
211
|
yield* mapper.map(event);
|
|
197
212
|
}
|
|
@@ -201,16 +216,16 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
201
216
|
const clarificationSuspended = isClarificationSuspended(conversationId, runId);
|
|
202
217
|
const suspended = connectionSuspended || clarificationSuspended;
|
|
203
218
|
const cancelled = mergedSignal.aborted || embeddedAborted;
|
|
204
|
-
const endStatus = cancelled ? "cancelled" : suspended ? "suspended" : "success";
|
|
205
|
-
const endSummary = cancelled ? "Interrupted" : connectionSuspended ? "Waiting for connection" : clarificationSuspended ? "Waiting for user input" : "Message processed successfully";
|
|
206
|
-
taskRunStatus = cancelled ? "cancelled" : "succeeded";
|
|
219
|
+
const endStatus = cancelled ? "cancelled" : suspended ? "suspended" : streamError ? "error" : "success";
|
|
220
|
+
const endSummary = cancelled ? "Interrupted" : connectionSuspended ? "Waiting for connection" : clarificationSuspended ? "Waiting for user input" : streamError ?? "Message processed successfully";
|
|
221
|
+
taskRunStatus = cancelled ? "cancelled" : streamError ? "failed" : "succeeded";
|
|
207
222
|
terminalStatus = endStatus;
|
|
208
223
|
taskRunSummary = endSummary;
|
|
209
224
|
yield* emitAndYield(mapper.end(endStatus, endSummary));
|
|
210
225
|
completeRealtimeTopic(`run:${runId}`);
|
|
211
226
|
runTopicCompleted = true;
|
|
212
227
|
return {
|
|
213
|
-
status: cancelled ? "aborted" : suspended ? "suspended" : "ok",
|
|
228
|
+
status: cancelled ? "aborted" : suspended ? "suspended" : streamError ? "error" : "ok",
|
|
214
229
|
summary: endSummary
|
|
215
230
|
};
|
|
216
231
|
} catch (error) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TurnOrigin } from '@xopcai/endpoint-tools-protocol';
|
|
2
|
+
import type { ConnectionWait } from '@xopcai/gateway-contract';
|
|
2
3
|
import { type SessionInput } from '../../storage/sqlite/session-input-repository.js';
|
|
3
4
|
import type { UserTurnAttachment } from '../user-turn-input.js';
|
|
4
5
|
import { type AgentSourceContext, type TurnContextRef } from '../../agent/source-context/types.js';
|
|
@@ -26,12 +27,15 @@ export declare class SessionInputCoordinator {
|
|
|
26
27
|
private readonly resumeAfter;
|
|
27
28
|
private readonly draining;
|
|
28
29
|
private readonly submissionTails;
|
|
30
|
+
private readonly pendingConnectionStops;
|
|
29
31
|
constructor(deps: {
|
|
30
32
|
prioritizeInput?: (input: SubmitSessionInput) => boolean;
|
|
31
|
-
interrupt?: (conversationId: string, runId: string) => Promise<void>;
|
|
33
|
+
interrupt?: (conversationId: string, runId: string, reason?: 'connection_cancel') => Promise<void>;
|
|
32
34
|
coalesceWindowMs?: number;
|
|
33
35
|
onInputReceived?: (conversationId: string) => void;
|
|
34
36
|
beforeExecute?: (input: SessionInput) => Promise<boolean>;
|
|
37
|
+
continueConnection?: (wait: ConnectionWait, idempotencyKey: string) => Promise<void>;
|
|
38
|
+
cancelConnection?: (wait: ConnectionWait) => void;
|
|
35
39
|
sessionExists: (conversationId: string) => Promise<boolean>;
|
|
36
40
|
execute: (input: {
|
|
37
41
|
inputReceivedAtMs?: number;
|
|
@@ -54,7 +58,9 @@ export declare class SessionInputCoordinator {
|
|
|
54
58
|
});
|
|
55
59
|
isAcceptingInput(conversationId: string): boolean;
|
|
56
60
|
snapshot(conversationId: string): SessionInputState;
|
|
61
|
+
private connectionTarget;
|
|
57
62
|
prepareInput(input: SubmitSessionInput): Promise<{
|
|
63
|
+
payload?: import("../../storage/sqlite/session-input-repository.js").SessionInputPayload;
|
|
58
64
|
status: "queued";
|
|
59
65
|
requestedDelivery: SessionInputDelivery;
|
|
60
66
|
effectiveDelivery: "next";
|
|
@@ -98,6 +104,9 @@ export declare class SessionInputCoordinator {
|
|
|
98
104
|
}>;
|
|
99
105
|
private submitLocked;
|
|
100
106
|
drain(conversationId: string): Promise<void>;
|
|
107
|
+
private requestConnectionStop;
|
|
108
|
+
private completeConnectionCancellation;
|
|
109
|
+
private executeConnectionControl;
|
|
101
110
|
update(conversationId: string, id: string, body: {
|
|
102
111
|
version: number;
|
|
103
112
|
content?: string;
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
4
|
+
import { init_session_instance_repository, readCurrentTranscriptId } from "../../storage/sqlite/session-instance-repository.js";
|
|
3
5
|
import { SessionInstanceChangedError, cancelQueuedSessionInput, claimNextSessionInput, findSessionInput, findSessionInputByRunId, finishSessionInputRun, getSessionInputById, getSessionInputState, init_session_input_repository, insertSessionInput, mutateQueuedSessionInput, recoverSessionInputState, setSessionInputStatus } from "../../storage/sqlite/session-input-repository.js";
|
|
4
|
-
import {
|
|
6
|
+
import { TaskRunRepository, init_task_run_repository } from "../../tasks/task-run-repository.js";
|
|
7
|
+
import { consumeClarificationResume, getActiveClarification, init_clarification_wait_repository, supersedeActiveClarification } from "../../storage/sqlite/clarification-wait-repository.js";
|
|
5
8
|
import { replaceLatestSessionTurnAndQueueInput, validateLatestSessionTurnTarget } from "../../storage/sqlite/session-turn-replace-repository.js";
|
|
6
|
-
import { cancelConnectionObjective, consumeConnectionResume, init_connection_wait_repository,
|
|
9
|
+
import { cancelConnectionObjective, consumeConnectionResume, getActiveConnectionWait, getConnectionWait, hasPendingConnectionMessages, init_connection_wait_repository, interruptedConnectionMessage, publishConnectionWait, reconcileConnectionWaits } from "../../storage/sqlite/connection-wait-repository.js";
|
|
10
|
+
import { appendTranscriptEntry, init_transcript_repository } from "../../storage/sqlite/transcript-repository.js";
|
|
7
11
|
import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
12
|
+
import { emitSessionTranscriptUpdate } from "../../session/transcript-events.js";
|
|
13
|
+
import { TaskApplicationService } from "../../tasks/task-application-service.js";
|
|
8
14
|
import { summarizeSourceContext } from "../../agent/source-context/types.js";
|
|
9
15
|
import { injectSourceContextsIntoUserMessage } from "../../agent/source-context/injector.js";
|
|
10
16
|
import { deleteMediaUrisNoLongerReferenced } from "../../media/session-references.js";
|
|
@@ -14,11 +20,37 @@ import { isDeepStrictEqual } from "node:util";
|
|
|
14
20
|
//#region src/gateway/service/session-input-coordinator.ts
|
|
15
21
|
init_session_input_repository();
|
|
16
22
|
init_connection_wait_repository();
|
|
23
|
+
init_transaction();
|
|
24
|
+
init_transcript_repository();
|
|
25
|
+
init_session_instance_repository();
|
|
17
26
|
init_clarification_wait_repository();
|
|
18
27
|
init_sqlite();
|
|
19
28
|
init_logger();
|
|
29
|
+
init_task_run_repository();
|
|
20
30
|
const log = createLogger("SessionInputCoordinator");
|
|
21
31
|
const MAX_PENDING_INPUTS = 10;
|
|
32
|
+
function connectionControl(input, wait) {
|
|
33
|
+
if (input.attachments?.length || input.contextRefs?.length || input.sourceContexts?.some((source) => source.kind !== "device_context") || input.origin.type === "system" && input.origin.source !== "cli") return void 0;
|
|
34
|
+
const text = input.content.trim().toLowerCase().replace(/[。.!!??]+$/u, "").trim();
|
|
35
|
+
if (/^(?:继续|继续看下|继续看看|继续这个目标|继续原目标|continue|resume)$/u.test(text)) {
|
|
36
|
+
if (text !== "继续原目标" && (hasPendingConnectionMessages(wait) || getActiveClarification(wait.conversationId))) return void 0;
|
|
37
|
+
return "continue";
|
|
38
|
+
}
|
|
39
|
+
if (/^(?:取消这个目标|取消原目标|取消当前目标|cancel this objective|cancel the original objective)$/u.test(text)) return "cancel";
|
|
40
|
+
}
|
|
41
|
+
function connectionInputPayload(wait, control) {
|
|
42
|
+
if (!wait) return void 0;
|
|
43
|
+
if (control) return {
|
|
44
|
+
waitId: wait.id,
|
|
45
|
+
objectiveRevision: wait.objectiveRevision,
|
|
46
|
+
connectionAction: control
|
|
47
|
+
};
|
|
48
|
+
if (wait.status !== "closed") return {
|
|
49
|
+
waitId: wait.id,
|
|
50
|
+
objectiveRevision: wait.objectiveRevision,
|
|
51
|
+
connectionBarrier: true
|
|
52
|
+
};
|
|
53
|
+
}
|
|
22
54
|
function sameAppContext(input, existing) {
|
|
23
55
|
const identity = (sources) => sources?.filter((source) => source.kind === "app_context").map((source) => ({
|
|
24
56
|
snapshot: source.appContext,
|
|
@@ -52,6 +84,7 @@ var SessionInputCoordinator = class {
|
|
|
52
84
|
resumeAfter = /* @__PURE__ */ new Map();
|
|
53
85
|
draining = /* @__PURE__ */ new Set();
|
|
54
86
|
submissionTails = /* @__PURE__ */ new Map();
|
|
87
|
+
pendingConnectionStops = /* @__PURE__ */ new Set();
|
|
55
88
|
constructor(deps) {
|
|
56
89
|
this.deps = deps;
|
|
57
90
|
}
|
|
@@ -61,9 +94,15 @@ var SessionInputCoordinator = class {
|
|
|
61
94
|
snapshot(conversationId) {
|
|
62
95
|
return getSessionInputState(conversationId);
|
|
63
96
|
}
|
|
97
|
+
connectionTarget(conversationId, runtime = this.snapshot(conversationId)) {
|
|
98
|
+
const active = runtime.activeInputId ? getSessionInputById(conversationId, runtime.activeInputId) : void 0;
|
|
99
|
+
return getActiveConnectionWait(conversationId) ?? (active?.kind === "connection_resume" && active.payload ? getConnectionWait(active.payload.waitId) : void 0);
|
|
100
|
+
}
|
|
64
101
|
async prepareInput(input) {
|
|
65
102
|
const attachments = await this.deps.prepareAttachments(input.conversationId, input.attachments);
|
|
66
103
|
const contexts = fitSourceContextsToBudget([...await this.deps.prepareContexts(input.conversationId, input.contextRefs) ?? [], ...input.sourceContexts ?? []]);
|
|
104
|
+
const wait = this.connectionTarget(input.conversationId);
|
|
105
|
+
const payload = connectionInputPayload(wait, wait?.principalId === "local-owner" ? connectionControl(input, wait) : void 0);
|
|
67
106
|
return {
|
|
68
107
|
status: "queued",
|
|
69
108
|
requestedDelivery: input.delivery,
|
|
@@ -71,10 +110,11 @@ var SessionInputCoordinator = class {
|
|
|
71
110
|
content: input.content.trim(),
|
|
72
111
|
attachments,
|
|
73
112
|
contextRefs: contexts.map(summarizeSourceContext),
|
|
74
|
-
interruptRequested: input.interrupt !== false && this.deps.prioritizeInput?.(input) === true,
|
|
113
|
+
interruptRequested: !wait && input.interrupt !== false && this.deps.prioritizeInput?.(input) === true,
|
|
75
114
|
contextSnapshots: contexts,
|
|
76
115
|
thinking: input.thinking,
|
|
77
|
-
origin: input.origin
|
|
116
|
+
origin: input.origin,
|
|
117
|
+
...payload ? { payload } : {}
|
|
78
118
|
};
|
|
79
119
|
}
|
|
80
120
|
async dispatchAcceptedInput(conversationId, inputId) {
|
|
@@ -84,6 +124,11 @@ var SessionInputCoordinator = class {
|
|
|
84
124
|
const row = getSessionInputById(conversationId, inputId);
|
|
85
125
|
const state = this.snapshot(input.conversationId);
|
|
86
126
|
if (!row || row.status !== "queued") return;
|
|
127
|
+
if (row.payload?.connectionAction === "cancel") this.completeConnectionCancellation(row);
|
|
128
|
+
if (row.payload?.connectionAction || this.connectionTarget(row.conversationId, state)) {
|
|
129
|
+
this.requestConnectionStop(row);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
87
132
|
if (row.interruptRequested) {
|
|
88
133
|
this.prioritizeAcceptedInput(row, state);
|
|
89
134
|
return;
|
|
@@ -158,6 +203,7 @@ var SessionInputCoordinator = class {
|
|
|
158
203
|
const remaining = (this.pendingSubmissions.get(conversationId) ?? 1) - 1;
|
|
159
204
|
if (remaining) this.pendingSubmissions.set(conversationId, remaining);
|
|
160
205
|
else this.pendingSubmissions.delete(conversationId);
|
|
206
|
+
this.drain(conversationId);
|
|
161
207
|
}
|
|
162
208
|
}
|
|
163
209
|
async submit(input) {
|
|
@@ -303,27 +349,36 @@ var SessionInputCoordinator = class {
|
|
|
303
349
|
};
|
|
304
350
|
}
|
|
305
351
|
const runtime = this.snapshot(conversationId);
|
|
306
|
-
const
|
|
307
|
-
const
|
|
352
|
+
const wait = this.connectionTarget(conversationId, runtime);
|
|
353
|
+
const control = wait?.principalId === "local-owner" ? connectionControl(input, wait) : void 0;
|
|
354
|
+
const payload = connectionInputPayload(wait, control);
|
|
355
|
+
const priority = !wait && input.interrupt !== false && this.deps.prioritizeInput?.(input) === true;
|
|
356
|
+
const canSteer = !wait && !priority && input.delivery === "steer" && runtime.activeRunId !== void 0 && !attachments?.length && canSteerContexts(runtime, input.origin, sourceContexts);
|
|
308
357
|
const effectiveDelivery = canSteer ? "steer" : "next";
|
|
309
|
-
const row =
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
358
|
+
const row = runSqliteWriteTransaction(() => {
|
|
359
|
+
const row = insertSessionInput({
|
|
360
|
+
expectedTranscriptId: input.expectedTranscriptId ?? (payload ? wait?.transcriptId : void 0),
|
|
361
|
+
id: crypto.randomUUID(),
|
|
362
|
+
conversationId,
|
|
363
|
+
clientMessageId,
|
|
364
|
+
requestedDelivery: input.delivery,
|
|
365
|
+
interruptRequested: priority,
|
|
366
|
+
effectiveDelivery,
|
|
367
|
+
status: canSteer ? "injecting" : "queued",
|
|
368
|
+
content,
|
|
369
|
+
attachments,
|
|
370
|
+
contextRefs: sourceContexts?.map(summarizeSourceContext),
|
|
371
|
+
contextSnapshots: sourceContexts,
|
|
372
|
+
thinking: input.thinking,
|
|
373
|
+
origin: input.origin,
|
|
374
|
+
targetRunId: canSteer ? runtime.activeRunId : void 0,
|
|
375
|
+
...payload ? { payload } : {}
|
|
376
|
+
});
|
|
377
|
+
if (control === "cancel") cancelConnectionObjective(conversationId, wait?.id, wait?.objectiveRevision);
|
|
378
|
+
return row;
|
|
325
379
|
});
|
|
326
|
-
|
|
380
|
+
if (control === "cancel") this.completeConnectionCancellation(row);
|
|
381
|
+
this.requestConnectionStop(row);
|
|
327
382
|
supersedeActiveClarification(conversationId);
|
|
328
383
|
if (priority) {
|
|
329
384
|
this.prioritizeAcceptedInput(row, runtime);
|
|
@@ -364,6 +419,7 @@ var SessionInputCoordinator = class {
|
|
|
364
419
|
this.draining.add(conversationId);
|
|
365
420
|
try {
|
|
366
421
|
while (true) {
|
|
422
|
+
if (this.isAcceptingInput(conversationId)) return;
|
|
367
423
|
const delay = (this.resumeAfter.get(conversationId) ?? 0) - Date.now();
|
|
368
424
|
if (delay > 0) {
|
|
369
425
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
@@ -375,7 +431,15 @@ var SessionInputCoordinator = class {
|
|
|
375
431
|
if (!input) return;
|
|
376
432
|
let allowed;
|
|
377
433
|
try {
|
|
378
|
-
allowed =
|
|
434
|
+
allowed = !this.deps.beforeExecute || await this.deps.beforeExecute(input);
|
|
435
|
+
const wait = input.kind === "connection_resume" && input.payload ? getConnectionWait(input.payload.waitId) : void 0;
|
|
436
|
+
if (allowed && wait?.status === "queued" && wait.queuedInputId === input.id && (this.isAcceptingInput(conversationId) || hasPendingConnectionMessages(wait, true))) {
|
|
437
|
+
finishSessionInputRun(conversationId, runId, "interrupted");
|
|
438
|
+
setSessionInputStatus(input.id, "queued");
|
|
439
|
+
this.publish(conversationId);
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
allowed = allowed && consumeConnectionResume(input) && consumeClarificationResume(input);
|
|
379
443
|
} catch (err) {
|
|
380
444
|
log.warn({
|
|
381
445
|
err,
|
|
@@ -384,6 +448,7 @@ var SessionInputCoordinator = class {
|
|
|
384
448
|
inputId: input.id
|
|
385
449
|
}, "Session input preflight failed");
|
|
386
450
|
finishSessionInputRun(conversationId, runId, "failed", "Input preflight failed");
|
|
451
|
+
if (input.kind === "connection_resume") reconcileConnectionWaits();
|
|
387
452
|
this.publish(conversationId);
|
|
388
453
|
continue;
|
|
389
454
|
}
|
|
@@ -396,7 +461,7 @@ var SessionInputCoordinator = class {
|
|
|
396
461
|
this.publish(conversationId);
|
|
397
462
|
let result;
|
|
398
463
|
try {
|
|
399
|
-
result = await this.deps.execute({
|
|
464
|
+
result = input.payload?.connectionAction ? await this.executeConnectionControl(input) : await this.deps.execute({
|
|
400
465
|
inputReceivedAtMs: input.createdAtMs,
|
|
401
466
|
runId,
|
|
402
467
|
taskRunId: input.taskRunId,
|
|
@@ -419,7 +484,37 @@ var SessionInputCoordinator = class {
|
|
|
419
484
|
inputId: input.id
|
|
420
485
|
}, "Session input execution failed");
|
|
421
486
|
}
|
|
422
|
-
const
|
|
487
|
+
const cancelledWait = input.kind === "connection_resume" && input.payload ? getConnectionWait(input.payload.waitId) : void 0;
|
|
488
|
+
const cancelled = cancelledWait?.resolution === "cancelled" && cancelledWait.objectiveRevision === input.payload?.objectiveRevision;
|
|
489
|
+
if (cancelled && input.taskRunId) {
|
|
490
|
+
const run = new TaskRunRepository().get(input.taskRunId);
|
|
491
|
+
if (run && [
|
|
492
|
+
"queued",
|
|
493
|
+
"running",
|
|
494
|
+
"waiting",
|
|
495
|
+
"verifying"
|
|
496
|
+
].includes(run.status)) new TaskApplicationService().completeRun({
|
|
497
|
+
runId: run.id,
|
|
498
|
+
expectedRunVersion: run.version,
|
|
499
|
+
actor: { kind: "user" },
|
|
500
|
+
terminalCode: "cancelled_by_user",
|
|
501
|
+
suppressAttention: true,
|
|
502
|
+
receipt: {
|
|
503
|
+
status: "cancelled",
|
|
504
|
+
summary: "Connection objective cancelled",
|
|
505
|
+
changes: [],
|
|
506
|
+
evidence: [],
|
|
507
|
+
verification: {
|
|
508
|
+
status: "unverified",
|
|
509
|
+
checks: []
|
|
510
|
+
},
|
|
511
|
+
remainingWork: [],
|
|
512
|
+
needsUser: false,
|
|
513
|
+
completionVerdict: "not_achieved"
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
const terminal = cancelled ? "cancelled" : result.status === "suspended" ? "suspended" : result.status === "ok" ? "completed" : result.status === "aborted" ? "cancelled" : "failed";
|
|
423
518
|
finishSessionInputRun(conversationId, runId, terminal, terminal === "failed" ? result.summary : void 0);
|
|
424
519
|
this.publish(conversationId);
|
|
425
520
|
}
|
|
@@ -427,6 +522,94 @@ var SessionInputCoordinator = class {
|
|
|
427
522
|
this.draining.delete(conversationId);
|
|
428
523
|
}
|
|
429
524
|
}
|
|
525
|
+
requestConnectionStop(input) {
|
|
526
|
+
const target = input.payload;
|
|
527
|
+
if (target?.connectionAction !== "cancel" || !this.deps.interrupt) return;
|
|
528
|
+
const wait = getConnectionWait(target.waitId);
|
|
529
|
+
if (!wait || wait.resolution !== "cancelled" || wait.objectiveRevision !== target.objectiveRevision || wait.transcriptId !== input.expectedTranscriptId) return;
|
|
530
|
+
const runtime = this.snapshot(input.conversationId);
|
|
531
|
+
const active = runtime.activeInputId ? getSessionInputById(input.conversationId, runtime.activeInputId) : void 0;
|
|
532
|
+
if (!runtime.activeRunId || active?.kind !== "connection_resume" || !active.payload) return;
|
|
533
|
+
const sameVersion = active.payload.waitId === target.waitId && active.payload.objectiveRevision === target.objectiveRevision;
|
|
534
|
+
const parent = getConnectionWait(active.payload.waitId);
|
|
535
|
+
const sameExecution = wait.originInputId === active.id && parent?.objectiveId === wait.objectiveId;
|
|
536
|
+
if (!sameVersion && !sameExecution || this.pendingConnectionStops.has(runtime.activeRunId)) return;
|
|
537
|
+
const runId = runtime.activeRunId;
|
|
538
|
+
this.pendingConnectionStops.add(runId);
|
|
539
|
+
this.deps.emit("session.input-interrupt", {
|
|
540
|
+
conversationId: input.conversationId,
|
|
541
|
+
runId,
|
|
542
|
+
inputId: input.id
|
|
543
|
+
});
|
|
544
|
+
this.deps.interrupt(input.conversationId, runId, "connection_cancel").catch((err) => {
|
|
545
|
+
log.warn({
|
|
546
|
+
err,
|
|
547
|
+
conversationId: input.conversationId,
|
|
548
|
+
runId
|
|
549
|
+
}, "Connection cancellation saved; execution stop was not confirmed");
|
|
550
|
+
}).finally(() => {
|
|
551
|
+
this.pendingConnectionStops.delete(runId);
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
completeConnectionCancellation(input) {
|
|
555
|
+
const wait = input.payload ? getConnectionWait(input.payload.waitId) : void 0;
|
|
556
|
+
if (wait?.objectiveRevision !== input.payload?.objectiveRevision || wait?.resolution !== "cancelled") return;
|
|
557
|
+
try {
|
|
558
|
+
this.deps.cancelConnection?.(wait);
|
|
559
|
+
} catch (err) {
|
|
560
|
+
log.warn({
|
|
561
|
+
err,
|
|
562
|
+
conversationId: input.conversationId,
|
|
563
|
+
waitId: wait.id
|
|
564
|
+
}, "Connection cancellation saved; domain cleanup will retry with its control");
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
async executeConnectionControl(input) {
|
|
568
|
+
const target = input.payload;
|
|
569
|
+
if (!target?.connectionAction) throw new Error("Connection control is required");
|
|
570
|
+
let wait = getConnectionWait(target.waitId);
|
|
571
|
+
if (target.connectionAction === "cancel" && wait?.objectiveRevision === target.objectiveRevision) this.deps.cancelConnection?.(wait);
|
|
572
|
+
if (target.connectionAction === "continue" && wait?.objectiveRevision === target.objectiveRevision) try {
|
|
573
|
+
await this.deps.continueConnection?.(wait, `connection-control:${input.id}`);
|
|
574
|
+
} catch (err) {
|
|
575
|
+
log.warn({
|
|
576
|
+
err,
|
|
577
|
+
conversationId: input.conversationId,
|
|
578
|
+
waitId: target.waitId
|
|
579
|
+
}, "Connection control preserved for current status feedback");
|
|
580
|
+
}
|
|
581
|
+
wait = getConnectionWait(target.waitId);
|
|
582
|
+
const zh = /[\u3400-\u9fff]/u.test(input.content);
|
|
583
|
+
const summary = !wait || wait.objectiveRevision !== target.objectiveRevision ? zh ? "原目标已发生变化,请查看当前目标状态。" : "The original objective changed. Check the current objective status." : target.connectionAction === "cancel" ? zh ? "已取消原目标。" : "The original objective was cancelled." : interruptedConnectionMessage(wait) ? zh ? "原目标已保留。请重新发送重启时中断的补充要求,或移除中断的消息后继续。" : "The original objective is saved. Resend the interrupted message or remove it before continuing." : wait.resolution === "cancelled" ? zh ? "原目标已取消。" : "The original objective was cancelled." : wait.status === "closed" ? zh ? "原目标已交给执行流程,无需重复继续。" : "The original objective has already been handed to execution. No additional continuation is needed." : wait.status === "queued" ? zh ? "原目标已准备好,正在等待执行,无需重复继续。" : "The original objective is queued. No additional continuation is needed." : wait.intent ? zh ? "原目标已保留,完成连接和能力检查后会自动继续。" : "The original objective is saved and will continue automatically after connection and capability checks." : zh ? "原目标已保留,请查看连接操作区完成所需操作。" : "The original objective is saved. Complete the required action in the connection panel.";
|
|
584
|
+
const persisted = runSqliteWriteTransaction(() => {
|
|
585
|
+
const runtime = this.snapshot(input.conversationId);
|
|
586
|
+
if (runtime.activeInputId !== input.id || runtime.activeRunId !== input.runId || readCurrentTranscriptId(getSqliteDatabase(), input.conversationId) !== input.expectedTranscriptId) return false;
|
|
587
|
+
appendTranscriptEntry(input.conversationId, {
|
|
588
|
+
role: "user",
|
|
589
|
+
content: input.content,
|
|
590
|
+
timestamp: input.createdAtMs
|
|
591
|
+
});
|
|
592
|
+
appendTranscriptEntry(input.conversationId, {
|
|
593
|
+
role: "custom",
|
|
594
|
+
customType: "connection_control_status",
|
|
595
|
+
content: summary,
|
|
596
|
+
details: {
|
|
597
|
+
inputId: input.id,
|
|
598
|
+
waitId: target.waitId,
|
|
599
|
+
objectiveRevision: target.objectiveRevision
|
|
600
|
+
},
|
|
601
|
+
display: true,
|
|
602
|
+
timestamp: Date.now()
|
|
603
|
+
});
|
|
604
|
+
finishSessionInputRun(input.conversationId, input.runId, "completed");
|
|
605
|
+
return true;
|
|
606
|
+
});
|
|
607
|
+
if (persisted) emitSessionTranscriptUpdate({ conversationId: input.conversationId });
|
|
608
|
+
return {
|
|
609
|
+
status: persisted ? "ok" : "aborted",
|
|
610
|
+
summary: persisted ? summary : ""
|
|
611
|
+
};
|
|
612
|
+
}
|
|
430
613
|
async update(conversationId, id, body) {
|
|
431
614
|
const attachments = body.attachments === void 0 ? void 0 : await this.deps.prepareAttachments(conversationId, body.attachments);
|
|
432
615
|
let sourceContexts;
|
|
@@ -463,6 +646,10 @@ var SessionInputCoordinator = class {
|
|
|
463
646
|
}
|
|
464
647
|
remove(conversationId, id, version) {
|
|
465
648
|
const ok = cancelQueuedSessionInput(conversationId, id, version);
|
|
649
|
+
if (ok) {
|
|
650
|
+
publishConnectionWait(conversationId);
|
|
651
|
+
this.drain(conversationId);
|
|
652
|
+
}
|
|
466
653
|
return {
|
|
467
654
|
ok,
|
|
468
655
|
state: ok ? this.publish(conversationId) : this.snapshot(conversationId)
|
|
@@ -478,7 +665,9 @@ var SessionInputCoordinator = class {
|
|
|
478
665
|
}
|
|
479
666
|
}
|
|
480
667
|
recover() {
|
|
481
|
-
|
|
668
|
+
const interrupted = recoverSessionInputState();
|
|
669
|
+
new TaskRunRepository().reconcileCancelledRuns();
|
|
670
|
+
for (const conversationId of new Set([...interrupted, ...reconcileConnectionWaits(true)])) {
|
|
482
671
|
this.publish(conversationId);
|
|
483
672
|
this.drain(conversationId);
|
|
484
673
|
}
|
|
@@ -155,6 +155,7 @@ export declare class GatewayService {
|
|
|
155
155
|
}>;
|
|
156
156
|
withSessionInputSubmission<T>(conversationId: string, operation: () => Promise<T>): Promise<T>;
|
|
157
157
|
prepareSessionCommandInput(input: Parameters<GatewayAgentRunner['inputs']['prepareInput']>[0]): Promise<{
|
|
158
|
+
payload?: import("../storage/sqlite/session-input-repository.js").SessionInputPayload;
|
|
158
159
|
status: "queued";
|
|
159
160
|
requestedDelivery: import("../storage/sqlite/session-input-repository.js").SessionInputDelivery;
|
|
160
161
|
effectiveDelivery: "next";
|
|
@@ -44,6 +44,7 @@ import { DomainOutboxDispatcher } from "../infra/domain-outbox-dispatcher.js";
|
|
|
44
44
|
import { ProjectService } from "../projects/project-service.js";
|
|
45
45
|
import { resolveProjectAgentId } from "../projects/project-agent.js";
|
|
46
46
|
import "../projects/index.js";
|
|
47
|
+
import { onTaskResultQueued } from "../tasks/task-result-delivery-repository.js";
|
|
47
48
|
import { runMemoryMaintenance } from "../memory-maintenance/service.js";
|
|
48
49
|
import "../memory-maintenance/index.js";
|
|
49
50
|
import { RealtimeExtensionBrowserProvider } from "../browser/providers/realtime-extension.js";
|
|
@@ -52,7 +53,6 @@ import { buildNoteAgentContext } from "../notes/agent-context.js";
|
|
|
52
53
|
import { NotesStore } from "../notes/store.js";
|
|
53
54
|
import { NotesService } from "../notes/service.js";
|
|
54
55
|
import { LocalAppService } from "../local-apps/service.js";
|
|
55
|
-
import { onTaskResultQueued } from "../tasks/task-result-delivery-repository.js";
|
|
56
56
|
import { TaskApplicationService } from "../tasks/task-application-service.js";
|
|
57
57
|
import { AutomationService } from "../automations/service/automation-service.js";
|
|
58
58
|
import { TaskSignalService } from "../tasks/task-signal-service.js";
|
|
@@ -73,12 +73,12 @@ import "../infra/bus/index.js";
|
|
|
73
73
|
import { collectMediaUrisFromMessages, deleteMediaUris } from "../media/session-references.js";
|
|
74
74
|
import { AgentService } from "../agent/service.js";
|
|
75
75
|
import { bootstrapApplicationStateSync } from "../bootstrap/application-state.js";
|
|
76
|
-
import { ChatPreviewService } from "../chat-previews/service.js";
|
|
77
|
-
import "../chat-previews/index.js";
|
|
78
|
-
import "../config/index.js";
|
|
79
76
|
import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
|
|
80
77
|
import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
|
|
81
78
|
import { ChannelManager } from "../channels/manager.js";
|
|
79
|
+
import { ChatPreviewService } from "../chat-previews/service.js";
|
|
80
|
+
import "../chat-previews/index.js";
|
|
81
|
+
import "../config/index.js";
|
|
82
82
|
import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
|
|
83
83
|
import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
|
|
84
84
|
import "../knowledge/index.js";
|
|
@@ -515,6 +515,8 @@ var GatewayService = class {
|
|
|
515
515
|
});
|
|
516
516
|
this.chatPreviews = new ChatPreviewService({ localApps: this.localApps });
|
|
517
517
|
this.agentRunner = new GatewayAgentRunner({
|
|
518
|
+
continueConnection: (wait, idempotencyKey) => this.connectionRecovery.continueObjective(wait, idempotencyKey),
|
|
519
|
+
cancelConnection: (wait) => this.connectionRecovery.cancelObjective(wait),
|
|
518
520
|
validateConnectionResume: async (input) => {
|
|
519
521
|
for (const source of input.contextSnapshots ?? []) if (source.kind === "app_context") await checkAppContextAccess(source, this.appContextDispatcher(), this.auth);
|
|
520
522
|
return this.connectionRecovery.preflight(input);
|