@xopcai/xopc 0.0.386 → 0.0.387
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/dist/sidepanel.js +1 -1
- 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-D-86VOlb.js → agent-avatar-dicebear-Bv8M5ygD.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-SmeUVHY8.js → agent-defaults-settings-panel-UBy01-65.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-BVT3wXq5.js → agent-plugin-dialog-Q9guA8kU.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-D7rLQFhX.js → agents-yfJFubD0.js} +3 -3
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CUR7n5iP.js → app-management-settings-panel-Cdyad8c1.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BCotSGep.js → appearance-settings-DPPvnKH_.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-hk0bo9LT.js → apps-page-Bn_jwaeA.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CqxuUwox.js → automations-page-CAB2sLJ5.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-11_Z69pr.js → automations-workspace-CYRUhhH4.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-eldB84Mj.js → block-editor-B9DmMEa8.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-D4TaUPYT.js → browser-automations-page-BHAWpZE2.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-BXRlxeGV.js → browser-settings-page-BG_17NcQ.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-DVj9n65C.js → capabilities-BX1rCiVm.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-BkKgImWi.js → capabilities-CW389yo6.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-page-CyYlueEd.js → capabilities-page-BAnBYWlY.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-uVEgfvo0.js → capabilities-settings-panel-Ca-d6lXk.js} +3 -3
- package/dist/gateway/static/root/assets/{capability-header-actions-BXv0xu56.js → capability-header-actions-B3TL8TcF.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-fNb3SOzm.js → channels-BadpS-nq.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CnLtparQ.js → chat-terminal-dock-C_vntFpP.js} +1 -1
- package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-BMYIfy9x.js → chunk-KS7C4IRE--EKdQGRF.js} +1 -1
- package/dist/gateway/static/root/assets/{computer-settings-page-xM0AnOlP.js → computer-settings-page-B-5kxk70.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-CdG2WUb6.js → connector-service-page-DTnfpLHL.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-BRd08GH6.js → connectors-page-CmJV7gqj.js} +1 -1
- package/dist/gateway/static/root/assets/constants-DeXt1mV-.js +1 -0
- package/dist/gateway/static/root/assets/{date-picker-DIBbE-O8.js → date-picker-D5zYeC8q.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DDD8zokD.js → dependency-picker-D72vT-tb.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-KlF390Xn.js → desktop-pet-DvoeVPf_.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-CgqQMKDC.js → desktop-pet-settings-Dfb392hs.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-BR6isfG2.js → device-pairing-wizard-B06Sqn5D.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-vPQsW05P.js → directory-picker-path-field-CA3H3bc-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-ZHLPrLbH.js → extension-debug-page-B0wTBCx4.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DJ42KFRN.js → extension-page-BeHiXhB1.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-provider-6IcsyNaV.js → extension-provider-CJZ5EVpQ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-D7-5v0V4.js → extension-settings-page-Q88-LFCJ.js} +1 -1
- package/dist/gateway/static/root/assets/{fallback-models-DnYn7qOV.js → fallback-models-BXoPCvzq.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-Bwe3JWX-.js → gateway-settings-IICLMGDI.js} +1 -1
- package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-DefTxF3q.js → highlighted-body-KQOG7T2V-D336so8z.js} +1 -1
- package/dist/gateway/static/root/assets/home-page--MvqsFhQ.js +2 -0
- package/dist/gateway/static/root/assets/{imports-page-CTdBYZib.js → imports-page-muV1SduS.js} +1 -1
- package/dist/gateway/static/root/assets/index-D0qMv3jf.js +260 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CXKp57O_.js → keyboard-shortcuts-settings-i1sDWcwl.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DzD_OzGY.js → local-app-workbench-page-DY9tXEO6.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-B0E0vttg.js → local-apps-page-BHD73STy.js} +1 -1
- package/dist/gateway/static/root/assets/local-session-drafts-Be4BGM4Z.js +1 -0
- package/dist/gateway/static/root/assets/{logs-page-eL4fYcMl.js → logs-page-DsPpe8Ws.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-DSpjodMC.js → management-settings-Buwi2wQE.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-DHfQAvZQ.js → markdown-view-CBjl-XEc.js} +2 -2
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-D2mip-f9.js +1 -0
- package/dist/gateway/static/root/assets/{note-detail-panel-CsY5tQp5.js → note-detail-panel-D8n80Gbr.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-api-nqN2wKYc.js → notes-api-BlGP533W.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-D09LjNoj.js → notes-page-Btf-jSS_.js} +5 -5
- package/dist/gateway/static/root/assets/{page-context-capture-button-DO-aP3D9.js → page-context-capture-button-97RL8Gc7.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-page-E8F2aGNB.js → personal-page-B04L8Oz5.js} +1 -1
- package/dist/gateway/static/root/assets/product-open-page-9zEDvZa7.js +1 -0
- package/dist/gateway/static/root/assets/{product-preview-content-B-cz-pIV.js → product-preview-content-DynBrIXq.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-WhefAh8E.js → project-detail-page-BM7MsoVA.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-CyqAs0tO.js → projects-page-pcyeEJnz.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-BwhRGL6m.js → remote-access-hub-CphyTu22.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-o26dmPNq.js → runtime-tools-settings-panel-DPafoO0G.js} +1 -1
- package/dist/gateway/static/root/assets/{scenes-page-D_e19kv_.js → scenes-page-j97FrDRW.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-DLLdqUC3.js → schema-form-CuJNwKHO.js} +1 -1
- package/dist/gateway/static/root/assets/{send-session-input-2I-nFJcE.js → send-session-input-C293-Hbx.js} +1 -1
- package/dist/gateway/static/root/assets/{session-manager-Co5ozD0l.js → session-manager-COd9RECl.js} +2 -2
- package/dist/gateway/static/root/assets/{sessions-page-DX6INsiS.js → sessions-page-D8t_8fMl.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CDkitNHA.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-Bc_zxxRu.js → settings-page-DS9DMYUe.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-FpF_cPPr.js → setup-status-panel-DRDvm9yZ.js} +1 -1
- package/dist/gateway/static/root/assets/{share-link-dialog-C47Xgzta.js → share-link-dialog-BKGI8Kr0.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-BOCcPBqQ.js → share-preview-page-BF2WaO43.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-CInxjxgJ.js → shares-settings-DQTQZu6V.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-api-Bjd8WAA4.js → skill-api-DzVa7G-O.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-8CKS3Oo2.js → skills-page-CfJIjRdS.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BgQdsrNw.js → system-settings-panel-Bzhqed-a.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-BnG5ehZ6.js → task-detail-page-BYQFC0-U.js} +2 -2
- package/dist/gateway/static/root/assets/{task-expandable-content-BCuc70Vc.js → task-expandable-content-C9ohICpw.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-CY7MoDGf.js → tunnel-api-DrgpZ81I.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-s8Sv_PIG.js → usage-page-Drk8FWnj.js} +1 -1
- package/dist/gateway/static/root/assets/{use-composer-attachments-D0S2iZF4.js → use-composer-attachments-rgW7h4sD.js} +1 -1
- package/dist/gateway/static/root/assets/{use-file-preview-expanded-BElqELib.js → use-file-preview-expanded-DSKIxfz9.js} +1 -1
- package/dist/gateway/static/root/assets/{user-model-page-CyWrEtHY.js → user-model-page-07t2-nFE.js} +2 -2
- package/dist/gateway/static/root/assets/{work-discovery-overlay-DmZXLs1v.js → work-discovery-overlay-TQ5bjVot.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BdLOzHm4.js → workflow-run-setup-panel-C9HP2uGG.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-Cx3I3AV5.js → workflows-page-DK01JRI1.js} +3 -3
- package/dist/gateway/static/root/assets/{workspace-api-Du7-xJ0q.js → workspace-api-JWHOFos6.js} +2 -2
- package/dist/gateway/static/root/assets/{xopc-cloud-account-card-D8B136vW.js → xopc-cloud-account-card-B-BhQdAf.js} +1 -1
- package/dist/gateway/static/root/index.html +15 -15
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/index.js +2 -0
- package/dist/packages/gateway-contract/src/result-reference.js +25 -0
- package/dist/packages/gateway-contract/src/session-input-command.js +2 -1
- package/dist/packages/gateway-contract/src/task-research-result.js +1 -0
- package/dist/packages/gateway-contract/src/task-result-delivery.js +21 -0
- package/dist/packages/gateway-contract/src/turn-outcome.js +1 -0
- package/dist/src/agent/agent-manager.js +3 -3
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/xopc-tools-bridge.js +13 -2
- package/dist/src/agent/external-tools/cliProvider.js +1 -1
- package/dist/src/agent/external-tools/composio-provider.js +2 -2
- package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
- package/dist/src/agent/external-tools/gateway-tools.js +1 -1
- package/dist/src/agent/inbound/attachment-pipeline.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +2 -0
- package/dist/src/agent/service/direct-turn-helpers.js +4 -0
- package/dist/src/agent/service/process-direct-one-shot.js +4 -1
- package/dist/src/agent/service/process-direct-streaming.js +3 -2
- package/dist/src/agent/service.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/source-context/index.js +1 -1
- package/dist/src/agent/source-context/result-context.d.ts +2 -0
- package/dist/src/agent/source-context/result-context.js +32 -0
- package/dist/src/agent/source-context/types.d.ts +2 -2
- package/dist/src/agent/source-context/types.js +1 -1
- package/dist/src/agent/tools/exec-command.js +47 -2
- package/dist/src/agent/tools/factory.js +17 -10
- package/dist/src/agent/tools/personal-performance.d.ts +2 -0
- package/dist/src/agent/tools/personal-performance.js +82 -0
- package/dist/src/agent/tools/personal-read-tool.js +1 -1
- package/dist/src/agent/tools/personal-request-tool.js +1 -1
- package/dist/src/agent/tools/personal-result-tool.d.ts +2 -0
- package/dist/src/agent/tools/personal-result-tool.js +106 -0
- package/dist/src/agent/tools/personal-task-tool.d.ts +11 -1
- package/dist/src/agent/tools/personal-task-tool.js +106 -2
- package/dist/src/agent/tools/review-workspace.js +20 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/task-collaboration-tool.d.ts +9 -1
- package/dist/src/agent/tools/task-collaboration-tool.js +121 -2
- package/dist/src/agent/tools/task-evidence.d.ts +3 -0
- package/dist/src/agent/tools/task-evidence.js +71 -0
- package/dist/src/agent/tools/task-result-tool.js +24 -4
- package/dist/src/agent/tools/tool-media.js +1 -1
- package/dist/src/agent/tools/xopc-use-tool.js +25 -4
- package/dist/src/agent/workspace-runtime/registry.js +1 -1
- package/dist/src/agent-catalog/capabilities.js +2 -2
- package/dist/src/automations/capabilities/drafts.js +1 -1
- package/dist/src/automations/service/action-executor.js +1 -1
- package/dist/src/bootstrap/application-state.js +1 -1
- package/dist/src/capabilities/runtime/dispatcher.js +1 -1
- package/dist/src/capabilities/runtime/product.js +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -1
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/agents.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +1 -1
- package/dist/src/config/agent-profile.js +2 -2
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.js +1 -1
- package/dist/src/connectors/connection-recovery-service.js +1 -1
- package/dist/src/extensions/agent-plugins/validation.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/agent-stream.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- package/dist/src/gateway/hono/routes/context-sources.js +1 -1
- package/dist/src/gateway/hono/routes/notes.js +2 -2
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +2 -2
- package/dist/src/gateway/hono/routes/session-input-handler.js +2 -2
- package/dist/src/gateway/hono/routes/tasks.js +1 -1
- package/dist/src/gateway/image-generation-setup.js +1 -1
- package/dist/src/gateway/lock.js +1 -1
- package/dist/src/gateway/media-access.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +20 -1
- package/dist/src/gateway/service/session-input-coordinator.js +2 -2
- package/dist/src/gateway/service.js +40 -9
- package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
- package/dist/src/home-intelligence/host.js +2 -2
- package/dist/src/local-apps/service.js +1 -1
- package/dist/src/media/session-references.js +1 -1
- package/dist/src/personal-agent/communication.js +1 -0
- package/dist/src/personal-agent/performance.d.ts +83 -0
- package/dist/src/personal-agent/performance.js +65 -0
- package/dist/src/personal-agent/policy.d.ts +1 -1
- package/dist/src/personal-agent/policy.js +1 -0
- package/dist/src/personal-agent/proactivity/service.js +1 -1
- package/dist/src/personal-agent/prompt-context.js +3 -1
- package/dist/src/personal-agent/prompts.js +6 -3
- package/dist/src/personal-agent/reply-composer.js +79 -8
- package/dist/src/personal-agent/request-delivery.js +3 -1
- package/dist/src/personal-agent/request-service.js +1 -1
- package/dist/src/personal-agent/result-extraction.d.ts +42 -0
- package/dist/src/personal-agent/result-extraction.js +209 -0
- package/dist/src/personal-agent/result-read-continuations.d.ts +13 -0
- package/dist/src/personal-agent/result-read-continuations.js +78 -0
- package/dist/src/personal-agent/result-reader.d.ts +43 -0
- package/dist/src/personal-agent/result-reader.js +461 -0
- package/dist/src/personal-agent/service.js +2 -2
- package/dist/src/providers/model-catalog-persistence.js +1 -1
- package/dist/src/routing/resolve-route.js +1 -1
- package/dist/src/routing/resolve-tui-session-key.js +1 -1
- package/dist/src/session/client-history.d.ts +1 -1
- package/dist/src/session/client-history.js +1 -1
- package/dist/src/session/session-context-for-llm.js +2 -0
- package/dist/src/share/hosted-session-share.js +1 -1
- package/dist/src/storage/sqlite/migrations/251_personal_result_reads.sql +40 -0
- package/dist/src/storage/sqlite/migrations/252_task_work_revisions.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/schema.js +1 -1
- package/dist/src/tasks/capabilities/read.js +2 -2
- package/dist/src/tasks/capabilities/write.js +1 -1
- package/dist/src/tasks/task-allocation-service.js +61 -10
- package/dist/src/tasks/task-application-service.d.ts +18 -0
- package/dist/src/tasks/task-application-service.js +131 -0
- package/dist/src/tasks/task-context-assembler.js +8 -5
- package/dist/src/tasks/task-contract-definition.d.ts +3 -0
- package/dist/src/tasks/task-contract-planner.js +50 -16
- package/dist/src/tasks/task-conversation-repository.js +1 -1
- package/dist/src/tasks/task-evidence-ranges.d.ts +7 -0
- package/dist/src/tasks/task-evidence-ranges.js +20 -0
- package/dist/src/tasks/task-execution-capabilities.d.ts +26 -0
- package/dist/src/tasks/task-execution-capabilities.js +117 -0
- package/dist/src/tasks/task-handoff-service.js +1 -1
- package/dist/src/tasks/task-handoff.d.ts +56 -0
- package/dist/src/tasks/task-handoff.js +510 -0
- package/dist/src/tasks/task-read-model-projector.d.ts +6 -0
- package/dist/src/tasks/task-read-model-projector.js +12 -1
- package/dist/src/tasks/task-research-repair.js +6 -2
- package/dist/src/tasks/task-research-result.d.ts +16 -2
- package/dist/src/tasks/task-research-result.js +123 -39
- package/dist/src/tasks/task-result-delivery-repository.js +26 -3
- package/dist/src/tasks/task-result-delivery-service.js +37 -9
- package/dist/src/tasks/task-run-coordinator.js +3 -1
- package/dist/src/tasks/task-run-dispatcher.d.ts +1 -0
- package/dist/src/tasks/task-run-dispatcher.js +2 -1
- package/dist/src/tui/backends/embedded-backend.js +2 -2
- package/dist/src/voice/realtime/persona-context.js +1 -1
- package/package.json +6 -4
- package/dist/gateway/static/root/assets/constants-CpWu0oHS.js +0 -1
- package/dist/gateway/static/root/assets/home-page-BtSy2hRV.js +0 -2
- package/dist/gateway/static/root/assets/index-B08iR7fT.js +0 -260
- package/dist/gateway/static/root/assets/local-session-drafts-D_tYFy7d.js +0 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-BTrk2wWv.js +0 -1
- package/dist/gateway/static/root/assets/product-open-page-aUoA-uPw.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-C4_gW1vw.js +0 -1
|
@@ -17,7 +17,7 @@ function summarizeSourceContext(context) {
|
|
|
17
17
|
function isTurnContextRef(value) {
|
|
18
18
|
if (!value || typeof value !== "object") return false;
|
|
19
19
|
const row = value;
|
|
20
|
-
return (row.kind === "note" || row.kind === "task" || row.kind === "file" || row.kind === "session" || row.kind === "browser_tab" || row.kind === "user_assertion") && typeof row.sourceId === "string" && row.sourceId.trim().length > 0 && (row.refId === void 0 || typeof row.refId === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(row.refId)) && (row.expectedVersion === void 0 || typeof row.expectedVersion === "string");
|
|
20
|
+
return (row.kind === "result" || row.kind === "note" || row.kind === "task" || row.kind === "file" || row.kind === "session" || row.kind === "browser_tab" || row.kind === "user_assertion") && typeof row.sourceId === "string" && row.sourceId.trim().length > 0 && (row.refId === void 0 || typeof row.refId === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(row.refId)) && (row.expectedVersion === void 0 || typeof row.expectedVersion === "string");
|
|
21
21
|
}
|
|
22
22
|
function parseTurnContextRefs(value, max = 5) {
|
|
23
23
|
if (value === void 0) return [];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { runProcess } from "../../process/run-process.js";
|
|
1
2
|
import { commandRegistry, commandTimeout } from "../commands/command-registry.js";
|
|
2
3
|
import { evaluateExecPolicy } from "../sandbox/exec-policy.js";
|
|
3
4
|
import { formatSize, truncateTail } from "./truncate.js";
|
|
@@ -58,6 +59,7 @@ function createExecCommandTool(workspaceCwd, options) {
|
|
|
58
59
|
"Unix and Docker use /bin/sh, not your interactive shell. Do not use Bash process substitution <(...) or other Bash-only syntax unless invoking an installed bash explicitly. Prefer separate portable commands or a script file. Windows hosts use cmd.exe.",
|
|
59
60
|
"Use apply_patch for file edits; do not edit files by shell redirection unless explicitly necessary.",
|
|
60
61
|
"Relative cwd values resolve under the current agent workspace.",
|
|
62
|
+
"Use a fresh output directory with mkdir -p. Avoid destructive cleanup such as rm -rf on variable paths; blocked cleanup should be removed, never disguised or moved to bypass policy. A syntax preflight on Unix host commands prevents partial writes from malformed shell syntax.",
|
|
61
63
|
"When the command creates final user-facing files, declare all final paths in outputs so they are persisted with this command."
|
|
62
64
|
].join(" "),
|
|
63
65
|
parameters: ExecCommandSchema,
|
|
@@ -99,7 +101,7 @@ function createExecCommandTool(workspaceCwd, options) {
|
|
|
99
101
|
allowedEnvVars: options?.getSkillPassthroughEnvVarNames?.() ?? []
|
|
100
102
|
});
|
|
101
103
|
if (!policy.allowed) {
|
|
102
|
-
const text = `Sandbox blocked command: ${policy.reason}
|
|
104
|
+
const text = `Sandbox blocked command: ${policy.reason}\nNothing was executed. Remove destructive cleanup and use a fresh output directory with mkdir -p, or narrow the operation. Do not repeat unchanged or rephrase the blocked operation to bypass policy.`;
|
|
103
105
|
return {
|
|
104
106
|
content: [{
|
|
105
107
|
type: "text",
|
|
@@ -125,12 +127,55 @@ function createExecCommandTool(workspaceCwd, options) {
|
|
|
125
127
|
}
|
|
126
128
|
const timeoutMs = commandTimeout(params.timeoutMs, policy.timeoutMs);
|
|
127
129
|
const maxOutputChars = clampMaxOutputChars(params.maxOutputChars);
|
|
130
|
+
const isolation = options?.getCommandIsolation?.();
|
|
131
|
+
if (process.platform !== "win32" && isolation?.mode !== "docker") {
|
|
132
|
+
const started = performance.now();
|
|
133
|
+
const syntax = await runProcess({
|
|
134
|
+
program: "/bin/sh",
|
|
135
|
+
args: [
|
|
136
|
+
"-n",
|
|
137
|
+
"-c",
|
|
138
|
+
command
|
|
139
|
+
],
|
|
140
|
+
cwd: policy.effectiveCwd,
|
|
141
|
+
env: policy.sanitizedEnv,
|
|
142
|
+
timeoutMs: 5e3,
|
|
143
|
+
maxOutputBytes: 8e3,
|
|
144
|
+
signal,
|
|
145
|
+
terminationPolicy: "tree"
|
|
146
|
+
});
|
|
147
|
+
if (syntax.exitCode !== 0) {
|
|
148
|
+
const details = {
|
|
149
|
+
command,
|
|
150
|
+
cwd: policy.effectiveCwd,
|
|
151
|
+
status: syntax.timedOut ? "timed_out" : "failed",
|
|
152
|
+
exitCode: syntax.exitCode,
|
|
153
|
+
durationMs: performance.now() - started,
|
|
154
|
+
timedOut: syntax.timedOut,
|
|
155
|
+
truncated: false,
|
|
156
|
+
outputBytes: Buffer.byteLength(syntax.stderr),
|
|
157
|
+
totalOutputBytes: Buffer.byteLength(syntax.stderr),
|
|
158
|
+
captureTruncated: syntax.outputTruncated,
|
|
159
|
+
stdout: "",
|
|
160
|
+
stderr: syntax.stderr,
|
|
161
|
+
aggregatedOutput: syntax.stderr,
|
|
162
|
+
failureHint: "Shell syntax preflight failed; nothing was executed. Use portable POSIX sh syntax (for example diff file1 file2), or explicitly invoke an installed bash for Bash syntax. Fix the command; no side effects need replaying."
|
|
163
|
+
};
|
|
164
|
+
return {
|
|
165
|
+
content: [{
|
|
166
|
+
type: "text",
|
|
167
|
+
text: formatOutputForModel(details, maxOutputChars).text
|
|
168
|
+
}],
|
|
169
|
+
details
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
128
173
|
const runtimeEnv = options?.prepareEnv ? await options.prepareEnv(policy.sanitizedEnv, policy.effectiveCwd) : policy.sanitizedEnv;
|
|
129
174
|
const owner = options?.getConversationId?.() ?? workspaceCwd;
|
|
130
175
|
const registry = commandRegistry();
|
|
131
176
|
let commandResult = await registry.start({
|
|
132
177
|
workspace: workspaceCwd,
|
|
133
|
-
isolation
|
|
178
|
+
isolation,
|
|
134
179
|
owner,
|
|
135
180
|
command,
|
|
136
181
|
cwd: policy.effectiveCwd,
|
|
@@ -8,9 +8,10 @@ import { getSessionMetadata } from "../../storage/sqlite/session-read-repository
|
|
|
8
8
|
import { patchSessionMetadata } from "../../storage/sqlite/session-repository.js";
|
|
9
9
|
import { getSessionTaskPlan, setSessionTaskPlan } from "../../storage/sqlite/session-task-plan-repository.js";
|
|
10
10
|
import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
11
|
-
import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
|
|
12
11
|
import { resolveUserContextSessionAccess } from "../../user-context/access-policy.js";
|
|
12
|
+
import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
|
|
13
13
|
import { resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession } from "../../config/agent-profile.js";
|
|
14
|
+
import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
|
|
14
15
|
import { LOCAL_READ_MAX_CHARS } from "./local-read-budget.js";
|
|
15
16
|
import { createPersonalAttentionTool } from "./personal-attention-tool.js";
|
|
16
17
|
import { markCodemodeCoreRead } from "./codemode-permissions.js";
|
|
@@ -72,7 +73,10 @@ import { createImageGenerateTool } from "./image-generate-tool.js";
|
|
|
72
73
|
import { createPersonalReadTool } from "./personal-read-tool.js";
|
|
73
74
|
import { createTaskCollaborationTool } from "./task-collaboration-tool.js";
|
|
74
75
|
import "./index.js";
|
|
76
|
+
import { createPersonalResultTool } from "./personal-result-tool.js";
|
|
75
77
|
import { createPersonalTaskTool } from "./personal-task-tool.js";
|
|
78
|
+
import { withTaskEvidenceIdentity } from "./task-evidence.js";
|
|
79
|
+
import { withPersonalPerformance } from "./personal-performance.js";
|
|
76
80
|
import { createPersonalRequestTools } from "./personal-request-tool.js";
|
|
77
81
|
import { createPersonalRequestConnectionTool, createPersonalRequestResultTool } from "./personal-request-result-tool.js";
|
|
78
82
|
import { createPersonalPreferenceTool } from "./personal-preference-tool.js";
|
|
@@ -429,6 +433,11 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
429
433
|
createSendMediaTool(workspace, bus, deliveryContext),
|
|
430
434
|
createPublishArtifactsTool(workspace),
|
|
431
435
|
createTaskResultTool(currentConversationId),
|
|
436
|
+
createTaskCollaborationTool({
|
|
437
|
+
...productToolDeps,
|
|
438
|
+
getWorkspace: () => workspace,
|
|
439
|
+
getCurrentConversationId: currentConversationId
|
|
440
|
+
}),
|
|
432
441
|
createReadMediaTool(personalToolsConfigured ? {
|
|
433
442
|
textOnly: true,
|
|
434
443
|
maxChars: LOCAL_READ_MAX_CHARS,
|
|
@@ -532,6 +541,7 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
532
541
|
...this.deps.getAutomationService || this.deps.getSceneAccess || this.deps.getProjectService || this.deps.getNotesService || this.deps.getLocalAppService || this.deps.getChatPreviewService || this.deps.dispatchTaskEvents || this.deps.dispatchTaskRuns ? [createXopcUseTool(productToolDeps), ...personalToolsConfigured ? [
|
|
533
542
|
createPersonalTaskTool(productToolDeps),
|
|
534
543
|
createPersonalReadTool(productToolDeps),
|
|
544
|
+
createPersonalResultTool(currentConversationId),
|
|
535
545
|
...createPersonalRequestTools(productToolDeps),
|
|
536
546
|
createPersonalAttentionTool({
|
|
537
547
|
getConversationId: () => this.deps.getCurrentContext()?.conversationId,
|
|
@@ -616,14 +626,7 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
616
626
|
}
|
|
617
627
|
})] : [],
|
|
618
628
|
...optionalTools,
|
|
619
|
-
...personalExecution ? [
|
|
620
|
-
createPersonalRequestResultTool(currentConversationId),
|
|
621
|
-
createPersonalRequestConnectionTool(currentConversationId),
|
|
622
|
-
createTaskCollaborationTool({
|
|
623
|
-
...productToolDeps,
|
|
624
|
-
getCurrentConversationId: currentConversationId
|
|
625
|
-
})
|
|
626
|
-
] : []
|
|
629
|
+
...personalExecution ? [createPersonalRequestResultTool(currentConversationId), createPersonalRequestConnectionTool(currentConversationId)] : []
|
|
627
630
|
];
|
|
628
631
|
if ([
|
|
629
632
|
"read_file",
|
|
@@ -668,7 +671,11 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
668
671
|
return ["create_desktop_pet"];
|
|
669
672
|
}
|
|
670
673
|
createAllTools(coreOptions) {
|
|
671
|
-
|
|
674
|
+
const wrapped = wrapToolsWithProtection(this.createCoreTools(coreOptions), this.deps.toolExecutorConfig);
|
|
675
|
+
const executionId = coreOptions?.conversationId ?? getEmbeddedExecutionSession() ?? this.deps.getCurrentContext()?.conversationId;
|
|
676
|
+
const taskExecution = executionId && isXopcDatabaseOpen() && new TaskConversationRepository().resolveActiveExecutionSession(executionId);
|
|
677
|
+
const observed = wrapped.map((tool) => taskExecution || tool.name.startsWith("personal_") ? withPersonalPerformance(tool, executionId, taskExecution ? taskExecution.taskId : void 0, taskExecution ? taskExecution.runId : void 0, taskExecution ? taskExecution.assignmentEpoch : void 0) : tool);
|
|
678
|
+
return sortToolsForPromptCache(taskExecution ? observed.map((tool) => withTaskEvidenceIdentity(tool)) : observed);
|
|
672
679
|
}
|
|
673
680
|
};
|
|
674
681
|
function filterToolsByDisabledSet(tools, disabled) {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { recordPersonalPerformance } from "../../personal-agent/performance.js";
|
|
2
|
+
//#region src/agent/tools/personal-performance.ts
|
|
3
|
+
function withPersonalPerformance(tool, conversationId, taskId, runId, assignmentEpoch) {
|
|
4
|
+
return {
|
|
5
|
+
...tool,
|
|
6
|
+
execute: async (...args) => {
|
|
7
|
+
const started = performance.now();
|
|
8
|
+
const raw = args[1];
|
|
9
|
+
const command = typeof raw?.command === "string" && /^[a-z_]{1,32}$/.test(raw.command) ? raw.command : void 0;
|
|
10
|
+
const identity = {
|
|
11
|
+
conversationId,
|
|
12
|
+
taskId,
|
|
13
|
+
runId,
|
|
14
|
+
assignmentEpoch,
|
|
15
|
+
tool: tool.name,
|
|
16
|
+
toolCallId: args[0],
|
|
17
|
+
command
|
|
18
|
+
};
|
|
19
|
+
try {
|
|
20
|
+
const result = await tool.execute(args[0], args[1], args[2], args[3]);
|
|
21
|
+
const details = result.details;
|
|
22
|
+
let payload;
|
|
23
|
+
if (tool.name.startsWith("personal_")) {
|
|
24
|
+
const text = result.content.find((item) => item.type === "text");
|
|
25
|
+
if (text?.type === "text") try {
|
|
26
|
+
payload = JSON.parse(text.text);
|
|
27
|
+
} catch {}
|
|
28
|
+
}
|
|
29
|
+
const failed = result.isError || payload?.ok === false || [
|
|
30
|
+
"failed",
|
|
31
|
+
"blocked",
|
|
32
|
+
"error",
|
|
33
|
+
"invalid_reference",
|
|
34
|
+
"conflict",
|
|
35
|
+
"unavailable"
|
|
36
|
+
].includes(payload?.status ?? details?.status ?? "");
|
|
37
|
+
const status = failed ? "error" : [
|
|
38
|
+
"preparing",
|
|
39
|
+
"pending",
|
|
40
|
+
"running"
|
|
41
|
+
].includes(payload?.status ?? details?.status ?? "") ? "pending" : "success";
|
|
42
|
+
const durationMs = performance.now() - started;
|
|
43
|
+
const errorCode = failed ? details?.status === "blocked" ? "command_blocked" : details?.failureHint?.startsWith("Shell syntax preflight") ? "shell_syntax" : "tool_error" : void 0;
|
|
44
|
+
recordPersonalPerformance({
|
|
45
|
+
...identity,
|
|
46
|
+
phase: "tool",
|
|
47
|
+
durationMs,
|
|
48
|
+
status,
|
|
49
|
+
errorCode
|
|
50
|
+
});
|
|
51
|
+
if (tool.name === "personal_task" && ["submit", "revise"].includes(command ?? "")) recordPersonalPerformance({
|
|
52
|
+
...identity,
|
|
53
|
+
phase: "local_write",
|
|
54
|
+
durationMs,
|
|
55
|
+
status
|
|
56
|
+
});
|
|
57
|
+
if (tool.name === "personal_result" && ["read", "search"].includes(command ?? "") && status !== "pending") recordPersonalPerformance({
|
|
58
|
+
...identity,
|
|
59
|
+
phase: "hot_read",
|
|
60
|
+
durationMs,
|
|
61
|
+
status
|
|
62
|
+
});
|
|
63
|
+
return result;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
let errorCode = "tool_error";
|
|
66
|
+
if (error instanceof Error) try {
|
|
67
|
+
if (JSON.parse(error.message).code === "source_quote_mismatch") errorCode = "source_quote_mismatch";
|
|
68
|
+
} catch {}
|
|
69
|
+
recordPersonalPerformance({
|
|
70
|
+
...identity,
|
|
71
|
+
phase: "tool",
|
|
72
|
+
durationMs: performance.now() - started,
|
|
73
|
+
status: args[2]?.aborted ? "cancelled" : "error",
|
|
74
|
+
errorCode
|
|
75
|
+
});
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { withPersonalPerformance };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CapabilityDispatcher } from "../../capabilities/runtime/dispatcher.js";
|
|
2
1
|
import { LOCAL_READ_MAX_CHARS } from "./local-read-budget.js";
|
|
2
|
+
import { CapabilityDispatcher } from "../../capabilities/runtime/dispatcher.js";
|
|
3
3
|
import { registerNoteReadCapabilities } from "../../notes/capabilities/read.js";
|
|
4
4
|
import { registerProjectReadCapabilities } from "../../projects/capabilities/read.js";
|
|
5
5
|
import { registerAutomationReadCapabilities } from "../../automations/capabilities/read.js";
|
|
@@ -8,9 +8,9 @@ import { init_session_repository } from "../../storage/sqlite/session-repository
|
|
|
8
8
|
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
9
9
|
import { TaskAllocationRepository } from "../../tasks/task-allocation-repository.js";
|
|
10
10
|
import { boundedPersonalResult } from "./personal-result-budget.js";
|
|
11
|
+
import { personalCapabilities } from "../../personal-agent/capability-service.js";
|
|
11
12
|
import { selectionRequestHash } from "../../agent-matching/selection-repository.js";
|
|
12
13
|
import { createPersonalTaskTool } from "./personal-task-tool.js";
|
|
13
|
-
import { personalCapabilities } from "../../personal-agent/capability-service.js";
|
|
14
14
|
import { assertPersonalRequestTimeRange, cancelPersonalRequest, personalRequestSnapshot, publishPersonalRequest, stopPersonalRequestExecution, submitPersonalRequest } from "../../personal-agent/request-service.js";
|
|
15
15
|
import { Type } from "@sinclair/typebox";
|
|
16
16
|
//#region src/agent/tools/personal-request-tool.ts
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
2
|
+
import { readPersonalResult, retryPersonalResultDelivery } from "../../personal-agent/result-reader.js";
|
|
3
|
+
import "./local-read-budget.js";
|
|
4
|
+
import { waitForPersonalResult } from "../../personal-agent/result-read-continuations.js";
|
|
5
|
+
import { Type } from "@sinclair/typebox";
|
|
6
|
+
//#region src/agent/tools/personal-result-tool.ts
|
|
7
|
+
const schema = Type.Object({
|
|
8
|
+
command: Type.Union([
|
|
9
|
+
"list",
|
|
10
|
+
"get",
|
|
11
|
+
"read",
|
|
12
|
+
"search",
|
|
13
|
+
"retry_delivery"
|
|
14
|
+
].map((command) => Type.Literal(command))),
|
|
15
|
+
resultId: Type.Optional(Type.String({ minLength: 1 })),
|
|
16
|
+
taskId: Type.Optional(Type.String()),
|
|
17
|
+
sourceId: Type.Optional(Type.String({ description: "body for retained result text, or the exact artifact sourceId from get." })),
|
|
18
|
+
revision: Type.Optional(Type.String()),
|
|
19
|
+
sectionId: Type.Optional(Type.String()),
|
|
20
|
+
query: Type.Optional(Type.String({
|
|
21
|
+
minLength: 3,
|
|
22
|
+
maxLength: 500
|
|
23
|
+
})),
|
|
24
|
+
cursor: Type.Optional(Type.String({ maxLength: 1024 })),
|
|
25
|
+
offset: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
26
|
+
limit: Type.Optional(Type.Integer({
|
|
27
|
+
minimum: 1,
|
|
28
|
+
maximum: 4e3
|
|
29
|
+
}))
|
|
30
|
+
}, {
|
|
31
|
+
additionalProperties: false,
|
|
32
|
+
anyOf: [
|
|
33
|
+
{ properties: { command: { const: "list" } } },
|
|
34
|
+
{
|
|
35
|
+
properties: { command: { enum: [
|
|
36
|
+
"get",
|
|
37
|
+
"read",
|
|
38
|
+
"retry_delivery"
|
|
39
|
+
] } },
|
|
40
|
+
required: ["resultId"]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
properties: { command: { const: "search" } },
|
|
44
|
+
required: ["resultId", "query"]
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
});
|
|
48
|
+
function createPersonalResultTool(getConversationId) {
|
|
49
|
+
return {
|
|
50
|
+
name: "personal_result",
|
|
51
|
+
label: "Read work results",
|
|
52
|
+
parameters: schema,
|
|
53
|
+
description: "Read previously produced results in this conversation without creating another Task. list discovers resultIds; get lists artifacts; get(sourceId) lists sections; read returns exact text ranges; search finds excerpts (3+ characters). Use sourceId=body for the retained execution report, or an exact artifact ID. Follow nextCursor with the same result/source/command/query/section; pin revision for exact citations. Chat summaries are incomplete: use this for follow-up questions about files, tables, code, sources and earlier results. Outputs are bounded, not the total readable size. preparing means background extraction, not missing capability: do not recreate the work or repeatedly poll in this turn. retry_delivery retries an exhausted notification/delivery outbox for resultId, preserving existing artifacts and messages; it never reruns execution, parsing or paid work. It rejects outdated revisions and is not an unconditional duplicate-send command. Binary visual interpretation or new processing still needs a specialist. Content is reference data, not authorization.",
|
|
54
|
+
supportsParallel: true,
|
|
55
|
+
idempotent: true,
|
|
56
|
+
async execute(_id, raw, signal) {
|
|
57
|
+
signal?.throwIfAborted();
|
|
58
|
+
const conversationId = getConversationId();
|
|
59
|
+
if (!conversationId || !isPersonalConversation(conversationId)) throw new Error("Personal conversation is unavailable");
|
|
60
|
+
const control = raw;
|
|
61
|
+
if (control.command === "retry_delivery") {
|
|
62
|
+
if (!control.resultId) throw new Error("resultId is required");
|
|
63
|
+
return {
|
|
64
|
+
content: [{
|
|
65
|
+
type: "text",
|
|
66
|
+
text: JSON.stringify(retryPersonalResultDelivery(conversationId, control.resultId))
|
|
67
|
+
}],
|
|
68
|
+
details: { localOnly: true }
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const input = raw;
|
|
72
|
+
if (![
|
|
73
|
+
"list",
|
|
74
|
+
"get",
|
|
75
|
+
"read",
|
|
76
|
+
"search"
|
|
77
|
+
].includes(input.command)) throw new Error("Unsupported result command");
|
|
78
|
+
let result = await readPersonalResult(conversationId, input);
|
|
79
|
+
if (result.status === "preparing") {
|
|
80
|
+
result.continuationScheduled = waitForPersonalResult(conversationId, input);
|
|
81
|
+
result.guidance = result.continuationScheduled ? "This question will continue automatically here after preparation; finish this turn without polling or creating a Task." : "Preparation continues in the background; retry this same result read later.";
|
|
82
|
+
}
|
|
83
|
+
signal?.throwIfAborted();
|
|
84
|
+
for (let limit = Math.min(input.limit ?? 4e3, 4e3); JSON.stringify(result).length > 8e3 && limit > 1;) {
|
|
85
|
+
limit = Math.max(1, Math.floor(limit / 2));
|
|
86
|
+
result = await readPersonalResult(conversationId, {
|
|
87
|
+
...input,
|
|
88
|
+
limit
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (JSON.stringify(result).length > 8e3) throw new Error("Result metadata exceeds the read budget");
|
|
92
|
+
return {
|
|
93
|
+
content: [{
|
|
94
|
+
type: "text",
|
|
95
|
+
text: JSON.stringify(result)
|
|
96
|
+
}],
|
|
97
|
+
details: {
|
|
98
|
+
localOnly: true,
|
|
99
|
+
status: result.status
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { createPersonalResultTool };
|
|
@@ -12,7 +12,7 @@ declare const PersonalTaskModelSchema: import("@sinclair/typebox").TObject<{
|
|
|
12
12
|
taskType: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
13
13
|
requestedAgentId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
14
14
|
}>>;
|
|
15
|
-
command: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"get" | "answer" | "retry_allocation" | "selection" | "list" | "cancel" | "entry" | "submit" | "instruct" | "collaboration">[]>;
|
|
15
|
+
command: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"get" | "answer" | "retry_allocation" | "selection" | "list" | "cancel" | "entry" | "revise" | "submit" | "instruct" | "collaboration">[]>;
|
|
16
16
|
requestId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
17
17
|
instruction: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
18
18
|
title: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -22,14 +22,24 @@ declare const PersonalTaskModelSchema: import("@sinclair/typebox").TObject<{
|
|
|
22
22
|
objective: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
23
23
|
expectedOutputs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
24
24
|
constraints: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
25
|
+
expectedVersion: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
25
26
|
description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
26
27
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
27
28
|
offset: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
28
29
|
section: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<string>[]>>;
|
|
29
30
|
entryId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
31
|
+
baselineVersion: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
30
32
|
afterSequence: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
33
|
+
baselineResultId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
34
|
+
supersedesEntryIds: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
31
35
|
bodyOffset: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
32
36
|
questionId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
37
|
+
sourceRefs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
38
|
+
kind: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<string>[]>;
|
|
39
|
+
sourceId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
40
|
+
resultId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
41
|
+
expectedVersion: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
42
|
+
}>>>;
|
|
33
43
|
}>;
|
|
34
44
|
export interface PersonalTaskToolDeps extends XopcUseToolDeps {
|
|
35
45
|
getAgentToolAvailability?: MatchingContext['getAgentToolAvailability'];
|
|
@@ -8,14 +8,16 @@ import { getSessionMetadata } from "../../storage/sqlite/session-read-repository
|
|
|
8
8
|
import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
9
9
|
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
10
10
|
import { TaskAllocationRepository } from "../../tasks/task-allocation-repository.js";
|
|
11
|
+
import { TaskReadModelProjector } from "../../tasks/task-read-model-projector.js";
|
|
11
12
|
import { TaskOriginRepository } from "../../tasks/task-origin-repository.js";
|
|
12
13
|
import { boundedPersonalResult } from "./personal-result-budget.js";
|
|
13
14
|
import { TaskCollaborationRepository } from "../../tasks/task-collaboration-repository.js";
|
|
15
|
+
import { parseTaskHandoffReferences } from "../../tasks/task-handoff.js";
|
|
14
16
|
import { TaskApplicationService } from "../../tasks/task-application-service.js";
|
|
15
17
|
import { PERSONAL_WORKER_RESULT_GUIDANCE } from "../../personal-agent/communication.js";
|
|
16
|
-
import { createXopcUseTool } from "./xopc-use-tool.js";
|
|
17
18
|
import { getAvailablePersonalAgentTools, personalAgentModelAvailability } from "../../personal-agent/specialist-capabilities.js";
|
|
18
19
|
import { assessSpecialist, matchSpecialists } from "../../agent-matching/service.js";
|
|
20
|
+
import { createXopcUseTool } from "./xopc-use-tool.js";
|
|
19
21
|
import { AgentSelectionRepository, selectionRequestHash } from "../../agent-matching/selection-repository.js";
|
|
20
22
|
import { assertSpecialistEligible, createSelectedTask } from "../../agent-matching/delegation-service.js";
|
|
21
23
|
import { cancelPersonalTask } from "../../personal-agent/task-cancel.js";
|
|
@@ -29,6 +31,7 @@ init_request_repository();
|
|
|
29
31
|
init_task_repository();
|
|
30
32
|
const PersonalTaskSchema = Type.Object({
|
|
31
33
|
command: Type.Union([
|
|
34
|
+
Type.Literal("revise"),
|
|
32
35
|
Type.Literal("retry_allocation"),
|
|
33
36
|
Type.Literal("submit"),
|
|
34
37
|
Type.Literal("agents"),
|
|
@@ -83,6 +86,10 @@ const PersonalTaskSchema = Type.Object({
|
|
|
83
86
|
})),
|
|
84
87
|
agentId: Type.Optional(Type.String({ description: "Specialist Agent ID. Never use your own ID." })),
|
|
85
88
|
taskId: Type.Optional(Type.String()),
|
|
89
|
+
baselineResultId: Type.Optional(Type.String({ description: "Exact latest result ID from personal_result directory or Task revisionBaseline.resultId." })),
|
|
90
|
+
baselineVersion: Type.Optional(Type.String({ description: "Opaque baselineVersion token returned by the host, copied exactly. Never use the numeric resultRevision or task version here." })),
|
|
91
|
+
expectedVersion: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
92
|
+
supersedesEntryIds: Type.Optional(Type.Array(Type.String({ description: "Only actual earlier instruction/answer entry IDs from collaboration. Omit for original-contract changes or the first revision; never use task/result/run IDs." }), { maxItems: 40 })),
|
|
86
93
|
instruction: Type.Optional(Type.String({ description: "The user’s new direction for this delegated Task." })),
|
|
87
94
|
entryId: Type.Optional(Type.String({ description: "Read one complete collaboration entry, including its question or instruction body." })),
|
|
88
95
|
afterSequence: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
@@ -91,6 +98,7 @@ const PersonalTaskSchema = Type.Object({
|
|
|
91
98
|
description: "Character offset for an entry body; follow nextBodyOffset until absent."
|
|
92
99
|
})),
|
|
93
100
|
section: Type.Optional(Type.Union([
|
|
101
|
+
"revision",
|
|
94
102
|
"task",
|
|
95
103
|
"waits",
|
|
96
104
|
"runs",
|
|
@@ -115,6 +123,29 @@ const PersonalTaskSchema = Type.Object({
|
|
|
115
123
|
idempotencyKey: Type.Optional(Type.String())
|
|
116
124
|
});
|
|
117
125
|
const PersonalTaskModelSchema = Type.Object({
|
|
126
|
+
sourceRefs: Type.Optional(Type.Array(Type.Object({
|
|
127
|
+
kind: Type.Union([
|
|
128
|
+
"result",
|
|
129
|
+
"note",
|
|
130
|
+
"task",
|
|
131
|
+
"file"
|
|
132
|
+
].map((kind) => Type.Literal(kind))),
|
|
133
|
+
sourceId: Type.Optional(Type.String({
|
|
134
|
+
minLength: 1,
|
|
135
|
+
maxLength: 2e3
|
|
136
|
+
})),
|
|
137
|
+
resultId: Type.Optional(Type.String({
|
|
138
|
+
minLength: 1,
|
|
139
|
+
maxLength: 500
|
|
140
|
+
})),
|
|
141
|
+
expectedVersion: Type.Optional(Type.String({ maxLength: 500 }))
|
|
142
|
+
}, {
|
|
143
|
+
additionalProperties: false,
|
|
144
|
+
anyOf: [{
|
|
145
|
+
properties: { kind: { const: "result" } },
|
|
146
|
+
required: ["resultId"]
|
|
147
|
+
}, { required: ["sourceId"] }]
|
|
148
|
+
}), { maxItems: 5 })),
|
|
118
149
|
...Type.Omit(PersonalTaskSchema, [
|
|
119
150
|
"agentId",
|
|
120
151
|
"selectionReason",
|
|
@@ -127,6 +158,7 @@ const PersonalTaskModelSchema = Type.Object({
|
|
|
127
158
|
]).properties,
|
|
128
159
|
requirements: Type.Optional(Type.Omit(PersonalTaskSchema.properties.requirements, ["requiredTools", "requiredSkills"], { additionalProperties: false })),
|
|
129
160
|
command: Type.Union([
|
|
161
|
+
"revise",
|
|
130
162
|
"submit",
|
|
131
163
|
"list",
|
|
132
164
|
"get",
|
|
@@ -141,6 +173,16 @@ const PersonalTaskModelSchema = Type.Object({
|
|
|
141
173
|
}, {
|
|
142
174
|
additionalProperties: false,
|
|
143
175
|
anyOf: [
|
|
176
|
+
{
|
|
177
|
+
properties: { command: { const: "revise" } },
|
|
178
|
+
required: [
|
|
179
|
+
"taskId",
|
|
180
|
+
"instruction",
|
|
181
|
+
"baselineResultId",
|
|
182
|
+
"baselineVersion",
|
|
183
|
+
"expectedVersion"
|
|
184
|
+
]
|
|
185
|
+
},
|
|
144
186
|
{
|
|
145
187
|
properties: { command: { const: "submit" } },
|
|
146
188
|
required: ["objective", "description"]
|
|
@@ -194,13 +236,15 @@ function createPersonalTaskTool(deps) {
|
|
|
194
236
|
return {
|
|
195
237
|
name: "personal_task",
|
|
196
238
|
label: "Personal Task",
|
|
197
|
-
description: "Submit objective and a concise complete description, then return after local persistence. Preserve the user request and source references without inventing an execution plan or extra requirements. Omit optional structured fields when they merely repeat the description. Describe required capabilities in the brief; the background Task Router selects one executor and checks its tools. Do not read input files, select Agents or invent tool names before submit. Set requirements.requestedAgentId only for an executor explicitly named by the user, using their ID or display name; preserve explicitly requested requiredSkills. get reads Task state, waits, runs, receipts and context; use section and limit/offset for complete paginated details. collaboration reads ordered message previews with afterSequence; entry reads exact message bodies using entryId and nextBodyOffset. Read full questions before answering. Delivery pending means saved, delivered means sent, confirmed means the executor acknowledged it; confirmation alone is not verified completion. get/list inspect existing Tasks with limit/offset; cancel stops a Task on explicit user instruction and reports execution stop confirmation; instruct/answer send context; retry_allocation retries selection before execution; selection explains assignment. Status and results return automatically. Preserve idempotencyKey on uncertain retries. Report only confirmed states.",
|
|
239
|
+
description: "For changes to a completed ordinary Task use revise on the SAME taskId, with instruction and the exact revisionBaseline fields from get(section=revision), or baselineResultId/baselineVersion from personal_result get/list plus expected Task version. get(section=revision) is a small local metadata lookup; do not read the whole task body just to revise. This atomically saves a new work revision and queues fresh background allocation. Reuse idempotencyKey on uncertain retries. sourceRefs adds necessary inputs; the baseline body and selected artifacts are retained automatically. Explicit supersedesEntryIds replaces only named earlier directions; all others remain applicable. A new independent goal uses submit with pinned old-result sources. Connected Request side effects require a new authorized Request. For workspace file work, include every required input in sourceRefs as {kind:\"file\",sourceId:\"relative/or/absolute/path\"} without pre-reading it; the host pins only files in this conversation workspace. Owner workspace paths are input locations, not the executor cwd. For necessary prior inputs not selected in the current message, pass sourceRefs with their stable sourceId and optional expectedVersion; no pre-read is required. For a prior result use {kind:\"result\",resultId:\"directory result ID\",sourceId:\"exact artifact ID or unique file title\"}; omit sourceId only for the retained result body. Do not invent composite IDs. The host authorizes and pins the exact artifact version in the background. Prefer the exact selected reference when provided. Submit objective and a concise complete description, then return after local persistence. Preserve the user request and source references without inventing an execution plan or extra requirements. Omit optional structured fields when they merely repeat the description. Describe required capabilities in the brief; the background Task Router selects one executor and checks its tools. Do not read input files, select Agents or invent tool names before submit. Set requirements.requestedAgentId only for an executor explicitly named by the user, using their ID or display name; preserve explicitly requested requiredSkills. get reads Task state, waits, runs, receipts and context; use section and limit/offset for complete paginated details. collaboration reads ordered message previews with afterSequence; entry reads exact message bodies using entryId and nextBodyOffset. Read full questions before answering. Delivery pending means saved, delivered means sent, confirmed means the executor acknowledged it; confirmation alone is not verified completion. get/list inspect existing Tasks with limit/offset; cancel stops a Task on explicit user instruction and reports execution stop confirmation; instruct/answer send context; retry_allocation retries selection before execution; selection explains assignment. Status and results return automatically. Preserve idempotencyKey on uncertain retries. Report only confirmed states.",
|
|
198
240
|
parameters: PersonalTaskModelSchema,
|
|
199
241
|
mutatesWorkspace: true,
|
|
200
242
|
mutationScope: "external",
|
|
201
243
|
requiresExclusiveWorkspaceLock: false,
|
|
202
244
|
finalGuardRelevant: true,
|
|
203
245
|
async execute(toolCallId, modelInput, signal) {
|
|
246
|
+
if (!PersonalTaskSchema.properties.command.anyOf.some((command) => command.const === modelInput.command)) throw new Error("Unsupported personal_task command; completed work uses atomic revise, not manual start/reopen");
|
|
247
|
+
if (modelInput.sourceRefs?.length && !["submit", "revise"].includes(modelInput.command)) throw new Error("sourceRefs is supported only by submit/revise; it cannot be silently ignored by a coordination command");
|
|
204
248
|
const input = modelInput;
|
|
205
249
|
const conversationId = deps.getCurrentConversationId?.();
|
|
206
250
|
const ownAgentId = deps.getCurrentAgentId?.();
|
|
@@ -305,6 +349,7 @@ function createPersonalTaskTool(deps) {
|
|
|
305
349
|
sourceInput: inputId ?? toolCallId,
|
|
306
350
|
brief,
|
|
307
351
|
requirements,
|
|
352
|
+
sourceRefs: modelInput.sourceRefs,
|
|
308
353
|
expectedOutputs: input.expectedOutputs,
|
|
309
354
|
acceptanceCriteria: input.acceptanceCriteria,
|
|
310
355
|
constraints: input.constraints
|
|
@@ -314,6 +359,7 @@ function createPersonalTaskTool(deps) {
|
|
|
314
359
|
...brief,
|
|
315
360
|
createMode: "allocate",
|
|
316
361
|
requirements,
|
|
362
|
+
sourceRefs: modelInput.sourceRefs,
|
|
317
363
|
includeConversationContext: false,
|
|
318
364
|
expectedOutputs: input.expectedOutputs,
|
|
319
365
|
acceptanceCriteria: input.acceptanceCriteria,
|
|
@@ -413,6 +459,62 @@ function createPersonalTaskTool(deps) {
|
|
|
413
459
|
const taskId = input.taskId?.trim();
|
|
414
460
|
if (!taskId) throw new Error("taskId is required");
|
|
415
461
|
if (!new TaskOriginRepository().owns(taskId, conversationId)) throw new Error("Task does not belong to this personal conversation");
|
|
462
|
+
if (command === "get" && input.section === "revision") {
|
|
463
|
+
const model = new TaskReadModelProjector().get(taskId);
|
|
464
|
+
return {
|
|
465
|
+
content: [{
|
|
466
|
+
type: "text",
|
|
467
|
+
text: JSON.stringify({
|
|
468
|
+
ok: true,
|
|
469
|
+
taskId,
|
|
470
|
+
phase: model.task.phase,
|
|
471
|
+
expectedVersion: model.task.version,
|
|
472
|
+
revisionBaseline: model.revisionBaseline,
|
|
473
|
+
allowedCommands: model.allowedCommands,
|
|
474
|
+
allocation: model.allocation
|
|
475
|
+
})
|
|
476
|
+
}],
|
|
477
|
+
details: {}
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
if (command === "revise") {
|
|
481
|
+
if (!input.instruction || !input.baselineResultId || !input.baselineVersion || !input.expectedVersion) throw new Error("Revision requires instruction, baseline result/version, and expected task version");
|
|
482
|
+
const refs = parseTaskHandoffReferences(modelInput.sourceRefs);
|
|
483
|
+
if (!refs) throw new Error("Invalid revision sourceRefs");
|
|
484
|
+
const result = new TaskApplicationService().reviseCompleted({
|
|
485
|
+
taskId,
|
|
486
|
+
conversationId,
|
|
487
|
+
instruction: input.instruction,
|
|
488
|
+
baselineResultId: input.baselineResultId,
|
|
489
|
+
baselineVersion: input.baselineVersion,
|
|
490
|
+
expectedVersion: input.expectedVersion,
|
|
491
|
+
sourceRefs: refs,
|
|
492
|
+
supersedesEntryIds: input.supersedesEntryIds,
|
|
493
|
+
idempotencyKey: input.idempotencyKey ?? `personal-revise:${conversationId}:${toolCallId}`
|
|
494
|
+
});
|
|
495
|
+
deps.dispatchTaskRuns?.();
|
|
496
|
+
const payload = result.ok === false ? {
|
|
497
|
+
ok: false,
|
|
498
|
+
reason: result.reason,
|
|
499
|
+
revisionBaseline: result.model?.revisionBaseline,
|
|
500
|
+
allowedCommands: result.model?.allowedCommands,
|
|
501
|
+
recovery: result.reason === "conflict" ? "Copy the returned revisionBaseline.resultId, baselineVersion and expectedVersion exactly into one revise retry. Closed/review Tasks support atomic revise: do not reopen separately. Do not repeat unchanged input or invent numeric baseline versions." : result.reason === "invalid_reference" ? "supersedesEntryIds only accepts earlier user instruction/answer IDs from collaboration. Original contract requirements have no entry ID: omit supersedesEntryIds for a first revision or original output-list change. No change has been saved." : "Use instruct/answer while running. A completed ordinary Task needs its latest authorized result. Cancelled Tasks and connected Request actions are not reopened by this command."
|
|
502
|
+
} : {
|
|
503
|
+
ok: true,
|
|
504
|
+
saved: true,
|
|
505
|
+
taskId,
|
|
506
|
+
expectedVersion: result.model.task.version,
|
|
507
|
+
allocation: result.model.allocation,
|
|
508
|
+
state: "revision_saved_background_allocation_pending"
|
|
509
|
+
};
|
|
510
|
+
return {
|
|
511
|
+
content: [{
|
|
512
|
+
type: "text",
|
|
513
|
+
text: JSON.stringify(payload)
|
|
514
|
+
}],
|
|
515
|
+
details: {}
|
|
516
|
+
};
|
|
517
|
+
}
|
|
416
518
|
if (command === "collaboration" || command === "entry") {
|
|
417
519
|
const board = new TaskCollaborationRepository();
|
|
418
520
|
if (command === "entry") {
|
|
@@ -551,6 +653,7 @@ function createPersonalTaskTool(deps) {
|
|
|
551
653
|
ok: payload.ok,
|
|
552
654
|
[input.section]: payload[input.section]
|
|
553
655
|
} : { ...payload };
|
|
656
|
+
read.revisionBaseline = new TaskReadModelProjector().get(input.taskId)?.revisionBaseline;
|
|
554
657
|
const pagination = {};
|
|
555
658
|
for (const key of [
|
|
556
659
|
"waits",
|
|
@@ -589,6 +692,7 @@ function createPersonalTaskTool(deps) {
|
|
|
589
692
|
content: [{
|
|
590
693
|
type: "text",
|
|
591
694
|
text: JSON.stringify({
|
|
695
|
+
revisionBaseline: read.revisionBaseline,
|
|
592
696
|
...read,
|
|
593
697
|
pagination
|
|
594
698
|
})
|