@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
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { isXopcDatabaseOpen } from "../../storage/sqlite/connection.js";
|
|
2
|
+
import { getSessionMetadata } from "../../storage/sqlite/session-read-repository.js";
|
|
3
|
+
import { getSessionConfig } from "../../storage/sqlite/config-repository.js";
|
|
4
|
+
import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
5
|
+
import { AgentCatalogRepository, init_repository } from "../../agent-catalog/repository.js";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { getCurrentTools } from "@earendil-works/pi-ai";
|
|
8
|
+
//#region src/agent/embedded/agent-profile-context.ts
|
|
9
|
+
init_repository();
|
|
10
|
+
init_sqlite();
|
|
11
|
+
const AGENT_PROFILE_CONTEXT_STATE = "xopc.agent-profile-context";
|
|
12
|
+
const AGENT_PROFILE_UPDATE_EVENT = "xopc.agent-profile-update";
|
|
13
|
+
function agentProfileContextFingerprint(agentId, profile, responseLanguage) {
|
|
14
|
+
return createHash("sha256").update(JSON.stringify({
|
|
15
|
+
agentId,
|
|
16
|
+
responseLanguage: responseLanguage ?? "auto",
|
|
17
|
+
name: profile?.name,
|
|
18
|
+
description: profile?.description,
|
|
19
|
+
creature: profile?.creature,
|
|
20
|
+
style: profile?.style,
|
|
21
|
+
language: profile?.language,
|
|
22
|
+
instructions: profile?.instructions
|
|
23
|
+
})).digest("hex");
|
|
24
|
+
}
|
|
25
|
+
/** Keep profile transitions separate from user messages and model-authored conversation. */
|
|
26
|
+
function createAgentProfileContextExtension(conversationId) {
|
|
27
|
+
return (pi) => {
|
|
28
|
+
const snapshotForTurn = (context) => {
|
|
29
|
+
if (!isXopcDatabaseOpen()) return;
|
|
30
|
+
const agentId = getSessionMetadata(conversationId)?.agentId;
|
|
31
|
+
if (!agentId) return;
|
|
32
|
+
const profile = new AgentCatalogRepository().get(agentId)?.profile;
|
|
33
|
+
const responseLanguage = getSessionConfig(conversationId)?.responseLanguage ?? "auto";
|
|
34
|
+
const fingerprint = agentProfileContextFingerprint(agentId, profile, responseLanguage);
|
|
35
|
+
const configuration = {
|
|
36
|
+
agentId,
|
|
37
|
+
name: profile?.name ?? agentId,
|
|
38
|
+
role: profile?.description || null,
|
|
39
|
+
type: profile?.creature || null,
|
|
40
|
+
style: profile?.style || null,
|
|
41
|
+
primaryLanguage: profile?.language || null,
|
|
42
|
+
responseLanguageOverride: responseLanguage
|
|
43
|
+
};
|
|
44
|
+
const previous = context.sessionManager.getBranch().findLast((entry) => entry.type === "custom" && entry.customType === "xopc.agent-profile-context");
|
|
45
|
+
const data = previous?.type === "custom" ? previous.data : void 0;
|
|
46
|
+
const changed = data?.fingerprint !== fingerprint || JSON.stringify(data?.configuration) !== JSON.stringify(configuration);
|
|
47
|
+
if (changed) pi.appendEntry(AGENT_PROFILE_CONTEXT_STATE, {
|
|
48
|
+
fingerprint,
|
|
49
|
+
configuration
|
|
50
|
+
});
|
|
51
|
+
const changedFields = Object.keys(configuration).filter((key) => configuration[key] !== data?.configuration?.[key]);
|
|
52
|
+
const updates = Object.fromEntries(changedFields.map((key) => [key, {
|
|
53
|
+
previous: data?.configuration?.[key] ?? null,
|
|
54
|
+
current: configuration[key] ?? null
|
|
55
|
+
}]));
|
|
56
|
+
return {
|
|
57
|
+
role: "custom",
|
|
58
|
+
timestamp: Date.now(),
|
|
59
|
+
customType: AGENT_PROFILE_UPDATE_EVENT,
|
|
60
|
+
content: JSON.stringify({
|
|
61
|
+
event: changed ? "agent_configuration_updated" : "agent_configuration_current",
|
|
62
|
+
source: "xopc-runtime",
|
|
63
|
+
...changed ? {
|
|
64
|
+
changedFields: changedFields.length ? changedFields : ["instructions"],
|
|
65
|
+
updates
|
|
66
|
+
} : {},
|
|
67
|
+
current: configuration
|
|
68
|
+
}),
|
|
69
|
+
display: false
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
let snapshot;
|
|
73
|
+
pi.on("before_agent_start", (_event, context) => {
|
|
74
|
+
snapshot = snapshotForTurn(context);
|
|
75
|
+
});
|
|
76
|
+
pi.on("context_with_system", (event, context) => {
|
|
77
|
+
snapshot ??= snapshotForTurn(context);
|
|
78
|
+
if (!snapshot) return;
|
|
79
|
+
const messages = event.messages.filter((message) => message.role !== "system" && !(message.role === "custom" && message.customType === "xopc.agent-profile-update"));
|
|
80
|
+
const inputIndex = messages.findLastIndex((message) => message.role === "user" || message.role === "custom");
|
|
81
|
+
messages.splice(inputIndex < 0 ? messages.length : inputIndex, 0, snapshot);
|
|
82
|
+
return { messages: [{
|
|
83
|
+
role: "system",
|
|
84
|
+
content: context.getSystemPrompt(),
|
|
85
|
+
toolsAdded: getCurrentTools(event.messages),
|
|
86
|
+
timestamp: Date.now()
|
|
87
|
+
}, ...messages] };
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { AGENT_PROFILE_CONTEXT_STATE, AGENT_PROFILE_UPDATE_EVENT, agentProfileContextFingerprint, createAgentProfileContextExtension };
|
|
@@ -17,6 +17,7 @@ import { assessContext, recoverContext as recoverContext$1 } from "../memory/con
|
|
|
17
17
|
import { resolveCompactionPolicy } from "../memory/compaction-policy.js";
|
|
18
18
|
import { runXopcEmbeddedTurn } from "./run-turn.js";
|
|
19
19
|
import { projectTurnOutcome } from "../../session/turn-outcome-projector.js";
|
|
20
|
+
import { connectionObjectiveContext } from "../context/connection-objective-context.js";
|
|
20
21
|
import { voicePresentationPrompt } from "../prompt/voice-presentation.js";
|
|
21
22
|
import { applyStartupContextToUserMessage } from "../reply/apply-turn-user-enrichment.js";
|
|
22
23
|
import { AgentRunSupervisor } from "../orchestration/agent-run-supervisor.js";
|
|
@@ -59,6 +60,7 @@ async function runEmbeddedTurnForSessionInner(params) {
|
|
|
59
60
|
...result,
|
|
60
61
|
ok: false,
|
|
61
62
|
retryable: false,
|
|
63
|
+
terminationReason: "deadline_exceeded",
|
|
62
64
|
errorMessage: supervisor.signal.reason.message
|
|
63
65
|
};
|
|
64
66
|
turnCompleted = result.ok && result.stopReason !== "connection_required" && result.stopReason !== "clarification_required";
|
|
@@ -138,7 +140,7 @@ async function runEmbeddedTurnForSessionInner(params) {
|
|
|
138
140
|
const executionToolPolicy = resolveExecutionToolPolicy(conversationId);
|
|
139
141
|
const tools = filterExecutionTools(executionToolPolicy, agent.state.tools);
|
|
140
142
|
const turnPolicy = agentManager.createAgentTurnPolicy(conversationId);
|
|
141
|
-
const systemPrompt = appendDynamicPromptSection([agent.state.systemPrompt ?? "", params.presentation === "voice" ? voicePresentationPrompt : ""].filter(Boolean).join("\n\n"), params.dynamicSystemContext
|
|
143
|
+
const systemPrompt = appendDynamicPromptSection([agent.state.systemPrompt ?? "", params.presentation === "voice" ? voicePresentationPrompt : ""].filter(Boolean).join("\n\n"), [params.dynamicSystemContext, connectionObjectiveContext(conversationId)].filter(Boolean).join("\n\n"));
|
|
142
144
|
const idlePolicy = resolveCompactionPolicy(config);
|
|
143
145
|
if (personal && idlePolicy.enabled && idlePolicy.personalIdle.enabled) idleJob = async (signal, isCurrent) => {
|
|
144
146
|
const messages = await sessionStore.load(conversationId);
|
|
@@ -304,6 +306,7 @@ async function runEmbeddedTurnForSessionInner(params) {
|
|
|
304
306
|
onAgentEvent: (event) => agentManager.emitRuntimeEvent(conversationId, event),
|
|
305
307
|
resumeLastUserMessage,
|
|
306
308
|
recoveryMessage: taskContinuation?.message,
|
|
309
|
+
recoveryReason: taskContinuation?.reason,
|
|
307
310
|
requireVisibleReply: params.requireVisibleReply
|
|
308
311
|
}), runId));
|
|
309
312
|
attempt.finish(turnResult.ok ? "success" : "error", turnResult.errorMessage);
|
|
@@ -350,7 +353,7 @@ async function runEmbeddedTurnForSessionInner(params) {
|
|
|
350
353
|
}, hasNextCandidate ? "Agent model call threw, trying fallback" : "Agent model call threw, no fallback remains");
|
|
351
354
|
}
|
|
352
355
|
if (hasNextCandidate && rowsBeforeAttempt) {
|
|
353
|
-
const preparation = await sessionStore.prepareModelFallback(conversationId, rowsBeforeAttempt);
|
|
356
|
+
const preparation = await sessionStore.prepareModelFallback(conversationId, rowsBeforeAttempt, { resumeTaskContinuation: Boolean(taskContinuation?.message) });
|
|
354
357
|
if (preparation === "unsafe") {
|
|
355
358
|
log.warn({
|
|
356
359
|
conversationId,
|
|
@@ -10,9 +10,10 @@ import { resolveEffectiveAgentConfigForSession } from "../../config/agent-profil
|
|
|
10
10
|
import { setTraceIdentity, traceOperation, traceRun, traceTools } from "../../observability/runtime.js";
|
|
11
11
|
import { continuesAfterTool, trackAiUsageStream } from "../../usage/recorder.js";
|
|
12
12
|
import { cloudCreditBudgetStopMessage, isCloudCreditBudgetExhausted, reportCloudCreditError, withCloudCreditBudget } from "../../providers/xopc-cloud-credit-budget.js";
|
|
13
|
-
import {
|
|
13
|
+
import { resolveAgentAbortReason } from "../orchestration/run-termination.js";
|
|
14
|
+
import { isAgentTurnTimeoutError, isAgentTurnUnsettledError, resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
|
|
14
15
|
import { isContextOverflowError } from "../orchestration/context-overflow.js";
|
|
15
|
-
import { canResumeAfterModelFailure, completedRecoveryToolResult } from "../orchestration/turn-recovery.js";
|
|
16
|
+
import { ACCEPTANCE_REPAIR_READ_TOOLS, canResumeAfterModelFailure, completedRecoveryToolResult } from "../orchestration/turn-recovery.js";
|
|
16
17
|
import { getAssistantTurnErrorMessage, isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure, stripTrailingErrorAssistantMessages } from "../orchestration/llm-turn-retry.js";
|
|
17
18
|
import { allowsExecutionTool, filterExecutionTools, resolveExecutionToolPolicy } from "./execution-tool-policy.js";
|
|
18
19
|
import { runWithEmbeddedExecutionSession } from "./execution-context.js";
|
|
@@ -360,6 +361,7 @@ async function runXopcEmbeddedTurnInner(params) {
|
|
|
360
361
|
await session.abort();
|
|
361
362
|
return {
|
|
362
363
|
ok: false,
|
|
364
|
+
terminationReason: resolveAgentAbortReason(runAbortSignal.reason),
|
|
363
365
|
errorMessage: "aborted"
|
|
364
366
|
};
|
|
365
367
|
}
|
|
@@ -650,7 +652,8 @@ async function runXopcEmbeddedTurnInner(params) {
|
|
|
650
652
|
"status",
|
|
651
653
|
"list"
|
|
652
654
|
].includes(String(context.args.action));
|
|
653
|
-
|
|
655
|
+
const repairPublication = ["acceptance_repair", "model_failure"].includes(params.recoveryReason ?? "") && ["publish_artifacts", "publish_task_result"].includes(context.toolCall.name);
|
|
656
|
+
if (recoveringModel && !readOnly && !repairPublication) {
|
|
654
657
|
const recorded = completedRecoveryToolResult(recoveryMessages, context.toolCall.name, context.args);
|
|
655
658
|
if (recorded) return {
|
|
656
659
|
block: true,
|
|
@@ -748,10 +751,16 @@ async function runXopcEmbeddedTurnInner(params) {
|
|
|
748
751
|
};
|
|
749
752
|
runAbortSignal.addEventListener("abort", abortListener, { once: true });
|
|
750
753
|
try {
|
|
754
|
+
if (runAbortSignal.aborted) return {
|
|
755
|
+
ok: false,
|
|
756
|
+
terminationReason: resolveAgentAbortReason(runAbortSignal.reason),
|
|
757
|
+
errorMessage: "aborted"
|
|
758
|
+
};
|
|
751
759
|
await runAgentTurnWithTimeout(session.agent, () => withDelegationScope({
|
|
752
760
|
tools,
|
|
753
761
|
authorizeToolCall: params.turnPolicy ? (context, signal) => runWithEmbeddedExecutionSession(conversationId, () => params.turnPolicy.beforeToolCall(context, signal), runId) : void 0
|
|
754
762
|
}, async () => {
|
|
763
|
+
if (runAbortSignal.aborted) return;
|
|
755
764
|
const connectionResume = getConnectionResumeInput(conversationId, runId);
|
|
756
765
|
const clarificationResume = getClarificationResumeInput(conversationId, runId);
|
|
757
766
|
if (connectionResume) await session.sendCustomMessage({
|
|
@@ -765,7 +774,7 @@ async function runXopcEmbeddedTurnInner(params) {
|
|
|
765
774
|
display: false
|
|
766
775
|
}, { triggerTurn: true });
|
|
767
776
|
else if (params.recoveryMessage && !params.resumeLastUserMessage) {
|
|
768
|
-
if (!canResumeAfterModelFailure(session.agent.state.messages)) throw new Error("Cannot resume because a tool outcome is unconfirmed");
|
|
777
|
+
if (!canResumeAfterModelFailure(session.agent.state.messages, ["acceptance_repair", "model_failure"].includes(params.recoveryReason ?? "") ? { allowFailedReadTools: ACCEPTANCE_REPAIR_READ_TOOLS } : void 0)) throw new Error("Cannot resume because a tool outcome is unconfirmed");
|
|
769
778
|
await session.sendCustomMessage({
|
|
770
779
|
customType: "task_continuation",
|
|
771
780
|
content: params.recoveryMessage,
|
|
@@ -840,7 +849,7 @@ async function runXopcEmbeddedTurnInner(params) {
|
|
|
840
849
|
await session.agent.waitForIdle();
|
|
841
850
|
await recoverSettledTurn();
|
|
842
851
|
}
|
|
843
|
-
}), timeoutMs);
|
|
852
|
+
}), timeoutMs, { timeoutExtensionMs: params.timeoutExtensionMs });
|
|
844
853
|
if (connectionStopped) runner.piSm.appendCustomEntry("connection_required", {
|
|
845
854
|
runId,
|
|
846
855
|
conversationId
|
|
@@ -858,11 +867,13 @@ async function runXopcEmbeddedTurnInner(params) {
|
|
|
858
867
|
if (runAbortSignal.aborted) return {
|
|
859
868
|
ok: false,
|
|
860
869
|
retryable: false,
|
|
870
|
+
terminationReason: resolveAgentAbortReason(runAbortSignal.reason),
|
|
861
871
|
errorMessage: "aborted"
|
|
862
872
|
};
|
|
863
873
|
if (isAssistantTurnAborted(session.agent)) return {
|
|
864
874
|
ok: false,
|
|
865
875
|
retryable: false,
|
|
876
|
+
terminationReason: "provider_error",
|
|
866
877
|
errorMessage: "aborted",
|
|
867
878
|
lastAssistantText: lastAssistantPlainText(session)
|
|
868
879
|
};
|
|
@@ -875,7 +886,8 @@ async function runXopcEmbeddedTurnInner(params) {
|
|
|
875
886
|
};
|
|
876
887
|
if (isAssistantTurnFailed(session.agent)) return {
|
|
877
888
|
ok: false,
|
|
878
|
-
retryable: canResumeAfterModelFailure(session.agent.state.messages),
|
|
889
|
+
retryable: canResumeAfterModelFailure(session.agent.state.messages, { allowFailedReadTools: ACCEPTANCE_REPAIR_READ_TOOLS }),
|
|
890
|
+
terminationReason: "provider_error",
|
|
879
891
|
errorMessage: getAssistantTurnErrorMessage(session.agent) ?? "Assistant turn failed",
|
|
880
892
|
lastAssistantText: lastAssistantPlainText(session)
|
|
881
893
|
};
|
|
@@ -935,6 +947,7 @@ async function runXopcEmbeddedTurnInner(params) {
|
|
|
935
947
|
});
|
|
936
948
|
return {
|
|
937
949
|
ok: false,
|
|
950
|
+
terminationReason: isAgentTurnTimeoutError(err) ? "deadline_exceeded" : params.abortSignal?.aborted ? resolveAgentAbortReason(params.abortSignal.reason) : "runtime_error",
|
|
938
951
|
errorMessage: em
|
|
939
952
|
};
|
|
940
953
|
} finally {
|
|
@@ -18,16 +18,23 @@ export type EmbeddedRunLease = {
|
|
|
18
18
|
attach(session: AgentSession, abort: () => Promise<void>): Promise<void>;
|
|
19
19
|
release(): void;
|
|
20
20
|
};
|
|
21
|
+
export type EmbeddedRunCancellation = {
|
|
22
|
+
signal: AbortSignal;
|
|
23
|
+
release(): void;
|
|
24
|
+
};
|
|
21
25
|
/** Owns one process-local execution lease per session while leaving steer/abort on the control plane. */
|
|
22
26
|
export declare class EmbeddedRunRegistry {
|
|
23
27
|
private readonly byConversationId;
|
|
28
|
+
private readonly prepared;
|
|
29
|
+
reserveCancellation(identity: Pick<EmbeddedRunIdentity, 'conversationId' | 'runId'>): EmbeddedRunCancellation;
|
|
24
30
|
acquire(identity: EmbeddedRunIdentity): EmbeddedRunLease;
|
|
25
31
|
getByConversationId(conversationId: string): EmbeddedRunHandle | undefined;
|
|
26
|
-
abortByConversationId(conversationId: string): Promise<boolean>;
|
|
32
|
+
abortByConversationId(conversationId: string, reason?: 'user_cancelled' | 'parent_cancelled', expectedRunId?: string): Promise<boolean>;
|
|
27
33
|
steerByConversationId(conversationId: string, text: string): Promise<boolean>;
|
|
28
34
|
size(): number;
|
|
29
35
|
}
|
|
30
36
|
export declare function acquireEmbeddedRunLease(identity: EmbeddedRunIdentity): EmbeddedRunLease;
|
|
37
|
+
export declare function reserveEmbeddedRunCancellation(identity: Pick<EmbeddedRunIdentity, 'conversationId' | 'runId'>): EmbeddedRunCancellation;
|
|
31
38
|
export declare function getEmbeddedRunByConversationId(conversationId: string): EmbeddedRunHandle | undefined;
|
|
32
|
-
export declare function abortEmbeddedRun(conversationId: string): Promise<boolean>;
|
|
39
|
+
export declare function abortEmbeddedRun(conversationId: string, reason?: 'user_cancelled' | 'parent_cancelled', expectedRunId?: string): Promise<boolean>;
|
|
33
40
|
export declare function queueEmbeddedSteer(conversationId: string, text: string): Promise<boolean>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AgentRunCancelledError } from "../orchestration/run-termination.js";
|
|
1
2
|
//#region src/agent/embedded/runs.ts
|
|
2
3
|
var EmbeddedRunConflictError = class extends Error {
|
|
3
4
|
constructor(conversationId, activeRunId) {
|
|
@@ -10,12 +11,26 @@ var EmbeddedRunConflictError = class extends Error {
|
|
|
10
11
|
/** Owns one process-local execution lease per session while leaving steer/abort on the control plane. */
|
|
11
12
|
var EmbeddedRunRegistry = class {
|
|
12
13
|
byConversationId = /* @__PURE__ */ new Map();
|
|
14
|
+
prepared = /* @__PURE__ */ new Map();
|
|
15
|
+
reserveCancellation(identity) {
|
|
16
|
+
const key = JSON.stringify([identity.conversationId, identity.runId]);
|
|
17
|
+
if (this.prepared.has(key)) throw new EmbeddedRunConflictError(identity.conversationId, identity.runId);
|
|
18
|
+
const controller = new AbortController();
|
|
19
|
+
this.prepared.set(key, controller);
|
|
20
|
+
return {
|
|
21
|
+
signal: controller.signal,
|
|
22
|
+
release: () => {
|
|
23
|
+
if (this.prepared.get(key) === controller) this.prepared.delete(key);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
13
27
|
acquire(identity) {
|
|
14
28
|
const active = this.byConversationId.get(identity.conversationId);
|
|
15
29
|
if (active) throw new EmbeddedRunConflictError(identity.conversationId, active.runId);
|
|
30
|
+
const controller = this.prepared.get(JSON.stringify([identity.conversationId, identity.runId]));
|
|
16
31
|
const entry = {
|
|
17
32
|
...identity,
|
|
18
|
-
abortController: new AbortController()
|
|
33
|
+
abortController: controller ?? new AbortController()
|
|
19
34
|
};
|
|
20
35
|
this.byConversationId.set(identity.conversationId, entry);
|
|
21
36
|
return {
|
|
@@ -36,10 +51,15 @@ var EmbeddedRunRegistry = class {
|
|
|
36
51
|
getByConversationId(conversationId) {
|
|
37
52
|
return this.byConversationId.get(conversationId)?.handle;
|
|
38
53
|
}
|
|
39
|
-
async abortByConversationId(conversationId) {
|
|
54
|
+
async abortByConversationId(conversationId, reason = "parent_cancelled", expectedRunId) {
|
|
40
55
|
const entry = this.byConversationId.get(conversationId);
|
|
41
|
-
if (!entry)
|
|
42
|
-
|
|
56
|
+
if (!entry || expectedRunId !== void 0 && entry.runId !== expectedRunId) {
|
|
57
|
+
const prepared = expectedRunId === void 0 ? void 0 : this.prepared.get(JSON.stringify([conversationId, expectedRunId]));
|
|
58
|
+
if (!prepared) return false;
|
|
59
|
+
prepared.abort(new AgentRunCancelledError("Embedded run aborted", reason));
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
entry.abortController.abort(new AgentRunCancelledError("Embedded run aborted", reason));
|
|
43
63
|
if (entry.handle) await entry.handle.abort();
|
|
44
64
|
return true;
|
|
45
65
|
}
|
|
@@ -57,14 +77,17 @@ const embeddedRunRegistry = new EmbeddedRunRegistry();
|
|
|
57
77
|
function acquireEmbeddedRunLease(identity) {
|
|
58
78
|
return embeddedRunRegistry.acquire(identity);
|
|
59
79
|
}
|
|
80
|
+
function reserveEmbeddedRunCancellation(identity) {
|
|
81
|
+
return embeddedRunRegistry.reserveCancellation(identity);
|
|
82
|
+
}
|
|
60
83
|
function getEmbeddedRunByConversationId(conversationId) {
|
|
61
84
|
return embeddedRunRegistry.getByConversationId(conversationId);
|
|
62
85
|
}
|
|
63
|
-
function abortEmbeddedRun(conversationId) {
|
|
64
|
-
return embeddedRunRegistry.abortByConversationId(conversationId);
|
|
86
|
+
function abortEmbeddedRun(conversationId, reason = "parent_cancelled", expectedRunId) {
|
|
87
|
+
return embeddedRunRegistry.abortByConversationId(conversationId, reason, expectedRunId);
|
|
65
88
|
}
|
|
66
89
|
function queueEmbeddedSteer(conversationId, text) {
|
|
67
90
|
return embeddedRunRegistry.steerByConversationId(conversationId, text);
|
|
68
91
|
}
|
|
69
92
|
//#endregion
|
|
70
|
-
export { EmbeddedRunConflictError, EmbeddedRunRegistry, abortEmbeddedRun, acquireEmbeddedRunLease, getEmbeddedRunByConversationId, queueEmbeddedSteer };
|
|
93
|
+
export { EmbeddedRunConflictError, EmbeddedRunRegistry, abortEmbeddedRun, acquireEmbeddedRunLease, getEmbeddedRunByConversationId, queueEmbeddedSteer, reserveEmbeddedRunCancellation };
|
|
@@ -12,6 +12,7 @@ import { xopcToolsToDefinitions } from "./xopc-tools-bridge.js";
|
|
|
12
12
|
import { createXopcCodemodeExtension } from "./codemode-extension.js";
|
|
13
13
|
import { TOOL_DISCOVERY_STATE, createXopcToolSearchExtension } from "./tool-search-extension.js";
|
|
14
14
|
import { getNativePiAgentDir } from "../mcp/native-mcp.js";
|
|
15
|
+
import { AGENT_PROFILE_CONTEXT_STATE, createAgentProfileContextExtension } from "./agent-profile-context.js";
|
|
15
16
|
import { join } from "node:path";
|
|
16
17
|
import { createHash } from "node:crypto";
|
|
17
18
|
import { DefaultResourceLoader, SettingsManager, createAgentSession, createMcpExtension } from "@earendil-works/pi-coding-agent";
|
|
@@ -242,6 +243,7 @@ var EmbeddedSessionRunnerPool = class {
|
|
|
242
243
|
"coding_run_started",
|
|
243
244
|
"coding_verification",
|
|
244
245
|
"xopc.model-selection",
|
|
246
|
+
AGENT_PROFILE_CONTEXT_STATE,
|
|
245
247
|
"connection_required",
|
|
246
248
|
"clarification_required"
|
|
247
249
|
],
|
|
@@ -282,7 +284,8 @@ var EmbeddedSessionRunnerPool = class {
|
|
|
282
284
|
...mcp ? [createMcpExtension({
|
|
283
285
|
loadConfig: () => mcp,
|
|
284
286
|
logPath: join(getNativePiAgentDir(), "mcp.log")
|
|
285
|
-
})] : []
|
|
287
|
+
})] : [],
|
|
288
|
+
createAgentProfileContextExtension(runtimeId)
|
|
286
289
|
]
|
|
287
290
|
});
|
|
288
291
|
await resourceLoader.reload();
|
|
@@ -300,7 +303,7 @@ var EmbeddedSessionRunnerPool = class {
|
|
|
300
303
|
});
|
|
301
304
|
boundSession = session;
|
|
302
305
|
session.setActiveToolsByName(toolNames);
|
|
303
|
-
|
|
306
|
+
await session.bindExtensions({});
|
|
304
307
|
const baseStreamFn = wrapStreamFnForXopcExtensions(session.agent.streamFunction);
|
|
305
308
|
session.agent.streamFunction = baseStreamFn;
|
|
306
309
|
return {
|
|
@@ -88,6 +88,8 @@ export type RunXopcEmbeddedTurnParams = {
|
|
|
88
88
|
sessionStore?: SessionStore;
|
|
89
89
|
transcriptRuntime?: EmbeddedTranscriptRuntime;
|
|
90
90
|
timeoutMs: number;
|
|
91
|
+
/** One bounded deadline extension for an already-dispatched budget handoff. */
|
|
92
|
+
timeoutExtensionMs?: () => number;
|
|
91
93
|
turnPolicy?: AgentTurnPolicy;
|
|
92
94
|
abortSignal?: AbortSignal;
|
|
93
95
|
onEvent?: (event: EmbeddedStreamEvent) => void;
|
|
@@ -96,10 +98,12 @@ export type RunXopcEmbeddedTurnParams = {
|
|
|
96
98
|
/** Continue from the persisted trailing user row instead of appending it again. */
|
|
97
99
|
resumeLastUserMessage?: boolean;
|
|
98
100
|
recoveryMessage?: string;
|
|
101
|
+
recoveryReason?: string;
|
|
99
102
|
verifyChanges?: boolean;
|
|
100
103
|
requireVisibleReply?: boolean;
|
|
101
104
|
};
|
|
102
105
|
export type RunXopcEmbeddedTurnResult = {
|
|
106
|
+
terminationReason?: import('../orchestration/run-termination.js').AgentTerminationReason;
|
|
103
107
|
ok: boolean;
|
|
104
108
|
stopReason?: 'connection_required' | 'clarification_required' | 'policy_limit' | 'response_truncated';
|
|
105
109
|
/** False for harness failures that must not trigger another model attempt. */
|
|
@@ -97,7 +97,8 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
|
|
|
97
97
|
...result,
|
|
98
98
|
connectionCandidates: candidates,
|
|
99
99
|
installCandidates,
|
|
100
|
-
...result.tools.length === 0 && (candidates.length > 0 || installCandidates.length > 0) ? { instruction: "
|
|
100
|
+
...result.tools.length === 0 && (candidates.length > 0 || installCandidates.length > 0) ? { instruction: "No executable tool matched this search. This alone does not prove the account is disconnected. Retry without restrictive sources and inspect the returned account state. If authorization or account selection is actually required, call xopc_require_connection with an exact candidateRef from this result; the host owns selection, authorization and automatic continuation. Do not ask the user whether to perform an already requested read, or to reply continue after authorization. Do not fall back to browser automation unless the user explicitly asked for browser use or skips the connection." } : {},
|
|
101
|
+
...result.tools.length > 0 ? { instruction: "Describe the relevant tool contracts and execute the requested read using the available authorized account. The user request already authorizes these reads; do not ask for another confirmation. Respect the exact contracts and host permission checks. Hand off to the user only when a required authorization, ambiguous account choice or essential missing decision cannot be resolved from existing context." } : {},
|
|
101
102
|
...installCatalogError ? { installCatalogError } : {},
|
|
102
103
|
...excludedSources.length ? { searchScope: {
|
|
103
104
|
excludedSources,
|
|
@@ -222,7 +223,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
|
|
|
222
223
|
name: EXTERNAL_TOOL_NAMES.requireConnection,
|
|
223
224
|
label: "Connect app",
|
|
224
225
|
parameters: requireSchema,
|
|
225
|
-
description: "
|
|
226
|
+
description: "Use only when a requested read cannot proceed because authorization, installation or account selection is required. Available authorized tools should be executed directly without asking the user to confirm the read. Request an exact connectionCandidates or installCandidates entry returned by xopc_tool_search. Explain the verified need once before calling. This saves and pauses the objective, displays one action area above the input, and lets the host resume automatically after the required user action. Stop this turn after connection_required; never ask the user to reply continue after authorization. Never invent a candidate reference, return OAuth URLs, or repeat a skipped request. If another objective is waiting, do not create a duplicate objective.",
|
|
226
227
|
async execute(_id, params) {
|
|
227
228
|
const context = getContext?.();
|
|
228
229
|
if (!context) throw new Error("No active conversation.");
|
|
@@ -285,7 +286,10 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
|
|
|
285
286
|
}))
|
|
286
287
|
});
|
|
287
288
|
publishConnectionWait(context.conversationId);
|
|
288
|
-
return textResult(
|
|
289
|
+
return textResult({
|
|
290
|
+
...result,
|
|
291
|
+
...result.status === "connection_required" ? { instruction: "The objective is saved and the host owns the connection or account-selection interaction. Stop this turn. After the required user action, the host will check readiness and continue automatically. Do not ask for another confirmation of this read or ask the user to reply continue." } : result.status === "objective_conflict" ? { instruction: "An objective is already waiting. Do not create another request or claim the account is disconnected. Inspect the existing objective before asking for a genuinely missing decision." } : {}
|
|
292
|
+
});
|
|
289
293
|
}
|
|
290
294
|
};
|
|
291
295
|
const reviseSchema = Type.Object({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AgentRunDeadlineError } from "./run-termination.js";
|
|
1
2
|
//#region src/agent/orchestration/agent-run-supervisor.ts
|
|
2
3
|
/** Minimal run-level coordination: root cancellation and per-attempt deadline planning. */
|
|
3
4
|
var AgentRunSupervisor = class {
|
|
@@ -18,7 +19,7 @@ var AgentRunSupervisor = class {
|
|
|
18
19
|
this.forwardParentAbort = () => this.controller.abort(this.parentSignal?.reason);
|
|
19
20
|
if (this.parentSignal?.aborted) this.forwardParentAbort();
|
|
20
21
|
else this.parentSignal?.addEventListener("abort", this.forwardParentAbort, { once: true });
|
|
21
|
-
this.timeout = setTimeout(() => this.controller.abort(
|
|
22
|
+
this.timeout = setTimeout(() => this.controller.abort(new AgentRunDeadlineError()), Math.max(0, this.deadlineAtMs - Date.now()));
|
|
22
23
|
}
|
|
23
24
|
planModelAttempt(isFallback) {
|
|
24
25
|
if (this.signal.aborted) return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { dataOperationCalls } from "../data-acquisition/schema.js";
|
|
2
2
|
//#region src/agent/orchestration/agent-turn-policy.ts
|
|
3
|
+
const expandedBatchContexts = /* @__PURE__ */ new WeakSet();
|
|
3
4
|
/** One user-visible run policy. A fresh instance is created for every embedded run. */
|
|
4
5
|
function createAgentTurnPolicy(options) {
|
|
5
6
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
@@ -12,7 +13,10 @@ function createAgentTurnPolicy(options) {
|
|
|
12
13
|
assistantTurns = 0;
|
|
13
14
|
},
|
|
14
15
|
async beforeToolCall(context, signal) {
|
|
15
|
-
const
|
|
16
|
+
const wrapper = { ...context };
|
|
17
|
+
const expand = context.toolCall.name === "data_batch" && !expandedBatchContexts.has(context);
|
|
18
|
+
if (expand) expandedBatchContexts.add(wrapper);
|
|
19
|
+
const contexts = expand ? [wrapper, ...dataOperationCalls(context.args).map((call, index) => ({
|
|
16
20
|
...context,
|
|
17
21
|
args: call.args,
|
|
18
22
|
toolCall: {
|
|
@@ -17,7 +17,7 @@ export declare const DELEGATION_BUDGETS: {
|
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
export type DelegationBudgetTier = keyof typeof DELEGATION_BUDGETS;
|
|
20
|
-
export type DelegationStopReason = 'completed' | 'tool_calls' | 'total_tokens' | 'model_turns' | 'tool_failures' | 'timeout' | 'cancelled' | 'parent_policy' | 'credit_budget' | 'runtime_error' | 'verification';
|
|
20
|
+
export type DelegationStopReason = 'completed' | 'tool_calls' | 'total_tokens' | 'model_turns' | 'tool_failures' | 'timeout' | 'deadline_exceeded' | 'user_cancelled' | 'parent_cancelled' | 'provider_error' | 'cancelled' | 'parent_policy' | 'credit_budget' | 'runtime_error' | 'verification';
|
|
21
21
|
export declare function resolveDelegationBudget(tier?: DelegationBudgetTier, maxIterations?: number, timeoutMs?: number): {
|
|
22
22
|
tier: "light" | "standard" | "deep";
|
|
23
23
|
limits: {
|
|
@@ -26,6 +26,7 @@ export declare function resolveDelegationBudget(tier?: DelegationBudgetTier, max
|
|
|
26
26
|
maxModelTurns: number;
|
|
27
27
|
maxToolFailures: number;
|
|
28
28
|
timeoutMs: number;
|
|
29
|
+
handoffReserveMs: number;
|
|
29
30
|
};
|
|
30
31
|
};
|
|
31
32
|
/** Reserve the last 20% for one tool-free handoff, without bypassing hard limits. */
|
|
@@ -34,6 +35,9 @@ export declare function createDelegationBudgetPolicy(budget: ReturnType<typeof r
|
|
|
34
35
|
authorizeToolCall?: AgentTurnPolicyOptions['authorizeToolCall'];
|
|
35
36
|
}, now?: () => number): {
|
|
36
37
|
policy: AgentTurnPolicy;
|
|
38
|
+
requestHandoff: (reason: DelegationStopReason) => void;
|
|
39
|
+
remainingMs: () => number;
|
|
40
|
+
researchRemainingMs: () => number;
|
|
37
41
|
addTokens(tokens: number): void;
|
|
38
42
|
stop(reason: DelegationStopReason, message?: string): void;
|
|
39
43
|
snapshot(): {
|
|
@@ -47,6 +51,7 @@ export declare function createDelegationBudgetPolicy(budget: ReturnType<typeof r
|
|
|
47
51
|
stopReason: DelegationStopReason;
|
|
48
52
|
stopMessage: string;
|
|
49
53
|
handoffRequested: boolean;
|
|
54
|
+
handoffRequestStarted: boolean;
|
|
50
55
|
handoffReason: DelegationStopReason;
|
|
51
56
|
tier: "light" | "standard" | "deep";
|
|
52
57
|
limits: {
|
|
@@ -55,6 +60,7 @@ export declare function createDelegationBudgetPolicy(budget: ReturnType<typeof r
|
|
|
55
60
|
maxModelTurns: number;
|
|
56
61
|
maxToolFailures: number;
|
|
57
62
|
timeoutMs: number;
|
|
63
|
+
handoffReserveMs: number;
|
|
58
64
|
};
|
|
59
65
|
};
|
|
60
66
|
};
|
|
@@ -25,7 +25,8 @@ function resolveDelegationBudget(tier = "standard", maxIterations, timeoutMs) {
|
|
|
25
25
|
maxTotalTokens: preset.maxTotalTokens,
|
|
26
26
|
maxModelTurns: Math.min(60, Math.max(1, Math.floor(maxIterations ?? preset.maxToolCalls))) + 1,
|
|
27
27
|
maxToolFailures: 5,
|
|
28
|
-
timeoutMs: Math.min(timeoutMs ?? preset.timeoutMs, preset.timeoutMs)
|
|
28
|
+
timeoutMs: Math.min(timeoutMs ?? preset.timeoutMs, preset.timeoutMs),
|
|
29
|
+
handoffReserveMs: Math.floor(Math.min(timeoutMs ?? preset.timeoutMs, preset.timeoutMs) * .2)
|
|
29
30
|
}
|
|
30
31
|
};
|
|
31
32
|
}
|
|
@@ -53,6 +54,12 @@ function createDelegationBudgetPolicy(budget, options, now = Date.now) {
|
|
|
53
54
|
if (usage.modelTurns >= limits.maxModelTurns * ratio) return "model_turns";
|
|
54
55
|
if (usage.toolFailures >= limits.maxToolFailures * ratio) return "tool_failures";
|
|
55
56
|
};
|
|
57
|
+
const requestHandoff = (reason) => {
|
|
58
|
+
if (handoffRequested) return;
|
|
59
|
+
handoffReason = reason;
|
|
60
|
+
handoffRequested = true;
|
|
61
|
+
continuation = handoff();
|
|
62
|
+
};
|
|
56
63
|
const handoff = () => `Delegation budget is approaching its ${handoffReason} limit. Do not call more tools. Return a concise handoff now: findings with file/line or source evidence, incomplete work, and precise next steps (including unread ranges). Do not claim the task is complete.`;
|
|
57
64
|
return {
|
|
58
65
|
policy: {
|
|
@@ -87,11 +94,12 @@ function createDelegationBudgetPolicy(budget, options, now = Date.now) {
|
|
|
87
94
|
reason: `Sub-agent budget exhausted: ${hard}.`
|
|
88
95
|
};
|
|
89
96
|
}
|
|
90
|
-
if (
|
|
97
|
+
if (now() - startedAt >= limits.timeoutMs * .8) requestHandoff("timeout");
|
|
98
|
+
if (handoffRequested && (context.toolCall.name !== "research_checkpoint" || handoffRequestStarted)) return {
|
|
91
99
|
block: true,
|
|
92
100
|
reason: handoff()
|
|
93
101
|
};
|
|
94
|
-
if (context.toolCall.name !== "data_batch") usage.toolCalls++;
|
|
102
|
+
if (context.toolCall.name !== "data_batch" && context.toolCall.name !== "research_checkpoint") usage.toolCalls++;
|
|
95
103
|
const decision = await options.authorizeToolCall?.(context, signal);
|
|
96
104
|
if (decision?.block && decision.terminate) {
|
|
97
105
|
stopReason = "parent_policy";
|
|
@@ -110,16 +118,12 @@ function createDelegationBudgetPolicy(budget, options, now = Date.now) {
|
|
|
110
118
|
stopReason ??= hard;
|
|
111
119
|
return true;
|
|
112
120
|
}
|
|
113
|
-
if (
|
|
121
|
+
if (handoffRequestStarted) {
|
|
114
122
|
stopReason = handoffReason;
|
|
115
123
|
return true;
|
|
116
124
|
}
|
|
117
125
|
const near = reasonAt(.8);
|
|
118
|
-
if (near && context.toolResults.length)
|
|
119
|
-
handoffReason = near;
|
|
120
|
-
handoffRequested = true;
|
|
121
|
-
continuation = handoff();
|
|
122
|
-
}
|
|
126
|
+
if (near && context.toolResults.length) requestHandoff(near);
|
|
123
127
|
return false;
|
|
124
128
|
},
|
|
125
129
|
takeContinuationMessage() {
|
|
@@ -129,6 +133,9 @@ function createDelegationBudgetPolicy(budget, options, now = Date.now) {
|
|
|
129
133
|
},
|
|
130
134
|
stopReason: () => !stopReason && options.isComplete?.() ? "completed" : "limit"
|
|
131
135
|
},
|
|
136
|
+
requestHandoff,
|
|
137
|
+
remainingMs: () => Math.max(0, limits.timeoutMs - (now() - startedAt)),
|
|
138
|
+
researchRemainingMs: () => Math.max(0, limits.timeoutMs - limits.handoffReserveMs - (now() - startedAt)),
|
|
132
139
|
addTokens(tokens) {
|
|
133
140
|
usage.totalTokens += Math.max(0, tokens);
|
|
134
141
|
},
|
|
@@ -146,6 +153,7 @@ function createDelegationBudgetPolicy(budget, options, now = Date.now) {
|
|
|
146
153
|
stopReason,
|
|
147
154
|
stopMessage,
|
|
148
155
|
handoffRequested,
|
|
156
|
+
handoffRequestStarted,
|
|
149
157
|
handoffReason
|
|
150
158
|
};
|
|
151
159
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Static } from '@sinclair/typebox';
|
|
2
|
+
import type { SearchCacheEntry } from '../tools/search/cache.js';
|
|
3
|
+
export declare const ResearchFindingSchema: import("@sinclair/typebox").TObject<{
|
|
4
|
+
id: import("@sinclair/typebox").TString;
|
|
5
|
+
subject: import("@sinclair/typebox").TString;
|
|
6
|
+
field: import("@sinclair/typebox").TString;
|
|
7
|
+
status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"confirmed">, import("@sinclair/typebox").TLiteral<"not_disclosed">, import("@sinclair/typebox").TLiteral<"conflicting">, import("@sinclair/typebox").TLiteral<"unverified">]>;
|
|
8
|
+
conclusion: import("@sinclair/typebox").TString;
|
|
9
|
+
sources: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
10
|
+
url: import("@sinclair/typebox").TString;
|
|
11
|
+
title: import("@sinclair/typebox").TString;
|
|
12
|
+
excerpt: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
13
|
+
}>>;
|
|
14
|
+
}>;
|
|
15
|
+
export declare const ResearchCheckpointUpdateSchema: import("@sinclair/typebox").TObject<{
|
|
16
|
+
findings: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
17
|
+
id: import("@sinclair/typebox").TString;
|
|
18
|
+
subject: import("@sinclair/typebox").TString;
|
|
19
|
+
field: import("@sinclair/typebox").TString;
|
|
20
|
+
status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"confirmed">, import("@sinclair/typebox").TLiteral<"not_disclosed">, import("@sinclair/typebox").TLiteral<"conflicting">, import("@sinclair/typebox").TLiteral<"unverified">]>;
|
|
21
|
+
conclusion: import("@sinclair/typebox").TString;
|
|
22
|
+
sources: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
23
|
+
url: import("@sinclair/typebox").TString;
|
|
24
|
+
title: import("@sinclair/typebox").TString;
|
|
25
|
+
excerpt: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
26
|
+
}>>;
|
|
27
|
+
}>>;
|
|
28
|
+
nextSteps: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
29
|
+
}>;
|
|
30
|
+
export type ResearchFinding = Static<typeof ResearchFindingSchema> & {
|
|
31
|
+
checkedAt: number;
|
|
32
|
+
};
|
|
33
|
+
export type ResearchCheckpointUpdate = Static<typeof ResearchCheckpointUpdateSchema>;
|
|
34
|
+
export interface ResearchEvidence {
|
|
35
|
+
toolCallId: string;
|
|
36
|
+
runId?: string;
|
|
37
|
+
toolName: string;
|
|
38
|
+
isError: boolean;
|
|
39
|
+
excerpt: string;
|
|
40
|
+
recordedAt: number;
|
|
41
|
+
}
|
|
42
|
+
export interface ResearchCheckpoint {
|
|
43
|
+
findings: ResearchFinding[];
|
|
44
|
+
nextSteps: string[];
|
|
45
|
+
evidence: ResearchEvidence[];
|
|
46
|
+
searches?: SearchCacheEntry[];
|
|
47
|
+
}
|
|
48
|
+
export interface ResearchCheckpointSink {
|
|
49
|
+
read(): ResearchCheckpoint;
|
|
50
|
+
save(update: ResearchCheckpointUpdate): ResearchCheckpoint;
|
|
51
|
+
recordEvidence(evidence: ResearchEvidence): void;
|
|
52
|
+
recordSearch?(entry: SearchCacheEntry): void;
|
|
53
|
+
}
|
|
54
|
+
/** Findings are model assertions with source evidence, never host-certified facts. */
|
|
55
|
+
export declare function mergeResearchCheckpoint(current: ResearchCheckpoint, update: ResearchCheckpointUpdate, now?: number): ResearchCheckpoint;
|
|
56
|
+
export declare function researchResumeContext(checkpoint: ResearchCheckpoint): string;
|