@xopcai/xopc 0.0.385 → 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-Cb9eaXxR.js → agent-avatar-dicebear-D-86VOlb.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-DEV-xtgm.js → agent-defaults-settings-panel-SmeUVHY8.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-DXKc3Luj.js → agent-plugin-dialog-BVT3wXq5.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-DcNxwpJQ.js → agents-D7rLQFhX.js} +3 -3
- package/dist/gateway/static/root/assets/{app-management-settings-panel-X5i0Tz7_.js → app-management-settings-panel-CUR7n5iP.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CmHHzquT.js → appearance-settings-BCotSGep.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-ChFA4Zp0.js → apps-page-hk0bo9LT.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BFqsIqOI.js → automations-page-CqxuUwox.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-Blfak-fT.js → automations-workspace-11_Z69pr.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CpOLG3Co.js → block-editor-eldB84Mj.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-BSbTJ9j2.js → browser-automations-page-D4TaUPYT.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-BUlILJrB.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-CeRdkwRf.js → capabilities-page-CyYlueEd.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-S-cKsGja.js → capabilities-settings-panel-uVEgfvo0.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-header-actions-6w8pQhnn.js → capability-header-actions-BXv0xu56.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-DfNTGBmp.js → channels-fNb3SOzm.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-DnoQHpDc.js → chat-terminal-dock-CnLtparQ.js} +1 -1
- package/dist/gateway/static/root/assets/{computer-settings-page-7yliE7sG.js → computer-settings-page-xM0AnOlP.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-DOLAUFSW.js → connector-service-page-CdG2WUb6.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-DAsn97XG.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-DNDqr4Fk.js → date-picker-DIBbE-O8.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-B5oG7RgE.js → dependency-picker-DDD8zokD.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-K7kUCX1O.js → desktop-pet-KlF390Xn.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-KgOAuqSh.js → desktop-pet-settings-CgqQMKDC.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-DvqniZDm.js → device-pairing-wizard-BR6isfG2.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BmOguLDl.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-DSSuMQxp.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-DSd__mNd.js → extension-settings-page-D7-5v0V4.js} +1 -1
- package/dist/gateway/static/root/assets/{fallback-models-D7bjbiwZ.js → fallback-models-DnYn7qOV.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-hSXGWumL.js → gateway-settings-Bwe3JWX-.js} +1 -1
- package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-C7xJwE61.js → highlighted-body-KQOG7T2V-DefTxF3q.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-DJNmlMfH.js → home-page-BtSy2hRV.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-BufZPzGE.js → imports-page-CTdBYZib.js} +1 -1
- package/dist/gateway/static/root/assets/{index-K8SXDtxr.js → index-B08iR7fT.js} +9 -9
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B8pPP5RF.js → keyboard-shortcuts-settings-CXKp57O_.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-zEtvE7pJ.js → local-app-workbench-page-DzD_OzGY.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-Bli7e_eg.js → local-apps-page-B0E0vttg.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-BimZk3R4.js → logs-page-eL4fYcMl.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-5Y4COyU9.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-KLDPLVg7.js → note-detail-panel-CsY5tQp5.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-page-DST0oPXD.js → notes-page-D09LjNoj.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-capture-button-Bmed83-6.js → page-context-capture-button-DO-aP3D9.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-page-BG4Ystrm.js → personal-page-E8F2aGNB.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CXkYP9xE.js → product-open-page-aUoA-uPw.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-DjmupQSq.js → product-preview-content-B-cz-pIV.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-CzBmV0P6.js → project-detail-page-WhefAh8E.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-DByqe5Em.js → projects-page-CyqAs0tO.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-DTjj-odF.js → remote-access-hub-BwhRGL6m.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-B_ptn3T8.js → runtime-tools-settings-panel-o26dmPNq.js} +1 -1
- package/dist/gateway/static/root/assets/{scenes-page-wkua4l5y.js → scenes-page-D_e19kv_.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-VvOSM84Y.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-D06XwYAT.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-C-6BJdb1.js → settings-page-Bc_zxxRu.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-L0JSG0K-.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-BbgAUM3v.js → shares-settings-CInxjxgJ.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-api-BFU1tPyw.js → skill-api-Bjd8WAA4.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-DZw6el4o.js → skills-page-8CKS3Oo2.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-DshSGWNg.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-DFDXwWnU.js → tunnel-api-CY7MoDGf.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-2RJLg54s.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-y1gjGYPI.js → user-model-page-CyWrEtHY.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-Ch-KfpCF.js → work-discovery-overlay-DmZXLs1v.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CTu297Hc.js → workflow-run-setup-panel-BdLOzHm4.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-CRZXG_rm.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-hEfjVjnc.js → xopc-cloud-account-card-D8B136vW.js} +1 -1
- package/dist/gateway/static/root/index.html +11 -11
- 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 +86 -12
- 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/run-for-session.js +5 -2
- package/dist/src/agent/embedded/run-turn.js +19 -6
- 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 +5 -2
- package/dist/src/agent/embedded/types.d.ts +4 -0
- package/dist/src/agent/external-tools/gateway-tools.js +7 -3
- package/dist/src/agent/orchestration/agent-run-supervisor.js +2 -1
- 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 +17 -9
- 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 +4 -1
- package/dist/src/agent/orchestration/turn-recovery.js +19 -3
- 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/tasks/task-judge-service.js +3 -1
- 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 +2 -0
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/language-diagnostics.js +1 -1
- package/dist/src/agent/tools/personal-request-tool.js +8 -13
- package/dist/src/agent/tools/personal-task-tool.d.ts +1 -2
- package/dist/src/agent/tools/personal-task-tool.js +9 -8
- 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-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 +2 -2
- 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/doctor/checks/database-schema.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 +3 -1
- package/dist/src/connectors/connection-recovery-service.js +66 -5
- package/dist/src/discussions/action-tasks.d.ts +2 -2
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -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 +12 -1
- package/dist/src/gateway/service/session-input-coordinator.d.ts +10 -1
- package/dist/src/gateway/service/session-input-coordinator.js +213 -26
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +9 -7
- package/dist/src/gateway/session-context-summary.js +1 -1
- package/dist/src/personal-agent/prompts.js +4 -1
- package/dist/src/personal-agent/reply-composer.d.ts +1 -0
- package/dist/src/personal-agent/reply-composer.js +70 -12
- 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-repository.d.ts +2 -0
- package/dist/src/personal-agent/request-service.d.ts +4 -0
- package/dist/src/personal-agent/request-service.js +90 -19
- 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/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 +13 -3
- package/dist/src/storage/sqlite/connection-wait-repository.d.ts +5 -2
- package/dist/src/storage/sqlite/connection-wait-repository.js +42 -17
- 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/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 +2 -2
- package/dist/src/tasks/task-context-assembler.js +6 -1
- package/dist/src/tasks/task-continuation.d.ts +1 -0
- package/dist/src/tasks/task-continuation.js +1 -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-model-call.d.ts +7 -0
- package/dist/src/tasks/task-model-call.js +35 -0
- 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.js +69 -15
- package/dist/src/tasks/task-run-dispatcher.js +1 -0
- package/dist/src/tasks/task-run-repository.d.ts +5 -0
- package/dist/src/tasks/task-run-repository.js +88 -1
- package/package.json +9 -5
- package/dist/gateway/static/root/assets/constants-Dy8Gw0sF.js +0 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-DBRj4-1-.js +0 -1
- package/dist/gateway/static/root/assets/session-manager-_yy4bxhT.js +0 -16
- package/dist/gateway/static/root/assets/settings-advanced-gate-DoAHy1wj.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-CfZhq4XZ.js +0 -2
- package/dist/gateway/static/root/assets/task-expandable-content-CF6Bj-Qa.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const PREVIOUS_PERSONAL_REPLY_STYLE_RULES: readonly ["Make the first sentence useful on its own. When you can answer, lead with the answer or the most relevant judgment and then explain. When checking or delegating is necessary, give one specific sentence of intent and proceed immediately; never present an unverified finding or an unconfirmed action as fact. In an emotional conversation, respond to the specific feeling naturally instead of adding a task-style acknowledgement.", "Use natural paragraphs, usually one to three sentences about one idea, separated by a blank line. A simple question may need only one sentence. Do not stretch the opening into a heading, checklist, restatement of the request, or generic reassurance. Respect requests for exact text, code, tables, full lists, and a different structure. Do not repeat an earlier acknowledgement in the final result or manufacture progress updates just to keep talking.", "Understand the user’s last words and what the result means for them before replying. Speak as the same familiar personal assistant throughout the conversation, rather than forwarding an execution report. A natural brief opening is welcome when it connects to what they said; do not mechanically add a greeting, name, reassurance, joke, or question.", "Use a conversational rhythm and concrete language. Start with what the user most needs now, then give enough explanation or detail to use the answer. Do not default to “Task completed”, “Here is the summary”, headings, or checklists. Use lists and tables when they genuinely make the requested information easier to use."];
|
|
2
2
|
export declare const PREVIOUS_PERSONAL_REPLY_EXAMPLES = "Examples of presentation, only when the evidence supports the facts:\nReport: \u201CQuery complete. Scanned 28 emails and found 3 important items.\u201D\nConversation: \u201CThree emails are worth looking at first. The contract confirmation is the most urgent: they need your reply today. I\u2019ve included the other two below.\u201D\nReport: \u201CTask failed: connector authorization expired.\u201D\nConversation: \u201CI couldn\u2019t finish checking the remaining emails because the connection expired. The results already retrieved are below; reconnecting will let us check the rest.\u201D\nThese are examples of rhythm, not facts or fixed templates. Match the user\u2019s language and preferences.";
|
|
3
|
-
export declare const PERSONAL_REPLY_STYLE_RULES: readonly ["Respond to what the user is saying now as the same attentive personal assistant. Begin with a natural sentence suited to the exchange: answer a question, share a relevant observation in casual conversation, acknowledge a feeling when it matters, or state a concrete intent before necessary work. Start speaking as soon as you have something useful and grounded to say; never invent a finding or claim an unconfirmed action to produce an early opening.", "Use flowing, short paragraphs for ordinary conversation, usually one to three sentences about one idea. A useful opening does not need a label or bold summary line. Reserve introductory labels such as “结论:”, “总结:”, “Conclusion:” and report-style headings or numbered recaps for a requested summary, report, comparison, or other structure that helps the user. Answer a narrow follow-up at its scope instead of repeating the whole earlier answer.", "Interpret short replies in the previous exchange. “嗯”, “K”, or “好的” can simply acknowledge what was said; do not automatically treat them as a request for more information, a new task, or cancellation. When the user accepts a clear offer to continue, pick up that topic. Ask one concise question only when context cannot resolve ambiguity that matters to the answer or an action; do not guess consequential authorization. Follow an explicit request to stop.", "Keep warmth and conversational rhythm specific to the moment. Vary openings naturally; a greeting, name, reassurance, joke, or follow-up question is optional, never a required wrapper. Do not repeat an acknowledgement in the final result or manufacture routine progress updates. Respect the user’s requested tone, detail, exact text, code, tables, and lists.", "Synthesis means understanding and organizing, not always shortening. Preserve requested lists, exact text, code, translations, limitations, and partial failures. Never make an uncertain result sound confirmed just to keep the reply smooth.", "Answer the question directly by default without appending a source list. Provide sources when the user asks for citations, verification, or original material. Otherwise include only a few links when they are necessary to use or understand the answer, with meaningful titles near the relevant findings. Keep material uncertainty and verification gaps visible even when omitting source links."];
|
|
3
|
+
export declare const PERSONAL_REPLY_STYLE_RULES: readonly ["Be concise by default: usually one short paragraph of one to three sentences, or a few brief items when necessary. Give the useful conclusion, material limitations, and only the context needed to act. Do not repeat the request, acknowledgements, report contents, execution steps, or an unnecessary closing offer. A narrow follow-up needs a narrow answer. Explicit requests for detail, complete reports, exact text, code, or lists take precedence; never omit required facts or uncertainty just to shorten the reply.", "Respond to what the user is saying now as the same attentive personal assistant. Begin with a natural sentence suited to the exchange: answer a question, share a relevant observation in casual conversation, acknowledge a feeling when it matters, or state a concrete intent before necessary work. Start speaking as soon as you have something useful and grounded to say; never invent a finding or claim an unconfirmed action to produce an early opening.", "Use flowing, short paragraphs for ordinary conversation, usually one to three sentences about one idea. A useful opening does not need a label or bold summary line. Reserve introductory labels such as “结论:”, “总结:”, “Conclusion:” and report-style headings or numbered recaps for a requested summary, report, comparison, or other structure that helps the user. Answer a narrow follow-up at its scope instead of repeating the whole earlier answer.", "Interpret short replies in the previous exchange. “嗯”, “K”, or “好的” can simply acknowledge what was said; do not automatically treat them as a request for more information, a new task, or cancellation. When the user accepts a clear offer to continue, pick up that topic. Ask one concise question only when context cannot resolve ambiguity that matters to the answer or an action; do not guess consequential authorization. Follow an explicit request to stop.", "Keep warmth and conversational rhythm specific to the moment. Vary openings naturally; a greeting, name, reassurance, joke, or follow-up question is optional, never a required wrapper. Do not repeat an acknowledgement in the final result or manufacture routine progress updates. Respect the user’s requested tone, detail, exact text, code, tables, and lists.", "Synthesis means understanding and organizing, not always shortening. Preserve requested lists, exact text, code, translations, limitations, and partial failures. Never make an uncertain result sound confirmed just to keep the reply smooth.", "Answer the question directly by default without appending a source list. Provide sources when the user asks for citations, verification, or original material. Otherwise include only a few links when they are necessary to use or understand the answer, with meaningful titles near the relevant findings. Keep material uncertainty and verification gaps visible even when omitting source links."];
|
|
4
4
|
export declare const PERSONAL_REPLY_EXAMPLES = "Conversation examples with hypothetical facts, only to demonstrate rhythm. Use the current language, evidence, and preferences; do not copy their facts or wording into another request.\n<examples>\n<example>\nContext: The user wants to chat about a verified news item concerning AI avatars and a popular human discussion forum.\nUser: \u7EE7\u7EED\u804A\u4E00\u804A AI \u76F8\u5173\u7684\u65B0\u95FB\u3002\nAssistant: AI \u5206\u8EAB\u90A3\u6761\u633A\u6709\u610F\u601D\uFF1A\u5927\u5BB6\u82B1\u94B1\u4F53\u9A8C\u865A\u62DF\u8001\u5E08\uFF0C\u6700\u540E\u6700\u7231\u7528\u7684\u5374\u662F\u540C\u5B66\u8BBA\u575B\u3002\u6280\u672F\u8D8A\u60F3\u590D\u523B\u4EBA\uFF0C\u8FD9\u4EF6\u4E8B\u53CD\u800C\u8D8A\u663E\u51FA\u771F\u4EBA\u4EA4\u6D41\u7684\u4EF7\u503C\u3002\n</example>\n<example>\nContext: The supplied records show publication dates of October 10\u201312 and one reference dated October 7.\nUser: \u8FD9\u4E9B\u65B0\u95FB\u4EC0\u4E48\u65F6\u5019\u7684\uFF1F\nAssistant: \u4E3B\u8981\u662F 10 \u6708 10\u201312 \u65E5\u7684\u62A5\u9053\u3002\u5176\u4E2D\u4E00\u6761\u5F15\u7528\u4E86 10 \u6708 7 \u65E5\u7684\u8D44\u6599\uFF0C\u62A5\u9053\u65E5\u671F\u548C\u539F\u59CB\u8D44\u6599\u7684\u65E5\u671F\u8981\u5206\u5F00\u770B\u3002\n</example>\n<example>\nContext: The assistant has finished answering; there is no pending question or requested continuation.\nUser: K.\nAssistant: \u55EF\u3002\n</example>\n<example>\nContext: The assistant offered to discuss why the human forum in the AI-avatar news item was popular; the user accepts that offer.\nUser: \u7EE7\u7EED\u3002\nAssistant: \u521A\u624D\u8BF4\u7684\u540C\u5B66\u8BBA\u575B\uFF0C\u5438\u5F15\u4EBA\u7684\u53EF\u80FD\u5C31\u662F\u80FD\u78B0\u5230\u6709\u76F8\u4F3C\u56F0\u60D1\u7684\u4EBA\u3002\u9664\u4E86\u62FF\u5230\u7B54\u6848\uFF0C\u5927\u5BB6\u4E5F\u60F3\u542C\u542C\u522B\u4EBA\u662F\u600E\u4E48\u8D70\u8FC7\u6765\u7684\u3002\n</example>\n<example>\nContext: Several recipients were discussed, and the recipient of an external message is unresolved.\nUser: \u53D1\u7ED9\u4ED6\u3002\nAssistant: \u4F60\u6307\u7684\u662F\u521A\u624D\u63D0\u5230\u7684\u54EA\u4E00\u4F4D\uFF1F\n</example>\n<example>\nUser: \u5148\u522B\u8BB2\u4E86\u3002\nAssistant: \u597D\uFF0C\u5148\u505C\u5728\u8FD9\u513F\u3002\n</example>\n<example>\nContext: A hypothetical report establishes reduced waiting, configurable preferences, and an outstanding need for real-conversation evaluation.\nUser: \u5E2E\u6211\u603B\u7ED3\u6210\u4E09\u70B9\u3002\nAssistant: 1. \u9996\u53E5\u7B49\u5F85\u7F29\u77ED\u4E86\u3002\n2. \u7528\u6237\u4ECD\u80FD\u8C03\u6574\u8868\u8FBE\u504F\u597D\u3002\n3. \u81EA\u7136\u5EA6\u8FD8\u9700\u8981\u771F\u5B9E\u5BF9\u8BDD\u9A8C\u8BC1\u3002\n</example>\n<example>\nContext: Some requested email results were retrieved, but authorization expired before the remaining items could be checked.\nAssistant: \u5DF2\u7ECF\u67E5\u5230\u7684\u51E0\u5C01\u90AE\u4EF6\u5728\u4E0B\u9762\u3002\u5269\u4E0B\u7684\u6682\u65F6\u6CA1\u67E5\u5B8C\uFF0C\u56E0\u4E3A\u8FDE\u63A5\u8FC7\u671F\u4E86\uFF1B\u91CD\u65B0\u8FDE\u63A5\u540E\u624D\u80FD\u63A5\u7740\u770B\u3002\n</example>\n</examples>";
|
|
@@ -12,6 +12,7 @@ Report: “Task failed: connector authorization expired.”
|
|
|
12
12
|
Conversation: “I couldn’t finish checking the remaining emails because the connection expired. The results already retrieved are below; reconnecting will let us check the rest.”
|
|
13
13
|
These are examples of rhythm, not facts or fixed templates. Match the user’s language and preferences.`;
|
|
14
14
|
const PERSONAL_REPLY_STYLE_RULES = [
|
|
15
|
+
"Be concise by default: usually one short paragraph of one to three sentences, or a few brief items when necessary. Give the useful conclusion, material limitations, and only the context needed to act. Do not repeat the request, acknowledgements, report contents, execution steps, or an unnecessary closing offer. A narrow follow-up needs a narrow answer. Explicit requests for detail, complete reports, exact text, code, or lists take precedence; never omit required facts or uncertainty just to shorten the reply.",
|
|
15
16
|
"Respond to what the user is saying now as the same attentive personal assistant. Begin with a natural sentence suited to the exchange: answer a question, share a relevant observation in casual conversation, acknowledge a feeling when it matters, or state a concrete intent before necessary work. Start speaking as soon as you have something useful and grounded to say; never invent a finding or claim an unconfirmed action to produce an early opening.",
|
|
16
17
|
"Use flowing, short paragraphs for ordinary conversation, usually one to three sentences about one idea. A useful opening does not need a label or bold summary line. Reserve introductory labels such as “结论:”, “总结:”, “Conclusion:” and report-style headings or numbered recaps for a requested summary, report, comparison, or other structure that helps the user. Answer a narrow follow-up at its scope instead of repeating the whole earlier answer.",
|
|
17
18
|
"Interpret short replies in the previous exchange. “嗯”, “K”, or “好的” can simply acknowledge what was said; do not automatically treat them as a request for more information, a new task, or cancellation. When the user accepts a clear offer to continue, pick up that topic. Ask one concise question only when context cannot resolve ambiguity that matters to the answer or an action; do not guess consequential authorization. Follow an explicit request to stop.",
|
|
@@ -24,7 +24,7 @@ export declare const DEFAULT_PERSONAL_PREFERENCES: {
|
|
|
24
24
|
readonly warmth: "balanced";
|
|
25
25
|
readonly humor: "occasional";
|
|
26
26
|
readonly supportMode: "untangle";
|
|
27
|
-
readonly detailLevel: "
|
|
27
|
+
readonly detailLevel: "brief";
|
|
28
28
|
readonly proactivity: "decisions";
|
|
29
29
|
};
|
|
30
30
|
export declare function personalAgentId(ownerId: string): string;
|
|
@@ -17,5 +17,9 @@ export declare function resolvePersonalRequestConnection(wait: ConnectionWait, r
|
|
|
17
17
|
/** A worker can request access recovery without requiring a new main-chat turn. */
|
|
18
18
|
export declare function requirePersonalWorkerConnection(conversationId: string): PersonalRequest;
|
|
19
19
|
export declare function personalRequestSnapshot(request: PersonalRequest): PersonalRequest;
|
|
20
|
+
/** Dispatch only the request's bound execution; SDK acknowledgement must not block input. */
|
|
21
|
+
export declare function stopPersonalRequestExecution(request: PersonalRequest): {
|
|
22
|
+
executionStopConfirmed: boolean;
|
|
23
|
+
};
|
|
20
24
|
export declare function cancelPersonalRequest(request: PersonalRequest): PersonalRequest;
|
|
21
25
|
export declare function publishPersonalRequest(request: PersonalRequest): void;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
1
3
|
import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
2
4
|
import { TaskCreateRequestSchema } from "../../packages/gateway-contract/src/tasks.js";
|
|
3
5
|
import { init_src } from "../../packages/gateway-contract/src/index.js";
|
|
@@ -15,12 +17,13 @@ import { canAccessConnectorAccount } from "../connectors/account-access.js";
|
|
|
15
17
|
import { connectorPrincipalForSession } from "../connectors/principal.js";
|
|
16
18
|
import { resolveConnectionCandidate } from "../connectors/connection-candidates.js";
|
|
17
19
|
import { TaskCollaborationRepository } from "../tasks/task-collaboration-repository.js";
|
|
18
|
-
import { TaskApplicationService } from "../tasks/task-application-service.js";
|
|
19
20
|
import { defineTaskContract } from "../tasks/task-contract-definition.js";
|
|
21
|
+
import { abortEmbeddedRun } from "../agent/embedded/runs.js";
|
|
22
|
+
import { TaskApplicationService } from "../tasks/task-application-service.js";
|
|
23
|
+
import { PERSONAL_WORKER_RESULT_GUIDANCE } from "./communication.js";
|
|
20
24
|
import { assessSpecialist } from "../agent-matching/service.js";
|
|
21
25
|
import { AgentSelectionRepository, selectionRequestHash } from "../agent-matching/selection-repository.js";
|
|
22
26
|
import { assertSpecialistEligible } from "../agent-matching/delegation-service.js";
|
|
23
|
-
import { PERSONAL_WORKER_RESULT_GUIDANCE } from "./communication.js";
|
|
24
27
|
import { personalCapabilities } from "./capability-service.js";
|
|
25
28
|
import { createHash, randomUUID } from "node:crypto";
|
|
26
29
|
//#region src/personal-agent/request-service.ts
|
|
@@ -34,6 +37,9 @@ init_task_repository();
|
|
|
34
37
|
init_task_run_repository();
|
|
35
38
|
init_connector_account_repository();
|
|
36
39
|
init_connector_repository();
|
|
40
|
+
init_logger();
|
|
41
|
+
const log = createLogger("PersonalRequest");
|
|
42
|
+
const pendingStops = /* @__PURE__ */ new Set();
|
|
37
43
|
function requestAssessment(request, accountId) {
|
|
38
44
|
const principal = connectorPrincipalForSession(request.conversationId);
|
|
39
45
|
const capability = personalCapabilities(request.conversationId, request.connectorId, accountId).find((item) => item.connectorId === request.connectorId);
|
|
@@ -294,7 +300,11 @@ function startPersonalRequest(request, accountId) {
|
|
|
294
300
|
return updatePersonalRequest(request, {
|
|
295
301
|
state: result.ok ? "queued" : "failed",
|
|
296
302
|
accountId,
|
|
297
|
-
taskId
|
|
303
|
+
taskId,
|
|
304
|
+
parameters: {
|
|
305
|
+
...request.parameters,
|
|
306
|
+
taskRunId: result.ok ? result.runId : void 0
|
|
307
|
+
}
|
|
298
308
|
});
|
|
299
309
|
}
|
|
300
310
|
/** Called inside the connection-resolution transaction; ordinary waits return undefined. */
|
|
@@ -407,7 +417,11 @@ function requirePersonalWorkerConnection(conversationId) {
|
|
|
407
417
|
});
|
|
408
418
|
return updatePersonalRequest(request, {
|
|
409
419
|
state: "waiting_connection",
|
|
410
|
-
connectionWaitId: result.waitId
|
|
420
|
+
connectionWaitId: result.waitId,
|
|
421
|
+
parameters: {
|
|
422
|
+
...request.parameters,
|
|
423
|
+
taskRunId: run.id
|
|
424
|
+
}
|
|
411
425
|
});
|
|
412
426
|
});
|
|
413
427
|
}
|
|
@@ -420,16 +434,58 @@ function personalRequestSnapshot(request) {
|
|
|
420
434
|
state
|
|
421
435
|
};
|
|
422
436
|
}
|
|
423
|
-
function
|
|
437
|
+
function personalRequestRunId(request) {
|
|
438
|
+
if (request.parameters.taskRunId) return request.parameters.taskRunId;
|
|
439
|
+
if (request.connectionWaitId) {
|
|
440
|
+
const wait = getSqliteDatabase().prepare(`SELECT task_run_id FROM task_waits
|
|
441
|
+
WHERE task_id = ? AND json_extract(condition_json, '$.connectionWaitId') = ? LIMIT 1`).get(request.taskId ?? null, request.connectionWaitId);
|
|
442
|
+
if (wait?.task_run_id) return wait.task_run_id;
|
|
443
|
+
}
|
|
444
|
+
const selected = new AgentSelectionRepository().find(request.conversationId, `personal-request-start:${request.requestId}`)?.taskRunId;
|
|
445
|
+
if (selected) return selected;
|
|
446
|
+
return (request.taskId ? getSqliteDatabase().prepare(`SELECT run_id FROM task_runs
|
|
447
|
+
WHERE task_id = ? AND parent_run_id IS NULL ORDER BY queued_at, rowid LIMIT 1`).get(request.taskId) : void 0)?.run_id;
|
|
448
|
+
}
|
|
449
|
+
/** Dispatch only the request's bound execution; SDK acknowledgement must not block input. */
|
|
450
|
+
function stopPersonalRequestExecution(request) {
|
|
451
|
+
if (request.state !== "cancelled") return { executionStopConfirmed: false };
|
|
452
|
+
const runId = personalRequestRunId(request);
|
|
453
|
+
const run = runId ? new TaskRunRepository().get(runId) : void 0;
|
|
454
|
+
if (!run || !run.conversationId && !run.startedAt) return { executionStopConfirmed: true };
|
|
455
|
+
if (run.conversationId) {
|
|
456
|
+
const state = getSessionInputState(run.conversationId);
|
|
457
|
+
const input = state.activeInputId ? getSessionInputById(run.conversationId, state.activeInputId) : void 0;
|
|
458
|
+
if (state.activeRunId && input?.taskRunId === run.id && !pendingStops.has(state.activeRunId)) {
|
|
459
|
+
const executionId = state.activeRunId;
|
|
460
|
+
pendingStops.add(executionId);
|
|
461
|
+
abortEmbeddedRun(run.conversationId, "user_cancelled", executionId).catch((err) => {
|
|
462
|
+
log.warn({
|
|
463
|
+
err,
|
|
464
|
+
requestId: request.requestId,
|
|
465
|
+
runId,
|
|
466
|
+
executionId
|
|
467
|
+
}, "Request cancelled; execution stop was not confirmed");
|
|
468
|
+
}).finally(() => {
|
|
469
|
+
pendingStops.delete(executionId);
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return { executionStopConfirmed: false };
|
|
474
|
+
}
|
|
475
|
+
function cancelPersonalRequestTask(request, runId = personalRequestRunId(request)) {
|
|
424
476
|
if (!request.taskId) return;
|
|
425
477
|
const runs = new TaskRunRepository();
|
|
426
|
-
const run = runs.
|
|
478
|
+
const run = runId ? runs.get(runId) : void 0;
|
|
427
479
|
if (!run) return;
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
480
|
+
if (![
|
|
481
|
+
"queued",
|
|
482
|
+
"running",
|
|
483
|
+
"waiting",
|
|
484
|
+
"verifying",
|
|
485
|
+
"cancelled"
|
|
486
|
+
].includes(run.status)) return;
|
|
487
|
+
runs.resolveCancelledRunWaits(run.id, { kind: "user" });
|
|
488
|
+
if (run.status === "cancelled") return;
|
|
433
489
|
if (!new TaskApplicationService().completeRun({
|
|
434
490
|
runId: run.id,
|
|
435
491
|
expectedRunVersion: run.version,
|
|
@@ -452,12 +508,17 @@ function cancelPersonalRequestTask(request) {
|
|
|
452
508
|
}).ok) throw new Error("Task changed while cancelling");
|
|
453
509
|
}
|
|
454
510
|
function cancelPersonalRequest(request) {
|
|
455
|
-
const
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
511
|
+
const cancelled = runSqliteWriteTransaction(() => {
|
|
512
|
+
request = getPersonalRequest(request.requestId);
|
|
513
|
+
if (request.parameters.cancellationCleanupCompleted) return request;
|
|
514
|
+
const snapshot = personalRequestSnapshot(request);
|
|
515
|
+
if (["completed", "failed"].includes(snapshot.state)) return snapshot;
|
|
516
|
+
const active = request.taskId ? new TaskRunRepository().getActiveRoot(request.taskId) : void 0;
|
|
517
|
+
const runId = personalRequestRunId(request);
|
|
518
|
+
const replacementRun = active && runId && active.id !== runId;
|
|
519
|
+
if (request.connectionWaitId) cancelConnectionObjective(request.conversationId, request.connectionWaitId);
|
|
520
|
+
cancelPersonalRequestTask(request, runId);
|
|
521
|
+
if (request.taskId && !replacementRun) {
|
|
461
522
|
const task = new TaskRepository().require(request.taskId);
|
|
462
523
|
if (task.phase !== "closed") new TaskApplicationService().execute({
|
|
463
524
|
taskId: task.id,
|
|
@@ -471,11 +532,21 @@ function cancelPersonalRequest(request) {
|
|
|
471
532
|
});
|
|
472
533
|
getSqliteDatabase().prepare("UPDATE task_allocations SET status = 'cancelled', lease_token = NULL WHERE task_id = ?").run(request.taskId);
|
|
473
534
|
}
|
|
474
|
-
|
|
535
|
+
const current = getPersonalRequest(request.requestId);
|
|
536
|
+
return updatePersonalRequest(current, {
|
|
537
|
+
state: "cancelled",
|
|
538
|
+
parameters: {
|
|
539
|
+
...current.parameters,
|
|
540
|
+
taskRunId: runId,
|
|
541
|
+
cancellationCleanupCompleted: true
|
|
542
|
+
}
|
|
543
|
+
});
|
|
475
544
|
});
|
|
545
|
+
stopPersonalRequestExecution(cancelled);
|
|
546
|
+
return cancelled;
|
|
476
547
|
}
|
|
477
548
|
function publishPersonalRequest(request) {
|
|
478
549
|
publishConnectionWait(request.conversationId);
|
|
479
550
|
}
|
|
480
551
|
//#endregion
|
|
481
|
-
export { assertPersonalRequestTimeRange, cancelPersonalRequest, personalRequestSnapshot, publishPersonalRequest, requirePersonalWorkerConnection, resolvePersonalRequestConnection, submitPersonalRequest };
|
|
552
|
+
export { assertPersonalRequestTimeRange, cancelPersonalRequest, personalRequestSnapshot, publishPersonalRequest, requirePersonalWorkerConnection, resolvePersonalRequestConnection, stopPersonalRequestExecution, submitPersonalRequest };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/personal-agent/result-file-links.ts
|
|
2
|
+
/** File delivery belongs to structured artifacts, not model-authored host links. */
|
|
3
|
+
function localTarget(value) {
|
|
4
|
+
let target = value.trim().replace(/^<|>$/g, "").replace(/\\([\\/])/g, "$1");
|
|
5
|
+
try {
|
|
6
|
+
target = decodeURIComponent(target);
|
|
7
|
+
} catch {}
|
|
8
|
+
return /^(?:\/|\\\\|~\/|\.\.?\/|[a-z]:[\\/]|file:|media:|xopc:\/\/workspace\/file)/i.test(target) || /^[^\s:?#]+\.(?:md|pdf|docx?|xlsx?|csv|pptx?|zip|png|jpe?g|webp|mp[34]|wav)(?:[?#].*)?$/i.test(target);
|
|
9
|
+
}
|
|
10
|
+
function cleanSegment(text) {
|
|
11
|
+
return text.replace(/^\s*MEDIA\s*:\s*.*$/gim, "").replace(/!?\[([^\]\n]*)\]\(\s*(<[^>]+>|[^\s)]+)(?:\s+["'][^\n]*?["'])?\s*\)/g, (match, label, target) => localTarget(target) ? label : match).replace(/^\s*\[[^\]\n]+\]:\s*(<[^>]+>|\S+).*$/gm, (match, target) => localTarget(target) ? "" : match).replace(/<([^<>\n]+)>/g, (match, target) => localTarget(target) ? "" : match).replace(/\b(?:file:\/\/|media:\/\/|xopc:\/\/workspace\/file)[^\s<>"'`]+/gi, "").replace(/(?<![\w:/])(?:\/(?:Users|home|tmp|private|workspace|var)\/|[a-z]:[\\/])[^\s<>"'`]+/gi, "");
|
|
12
|
+
}
|
|
13
|
+
/** Preserve literal code; remove actionable local file references from prose. */
|
|
14
|
+
function sanitizePersonalResultFileLinks(text) {
|
|
15
|
+
return text.split(/(```[\s\S]*?```|~~~[\s\S]*?~~~|`[^`\n]+`)/g).map((part, index) => index % 2 ? part : cleanSegment(part)).join("").trim();
|
|
16
|
+
}
|
|
17
|
+
function hasPersonalResultFileLinks(text) {
|
|
18
|
+
return sanitizePersonalResultFileLinks(text) !== text.trim();
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { hasPersonalResultFileLinks, sanitizePersonalResultFileLinks };
|
|
@@ -1,49 +1,36 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
1
3
|
import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
4
|
+
import { getSessionInputById, getSessionInputState, init_session_input_repository } from "../storage/sqlite/session-input-repository.js";
|
|
2
5
|
import { TaskRepository, init_task_repository } from "../tasks/task-repository.js";
|
|
3
6
|
import { TaskRunRepository, init_task_run_repository } from "../tasks/task-run-repository.js";
|
|
4
7
|
import { TaskAllocationRepository } from "../tasks/task-allocation-repository.js";
|
|
5
8
|
import { TaskOriginRepository } from "../tasks/task-origin-repository.js";
|
|
6
|
-
import { abortEmbeddedRun } from "../agent/embedded/runs.js";
|
|
9
|
+
import { abortEmbeddedRun, getEmbeddedRunByConversationId } from "../agent/embedded/runs.js";
|
|
7
10
|
import { TaskApplicationService } from "../tasks/task-application-service.js";
|
|
8
11
|
//#region src/personal-agent/task-cancel.ts
|
|
9
12
|
init_transaction();
|
|
10
13
|
init_task_repository();
|
|
11
14
|
init_task_run_repository();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
init_session_input_repository();
|
|
16
|
+
init_logger();
|
|
17
|
+
const log = createLogger("PersonalTaskCancel");
|
|
18
|
+
const pendingStops = /* @__PURE__ */ new Set();
|
|
19
|
+
function finalizeCancellation(runId) {
|
|
15
20
|
const runs = new TaskRunRepository();
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}).ok) throw new Error("Task changed while cancelling");
|
|
30
|
-
} else if (task.resolution !== "cancelled") throw new Error("Task is already closed");
|
|
31
|
-
getSqliteDatabase().prepare("UPDATE task_allocations SET status = 'cancelled', lease_token = NULL, updated_at = ? WHERE task_id = ? AND status != 'cancelled'").run(Date.now(), taskId);
|
|
32
|
-
return {
|
|
33
|
-
active: run,
|
|
34
|
-
changed: task.phase !== "closed"
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
const latest = active ?? runs.getLatestRoot(taskId);
|
|
38
|
-
let executionStopConfirmed = !latest || !latest.conversationId && !latest.startedAt && ["queued", "cancelled"].includes(latest.status);
|
|
39
|
-
if (active?.conversationId) {
|
|
40
|
-
await abortEmbeddedRun(active.conversationId);
|
|
41
|
-
executionStopConfirmed = false;
|
|
42
|
-
}
|
|
43
|
-
const current = active ? runs.get(active.id) : void 0;
|
|
44
|
-
if (current && runs.getActiveRoot(taskId)?.id === current.id) new TaskApplicationService().completeRun({
|
|
45
|
-
runId: current.id,
|
|
46
|
-
expectedRunVersion: current.version,
|
|
21
|
+
const run = runId ? runs.get(runId) : void 0;
|
|
22
|
+
if (!run || ![
|
|
23
|
+
"queued",
|
|
24
|
+
"running",
|
|
25
|
+
"waiting",
|
|
26
|
+
"verifying",
|
|
27
|
+
"cancelled"
|
|
28
|
+
].includes(run.status)) return;
|
|
29
|
+
runs.resolveCancelledRunWaits(run.id, { kind: "user" });
|
|
30
|
+
if (run.status === "cancelled") return;
|
|
31
|
+
if (!new TaskApplicationService().completeRun({
|
|
32
|
+
runId: run.id,
|
|
33
|
+
expectedRunVersion: run.version,
|
|
47
34
|
actor: { kind: "user" },
|
|
48
35
|
terminalCode: "cancelled_by_user",
|
|
49
36
|
suppressAttention: true,
|
|
@@ -60,7 +47,70 @@ async function cancelPersonalTask(taskId, conversationId, key) {
|
|
|
60
47
|
needsUser: false,
|
|
61
48
|
completionVerdict: "not_achieved"
|
|
62
49
|
}
|
|
50
|
+
}).ok) throw new Error("Task changed while cancelling");
|
|
51
|
+
}
|
|
52
|
+
/** Close before aborting so a late router decision or receipt cannot restart the task. */
|
|
53
|
+
async function cancelPersonalTask(taskId, conversationId, key) {
|
|
54
|
+
if (!new TaskOriginRepository().owns(taskId, conversationId)) throw new Error("Task does not belong to this personal conversation");
|
|
55
|
+
const runs = new TaskRunRepository();
|
|
56
|
+
const { active, changed, targetKnown } = runSqliteWriteTransaction(() => {
|
|
57
|
+
const previous = getSqliteDatabase().prepare(`SELECT subject_id, result_json FROM command_deduplication
|
|
58
|
+
WHERE idempotency_key = ?`).get(`personal-cancel:${key}`);
|
|
59
|
+
if (previous) {
|
|
60
|
+
if (previous.subject_id !== taskId) throw new Error("Cancellation key belongs to another Task");
|
|
61
|
+
const saved = JSON.parse(previous.result_json);
|
|
62
|
+
const active = saved.cancellationRunId ? runs.get(saved.cancellationRunId) : void 0;
|
|
63
|
+
finalizeCancellation(active?.id);
|
|
64
|
+
return {
|
|
65
|
+
active,
|
|
66
|
+
changed: false,
|
|
67
|
+
targetKnown: Object.hasOwn(saved, "cancellationRunId")
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const task = new TaskRepository().require(taskId);
|
|
71
|
+
if (task.phase === "closed" && task.resolution !== "cancelled") throw new Error("Task is already closed");
|
|
72
|
+
const run = runs.getActiveRoot(taskId) ?? (task.phase === "closed" ? runs.getLatestRoot(taskId) : void 0);
|
|
73
|
+
if (!new TaskApplicationService().execute({
|
|
74
|
+
taskId,
|
|
75
|
+
expectedVersion: task.version,
|
|
76
|
+
idempotencyKey: `personal-cancel:${key}`,
|
|
77
|
+
command: {
|
|
78
|
+
type: "close",
|
|
79
|
+
resolution: "cancelled"
|
|
80
|
+
},
|
|
81
|
+
actor: { kind: "user" }
|
|
82
|
+
}).ok) throw new Error("Task changed while cancelling");
|
|
83
|
+
getSqliteDatabase().prepare(`UPDATE command_deduplication SET result_json = json_set(result_json, '$.cancellationRunId', ?)
|
|
84
|
+
WHERE idempotency_key = ?`).run(run?.id ?? null, `personal-cancel:${key}`);
|
|
85
|
+
getSqliteDatabase().prepare("UPDATE task_allocations SET status = 'cancelled', lease_token = NULL, updated_at = ? WHERE task_id = ? AND status != 'cancelled'").run(Date.now(), taskId);
|
|
86
|
+
finalizeCancellation(run?.id);
|
|
87
|
+
return {
|
|
88
|
+
active: run,
|
|
89
|
+
changed: task.phase !== "closed",
|
|
90
|
+
targetKnown: true
|
|
91
|
+
};
|
|
63
92
|
});
|
|
93
|
+
let executionStopConfirmed = targetKnown && (!active || !active.conversationId && !active.startedAt && ["queued", "cancelled"].includes(active.status));
|
|
94
|
+
if (active?.conversationId) {
|
|
95
|
+
const state = getSessionInputState(active.conversationId);
|
|
96
|
+
const input = state.activeInputId ? getSessionInputById(active.conversationId, state.activeInputId) : void 0;
|
|
97
|
+
const embedded = getEmbeddedRunByConversationId(active.conversationId);
|
|
98
|
+
const executionId = input?.taskRunId === active.id ? state.activeRunId : embedded?.runId === active.id ? active.id : void 0;
|
|
99
|
+
if (executionId && !pendingStops.has(executionId)) {
|
|
100
|
+
pendingStops.add(executionId);
|
|
101
|
+
abortEmbeddedRun(active.conversationId, "user_cancelled", executionId).catch((err) => {
|
|
102
|
+
log.warn({
|
|
103
|
+
err,
|
|
104
|
+
taskId,
|
|
105
|
+
runId: active.id,
|
|
106
|
+
executionId
|
|
107
|
+
}, "Task cancelled; execution stop was not confirmed");
|
|
108
|
+
}).finally(() => {
|
|
109
|
+
pendingStops.delete(executionId);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
executionStopConfirmed = false;
|
|
113
|
+
}
|
|
64
114
|
if (changed && new TaskAllocationRepository().get(taskId)) {
|
|
65
115
|
const zh = new TaskRepository().require(taskId).locale === "zh";
|
|
66
116
|
runSqliteWriteTransaction(() => new TaskAllocationRepository().publish(taskId, zh ? "任务已取消。" : "Task cancelled."));
|
|
@@ -50,7 +50,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
50
50
|
task: {
|
|
51
51
|
id: string;
|
|
52
52
|
title: string;
|
|
53
|
-
phase: "
|
|
53
|
+
phase: "review" | "backlog" | "ready" | "active" | "closed";
|
|
54
54
|
priority: "low" | "normal" | "high" | "critical";
|
|
55
55
|
source: string;
|
|
56
56
|
latestContractVersion: number;
|
|
@@ -170,6 +170,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
170
170
|
criterion: string;
|
|
171
171
|
status: "failed" | "passed" | "unverified";
|
|
172
172
|
evidenceTitles: string[];
|
|
173
|
+
note?: string;
|
|
174
|
+
method?: "unverified" | "model_reviewed" | "tool_verified";
|
|
173
175
|
}[];
|
|
174
176
|
};
|
|
175
177
|
remainingWork: string[];
|
|
@@ -201,7 +203,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
201
203
|
task: {
|
|
202
204
|
id: string;
|
|
203
205
|
title: string;
|
|
204
|
-
phase: "
|
|
206
|
+
phase: "review" | "backlog" | "ready" | "active" | "closed";
|
|
205
207
|
priority: "low" | "normal" | "high" | "critical";
|
|
206
208
|
source: string;
|
|
207
209
|
latestContractVersion: number;
|
|
@@ -321,6 +323,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
321
323
|
criterion: string;
|
|
322
324
|
status: "failed" | "passed" | "unverified";
|
|
323
325
|
evidenceTitles: string[];
|
|
326
|
+
note?: string;
|
|
327
|
+
method?: "unverified" | "model_reviewed" | "tool_verified";
|
|
324
328
|
}[];
|
|
325
329
|
};
|
|
326
330
|
remainingWork: string[];
|
|
@@ -351,7 +355,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
351
355
|
task: {
|
|
352
356
|
id: string;
|
|
353
357
|
title: string;
|
|
354
|
-
phase: "
|
|
358
|
+
phase: "review" | "backlog" | "ready" | "active" | "closed";
|
|
355
359
|
priority: "low" | "normal" | "high" | "critical";
|
|
356
360
|
source: string;
|
|
357
361
|
latestContractVersion: number;
|
|
@@ -471,6 +475,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
471
475
|
criterion: string;
|
|
472
476
|
status: "failed" | "passed" | "unverified";
|
|
473
477
|
evidenceTitles: string[];
|
|
478
|
+
note?: string;
|
|
479
|
+
method?: "unverified" | "model_reviewed" | "tool_verified";
|
|
474
480
|
}[];
|
|
475
481
|
};
|
|
476
482
|
remainingWork: string[];
|
|
@@ -527,7 +533,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
527
533
|
task: {
|
|
528
534
|
id: string;
|
|
529
535
|
title: string;
|
|
530
|
-
phase: "
|
|
536
|
+
phase: "review" | "backlog" | "ready" | "active" | "closed";
|
|
531
537
|
priority: "low" | "normal" | "high" | "critical";
|
|
532
538
|
source: string;
|
|
533
539
|
latestContractVersion: number;
|
|
@@ -647,6 +653,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
647
653
|
criterion: string;
|
|
648
654
|
status: "failed" | "passed" | "unverified";
|
|
649
655
|
evidenceTitles: string[];
|
|
656
|
+
note?: string;
|
|
657
|
+
method?: "unverified" | "model_reviewed" | "tool_verified";
|
|
650
658
|
}[];
|
|
651
659
|
};
|
|
652
660
|
remainingWork: string[];
|
|
@@ -677,7 +685,7 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
677
685
|
task: {
|
|
678
686
|
id: string;
|
|
679
687
|
title: string;
|
|
680
|
-
phase: "
|
|
688
|
+
phase: "review" | "backlog" | "ready" | "active" | "closed";
|
|
681
689
|
priority: "low" | "normal" | "high" | "critical";
|
|
682
690
|
source: string;
|
|
683
691
|
latestContractVersion: number;
|
|
@@ -797,6 +805,8 @@ export declare class SceneTaskExecutionService implements SceneActivationAdapter
|
|
|
797
805
|
criterion: string;
|
|
798
806
|
status: "failed" | "passed" | "unverified";
|
|
799
807
|
evidenceTitles: string[];
|
|
808
|
+
note?: string;
|
|
809
|
+
method?: "unverified" | "model_reviewed" | "tool_verified";
|
|
800
810
|
}[];
|
|
801
811
|
};
|
|
802
812
|
remainingWork: string[];
|
|
@@ -297,7 +297,7 @@ function buildSessionContextForLlm(rows) {
|
|
|
297
297
|
continue;
|
|
298
298
|
}
|
|
299
299
|
if (isTranscriptCustomMessageEntry(r)) {
|
|
300
|
-
if (r.customType === "personal_request_status") continue;
|
|
300
|
+
if (r.customType === "personal_request_status" || r.customType === "connection_control_status") continue;
|
|
301
301
|
if (r.customType === "personal_proactive_message") {
|
|
302
302
|
const message = parsePersonalProactiveMessage(r.details);
|
|
303
303
|
if (message) out.push({
|
|
@@ -350,7 +350,7 @@ function buildSessionDisplayMessages(rows) {
|
|
|
350
350
|
const out = [];
|
|
351
351
|
for (const r of rows) {
|
|
352
352
|
if (isTranscriptCustomMessageEntry(r)) {
|
|
353
|
-
if (r.customType === "personal_request_status") {
|
|
353
|
+
if (r.customType === "personal_request_status" || r.customType === "connection_control_status") {
|
|
354
354
|
out.push({
|
|
355
355
|
role: "assistant",
|
|
356
356
|
content: [{
|
|
@@ -116,7 +116,9 @@ export declare class SessionStore {
|
|
|
116
116
|
private buildSessionDetail;
|
|
117
117
|
loadTranscriptRows(key: string): Promise<TranscriptStoredRow[]>;
|
|
118
118
|
loadTranscriptHistoryRows(key: string): Promise<TranscriptStoredRow[]>;
|
|
119
|
-
prepareModelFallback(key: string, rowsBeforeAttempt: readonly TranscriptStoredRow[]
|
|
119
|
+
prepareModelFallback(key: string, rowsBeforeAttempt: readonly TranscriptStoredRow[], options?: {
|
|
120
|
+
resumeTaskContinuation?: boolean;
|
|
121
|
+
}): Promise<ModelFallbackPreparation>;
|
|
120
122
|
getMetadata(key: string): Promise<SessionMetadata | null>;
|
|
121
123
|
resolveKeyByTranscriptId(transcriptId: string): Promise<string | null>;
|
|
122
124
|
updateMetadata(key: string, updates: Partial<SessionMetadata>): Promise<void>;
|
|
@@ -15,7 +15,7 @@ import { init_sqlite } from "../storage/sqlite/index.js";
|
|
|
15
15
|
import { init_agent_session_key, resolveAgentIdFromConversationId } from "../routing/agent-session-key.js";
|
|
16
16
|
import { resolveUserContextSessionAccess } from "../user-context/access-policy.js";
|
|
17
17
|
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
18
|
-
import { canResumeAfterModelFailure } from "../agent/orchestration/turn-recovery.js";
|
|
18
|
+
import { ACCEPTANCE_REPAIR_READ_TOOLS, canResumeAfterModelFailure } from "../agent/orchestration/turn-recovery.js";
|
|
19
19
|
import { DurableState } from "../storage/sqlite/durable-state.js";
|
|
20
20
|
import { transcriptRowsToClientHistory } from "./client-history.js";
|
|
21
21
|
import { SessionCompactor } from "../agent/memory/compaction.js";
|
|
@@ -272,7 +272,7 @@ var SessionStore = class {
|
|
|
272
272
|
requireXopcDatabase();
|
|
273
273
|
return loadTranscriptHistoryRowsForSession(key);
|
|
274
274
|
}
|
|
275
|
-
async prepareModelFallback(key, rowsBeforeAttempt) {
|
|
275
|
+
async prepareModelFallback(key, rowsBeforeAttempt, options) {
|
|
276
276
|
return this.runStoreMutation(async () => {
|
|
277
277
|
requireXopcDatabase();
|
|
278
278
|
const currentRows = loadTranscriptRowsForSession(key);
|
|
@@ -289,7 +289,17 @@ var SessionStore = class {
|
|
|
289
289
|
"assistant",
|
|
290
290
|
"toolResult"
|
|
291
291
|
].includes(String(row.role)));
|
|
292
|
-
|
|
292
|
+
const onlyRecoveryMetadata = appendedRows.every((row) => "type" in row && row.type === "custom" && [
|
|
293
|
+
"coding_run_started",
|
|
294
|
+
"coding_verification",
|
|
295
|
+
"codemode-store",
|
|
296
|
+
"xopc-tool-discovery-state"
|
|
297
|
+
].includes(String(row.customType)));
|
|
298
|
+
if (removedError && options?.resumeTaskContinuation && onlyRecoveryMetadata && canResumeAfterModelFailure(preparedRows, { allowFailedReadTools: ACCEPTANCE_REPAIR_READ_TOOLS })) {
|
|
299
|
+
archiveFailedModelAttempts(key, rowsBeforeAttempt.length);
|
|
300
|
+
return "prompt";
|
|
301
|
+
}
|
|
302
|
+
if (appendedRows.some((row) => isTranscriptMessageRole(row, "user")) && appendedRows.filter((row) => isTranscriptMessageRole(row, "user")).length === 1 && (isTranscriptMessageRole(tail, "user") || isTranscriptMessageRole(tail, "toolResult")) && canResumeAfterModelFailure(preparedRows, { allowFailedReadTools: ACCEPTANCE_REPAIR_READ_TOOLS }) || appendedRows.length === 1 && isTranscriptMessageRole(appendedRows[0], "user") || removedError && appendedRows.length === 0 && isTranscriptMessageRole(preparedRows.at(-1), "user") || removedError && onlyRecoveryMetadata && (isTranscriptMessageRole(tail, "user") || isTranscriptMessageRole(tail, "toolResult")) && canResumeAfterModelFailure(preparedRows, { allowFailedReadTools: ACCEPTANCE_REPAIR_READ_TOOLS })) {
|
|
293
303
|
if (removedError) archiveFailedModelAttempts(key, rowsBeforeAttempt.length);
|
|
294
304
|
return "resume";
|
|
295
305
|
}
|
|
@@ -21,6 +21,9 @@ export declare function requireSessionConnection(input: {
|
|
|
21
21
|
status: 'connection_required' | 'skipped' | 'objective_conflict';
|
|
22
22
|
waitId?: string;
|
|
23
23
|
};
|
|
24
|
+
/** Pending messages may revise the goal; controls cannot become a competing model execution. */
|
|
25
|
+
export declare function interruptedConnectionMessage(wait: ConnectionWait): SessionInput | undefined;
|
|
26
|
+
export declare function hasPendingConnectionMessages(wait: ConnectionWait, includeControls?: boolean): boolean;
|
|
24
27
|
/** The input and the wait transition commit together, using the existing queue's unique key. */
|
|
25
28
|
export declare function queueConnectionResolution(wait: ConnectionWait, resolution: 'continued' | 'skipped', resolvePersonal?: (wait: ConnectionWait, resolution: 'continued' | 'skipped') => unknown): ConnectionWait;
|
|
26
29
|
export declare function consumeConnectionResume(input: SessionInput): boolean;
|
|
@@ -29,10 +32,10 @@ export declare function connectionBindings(conversationId: string): ConnectionNe
|
|
|
29
32
|
export declare function connectorObjectiveScope(conversationId: string): string | undefined;
|
|
30
33
|
export declare function bindObjectiveAccount(conversationId: string, connectorId: string, accountId: string): void;
|
|
31
34
|
export declare function connectionBinding(conversationId: string, connectorId: string): string | undefined;
|
|
32
|
-
/**
|
|
35
|
+
/** Explicit objective changes invalidate an outstanding auto-resume intent. */
|
|
33
36
|
export declare function invalidateConnectionResumeIntent(conversationId: string): void;
|
|
34
37
|
export declare function reviseCurrentConnectionObjective(conversationId: string, summary: string | undefined): void;
|
|
35
|
-
export declare function cancelConnectionObjective(conversationId: string): void;
|
|
38
|
+
export declare function cancelConnectionObjective(conversationId: string, expectedWaitId?: string, expectedObjectiveRevision?: number): void;
|
|
36
39
|
export declare function getConnectionResumeInput(conversationId: string, runId: string): SessionInput | undefined;
|
|
37
40
|
export declare function listConnectionWaitsToCheck(): ConnectionWait[];
|
|
38
41
|
/** A queued wait has not crossed consumeConnectionResume's execution boundary. */
|