@xopcai/xopc 0.0.244 → 0.0.245
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/{activity-store-CAah-_8h.js → activity-store-BlxqErph.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BhXGsupm.js → agent-avatar-dicebear-DRQnogaU.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-Blzn2H6t.js → agent-defaults-settings-panel-CpOxGbMD.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-Cmp-z8Y_.js → agents-flnXZLaT.js} +1 -1
- package/dist/gateway/static/root/assets/{api-B2tKxbcz.js → api-BbXzyQMj.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CezjAP1K.js → app-management-settings-panel-CZl6n2xi.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-C-CfS05x.js → appearance-settings-Bglp-pn6.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-7Y13_bqZ.js → apps-page-CmsWarVB.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-BmSx7wzY.js → archive-plugin-DD2SweEH.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DI4CoIga.js → attachment-load-G0HenUmG.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-D04Xceck.js → automations-page-B78bFjH2.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-wEO1OWk0.js → automations-workspace-BMQGmn50.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-BJQe8TRu.js → binary-plugins-BbSQmXqn.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BSzGjJC6.js → block-editor-DutTIH81.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-DjAZ_LF2.js → browser-settings-page-CALiFKm4.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-CRnkgZHI.js → browser-workflow-inputs-BAAc151l.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CwbxA3B7.js → browser-workflows-page-DE5HPrHZ.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-jt9bqUMK.js → capabilities-settings-panel-Dts7XtP3.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-Cz_TWY3a.js → channels-settings-CWEd3wzh.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-status-swr-DuY4MGxe.js → channels-status-swr-CCBCtLDg.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-D3gj2D3U.js → chat-terminal-dock-Bp1fXQm1.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-Shs5vbzx.js → connectors-page-CQ6wVNLm.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-expression-DgWHw0jX.js → cron-expression-B8HA5IRb.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-CKg-RPbs.js → date-picker-DD8b7oad.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-CVYkw-NN.js → dependency-picker-BC9zwIyH.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Bf46oXTY.js → desktop-pet-DsrsPZTW.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BJO_klc7.js → desktop-pet-settings-D7gp_HNA.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-T2PmFFOW.js → extension-debug-page-BoKbOX7x.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-2wAE2RCe.js → extension-page-BegL4FW8.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Y9ZiCJ21.js → extension-settings-page-CjPqq57s.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-DaYY1Gkn.js → gateway-config-api-DaG57o4X.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BC3pgb_P.js → gateway-config-swr-826dipyU.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-eO3IzW_J.js → gateway-settings-DkJGpgm6.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-uMcSfLru.js → gateway-startup-retry-DyvcAIMm.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-BAgrkyHc.js → heartbeat-settings-BLZ48kSU.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-GTjKH7LK.js → home-page-Dtw7Ipt1.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-D1qlQA-A.js → image-generation-api-D7cyfks6.js} +1 -1
- package/dist/gateway/static/root/assets/{index-DUz0O54y.js → index-DG5CfYat.js} +10 -10
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CWGqL6o5.js → keyboard-shortcuts-settings-D2Has7-N.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DKJ-rks0.js → local-app-workbench-page-BWidWY93.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-Bfidv29d.js → local-apps-page-Bkekjoxf.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-CMZljTJx.js → locale-store-CBoCuIMx.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-DwAHrPbF.js → logs-page-C5zSSgvA.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-BG7j1I9f.js → management-settings-B8c62vRS.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-AnmmpLs6.js → markdown-split-3kxTTGO7.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-PPCLt7fu.js → markdown-view-BXsHghJd.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CGS-05cE.js → media-plugins-BW8J1nCG.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BbdwoxVo.js +3 -0
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-DoKK5GfV.js → mobile-pairing-wizard-nwQ8iUcd.js} +1 -1
- package/dist/gateway/static/root/assets/models-hub-cache-88f4fzYS.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-Lr8rsFAR.js → notes-page-DdybD0QM.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-ISWnKLxO.js → notes-workbench-IYfpy2Jx.js} +2 -2
- package/dist/gateway/static/root/assets/{oauth-api-4VeMbkTJ.js → oauth-api-BjSUDIgq.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-BU0HiZtv.js → product-open-page-CAJeUXeU.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-BZqr4yam.js → project-detail-page-4wjw-b7h.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-Dau8733A.js → projects-page-CCMj9PeL.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-CWOtPFrE.js → registry-api-BhGKnvLP.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-DdChlvGP.js → remote-access-hub-DsBJqWIk.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CmZTNv1W.js → runtime-tools-settings-panel-B4IDcqx0.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-XlVPyiVQ.js → schema-form-DiGUUjO6.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-C3kADsd4.js → sessions-page-BwGj0t-2.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BJCfUghk.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-DblUeM3V.js → settings-page-CVQUsAhd.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-bDfRfSnq.js → setup-status-panel-CQACRh1i.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-DBMWFMN-.js → share-preview-page-DTP1dtuS.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-Bu6lIStj.js → shares-settings-D_YPh6Rw.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-B43xlJlX.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-CSOseeQe.js → skills-page-Czpn7Y28.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-CniRGhkJ.js → skills-page.utils-d39rm3hb.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-D0GqNpKy.js → system-settings-panel-CXXySCSp.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-BRCq-nR7.js → task-detail-page-DHiOqQMx.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-uxUwr10D.js → theme-store-hybK3oC9.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-BtjS2nrM.js → tunnel-api-BiBGK7O2.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-TwuAycG8.js → use-autosave-DjpzpeIm.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-CbqPu8xZ.js → user-context-page-1XBRV5gX.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CzwG5plu.js → voice-api-key-field-CUIPNmOc.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-MqyI6cgq.js → voice-config-api-CBbiF1T3.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-DS15FzQA.js → work-discovery-overlay-DVNxhb1x.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C_boCemi.js → workflow-run-setup-panel-HxxFQFY7.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-CaI2ruyy.js → workflows-page-BCgL7PRm.js} +1 -1
- package/dist/gateway/static/root/index.html +11 -11
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/turn-outcome.js +3 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +3 -1
- package/dist/src/agent/agent-manager.d.ts +2 -4
- package/dist/src/agent/agent-manager.js +28 -32
- package/dist/src/agent/background-review/coordinator.js +1 -1
- package/dist/src/agent/background-review/run-background-review.js +2 -2
- package/dist/src/agent/child-agent-factory.d.ts +10 -7
- package/dist/src/agent/child-agent-factory.js +112 -158
- package/dist/src/agent/coding/index.d.ts +1 -1
- package/dist/src/agent/coding/index.js +2 -2
- package/dist/src/agent/coding/repository-instructions.d.ts +12 -0
- package/dist/src/agent/coding/repository-instructions.js +76 -0
- package/dist/src/agent/coding/run-verification.d.ts +34 -0
- package/dist/src/agent/coding/run-verification.js +134 -0
- package/dist/src/agent/coding/verification-command.d.ts +3 -0
- package/dist/src/agent/coding/verification-command.js +50 -0
- package/dist/src/agent/coding/workspace-revision.d.ts +2 -0
- package/dist/src/agent/coding/workspace-revision.js +77 -0
- package/dist/src/agent/commands/command-isolation.d.ts +21 -0
- package/dist/src/agent/commands/command-isolation.js +71 -0
- package/dist/src/agent/commands/command-registry.d.ts +56 -0
- package/dist/src/agent/commands/command-registry.js +259 -0
- package/dist/src/agent/embedded/index.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +3 -2
- package/dist/src/agent/embedded/run-turn.js +88 -25
- package/dist/src/agent/embedded/session-tool-result-guard.js +2 -2
- package/dist/src/agent/embedded/subscribe-session.d.ts +2 -1
- package/dist/src/agent/embedded/subscribe-session.js +2 -1
- package/dist/src/agent/embedded/types.d.ts +3 -1
- package/dist/src/agent/embedded/xopc-tools-bridge.js +4 -1
- package/dist/src/agent/image/index.js +1 -1
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/index.js +3 -3
- package/dist/src/agent/ipc/inbox.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
- package/dist/src/agent/memory/user-context-coordinator.js +1 -1
- package/dist/src/agent/middleware/index.d.ts +0 -5
- package/dist/src/agent/middleware/index.js +1 -2
- package/dist/src/agent/orchestration/agent-event-handler.d.ts +0 -5
- package/dist/src/agent/orchestration/agent-event-handler.js +1 -96
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
- package/dist/src/agent/orchestration/agent-turn-policy.js +5 -5
- package/dist/src/agent/orchestration/index.d.ts +1 -1
- package/dist/src/agent/orchestration/index.js +2 -2
- package/dist/src/agent/orchestration/loop-guard.d.ts +4 -31
- package/dist/src/agent/orchestration/loop-guard.js +14 -99
- package/dist/src/agent/prompt/sections/tooling.js +2 -4
- package/dist/src/agent/sandbox/types.d.ts +2 -2
- package/dist/src/agent/sandbox/types.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +1 -1
- package/dist/src/agent/service.d.ts +0 -2
- package/dist/src/agent/service.js +8 -25
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.d.ts +7 -0
- package/dist/src/agent/tasks/task-judge-service.js +27 -5
- package/dist/src/agent/tools/delegate-tool.d.ts +2 -1
- package/dist/src/agent/tools/delegate-tool.js +102 -124
- package/dist/src/agent/tools/exec-command.d.ts +8 -1
- package/dist/src/agent/tools/exec-command.js +77 -169
- package/dist/src/agent/tools/executor.js +9 -2
- package/dist/src/agent/tools/factory.js +50 -5
- package/dist/src/agent/tools/find.d.ts +10 -13
- package/dist/src/agent/tools/find.js +33 -80
- package/dist/src/agent/tools/grep.d.ts +14 -18
- package/dist/src/agent/tools/grep.js +56 -144
- package/dist/src/agent/tools/index.d.ts +0 -1
- package/dist/src/agent/tools/index.js +2 -3
- package/dist/src/agent/tools/language-diagnostics.d.ts +11 -0
- package/dist/src/agent/tools/language-diagnostics.js +62 -0
- package/dist/src/agent/tools/managed-job-tool.d.ts +2 -1
- package/dist/src/agent/tools/managed-job-tool.js +58 -118
- package/dist/src/agent/tools/read.js +24 -7
- package/dist/src/agent/tools/repository-search.d.ts +5 -0
- package/dist/src/agent/tools/repository-search.js +56 -0
- package/dist/src/agent/tools/review-workspace.d.ts +2 -0
- package/dist/src/agent/tools/review-workspace.js +103 -0
- package/dist/src/agent/tools/write.js +4 -4
- package/dist/src/agent/transcript/index.js +2 -2
- package/dist/src/agent/transcript/transcript-hygiene.js +2 -2
- package/dist/src/agent/workflow/subagent-runner.d.ts +0 -2
- package/dist/src/agent/workflow/subagent-runner.js +12 -31
- package/dist/src/agent-config/schema.d.ts +42 -0
- package/dist/src/agent-config/schema.js +5 -0
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/models.js +2 -2
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/profile.js +1 -1
- package/dist/src/cli/commands/tunnel.js +1 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.d.ts +28 -0
- package/dist/src/execution-environments/local-worktree-manager.d.ts +3 -1
- package/dist/src/execution-environments/local-worktree-manager.js +8 -3
- package/dist/src/execution-environments/session-environment-service.js +5 -3
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +7 -0
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +1 -1
- package/dist/src/gateway/media-access.js +1 -1
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/service/config-coordinator.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +4 -1
- package/dist/src/gateway/service.js +7 -7
- package/dist/src/gateway/session-reset-service.js +1 -1
- package/dist/src/gateway/workspace-ripgrep.d.ts +0 -6
- package/dist/src/gateway/workspace-ripgrep.js +2 -40
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/ripgrep.d.ts +13 -0
- package/dist/src/infra/ripgrep.js +46 -0
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/proactive/execution/agent-executor.js +1 -1
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/session/store.js +1 -1
- package/dist/src/session/turn-outcome-projector.js +26 -6
- package/dist/src/share/hosted-session-share.js +1 -1
- package/dist/src/tasks/task-run-coordinator.d.ts +2 -2
- package/dist/src/tasks/task-run-coordinator.js +14 -12
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/messages-CTSgFlE4.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-cache-ZrbGRiGY.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CSYy6SUa.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BNMc4l04.js +0 -1
- package/dist/src/agent/coding/turn-diff-tracker.d.ts +0 -67
- package/dist/src/agent/coding/turn-diff-tracker.js +0 -231
- package/dist/src/agent/middleware/self-verify.d.ts +0 -136
- package/dist/src/agent/middleware/self-verify.js +0 -380
- package/dist/src/agent/tools/execute-code-tool.d.ts +0 -11
- package/dist/src/agent/tools/execute-code-tool.js +0 -208
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { readWorkspaceRevision } from "../coding/workspace-revision.js";
|
|
1
2
|
import { EXTERNAL_TOOL_NAMES } from "../external-tools/gateway-tools.js";
|
|
2
3
|
import "../external-tools/index.js";
|
|
3
4
|
import { createDelegateChildHandle } from "../child-agent-factory.js";
|
|
5
|
+
import { runGit } from "../../execution-environments/git.js";
|
|
6
|
+
import { LocalWorktreeManager } from "../../execution-environments/local-worktree-manager.js";
|
|
7
|
+
import { SessionEnvironmentService } from "../../execution-environments/session-environment-service.js";
|
|
4
8
|
import { Type } from "@sinclair/typebox";
|
|
5
9
|
//#region src/agent/tools/delegate-tool.ts
|
|
6
|
-
const DEFAULT_MAX_ITERATIONS = 30;
|
|
7
10
|
const DEFAULT_DELEGATE_TOOLS = [
|
|
8
11
|
"exec_command",
|
|
9
12
|
"read_file",
|
|
@@ -36,160 +39,135 @@ const DELEGATE_BLOCKED_TOOLS = new Set([
|
|
|
36
39
|
EXTERNAL_TOOL_NAMES.execute,
|
|
37
40
|
"managed_job"
|
|
38
41
|
]);
|
|
42
|
+
const INSPECTION_TOOLS = new Set([
|
|
43
|
+
"read_file",
|
|
44
|
+
"grep",
|
|
45
|
+
"find",
|
|
46
|
+
"list_dir",
|
|
47
|
+
"review_workspace"
|
|
48
|
+
]);
|
|
39
49
|
const DelegateTaskSchema = Type.Object({
|
|
40
|
-
goal: Type.String({
|
|
41
|
-
context: Type.Optional(Type.String(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
goal: Type.String({ minLength: 1 }),
|
|
51
|
+
context: Type.Optional(Type.String()),
|
|
52
|
+
mode: Type.Optional(Type.Union([
|
|
53
|
+
Type.Literal("inspect"),
|
|
54
|
+
Type.Literal("review"),
|
|
55
|
+
Type.Literal("implement")
|
|
56
|
+
])),
|
|
57
|
+
toolset: Type.Optional(Type.Array(Type.String())),
|
|
58
|
+
maxIterations: Type.Optional(Type.Integer({
|
|
59
|
+
minimum: 1,
|
|
60
|
+
maximum: 60
|
|
46
61
|
}))
|
|
47
62
|
});
|
|
63
|
+
function delegateToolNames(mode, requested) {
|
|
64
|
+
const available = mode === "implement" ? new Set([
|
|
65
|
+
...DEFAULT_DELEGATE_TOOLS,
|
|
66
|
+
"review_workspace",
|
|
67
|
+
"language_diagnostics"
|
|
68
|
+
]) : INSPECTION_TOOLS;
|
|
69
|
+
return [...new Set(requested ?? [...available])].filter((name) => available.has(name) && !DELEGATE_BLOCKED_TOOLS.has(name));
|
|
70
|
+
}
|
|
48
71
|
function createDelegateTool(deps) {
|
|
49
72
|
return {
|
|
50
73
|
name: "delegate_task",
|
|
51
|
-
label: "
|
|
52
|
-
description: "Spawn a sub-agent for an isolated subtask with a fresh conversation (no parent transcript).\n\nThe sub-agent returns a text summary only — tool traces stay out of your context.\n\nWHEN TO USE:\n- Independent work (research, multi-file exploration) where you only need the task\n- Avoiding context bloat from long intermediate tool output\n\nWHEN NOT TO USE:\n- Tasks that need this chat history or user clarification\n- Single trivial steps\n\nSub-agents cannot use clarify, messaging, memory tools, todo, or nested delegate_task.",
|
|
74
|
+
label: "Delegate task",
|
|
53
75
|
parameters: DelegateTaskSchema,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
summary: "",
|
|
76
|
-
iterations: 0
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
let model;
|
|
80
|
-
try {
|
|
81
|
-
model = deps.getSubagentModel();
|
|
82
|
-
} catch (e) {
|
|
83
|
-
return {
|
|
84
|
-
content: [{
|
|
85
|
-
type: "text",
|
|
86
|
-
text: `delegate_task: ${e instanceof Error ? e.message : String(e)}`
|
|
87
|
-
}],
|
|
88
|
-
details: {
|
|
89
|
-
summary: "",
|
|
90
|
-
iterations: 0
|
|
91
|
-
}
|
|
92
|
-
};
|
|
76
|
+
description: "Run one bounded leaf worker with a fresh context. inspect/review receive only read tools; review reports findings against a workspace revision. implement requires an attached project and clean Git workspace, creates a separate managed worktree, and returns its patch for parent review. Child changes are never merged automatically. No nested delegation, external messages or background jobs. Up to 60 tool calls, 100k tokens and five minutes per child.",
|
|
77
|
+
supportsParallel: false,
|
|
78
|
+
idempotent: false,
|
|
79
|
+
async execute(_id, input, signal) {
|
|
80
|
+
signal?.throwIfAborted();
|
|
81
|
+
const mode = input.mode ?? "inspect";
|
|
82
|
+
const tools = delegateToolNames(mode, input.toolset);
|
|
83
|
+
if (!tools.length) throw new Error("No permitted tools in the requested toolset");
|
|
84
|
+
const parentSessionKey = deps.getCurrentContext?.()?.sessionKey;
|
|
85
|
+
const model = deps.getSubagentModel();
|
|
86
|
+
let workspace = deps.workspace, environmentId;
|
|
87
|
+
if (mode === "implement") {
|
|
88
|
+
if (!parentSessionKey) throw new Error("Implementation delegation requires a project session");
|
|
89
|
+
const parent = new SessionEnvironmentService().get(parentSessionKey);
|
|
90
|
+
if (!parent?.projectId) throw new Error("Attach this session to a project before implementation delegation");
|
|
91
|
+
const environment = await new LocalWorktreeManager().provisionManagedWorktree({
|
|
92
|
+
projectId: parent.projectId,
|
|
93
|
+
repositoryPath: workspace
|
|
94
|
+
});
|
|
95
|
+
workspace = environment.rootPath;
|
|
96
|
+
environmentId = environment.id;
|
|
93
97
|
}
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
context: p.context,
|
|
98
|
+
const revision = await readWorkspaceRevision(workspace);
|
|
99
|
+
const child = createDelegateChildHandle({
|
|
100
|
+
workspace,
|
|
101
|
+
goal: mode === "review" ? `Independently review the actual changes. Inspect review_workspace and relevant source/tests. Report actionable defects with file and line evidence, severity and a concrete failure example. If there are no findings, state the checks and remaining uncertainty. Do not treat the parent's completion claim as evidence.\n\n${input.goal}` : input.goal,
|
|
102
|
+
context: input.context,
|
|
100
103
|
requesterSessionKey: parentSessionKey,
|
|
101
|
-
allowedToolNames:
|
|
102
|
-
maxIterations,
|
|
104
|
+
allowedToolNames: tools,
|
|
105
|
+
maxIterations: input.maxIterations ?? 30,
|
|
103
106
|
model,
|
|
104
107
|
bus: deps.bus,
|
|
105
108
|
getConfig: deps.getConfig,
|
|
106
109
|
toolExecutorConfig: deps.toolExecutorConfig,
|
|
107
|
-
buildChildTools: deps.buildChildTools
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const parsed = parseSessionKey(parentSessionKey);
|
|
114
|
-
if (parsed) childSessionKey = buildSessionKey({
|
|
115
|
-
agentId: "subagent",
|
|
116
|
-
source: parsed.agentId,
|
|
117
|
-
accountId: parsed.accountId,
|
|
118
|
-
peerKind: parsed.peerKind,
|
|
119
|
-
peerId: parsed.peerId,
|
|
120
|
-
threadId: parsed.threadId,
|
|
121
|
-
scopeId: parsed.scopeId
|
|
122
|
-
});
|
|
123
|
-
if (childSessionKey) {
|
|
124
|
-
const r = await deps.hookRunner.runHooksWithResult("subagent_spawning", {
|
|
125
|
-
childSessionKey,
|
|
126
|
-
requester: {
|
|
127
|
-
channel: ctx?.channel,
|
|
128
|
-
accountId: ctx?.accountId,
|
|
129
|
-
to: ctx?.to,
|
|
130
|
-
threadId: ctx?.threadId
|
|
131
|
-
},
|
|
132
|
-
threadRequested: true,
|
|
133
|
-
agentId: "subagent",
|
|
134
|
-
label: "delegate_task"
|
|
135
|
-
}, {
|
|
136
|
-
sessionKey: parentSessionKey,
|
|
137
|
-
agentId: ctx?.channel
|
|
138
|
-
});
|
|
139
|
-
if (r && r.status === "error") return {
|
|
140
|
-
content: [{
|
|
141
|
-
type: "text",
|
|
142
|
-
text: `delegate_task: ${String(r.error || "subagent spawn blocked")}`
|
|
143
|
-
}],
|
|
144
|
-
details: {
|
|
145
|
-
summary: "",
|
|
146
|
-
iterations: 0
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
} catch {}
|
|
152
|
-
const child = createDelegateChildHandle(childOptions);
|
|
153
|
-
if (signal) signal.addEventListener("abort", () => child.abort(), { once: true });
|
|
110
|
+
buildChildTools: deps.buildChildTools,
|
|
111
|
+
verifyChanges: mode === "implement"
|
|
112
|
+
});
|
|
113
|
+
const abort = () => child.abort();
|
|
114
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
115
|
+
if (signal?.aborted) abort();
|
|
154
116
|
try {
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
117
|
+
const result = await child.run();
|
|
118
|
+
const currentRevision = await readWorkspaceRevision(workspace);
|
|
119
|
+
const stale = mode !== "implement" && (!revision || revision !== currentRevision);
|
|
120
|
+
const patch = mode === "implement" ? await runGit(workspace, [
|
|
121
|
+
"diff",
|
|
122
|
+
"--no-ext-diff",
|
|
123
|
+
"--no-textconv",
|
|
124
|
+
"--binary",
|
|
125
|
+
"HEAD"
|
|
126
|
+
]).catch(() => "") : void 0;
|
|
162
127
|
return {
|
|
163
128
|
content: [{
|
|
164
129
|
type: "text",
|
|
165
|
-
text:
|
|
130
|
+
text: [
|
|
131
|
+
result.summary,
|
|
132
|
+
stale ? "Workspace changed or could not be fingerprinted; review findings require revalidation." : "",
|
|
133
|
+
environmentId ? `Changes retained in ${workspace} (environment ${environmentId}). Review and integrate from this workspace, then verify the parent workspace again.` : "",
|
|
134
|
+
patch ? `Patch preview:\n${patch.slice(0, 3e4)}` : ""
|
|
135
|
+
].filter(Boolean).join("\n\n")
|
|
166
136
|
}],
|
|
167
137
|
details: {
|
|
168
|
-
|
|
169
|
-
|
|
138
|
+
status: stale && result.status === "success" ? "partial" : result.status,
|
|
139
|
+
mode,
|
|
140
|
+
summary: result.summary,
|
|
141
|
+
iterations: result.toolIterations,
|
|
142
|
+
revision: currentRevision,
|
|
143
|
+
reviewedRevision: revision,
|
|
144
|
+
...result.verification ? { childVerification: result.verification } : {},
|
|
145
|
+
...environmentId ? {
|
|
146
|
+
environmentId,
|
|
147
|
+
workspace,
|
|
148
|
+
patchTruncated: (patch?.length ?? 0) > 3e4
|
|
149
|
+
} : {}
|
|
170
150
|
}
|
|
171
151
|
};
|
|
172
152
|
} catch (error) {
|
|
173
|
-
child.abort();
|
|
174
|
-
try {
|
|
175
|
-
if (deps.hookRunner && childSessionKey) await deps.hookRunner.runHooks("subagent_ended", {
|
|
176
|
-
targetSessionKey: childSessionKey,
|
|
177
|
-
accountId: ctx?.accountId
|
|
178
|
-
}, { sessionKey: parentSessionKey });
|
|
179
|
-
} catch {}
|
|
180
153
|
return {
|
|
181
154
|
content: [{
|
|
182
155
|
type: "text",
|
|
183
|
-
text: `
|
|
156
|
+
text: `Delegation failed: ${String(error)}${environmentId ? `; work retained in ${workspace} (${environmentId})` : ""}`
|
|
184
157
|
}],
|
|
185
158
|
details: {
|
|
186
|
-
|
|
187
|
-
|
|
159
|
+
status: signal?.aborted ? "cancelled" : "failed",
|
|
160
|
+
...environmentId ? {
|
|
161
|
+
environmentId,
|
|
162
|
+
workspace
|
|
163
|
+
} : {}
|
|
188
164
|
}
|
|
189
165
|
};
|
|
166
|
+
} finally {
|
|
167
|
+
signal?.removeEventListener("abort", abort);
|
|
190
168
|
}
|
|
191
169
|
}
|
|
192
170
|
};
|
|
193
171
|
}
|
|
194
172
|
//#endregion
|
|
195
|
-
export { DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS, createDelegateTool };
|
|
173
|
+
export { DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS, INSPECTION_TOOLS, createDelegateTool, delegateToolNames };
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
2
|
import type { TurnOutcomeDeliverable } from '@xopcai/gateway-contract';
|
|
3
|
+
import type { CommandIsolation } from '../commands/command-isolation.js';
|
|
4
|
+
import { type CommandStatus } from '../commands/command-registry.js';
|
|
3
5
|
export interface ExecCommandDetails {
|
|
4
6
|
command: string;
|
|
5
7
|
cwd: string;
|
|
6
|
-
status:
|
|
8
|
+
status: CommandStatus | 'blocked';
|
|
9
|
+
id?: string;
|
|
10
|
+
logPath?: string;
|
|
11
|
+
logTruncated?: boolean;
|
|
7
12
|
exitCode: number | null;
|
|
8
13
|
durationMs: number;
|
|
9
14
|
timedOut: boolean;
|
|
@@ -27,6 +32,8 @@ export interface ExecCommandUpdateDetails {
|
|
|
27
32
|
}
|
|
28
33
|
export interface CreateExecCommandToolOptions {
|
|
29
34
|
/** Env var names allowed through prepareSafeToolEnv even if they match secret heuristics. */
|
|
35
|
+
getCommandIsolation?: () => CommandIsolation | undefined;
|
|
36
|
+
getSessionKey?: () => string | undefined;
|
|
30
37
|
getSkillPassthroughEnvVarNames?: () => string[];
|
|
31
38
|
prepareEnv?: (baseEnv: Record<string, string>, cwd: string) => Promise<Record<string, string>>;
|
|
32
39
|
}
|
|
@@ -1,76 +1,32 @@
|
|
|
1
|
+
import { commandRegistry, commandTimeout } from "../commands/command-registry.js";
|
|
1
2
|
import { formatSize, truncateTail } from "./truncate.js";
|
|
2
3
|
import { evaluateExecPolicy } from "../sandbox/exec-policy.js";
|
|
3
4
|
import { publishArtifactPaths } from "./publish-artifacts.js";
|
|
4
5
|
import { resolve } from "node:path";
|
|
5
|
-
import { spawn } from "node:child_process";
|
|
6
6
|
import { Type } from "@sinclair/typebox";
|
|
7
7
|
//#region src/agent/tools/exec-command.ts
|
|
8
|
-
const MAX_COMMAND_TIMEOUT_MS = 14400 * 1e3;
|
|
9
|
-
const DEFAULT_TIMEOUT_MS = 1800 * 1e3;
|
|
10
8
|
const DEFAULT_MAX_OUTPUT_CHARS = 5e4;
|
|
11
|
-
const STREAM_DELTA_MAX_CHARS = 16e3;
|
|
12
9
|
const ExecCommandSchema = Type.Object({
|
|
13
10
|
cmd: Type.String({ description: "Shell command to execute." }),
|
|
14
11
|
cwd: Type.Optional(Type.String({ description: "Working directory. Relative paths are resolved under the agent workspace." })),
|
|
15
12
|
timeoutMs: Type.Optional(Type.Number({ description: "Command timeout in milliseconds. Defaults to 1800000 (30m) and is capped at 14400000 (4h)." })),
|
|
16
13
|
maxOutputChars: Type.Optional(Type.Number({ description: "Maximum characters returned to the model. UI streaming still receives output deltas." })),
|
|
14
|
+
yieldTimeMs: Type.Optional(Type.Number({
|
|
15
|
+
minimum: 0,
|
|
16
|
+
maximum: 6e4,
|
|
17
|
+
description: "Return a running job after this wait; manage it with managed_job. Omit to wait for completion. Cannot be combined with outputs."
|
|
18
|
+
})),
|
|
17
19
|
outputs: Type.Optional(Type.Array(Type.String({ minLength: 1 }), {
|
|
18
20
|
maxItems: 50,
|
|
19
21
|
description: "Final user-facing files created by this command. Relative paths resolve under the effective cwd and are persisted as chat deliverables after a successful command."
|
|
20
22
|
}))
|
|
21
23
|
});
|
|
22
|
-
function clampTimeoutMs(raw) {
|
|
23
|
-
return Math.min(MAX_COMMAND_TIMEOUT_MS, Math.max(1e3, Math.floor(typeof raw === "number" && Number.isFinite(raw) ? raw : DEFAULT_TIMEOUT_MS)));
|
|
24
|
-
}
|
|
25
24
|
function clampMaxOutputChars(raw) {
|
|
26
25
|
return Math.max(1e3, Math.min(5e5, Math.floor(typeof raw === "number" && Number.isFinite(raw) ? raw : DEFAULT_MAX_OUTPUT_CHARS)));
|
|
27
26
|
}
|
|
28
|
-
function commandStatus(exitCode, timedOut) {
|
|
29
|
-
if (timedOut) return "timed_out";
|
|
30
|
-
if (exitCode === 0) return "success";
|
|
31
|
-
return "failed";
|
|
32
|
-
}
|
|
33
|
-
function appendBoundedTail(current, chunk, maxChars) {
|
|
34
|
-
const combined = current + chunk;
|
|
35
|
-
if (combined.length <= maxChars) return {
|
|
36
|
-
value: combined,
|
|
37
|
-
truncated: false
|
|
38
|
-
};
|
|
39
|
-
return {
|
|
40
|
-
value: combined.slice(-maxChars),
|
|
41
|
-
truncated: true
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function terminateProcessTree(proc) {
|
|
45
|
-
if (!proc.pid) return;
|
|
46
|
-
if (process.platform === "win32") {
|
|
47
|
-
const killer = spawn("taskkill", [
|
|
48
|
-
"/pid",
|
|
49
|
-
String(proc.pid),
|
|
50
|
-
"/t",
|
|
51
|
-
"/f"
|
|
52
|
-
], {
|
|
53
|
-
stdio: "ignore",
|
|
54
|
-
windowsHide: true
|
|
55
|
-
});
|
|
56
|
-
killer.once("error", () => {
|
|
57
|
-
try {
|
|
58
|
-
proc.kill("SIGKILL");
|
|
59
|
-
} catch {}
|
|
60
|
-
});
|
|
61
|
-
killer.unref();
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
try {
|
|
65
|
-
process.kill(-proc.pid, "SIGKILL");
|
|
66
|
-
return;
|
|
67
|
-
} catch {}
|
|
68
|
-
try {
|
|
69
|
-
proc.kill("SIGKILL");
|
|
70
|
-
} catch {}
|
|
71
|
-
}
|
|
72
27
|
function commandFailureHint(details) {
|
|
73
|
-
if (details.status === "success") return void 0;
|
|
28
|
+
if (details.status === "success" || details.status === "running") return void 0;
|
|
29
|
+
if (details.status === "cancelled") return "The command was cancelled. Inspect its partial output before deciding whether to restart.";
|
|
74
30
|
if (details.status === "timed_out") return "The command timed out. Re-run a narrower command, increase timeoutMs if the long run is expected, or inspect partial output before retrying.";
|
|
75
31
|
if (details.exitCode !== 0 && details.stderr.trim()) return "The command failed. Inspect stderr first, fix the underlying issue, then re-run the narrowest relevant verification command.";
|
|
76
32
|
if (details.exitCode !== 0 && details.stdout.trim()) return "The command failed. Inspect stdout for the failure location, then re-run the narrowest relevant verification command.";
|
|
@@ -80,7 +36,7 @@ function formatOutputForModel(details, maxOutputChars) {
|
|
|
80
36
|
let prefix = "";
|
|
81
37
|
if (details.timedOut) prefix += `Command timed out after ${Math.round(details.durationMs / 1e3)}s\n`;
|
|
82
38
|
if (details.exitCode !== 0 && details.exitCode != null) prefix += `Command exited with code ${details.exitCode}\n`;
|
|
83
|
-
if (details.captureTruncated) prefix += `Earlier command output was discarded after ${formatSize(details.totalOutputBytes)}; showing the latest captured output.\n`;
|
|
39
|
+
if (details.captureTruncated) prefix += `Earlier command output was discarded from model context after ${formatSize(details.totalOutputBytes)}; showing the latest captured output.\n`;
|
|
84
40
|
const truncation = truncateTail(details.aggregatedOutput, { maxBytes: Math.min(maxOutputChars, DEFAULT_MAX_OUTPUT_CHARS) });
|
|
85
41
|
let text = `${prefix}${truncation.content}`.trimEnd();
|
|
86
42
|
if (!text) text = "(no output)";
|
|
@@ -109,7 +65,8 @@ function createExecCommandTool(workspaceCwd, options) {
|
|
|
109
65
|
idempotent: false,
|
|
110
66
|
finalGuardRelevant: true,
|
|
111
67
|
async execute(toolCallId, params, signal, onUpdate) {
|
|
112
|
-
const command = (params.cmd ??
|
|
68
|
+
const command = (params.cmd ?? "").trim();
|
|
69
|
+
if (params.yieldTimeMs !== void 0 && params.outputs?.length) throw new Error("yieldTimeMs cannot be combined with outputs; publish files after the job completes.");
|
|
113
70
|
if (!command) return {
|
|
114
71
|
content: [{
|
|
115
72
|
type: "text",
|
|
@@ -163,127 +120,78 @@ function createExecCommandTool(workspaceCwd, options) {
|
|
|
163
120
|
}
|
|
164
121
|
};
|
|
165
122
|
}
|
|
166
|
-
const timeoutMs =
|
|
123
|
+
const timeoutMs = commandTimeout(params.timeoutMs, policy.timeoutMs);
|
|
167
124
|
const maxOutputChars = clampMaxOutputChars(params.maxOutputChars);
|
|
168
|
-
const startTime = Date.now();
|
|
169
125
|
const runtimeEnv = options?.prepareEnv ? await options.prepareEnv(policy.sanitizedEnv, policy.effectiveCwd) : policy.sanitizedEnv;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
let
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
totalOutputBytes += Buffer.byteLength(text);
|
|
191
|
-
if (stream === "stdout") {
|
|
192
|
-
const next = appendBoundedTail(stdout, text, maxOutputChars);
|
|
193
|
-
stdout = next.value;
|
|
194
|
-
captureTruncated ||= next.truncated;
|
|
195
|
-
} else {
|
|
196
|
-
const next = appendBoundedTail(stderr, text, maxOutputChars);
|
|
197
|
-
stderr = next.value;
|
|
198
|
-
captureTruncated ||= next.truncated;
|
|
199
|
-
}
|
|
200
|
-
const nextAggregate = appendBoundedTail(aggregatedOutput, text, maxOutputChars);
|
|
201
|
-
aggregatedOutput = nextAggregate.value;
|
|
202
|
-
captureTruncated ||= nextAggregate.truncated;
|
|
203
|
-
const delta = text.length > STREAM_DELTA_MAX_CHARS ? `${text.slice(0, STREAM_DELTA_MAX_CHARS)}\n[stream delta truncated]` : text;
|
|
204
|
-
onUpdate?.({
|
|
205
|
-
content: [],
|
|
206
|
-
details: {
|
|
207
|
-
kind: "command_output_delta",
|
|
208
|
-
command,
|
|
209
|
-
cwd: policy.effectiveCwd,
|
|
210
|
-
stream,
|
|
211
|
-
delta
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
};
|
|
215
|
-
const finish = async (exitCode, errorText) => {
|
|
216
|
-
if (settled) return;
|
|
217
|
-
settled = true;
|
|
218
|
-
clearTimeout(timeout);
|
|
219
|
-
signal?.removeEventListener("abort", abort);
|
|
220
|
-
if (errorText) {
|
|
221
|
-
totalOutputBytes += Buffer.byteLength(errorText);
|
|
222
|
-
const nextStderr = appendBoundedTail(stderr, errorText, maxOutputChars);
|
|
223
|
-
stderr = nextStderr.value;
|
|
224
|
-
const nextAggregate = appendBoundedTail(aggregatedOutput, errorText, maxOutputChars);
|
|
225
|
-
aggregatedOutput = nextAggregate.value;
|
|
226
|
-
captureTruncated ||= nextStderr.truncated || nextAggregate.truncated;
|
|
227
|
-
}
|
|
228
|
-
const durationMs = Date.now() - startTime;
|
|
229
|
-
const baseDetails = {
|
|
126
|
+
const owner = options?.getSessionKey?.() ?? workspaceCwd;
|
|
127
|
+
const registry = commandRegistry();
|
|
128
|
+
let commandResult = await registry.start({
|
|
129
|
+
workspace: workspaceCwd,
|
|
130
|
+
isolation: options?.getCommandIsolation?.(),
|
|
131
|
+
owner,
|
|
132
|
+
command,
|
|
133
|
+
cwd: policy.effectiveCwd,
|
|
134
|
+
env: {
|
|
135
|
+
...runtimeEnv,
|
|
136
|
+
COLUMNS: "200"
|
|
137
|
+
},
|
|
138
|
+
timeoutMs,
|
|
139
|
+
maxOutputChars,
|
|
140
|
+
signal,
|
|
141
|
+
snapshot: true,
|
|
142
|
+
onOutput: (stream, delta) => onUpdate?.({
|
|
143
|
+
content: [],
|
|
144
|
+
details: {
|
|
145
|
+
kind: "command_output_delta",
|
|
230
146
|
command,
|
|
231
147
|
cwd: policy.effectiveCwd,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
durationMs,
|
|
235
|
-
timedOut,
|
|
236
|
-
truncated: false,
|
|
237
|
-
outputBytes: Buffer.byteLength(aggregatedOutput),
|
|
238
|
-
totalOutputBytes,
|
|
239
|
-
captureTruncated,
|
|
240
|
-
stdout,
|
|
241
|
-
stderr,
|
|
242
|
-
aggregatedOutput
|
|
243
|
-
};
|
|
244
|
-
baseDetails.failureHint = commandFailureHint(baseDetails);
|
|
245
|
-
const formatted = formatOutputForModel(baseDetails, maxOutputChars);
|
|
246
|
-
const details = {
|
|
247
|
-
...baseDetails,
|
|
248
|
-
truncated: formatted.truncated,
|
|
249
|
-
truncatedBy: formatted.truncatedBy,
|
|
250
|
-
outputBytes: formatted.outputBytes
|
|
251
|
-
};
|
|
252
|
-
let resultText = formatted.text;
|
|
253
|
-
if (details.status === "success" && params.outputs?.length) {
|
|
254
|
-
details.artifacts = await publishArtifactPaths({
|
|
255
|
-
paths: params.outputs,
|
|
256
|
-
baseDir: policy.effectiveCwd,
|
|
257
|
-
workspaceRoot: workspaceCwd,
|
|
258
|
-
toolCallId
|
|
259
|
-
});
|
|
260
|
-
const published = details.artifacts.filter((item) => item.availability === "available").length;
|
|
261
|
-
const failed = details.artifacts.length - published;
|
|
262
|
-
resultText += `\n\nArtifacts: ${published} published${failed > 0 ? `, ${failed} failed` : ""}.`;
|
|
148
|
+
stream,
|
|
149
|
+
delta
|
|
263
150
|
}
|
|
264
|
-
|
|
265
|
-
content: [{
|
|
266
|
-
type: "text",
|
|
267
|
-
text: resultText
|
|
268
|
-
}],
|
|
269
|
-
details
|
|
270
|
-
});
|
|
271
|
-
};
|
|
272
|
-
const abort = () => {
|
|
273
|
-
timedOut = true;
|
|
274
|
-
terminateProcessTree(proc);
|
|
275
|
-
};
|
|
276
|
-
const timeout = setTimeout(() => {
|
|
277
|
-
timedOut = true;
|
|
278
|
-
terminateProcessTree(proc);
|
|
279
|
-
}, timeoutMs);
|
|
280
|
-
if (signal?.aborted) abort();
|
|
281
|
-
else signal?.addEventListener("abort", abort, { once: true });
|
|
282
|
-
proc.stdout?.on("data", (data) => publishDelta("stdout", data));
|
|
283
|
-
proc.stderr?.on("data", (data) => publishDelta("stderr", data));
|
|
284
|
-
proc.on("error", (err) => void finish(null, `Error: ${err.message}`));
|
|
285
|
-
proc.on("close", (code) => void finish(code));
|
|
151
|
+
})
|
|
286
152
|
});
|
|
153
|
+
try {
|
|
154
|
+
do
|
|
155
|
+
commandResult = await registry.wait(owner, commandResult.id, params.yieldTimeMs ?? 6e4, signal);
|
|
156
|
+
while (params.yieldTimeMs === void 0 && commandResult.status === "running");
|
|
157
|
+
} catch (error) {
|
|
158
|
+
if (!signal?.aborted) throw error;
|
|
159
|
+
commandResult = await registry.cancel(owner, commandResult.id);
|
|
160
|
+
}
|
|
161
|
+
const baseDetails = {
|
|
162
|
+
...commandResult,
|
|
163
|
+
truncated: false,
|
|
164
|
+
outputBytes: Buffer.byteLength(commandResult.aggregatedOutput)
|
|
165
|
+
};
|
|
166
|
+
baseDetails.failureHint = commandFailureHint(baseDetails);
|
|
167
|
+
const formatted = formatOutputForModel(baseDetails, maxOutputChars);
|
|
168
|
+
const details = {
|
|
169
|
+
...baseDetails,
|
|
170
|
+
truncated: formatted.truncated,
|
|
171
|
+
truncatedBy: formatted.truncatedBy,
|
|
172
|
+
outputBytes: formatted.outputBytes
|
|
173
|
+
};
|
|
174
|
+
let resultText = formatted.text;
|
|
175
|
+
if (details.status === "running") resultText += `\n\nCommand is running (jobId: ${details.id}). Use managed_job wait/status/stdin/cancel.`;
|
|
176
|
+
if (details.logPath) resultText += `\n\nLog: ${details.logPath}${details.logTruncated ? " (truncated)" : ""}`;
|
|
177
|
+
if (details.status === "success" && params.outputs?.length) {
|
|
178
|
+
details.artifacts = await publishArtifactPaths({
|
|
179
|
+
paths: params.outputs,
|
|
180
|
+
baseDir: policy.effectiveCwd,
|
|
181
|
+
workspaceRoot: workspaceCwd,
|
|
182
|
+
toolCallId
|
|
183
|
+
});
|
|
184
|
+
const published = details.artifacts.filter((item) => item.availability === "available").length;
|
|
185
|
+
const failed = details.artifacts.length - published;
|
|
186
|
+
resultText += `\n\nArtifacts: ${published} published${failed > 0 ? `, ${failed} failed` : ""}.`;
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
content: [{
|
|
190
|
+
type: "text",
|
|
191
|
+
text: resultText
|
|
192
|
+
}],
|
|
193
|
+
details
|
|
194
|
+
};
|
|
287
195
|
}
|
|
288
196
|
};
|
|
289
197
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { commandTimeout } from "../commands/command-registry.js";
|
|
3
4
|
import { DEFAULT_TOOL_EXECUTION_TIMEOUT_MS, TimeoutError, executeWithTimeout } from "../lifecycle/timeout-wrapper.js";
|
|
4
5
|
import { withRetry } from "../../infra/retry.js";
|
|
5
6
|
import { ToolConcurrencyController, resolveToolLockMode } from "./concurrency.js";
|
|
@@ -41,8 +42,14 @@ async function executeToolWithProtection(tool, toolCallId, params, signal, onUpd
|
|
|
41
42
|
const onParentAbort = () => controller.abort(signal?.reason);
|
|
42
43
|
if (signal?.aborted) onParentAbort();
|
|
43
44
|
else signal?.addEventListener("abort", onParentAbort, { once: true });
|
|
44
|
-
const
|
|
45
|
-
|
|
45
|
+
const policyDeadline = fullConfig.resolveTimeoutMs?.(toolName);
|
|
46
|
+
const commandDeadlineField = toolName === "exec_command" ? "timeoutMs" : toolName === "managed_job" && params.action === "start" ? "maxRuntimeMs" : void 0;
|
|
47
|
+
const executionParams = commandDeadlineField && policyDeadline ? {
|
|
48
|
+
...params,
|
|
49
|
+
[commandDeadlineField]: Math.min(commandTimeout(params[commandDeadlineField]), policyDeadline)
|
|
50
|
+
} : params;
|
|
51
|
+
const execute = () => tool.execute(toolCallId, executionParams, controller.signal, onUpdate);
|
|
52
|
+
return (fullConfig.enableTimeout && toolName !== "exec_command" ? executeWithTimeout(execute, {
|
|
46
53
|
toolName,
|
|
47
54
|
timeoutMs: resolveTimeoutMs(tool, fullConfig),
|
|
48
55
|
description: `Executing ${toolName}`,
|