@duckmind/dm-windows-x64 0.61.5 → 0.62.1
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/dm.exe +0 -0
- package/extensions/.dm-extensions.json +215 -71
- package/extensions/dm-cua/bin/browser-cua.mjs +6 -1
- package/extensions/dm-cua/index.js +3 -2
- package/extensions/dm-cua/src/browser-cua-lib.mjs +69 -13
- package/extensions/dm-subagents/agents/claude-code-writer.md +15 -0
- package/extensions/dm-subagents/agents/claude-code.md +15 -0
- package/extensions/dm-subagents/agents/codex-exec-writer.md +15 -0
- package/extensions/dm-subagents/agents/codex-exec.md +15 -0
- package/extensions/dm-subagents/agents/cursor-agent-writer.md +14 -0
- package/extensions/dm-subagents/agents/cursor-agent.md +14 -0
- package/extensions/dm-subagents/agents/delegate.md +3 -2
- package/extensions/dm-subagents/agents/oracle.md +10 -5
- package/extensions/dm-subagents/agents/researcher.md +2 -2
- package/extensions/dm-subagents/agents/reviewer.md +17 -7
- package/extensions/dm-subagents/agents/scout.md +5 -5
- package/extensions/dm-subagents/agents/worker.md +6 -2
- package/extensions/dm-subagents/async-retention-discovery-worker.mjs +167 -0
- package/extensions/dm-subagents/index.js +4 -0
- package/extensions/dm-subagents/inspector-runner.mjs +10 -0
- package/extensions/dm-subagents/install.mjs +3 -2
- package/extensions/dm-subagents/package.json +2 -2
- package/extensions/dm-subagents/prompts/council.md +60 -0
- package/extensions/dm-subagents/prompts/parallel-review.md +5 -1
- package/extensions/dm-subagents/prompts/review-loop.md +13 -7
- package/extensions/dm-subagents/skills/council-mode/SKILL.md +59 -0
- package/extensions/dm-subagents/skills/council-mode/references/pass-contracts.md +150 -0
- package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +96 -911
- package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +70 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +539 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +161 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +51 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +295 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/review-and-validation.md +73 -0
- package/extensions/dm-subagents/src/agents/agent-management.js +716 -484
- package/extensions/dm-subagents/src/agents/agent-refinements.js +563 -0
- package/extensions/dm-subagents/src/agents/agent-serializer.js +70 -5
- package/extensions/dm-subagents/src/agents/agents.js +1447 -299
- package/extensions/dm-subagents/src/agents/builtin-names.js +15 -0
- package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -7
- package/extensions/dm-subagents/src/agents/frontmatter.js +64 -14
- package/extensions/dm-subagents/src/agents/identity.js +1 -1
- package/extensions/dm-subagents/src/agents/proactive-skills.js +14 -11
- package/extensions/dm-subagents/src/agents/runtime-agent-events.js +49 -0
- package/extensions/dm-subagents/src/agents/runtime-agent-registry.js +412 -0
- package/extensions/dm-subagents/src/agents/skills.js +52 -35
- package/extensions/dm-subagents/src/api/agents.js +6 -0
- package/extensions/dm-subagents/src/api/background-work.js +151 -0
- package/extensions/dm-subagents/src/api/capability-ceiling.js +12 -0
- package/extensions/dm-subagents/src/api/control-channel.js +3 -0
- package/extensions/dm-subagents/src/api/delegation.js +5 -0
- package/extensions/dm-subagents/src/api/dm-args.js +3 -0
- package/extensions/dm-subagents/src/api/external-job-provider.js +137 -0
- package/extensions/dm-subagents/src/api/external-runs.js +233 -0
- package/extensions/dm-subagents/src/api/intercom-bridge.js +3 -0
- package/extensions/dm-subagents/src/api/preflight.js +322 -0
- package/extensions/dm-subagents/src/api/project-panes.js +11 -0
- package/extensions/dm-subagents/src/api/shared-types.js +4 -0
- package/extensions/dm-subagents/src/extension/config.js +175 -0
- package/extensions/dm-subagents/src/extension/control-notices.js +4 -43
- package/extensions/dm-subagents/src/extension/doctor.js +71 -17
- package/extensions/dm-subagents/src/extension/fanout-child.js +49 -32
- package/extensions/dm-subagents/src/extension/index.js +711 -265
- package/extensions/dm-subagents/src/extension/public-execution.js +114 -0
- package/extensions/dm-subagents/src/extension/rpc.js +427 -22
- package/extensions/dm-subagents/src/extension/schemas.js +158 -65
- package/extensions/dm-subagents/src/extension/steering-notices.js +23 -0
- package/extensions/dm-subagents/src/extension/subagent-guide.js +31 -0
- package/extensions/dm-subagents/src/extension/tool-description.js +92 -74
- package/extensions/dm-subagents/src/extension/tool-result.js +7 -0
- package/extensions/dm-subagents/src/inspectors/herdr/actions.js +218 -0
- package/extensions/dm-subagents/src/inspectors/herdr/client.js +123 -0
- package/extensions/dm-subagents/src/inspectors/herdr/focus.js +47 -0
- package/extensions/dm-subagents/src/inspectors/herdr/inspector-runner.js +160 -0
- package/extensions/dm-subagents/src/inspectors/herdr/project-panes.js +618 -0
- package/extensions/dm-subagents/src/inspectors/herdr/session-roots-codec.js +21 -0
- package/extensions/dm-subagents/src/inspectors/herdr/shell-command.js +15 -0
- package/extensions/dm-subagents/src/integrations/herdr-status.js +377 -0
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +17 -13
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +371 -79
- package/extensions/dm-subagents/src/intercom/result-intercom.js +47 -7
- package/extensions/dm-subagents/src/missions/actions.js +394 -0
- package/extensions/dm-subagents/src/missions/goal-driver.js +149 -0
- package/extensions/dm-subagents/src/missions/lifecycle.js +331 -0
- package/extensions/dm-subagents/src/missions/store.js +548 -0
- package/extensions/dm-subagents/src/missions/types.js +9 -0
- package/extensions/dm-subagents/src/missions/workflow-state.js +245 -0
- package/extensions/dm-subagents/src/policy/authority.js +37 -0
- package/extensions/dm-subagents/src/profiles/profiles.js +36 -18
- package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +427 -0
- package/extensions/dm-subagents/src/runs/background/active-run-index.js +122 -0
- package/extensions/dm-subagents/src/runs/background/async-execution.js +925 -137
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +515 -148
- package/extensions/dm-subagents/src/runs/background/async-resume.js +378 -51
- package/extensions/dm-subagents/src/runs/background/async-retention.js +828 -0
- package/extensions/dm-subagents/src/runs/background/async-status-snapshot.js +31 -0
- package/extensions/dm-subagents/src/runs/background/async-status.js +259 -22
- package/extensions/dm-subagents/src/runs/background/auto-drain.js +46 -0
- package/extensions/dm-subagents/src/runs/background/chain-append.js +50 -15
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +67 -12
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +5 -1
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +3 -11
- package/extensions/dm-subagents/src/runs/background/completion-replay.js +245 -0
- package/extensions/dm-subagents/src/runs/background/control-channel.js +423 -36
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +132 -59
- package/extensions/dm-subagents/src/runs/background/index-segment.js +38 -0
- package/extensions/dm-subagents/src/runs/background/inspect-rpc.js +373 -0
- package/extensions/dm-subagents/src/runs/background/notify.js +357 -57
- package/extensions/dm-subagents/src/runs/background/owned-process-tree.js +86 -0
- package/extensions/dm-subagents/src/runs/background/process-terminal.js +269 -0
- package/extensions/dm-subagents/src/runs/background/result-delivery-ownership.js +34 -0
- package/extensions/dm-subagents/src/runs/background/result-files.js +469 -0
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +540 -75
- package/extensions/dm-subagents/src/runs/background/resume-guidance.js +44 -0
- package/extensions/dm-subagents/src/runs/background/retained-children.js +119 -0
- package/extensions/dm-subagents/src/runs/background/run-id-query.js +5 -0
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +93 -9
- package/extensions/dm-subagents/src/runs/background/run-status.js +303 -32
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +784 -376
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +75 -34
- package/extensions/dm-subagents/src/runs/background/steering.js +221 -0
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +3106 -844
- package/extensions/dm-subagents/src/runs/background/subagent-wait.js +529 -0
- package/extensions/dm-subagents/src/runs/background/terminal-run-index.js +106 -0
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -1
- package/extensions/dm-subagents/src/runs/background/wait-completions.js +155 -0
- package/extensions/dm-subagents/src/runs/background/wait-config.js +46 -0
- package/extensions/dm-subagents/src/runs/background/wait-subscriptions.js +278 -0
- package/extensions/dm-subagents/src/runs/background/wait-tool.js +47 -0
- package/extensions/dm-subagents/src/runs/foreground/async-dismiss-action.js +81 -0
- package/extensions/dm-subagents/src/runs/foreground/async-steering-action.js +245 -0
- package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +74 -0
- package/extensions/dm-subagents/src/runs/foreground/execution.js +1401 -342
- package/extensions/dm-subagents/src/runs/foreground/foreground-control.js +133 -0
- package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +148 -0
- package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +139 -0
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +4278 -1441
- package/extensions/dm-subagents/src/runs/foreground/workflow-detach-reconcile.js +278 -0
- package/extensions/dm-subagents/src/runs/foreground/workflow-foreground-steering.js +155 -0
- package/extensions/dm-subagents/src/runs/shared/abort-recovery.js +97 -0
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +597 -148
- package/extensions/dm-subagents/src/runs/shared/agent-contract.js +35 -0
- package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +472 -0
- package/extensions/dm-subagents/src/runs/shared/background-process-options.js +6 -0
- package/extensions/dm-subagents/src/runs/shared/capability-ceiling.js +175 -0
- package/extensions/dm-subagents/src/runs/shared/child-identity.js +32 -0
- package/extensions/dm-subagents/src/runs/shared/child-launch-plan.js +65 -0
- package/extensions/dm-subagents/src/runs/shared/child-protocol.js +447 -0
- package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +120 -0
- package/extensions/dm-subagents/src/runs/shared/codex-exec-adapter.js +129 -0
- package/extensions/dm-subagents/src/runs/shared/completion-evidence.js +40 -0
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +140 -83
- package/extensions/dm-subagents/src/runs/shared/context-mode.js +38 -0
- package/extensions/dm-subagents/src/runs/shared/cursor-agent-adapter.js +101 -0
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +445 -72
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +27 -16
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +19 -6
- package/extensions/dm-subagents/src/runs/shared/extension-bindings.js +81 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-contract.js +134 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +98 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +419 -0
- package/extensions/dm-subagents/src/runs/shared/external-job-bridge.js +404 -0
- package/extensions/dm-subagents/src/runs/shared/external-job-runner.js +334 -0
- package/extensions/dm-subagents/src/runs/shared/fast-mode-extension.js +8 -0
- package/extensions/dm-subagents/src/runs/shared/host-step-status.js +228 -0
- package/extensions/dm-subagents/src/runs/shared/lane-metadata.js +104 -0
- package/extensions/dm-subagents/src/runs/shared/launch-cwd.js +17 -0
- package/extensions/dm-subagents/src/runs/shared/llm-intent-arbiter.js +190 -0
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +48 -3
- package/extensions/dm-subagents/src/runs/shared/mcp-config-sources.js +387 -0
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +212 -137
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-grant.js +131 -0
- package/extensions/dm-subagents/src/runs/shared/model-exclusions.js +207 -0
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +225 -55
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +85 -28
- package/extensions/dm-subagents/src/runs/shared/mutation-evidence.js +182 -0
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +264 -102
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +15 -5
- package/extensions/dm-subagents/src/runs/shared/orca-progress-tabs.js +505 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +653 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +29 -12
- package/extensions/dm-subagents/src/runs/shared/permissions.js +108 -0
- package/extensions/dm-subagents/src/runs/shared/process-signal.js +13 -0
- package/extensions/dm-subagents/src/runs/shared/run-fanout-budget.js +257 -0
- package/extensions/dm-subagents/src/runs/shared/run-history.js +133 -13
- package/extensions/dm-subagents/src/runs/shared/runtime-acknowledged-extensions.js +62 -0
- package/extensions/dm-subagents/src/runs/shared/session-lease.js +225 -0
- package/extensions/dm-subagents/src/runs/shared/single-output.js +129 -27
- package/extensions/dm-subagents/src/runs/shared/spawn-budget.js +95 -0
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +129 -10
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +66 -11
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +548 -70
- package/extensions/dm-subagents/src/runs/shared/subagent-startup-retry.js +50 -0
- package/extensions/dm-subagents/src/runs/shared/task-intent.js +130 -0
- package/extensions/dm-subagents/src/runs/shared/tool-availability.js +59 -0
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +7 -5
- package/extensions/dm-subagents/src/runs/shared/tool-timeout.js +64 -0
- package/extensions/dm-subagents/src/runs/shared/usage-budget.js +74 -0
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +22 -0
- package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +721 -0
- package/extensions/dm-subagents/src/runs/shared/worktree.js +168 -19
- package/extensions/dm-subagents/src/shared/accessible-dir.js +35 -0
- package/extensions/dm-subagents/src/shared/agent-stream-options.js +3 -0
- package/extensions/dm-subagents/src/shared/artifacts.js +170 -11
- package/extensions/dm-subagents/src/shared/atomic-json.js +36 -38
- package/extensions/dm-subagents/src/shared/capacity-resilient-json.js +77 -0
- package/extensions/dm-subagents/src/shared/child-session-name.js +15 -0
- package/extensions/dm-subagents/src/shared/child-transcript.js +57 -2
- package/extensions/dm-subagents/src/shared/completion-owner.js +7 -0
- package/extensions/dm-subagents/src/shared/display-text.js +142 -0
- package/extensions/dm-subagents/src/shared/extension-context.js +17 -0
- package/extensions/dm-subagents/src/shared/file-coalescer.js +9 -0
- package/extensions/dm-subagents/src/shared/file-system-retry.js +56 -0
- package/extensions/dm-subagents/src/shared/fork-context.js +96 -33
- package/extensions/dm-subagents/src/shared/formatters.js +21 -7
- package/extensions/dm-subagents/src/shared/launch-contract.js +94 -0
- package/extensions/dm-subagents/src/shared/model-info.js +10 -5
- package/extensions/dm-subagents/src/shared/node-executable.js +19 -0
- package/extensions/dm-subagents/src/shared/prompt-resources.js +10 -0
- package/extensions/dm-subagents/src/shared/pruned-fork.js +427 -0
- package/extensions/dm-subagents/src/shared/session-file-trust.js +19 -0
- package/extensions/dm-subagents/src/shared/session-tokens.js +14 -3
- package/extensions/dm-subagents/src/shared/settings.js +39 -47
- package/extensions/dm-subagents/src/shared/shortcuts.js +16 -0
- package/extensions/dm-subagents/src/shared/status-format.js +9 -2
- package/extensions/dm-subagents/src/shared/thinking-ceiling.js +41 -0
- package/extensions/dm-subagents/src/shared/types.js +47 -7
- package/extensions/dm-subagents/src/shared/utf8.js +12 -0
- package/extensions/dm-subagents/src/shared/utils.js +151 -131
- package/extensions/dm-subagents/src/shared/watch-strategy.js +3 -0
- package/extensions/dm-subagents/src/shared/workflow-child-permit.js +84 -0
- package/extensions/dm-subagents/src/slash/delegation-adapters.js +274 -0
- package/extensions/dm-subagents/src/slash/delegation-json.js +113 -0
- package/extensions/dm-subagents/src/slash/delegation-request.js +152 -0
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +294 -243
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +35 -73
- package/extensions/dm-subagents/src/slash/selector.js +101 -0
- package/extensions/dm-subagents/src/slash/slash-bridge.js +17 -1
- package/extensions/dm-subagents/src/slash/slash-commands.js +722 -732
- package/extensions/dm-subagents/src/slash/slash-live-state.js +37 -19
- package/extensions/dm-subagents/src/slash/subagents-admin.js +410 -0
- package/extensions/dm-subagents/src/tui/fleet-status.js +824 -0
- package/extensions/dm-subagents/src/tui/fleet-transcript.js +479 -0
- package/extensions/dm-subagents/src/tui/fleet.js +1326 -0
- package/extensions/dm-subagents/src/tui/render-helpers.js +22 -0
- package/extensions/dm-subagents/src/tui/render.js +1511 -261
- package/extensions/dm-subagents/src/watchdog/change-signature.js +220 -0
- package/extensions/dm-subagents/src/watchdog/child-status.js +151 -0
- package/extensions/dm-subagents/src/watchdog/emission-guard.js +90 -0
- package/extensions/dm-subagents/src/watchdog/lsp-diagnostics.js +484 -0
- package/extensions/dm-subagents/src/watchdog/model-selection.js +154 -0
- package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +138 -0
- package/extensions/dm-subagents/src/watchdog/register-child.js +112 -0
- package/extensions/dm-subagents/src/watchdog/register-main.js +419 -0
- package/extensions/dm-subagents/src/watchdog/render.js +54 -0
- package/extensions/dm-subagents/src/watchdog/review.js +251 -0
- package/extensions/dm-subagents/src/watchdog/runtime.js +803 -0
- package/extensions/dm-subagents/src/watchdog/scope.js +56 -0
- package/extensions/dm-subagents/src/watchdog/settings.js +515 -0
- package/extensions/dm-subagents/src/watchdog/tool-actions.js +151 -0
- package/extensions/dm-subagents/src/watchdog/turn-delta.js +169 -0
- package/extensions/dm-subagents/src/watchdog/types.js +29 -0
- package/extensions/dm-subagents/src/watchdog/warning-format.js +58 -0
- package/extensions/dm-subagents/src/workflows/chat-progress.js +116 -0
- package/extensions/dm-subagents/src/workflows/host-command.js +227 -0
- package/extensions/dm-subagents/src/workflows/scripted-workflow.js +2011 -0
- package/extensions/dm-subagents/src/workflows/workflow-child-summary.js +116 -0
- package/extensions/dm-subagents/src/workflows/workflow-preflight.js +243 -0
- package/extensions/dm-subagents/src/workflows/workflow-receipt.js +387 -0
- package/extensions/dm-subagents/src/workflows/workflow-settlement.js +189 -0
- package/extensions/greedysearch-dm/bin/cdp.mjs +28 -3
- package/extensions/greedysearch-dm/bin/launch.mjs +2 -3
- package/extensions/greedysearch-dm/src/search/constants.mjs +5 -2
- package/package.json +4 -3
- package/extensions/dm-fff/package.json +0 -21
- package/extensions/dm-fff/src/index.js +0 -691
- package/extensions/dm-fff/src/query.js +0 -60
- package/extensions/dm-subagents/agents/context-builder.md +0 -46
- package/extensions/dm-subagents/agents/planner.md +0 -55
- package/extensions/dm-subagents/prompts/parallel-context-build.md +0 -55
- package/extensions/dm-subagents/prompts/parallel-handoff-plan.md +0 -61
- package/extensions/dm-subagents/src/runs/background/wait.js +0 -206
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +0 -1013
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +0 -981
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +0 -50
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { cloneJsonWithinByteLimit } from "./delegation-json.js";
|
|
2
|
+
export function parsePromptTemplateRequest(data) {
|
|
3
|
+
if (!data || typeof data !== "object")
|
|
4
|
+
return;
|
|
5
|
+
const value = data;
|
|
6
|
+
if (value.tasks !== undefined || value.worktree !== undefined)
|
|
7
|
+
return;
|
|
8
|
+
if (typeof value.requestId !== "string" || !value.requestId)
|
|
9
|
+
return;
|
|
10
|
+
if (typeof value.agent !== "string" || !value.agent)
|
|
11
|
+
return;
|
|
12
|
+
if (typeof value.task !== "string" || !value.task)
|
|
13
|
+
return;
|
|
14
|
+
if (typeof value.model !== "string" || !value.model)
|
|
15
|
+
return;
|
|
16
|
+
if (typeof value.cwd !== "string" || !value.cwd)
|
|
17
|
+
return;
|
|
18
|
+
if (value.context !== "fresh" && value.context !== "fork")
|
|
19
|
+
return;
|
|
20
|
+
return {
|
|
21
|
+
requestId: value.requestId,
|
|
22
|
+
agent: value.agent,
|
|
23
|
+
task: value.task,
|
|
24
|
+
context: value.context,
|
|
25
|
+
model: value.model,
|
|
26
|
+
cwd: value.cwd
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function firstTextContent(content) {
|
|
30
|
+
if (!Array.isArray(content))
|
|
31
|
+
return;
|
|
32
|
+
for (const part of content) {
|
|
33
|
+
if (!part || typeof part !== "object")
|
|
34
|
+
continue;
|
|
35
|
+
if (part.type !== "text")
|
|
36
|
+
continue;
|
|
37
|
+
const text = part.text;
|
|
38
|
+
if (typeof text === "string" && text.trim())
|
|
39
|
+
return text.trim();
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
function filterRecentOutput(lines) {
|
|
44
|
+
if (!lines || lines.length === 0)
|
|
45
|
+
return;
|
|
46
|
+
const filtered = lines.filter((line) => typeof line === "string" && line.trim() && line.trim() !== "(running...)");
|
|
47
|
+
if (filtered.length === 0)
|
|
48
|
+
return;
|
|
49
|
+
return filtered;
|
|
50
|
+
}
|
|
51
|
+
function sanitizeRecentTools(tools) {
|
|
52
|
+
if (!tools || tools.length === 0)
|
|
53
|
+
return;
|
|
54
|
+
const sanitized = tools.flatMap((entry) => {
|
|
55
|
+
if (typeof entry.tool !== "string" || entry.tool.trim().length === 0)
|
|
56
|
+
return [];
|
|
57
|
+
return [{
|
|
58
|
+
tool: entry.tool,
|
|
59
|
+
args: typeof entry.args === "string" ? entry.args : String(entry.args ?? "")
|
|
60
|
+
}];
|
|
61
|
+
});
|
|
62
|
+
return sanitized.length > 0 ? sanitized : undefined;
|
|
63
|
+
}
|
|
64
|
+
function resolveProgressModel(update, entry) {
|
|
65
|
+
const results = update.details?.results;
|
|
66
|
+
if (!results || results.length === 0)
|
|
67
|
+
return;
|
|
68
|
+
if (typeof entry.index === "number" && entry.index >= 0) {
|
|
69
|
+
const byIndex = results[entry.index];
|
|
70
|
+
if (typeof byIndex?.model === "string")
|
|
71
|
+
return byIndex.model;
|
|
72
|
+
}
|
|
73
|
+
if (entry.agent) {
|
|
74
|
+
const byAgent = results.find((result) => result.agent === entry.agent && typeof result.model === "string");
|
|
75
|
+
if (byAgent?.model)
|
|
76
|
+
return byAgent.model;
|
|
77
|
+
}
|
|
78
|
+
const firstWithModel = results.find((result) => typeof result.model === "string");
|
|
79
|
+
return firstWithModel?.model;
|
|
80
|
+
}
|
|
81
|
+
function toolCallNameFromSummary(summary) {
|
|
82
|
+
const text = typeof summary.expandedText === "string" && summary.expandedText.trim().length > 0 ? summary.expandedText.trim() : typeof summary.text === "string" ? summary.text.trim() : "";
|
|
83
|
+
if (!text)
|
|
84
|
+
return;
|
|
85
|
+
if (text.startsWith("$ "))
|
|
86
|
+
return "bash";
|
|
87
|
+
return text.match(/^[A-Za-z_][\w.-]*/)?.[0];
|
|
88
|
+
}
|
|
89
|
+
function buildDelegationMessages(result, fallbackText) {
|
|
90
|
+
if (Array.isArray(result.messages) && result.messages.length > 0)
|
|
91
|
+
return result.messages;
|
|
92
|
+
const toolCallParts = (result.toolCalls ?? []).flatMap((summary) => {
|
|
93
|
+
const name = toolCallNameFromSummary(summary);
|
|
94
|
+
return name ? [{ type: "toolCall", name, arguments: { summary: summary.expandedText ?? summary.text ?? "" } }] : [];
|
|
95
|
+
});
|
|
96
|
+
const text = typeof result.finalOutput === "string" && result.finalOutput.trim().length > 0 ? result.finalOutput.trim() : fallbackText;
|
|
97
|
+
const content = [
|
|
98
|
+
...toolCallParts,
|
|
99
|
+
...text ? [{ type: "text", text }] : []
|
|
100
|
+
];
|
|
101
|
+
if (content.length === 0)
|
|
102
|
+
return [];
|
|
103
|
+
return [{ role: "assistant", content }];
|
|
104
|
+
}
|
|
105
|
+
export function toDelegationUpdate(requestId, update) {
|
|
106
|
+
const progress = update.details?.progress?.[0];
|
|
107
|
+
const taskProgress = update.details?.progress?.map((entry) => {
|
|
108
|
+
const lastOutput = entry.recentOutput?.[entry.recentOutput.length - 1];
|
|
109
|
+
const safeLastOutput = typeof lastOutput === "string" && lastOutput.trim() && lastOutput !== "(running...)" ? lastOutput : undefined;
|
|
110
|
+
return {
|
|
111
|
+
index: entry.index,
|
|
112
|
+
agent: entry.agent ?? "delegate",
|
|
113
|
+
status: entry.status,
|
|
114
|
+
currentTool: entry.currentTool,
|
|
115
|
+
currentToolArgs: entry.currentToolArgs,
|
|
116
|
+
recentOutput: safeLastOutput,
|
|
117
|
+
recentOutputLines: filterRecentOutput(entry.recentOutput),
|
|
118
|
+
recentTools: sanitizeRecentTools(entry.recentTools),
|
|
119
|
+
model: resolveProgressModel(update, entry),
|
|
120
|
+
toolCount: entry.toolCount,
|
|
121
|
+
durationMs: entry.durationMs,
|
|
122
|
+
tokens: entry.tokens
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
if (!progress && (!taskProgress || taskProgress.length === 0))
|
|
126
|
+
return;
|
|
127
|
+
const lastOutput = progress?.recentOutput?.[progress.recentOutput.length - 1];
|
|
128
|
+
const safeLastOutput = typeof lastOutput === "string" && lastOutput.trim() && lastOutput !== "(running...)" ? lastOutput : undefined;
|
|
129
|
+
return {
|
|
130
|
+
requestId,
|
|
131
|
+
...update.details?.runId ? { runId: update.details.runId } : {},
|
|
132
|
+
currentTool: progress?.currentTool,
|
|
133
|
+
currentToolArgs: progress?.currentToolArgs,
|
|
134
|
+
recentOutput: safeLastOutput,
|
|
135
|
+
recentOutputLines: filterRecentOutput(progress?.recentOutput),
|
|
136
|
+
recentTools: sanitizeRecentTools(progress?.recentTools),
|
|
137
|
+
model: progress ? resolveProgressModel(update, progress) : undefined,
|
|
138
|
+
toolCount: progress?.toolCount,
|
|
139
|
+
durationMs: progress?.durationMs,
|
|
140
|
+
tokens: progress?.tokens,
|
|
141
|
+
taskProgress
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export function toSubagentDelegationExecutionParams(request) {
|
|
145
|
+
return {
|
|
146
|
+
agent: request.agent,
|
|
147
|
+
task: request.task,
|
|
148
|
+
context: request.context,
|
|
149
|
+
cwd: request.cwd,
|
|
150
|
+
model: request.model,
|
|
151
|
+
timeoutMs: request.timeoutMs,
|
|
152
|
+
toolBudget: request.toolBudget,
|
|
153
|
+
skill: request.skill,
|
|
154
|
+
...request.result.kind === "structured" ? { outputSchema: request.result.schema } : {},
|
|
155
|
+
acceptance: false,
|
|
156
|
+
artifacts: request.artifacts,
|
|
157
|
+
delegatedThinkingOverride: request.thinking,
|
|
158
|
+
delegatedAllowZeroToolBudget: true,
|
|
159
|
+
async: false,
|
|
160
|
+
foregroundOnly: true,
|
|
161
|
+
clarify: false
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
export function toSubagentDelegationUpdate(request, result) {
|
|
165
|
+
const legacy = toDelegationUpdate(request.requestId, result);
|
|
166
|
+
if (!legacy)
|
|
167
|
+
return;
|
|
168
|
+
return {
|
|
169
|
+
requestId: request.requestId,
|
|
170
|
+
ownerRunId: request.ownerRunId,
|
|
171
|
+
nodeId: request.nodeId,
|
|
172
|
+
...legacy.runId ? { runId: legacy.runId } : {},
|
|
173
|
+
...legacy.currentTool ? { currentTool: legacy.currentTool } : {},
|
|
174
|
+
...legacy.currentToolArgs ? { currentToolArgs: legacy.currentToolArgs } : {},
|
|
175
|
+
...legacy.recentOutput ? { recentOutput: legacy.recentOutput } : {},
|
|
176
|
+
...legacy.recentOutputLines ? { recentOutputLines: legacy.recentOutputLines } : {},
|
|
177
|
+
...legacy.recentTools ? { recentTools: legacy.recentTools } : {},
|
|
178
|
+
...legacy.model ? { model: legacy.model } : {},
|
|
179
|
+
...typeof legacy.toolCount === "number" ? { toolCount: legacy.toolCount } : {},
|
|
180
|
+
...typeof legacy.durationMs === "number" ? { durationMs: legacy.durationMs } : {},
|
|
181
|
+
...typeof legacy.tokens === "number" ? { tokens: legacy.tokens } : {}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function resolveSubagentDelegationStatus(result, aborted) {
|
|
185
|
+
if (aborted)
|
|
186
|
+
return "cancelled";
|
|
187
|
+
const child = result.details?.results?.[0];
|
|
188
|
+
if (!child)
|
|
189
|
+
return "failed";
|
|
190
|
+
if (result.details?.timedOut || child.timedOut)
|
|
191
|
+
return "timed_out";
|
|
192
|
+
if (child?.structuredOutputFailed)
|
|
193
|
+
return "structured_output_failed";
|
|
194
|
+
if (child?.toolBudgetBlocked)
|
|
195
|
+
return "tool_budget_exhausted";
|
|
196
|
+
if (child?.acceptance?.status === "rejected" && child.acceptance.explicit)
|
|
197
|
+
return "acceptance_failed";
|
|
198
|
+
if (result.details?.stopped || child?.stopped || child?.interrupted)
|
|
199
|
+
return "interrupted";
|
|
200
|
+
if (result.isError || child?.error || typeof child?.exitCode === "number" && child.exitCode !== 0)
|
|
201
|
+
return "failed";
|
|
202
|
+
return "completed";
|
|
203
|
+
}
|
|
204
|
+
const MAX_RESULT_BYTES = 1024 * 1024;
|
|
205
|
+
export function toSubagentDelegationResponse(request, result, aborted) {
|
|
206
|
+
const child = result.details?.results?.[0];
|
|
207
|
+
const progress = child?.progressSummary ?? result.details?.progress?.[0];
|
|
208
|
+
let status = resolveSubagentDelegationStatus(result, aborted);
|
|
209
|
+
let error = child?.error ?? (status === "failed" ? firstTextContent(result.content) : undefined);
|
|
210
|
+
let projectedResult;
|
|
211
|
+
if (status === "completed") {
|
|
212
|
+
if (request.result.kind === "text") {
|
|
213
|
+
if (typeof child?.finalOutput !== "string") {
|
|
214
|
+
status = "failed";
|
|
215
|
+
error = "Delegated subagent did not capture a text result.";
|
|
216
|
+
} else if (Buffer.byteLength(child.finalOutput, "utf8") > MAX_RESULT_BYTES) {
|
|
217
|
+
status = "failed";
|
|
218
|
+
error = "Delegated text result exceeds 1 MiB when UTF-8 encoded.";
|
|
219
|
+
} else {
|
|
220
|
+
projectedResult = { kind: "text", text: child.finalOutput };
|
|
221
|
+
}
|
|
222
|
+
} else if (child?.structuredOutput === undefined) {
|
|
223
|
+
status = "failed";
|
|
224
|
+
error = "Delegated subagent did not capture the requested structured result.";
|
|
225
|
+
} else {
|
|
226
|
+
const inspected = cloneJsonWithinByteLimit(child.structuredOutput, MAX_RESULT_BYTES);
|
|
227
|
+
if (inspected.ok === false) {
|
|
228
|
+
status = "failed";
|
|
229
|
+
error = inspected.reason === "too_large" ? "Delegated structured result exceeds 1 MiB when encoded." : "Delegated structured result is not plain JSON data.";
|
|
230
|
+
} else {
|
|
231
|
+
projectedResult = { kind: "structured", value: inspected.value };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const usage = child?.usage;
|
|
236
|
+
const childLaunchContractDigest = child?.launchContractDigest;
|
|
237
|
+
return {
|
|
238
|
+
requestId: request.requestId,
|
|
239
|
+
ownerRunId: request.ownerRunId,
|
|
240
|
+
nodeId: request.nodeId,
|
|
241
|
+
status,
|
|
242
|
+
...error ? { error } : {},
|
|
243
|
+
...result.details?.runId ? { runId: result.details.runId } : {},
|
|
244
|
+
...child?.agent ? { agent: child.agent } : {},
|
|
245
|
+
...child?.model ? { model: child.model } : {},
|
|
246
|
+
...child?.thinking ? { thinking: child.thinking } : {},
|
|
247
|
+
...typeof child?.exitCode === "number" ? { exitCode: child.exitCode } : {},
|
|
248
|
+
...childLaunchContractDigest ? { launchContractDigest: childLaunchContractDigest } : {},
|
|
249
|
+
...projectedResult ? { result: projectedResult } : {},
|
|
250
|
+
...usage ? {
|
|
251
|
+
usage: {
|
|
252
|
+
input: usage.input,
|
|
253
|
+
output: usage.output,
|
|
254
|
+
cacheRead: usage.cacheRead,
|
|
255
|
+
cacheWrite: usage.cacheWrite,
|
|
256
|
+
cost: usage.cost,
|
|
257
|
+
turns: usage.turns,
|
|
258
|
+
toolCalls: progress?.toolCount ?? 0,
|
|
259
|
+
durationMs: progress?.durationMs ?? 0
|
|
260
|
+
}
|
|
261
|
+
} : {}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
export function toPromptTemplateResponse(request, result) {
|
|
265
|
+
const contentText = firstTextContent(result.content);
|
|
266
|
+
const messages = buildDelegationMessages(result.details?.results?.[0] ?? {}, contentText);
|
|
267
|
+
return {
|
|
268
|
+
...request,
|
|
269
|
+
messages,
|
|
270
|
+
...contentText ? { contentText } : {},
|
|
271
|
+
isError: result.isError === true,
|
|
272
|
+
errorText: result.isError ? contentText : undefined
|
|
273
|
+
};
|
|
274
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const MAX_JSON_DEPTH = 64;
|
|
2
|
+
const MAX_JSON_ENTRIES = 1e5;
|
|
3
|
+
export function cloneJsonWithinByteLimit(input, maxBytes) {
|
|
4
|
+
let minimumBytes = 0;
|
|
5
|
+
let entries = 0;
|
|
6
|
+
const active = new WeakSet;
|
|
7
|
+
const addMinimumBytes = (bytes) => {
|
|
8
|
+
minimumBytes += bytes;
|
|
9
|
+
if (minimumBytes > maxBytes)
|
|
10
|
+
throw new RangeError("too_large");
|
|
11
|
+
};
|
|
12
|
+
const visit = (value, depth) => {
|
|
13
|
+
if (depth > MAX_JSON_DEPTH)
|
|
14
|
+
throw new TypeError("invalid");
|
|
15
|
+
if (value === null) {
|
|
16
|
+
addMinimumBytes(4);
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
if (typeof value === "boolean") {
|
|
20
|
+
addMinimumBytes(value ? 4 : 5);
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
if (typeof value === "number") {
|
|
24
|
+
if (!Number.isFinite(value))
|
|
25
|
+
throw new TypeError("invalid");
|
|
26
|
+
const encoded = JSON.stringify(Object.is(value, -0) ? 0 : value);
|
|
27
|
+
addMinimumBytes(Buffer.byteLength(encoded, "utf8"));
|
|
28
|
+
return Object.is(value, -0) ? 0 : value;
|
|
29
|
+
}
|
|
30
|
+
if (typeof value === "string") {
|
|
31
|
+
addMinimumBytes(Buffer.byteLength(value, "utf8") + 2);
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
if (typeof value !== "object")
|
|
35
|
+
throw new TypeError("invalid");
|
|
36
|
+
const object = value;
|
|
37
|
+
if (active.has(object))
|
|
38
|
+
throw new TypeError("invalid");
|
|
39
|
+
active.add(object);
|
|
40
|
+
try {
|
|
41
|
+
const prototype = Object.getPrototypeOf(object);
|
|
42
|
+
const keys = Reflect.ownKeys(object);
|
|
43
|
+
if (Array.isArray(object)) {
|
|
44
|
+
if (prototype !== Array.prototype)
|
|
45
|
+
throw new TypeError("invalid");
|
|
46
|
+
const lengthDescriptor = Object.getOwnPropertyDescriptor(object, "length");
|
|
47
|
+
if (!lengthDescriptor || !("value" in lengthDescriptor) || !Number.isSafeInteger(lengthDescriptor.value) || lengthDescriptor.value < 0) {
|
|
48
|
+
throw new TypeError("invalid");
|
|
49
|
+
}
|
|
50
|
+
const length = lengthDescriptor.value;
|
|
51
|
+
addMinimumBytes(2 + Math.max(0, length - 1));
|
|
52
|
+
const output = [];
|
|
53
|
+
for (const key of keys) {
|
|
54
|
+
if (typeof key === "symbol")
|
|
55
|
+
throw new TypeError("invalid");
|
|
56
|
+
if (key === "length")
|
|
57
|
+
continue;
|
|
58
|
+
if (!/^(?:0|[1-9][0-9]*)$/.test(key) || Number(key) >= length)
|
|
59
|
+
throw new TypeError("invalid");
|
|
60
|
+
}
|
|
61
|
+
for (let index = 0;index < length; index++) {
|
|
62
|
+
const descriptor = Object.getOwnPropertyDescriptor(object, String(index));
|
|
63
|
+
if (!descriptor || !("value" in descriptor) || !descriptor.enumerable)
|
|
64
|
+
throw new TypeError("invalid");
|
|
65
|
+
entries++;
|
|
66
|
+
if (entries > MAX_JSON_ENTRIES)
|
|
67
|
+
throw new TypeError("invalid");
|
|
68
|
+
output.push(visit(descriptor.value, depth + 1));
|
|
69
|
+
}
|
|
70
|
+
return output;
|
|
71
|
+
}
|
|
72
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
73
|
+
throw new TypeError("invalid");
|
|
74
|
+
addMinimumBytes(2 + Math.max(0, keys.length - 1));
|
|
75
|
+
const output = {};
|
|
76
|
+
for (const key of keys) {
|
|
77
|
+
if (typeof key === "symbol")
|
|
78
|
+
throw new TypeError("invalid");
|
|
79
|
+
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
80
|
+
if (!descriptor || !("value" in descriptor) || !descriptor.enumerable)
|
|
81
|
+
throw new TypeError("invalid");
|
|
82
|
+
entries++;
|
|
83
|
+
if (entries > MAX_JSON_ENTRIES)
|
|
84
|
+
throw new TypeError("invalid");
|
|
85
|
+
addMinimumBytes(Buffer.byteLength(JSON.stringify(key), "utf8") + 1);
|
|
86
|
+
Object.defineProperty(output, key, {
|
|
87
|
+
value: visit(descriptor.value, depth + 1),
|
|
88
|
+
enumerable: true,
|
|
89
|
+
configurable: true,
|
|
90
|
+
writable: true
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return output;
|
|
94
|
+
} finally {
|
|
95
|
+
active.delete(object);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
try {
|
|
99
|
+
const value = visit(input, 0);
|
|
100
|
+
const encoded = JSON.stringify(value);
|
|
101
|
+
if (encoded === undefined)
|
|
102
|
+
return { ok: false, reason: "invalid" };
|
|
103
|
+
const encodedBytes = Buffer.byteLength(encoded, "utf8");
|
|
104
|
+
if (encodedBytes > maxBytes)
|
|
105
|
+
return { ok: false, reason: "too_large" };
|
|
106
|
+
return { ok: true, value, encodedBytes };
|
|
107
|
+
} catch (error) {
|
|
108
|
+
return {
|
|
109
|
+
ok: false,
|
|
110
|
+
reason: error instanceof RangeError && error.message === "too_large" ? "too_large" : "invalid"
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { validateToolBudgetConfig } from "../runs/shared/tool-budget.js";
|
|
2
|
+
import { cloneJsonWithinByteLimit } from "./delegation-json.js";
|
|
3
|
+
const supportedFields = new Set([
|
|
4
|
+
"requestId",
|
|
5
|
+
"ownerRunId",
|
|
6
|
+
"nodeId",
|
|
7
|
+
"agent",
|
|
8
|
+
"task",
|
|
9
|
+
"context",
|
|
10
|
+
"cwd",
|
|
11
|
+
"model",
|
|
12
|
+
"thinking",
|
|
13
|
+
"timeoutMs",
|
|
14
|
+
"toolBudget",
|
|
15
|
+
"skill",
|
|
16
|
+
"artifacts",
|
|
17
|
+
"result"
|
|
18
|
+
]);
|
|
19
|
+
const thinkingLevels = new Set(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
20
|
+
const MAX_SCHEMA_BYTES = 64 * 1024;
|
|
21
|
+
const MAX_TASK_BYTES = 1024 * 1024;
|
|
22
|
+
const MAX_CWD_BYTES = 32 * 1024;
|
|
23
|
+
const MAX_SHORT_TEXT_BYTES = 1024;
|
|
24
|
+
const MAX_SKILL_ENTRIES = 256;
|
|
25
|
+
const MAX_SKILL_AGGREGATE_BYTES = 64 * 1024;
|
|
26
|
+
function nonEmptyString(value) {
|
|
27
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
28
|
+
}
|
|
29
|
+
function validateId(value) {
|
|
30
|
+
if (!nonEmptyString(value) || value.length > 256 || /[\r\n]/.test(value))
|
|
31
|
+
return;
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
export function parseSubagentDelegationRequest(data) {
|
|
35
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
36
|
+
return { ok: false, error: "Delegation request must be an object." };
|
|
37
|
+
}
|
|
38
|
+
const value = data;
|
|
39
|
+
const requestId = validateId(value.requestId);
|
|
40
|
+
if (!requestId) {
|
|
41
|
+
return { ok: false, error: "Delegation requestId must be a non-empty string of at most 256 characters without newlines." };
|
|
42
|
+
}
|
|
43
|
+
const ownerRunId = validateId(value.ownerRunId);
|
|
44
|
+
if (!ownerRunId) {
|
|
45
|
+
return { ok: false, requestId, error: "Delegation ownerRunId must be a non-empty string of at most 256 characters without newlines." };
|
|
46
|
+
}
|
|
47
|
+
const nodeId = validateId(value.nodeId);
|
|
48
|
+
if (!nodeId) {
|
|
49
|
+
return { ok: false, requestId, ownerRunId, error: "Delegation nodeId must be a non-empty string of at most 256 characters without newlines." };
|
|
50
|
+
}
|
|
51
|
+
const identity = { requestId, ownerRunId, nodeId };
|
|
52
|
+
const unsupportedField = Object.keys(value).find((key) => !supportedFields.has(key));
|
|
53
|
+
if (unsupportedField)
|
|
54
|
+
return { ok: false, ...identity, error: `Unsupported delegation field: ${unsupportedField}.` };
|
|
55
|
+
if (!nonEmptyString(value.agent))
|
|
56
|
+
return { ok: false, ...identity, error: "Delegation agent must be a non-empty string." };
|
|
57
|
+
if (!nonEmptyString(value.task))
|
|
58
|
+
return { ok: false, ...identity, error: "Delegation task must be a non-empty string." };
|
|
59
|
+
if (value.context !== "fresh" && value.context !== "fork") {
|
|
60
|
+
return { ok: false, ...identity, error: "Delegation context must be fresh or fork." };
|
|
61
|
+
}
|
|
62
|
+
if (!nonEmptyString(value.cwd))
|
|
63
|
+
return { ok: false, ...identity, error: "Delegation cwd must be a non-empty string." };
|
|
64
|
+
if (value.model !== undefined && !nonEmptyString(value.model)) {
|
|
65
|
+
return { ok: false, ...identity, error: "model must be a non-empty string when provided." };
|
|
66
|
+
}
|
|
67
|
+
if (value.timeoutMs !== undefined && (typeof value.timeoutMs !== "number" || !Number.isInteger(value.timeoutMs) || value.timeoutMs < 1)) {
|
|
68
|
+
return { ok: false, ...identity, error: "timeoutMs must be an integer >= 1." };
|
|
69
|
+
}
|
|
70
|
+
const timeoutMs = typeof value.timeoutMs === "number" ? value.timeoutMs : undefined;
|
|
71
|
+
if (timeoutMs !== undefined && timeoutMs > 2147483647) {
|
|
72
|
+
return { ok: false, ...identity, error: "timeoutMs must be <= 2147483647." };
|
|
73
|
+
}
|
|
74
|
+
if (value.toolBudget && typeof value.toolBudget === "object" && !Array.isArray(value.toolBudget)) {
|
|
75
|
+
const unsupportedToolBudgetField = Object.keys(value.toolBudget).find((key) => key !== "soft" && key !== "hard" && key !== "block");
|
|
76
|
+
if (unsupportedToolBudgetField) {
|
|
77
|
+
return { ok: false, ...identity, error: `toolBudget.${unsupportedToolBudgetField} is not supported.` };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const toolBudget = validateToolBudgetConfig(value.toolBudget, "toolBudget", { minimumHard: 0 });
|
|
81
|
+
if (toolBudget.error)
|
|
82
|
+
return { ok: false, ...identity, error: toolBudget.error };
|
|
83
|
+
if (value.skill !== undefined) {
|
|
84
|
+
const validSkill = typeof value.skill === "boolean" || nonEmptyString(value.skill) || Array.isArray(value.skill) && value.skill.length > 0 && value.skill.every(nonEmptyString);
|
|
85
|
+
if (!validSkill) {
|
|
86
|
+
return { ok: false, ...identity, error: "skill must be a boolean, non-empty string, or non-empty string array." };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (value.artifacts !== undefined && typeof value.artifacts !== "boolean") {
|
|
90
|
+
return { ok: false, ...identity, error: "artifacts must be a boolean." };
|
|
91
|
+
}
|
|
92
|
+
if (Buffer.byteLength(value.task, "utf8") > MAX_TASK_BYTES) {
|
|
93
|
+
return { ok: false, ...identity, error: "Delegation task exceeds 1 MiB when UTF-8 encoded." };
|
|
94
|
+
}
|
|
95
|
+
if (Buffer.byteLength(value.cwd, "utf8") > MAX_CWD_BYTES) {
|
|
96
|
+
return { ok: false, ...identity, error: "Delegation cwd exceeds 32 KiB when UTF-8 encoded." };
|
|
97
|
+
}
|
|
98
|
+
if (Buffer.byteLength(value.agent, "utf8") > MAX_SHORT_TEXT_BYTES) {
|
|
99
|
+
return { ok: false, ...identity, error: "Delegation agent exceeds 1 KiB when UTF-8 encoded." };
|
|
100
|
+
}
|
|
101
|
+
if (typeof value.model === "string" && Buffer.byteLength(value.model, "utf8") > MAX_SHORT_TEXT_BYTES) {
|
|
102
|
+
return { ok: false, ...identity, error: "Delegation model exceeds 1 KiB when UTF-8 encoded." };
|
|
103
|
+
}
|
|
104
|
+
const skillEntries = typeof value.skill === "string" ? [value.skill] : Array.isArray(value.skill) ? value.skill : [];
|
|
105
|
+
if (skillEntries.length > MAX_SKILL_ENTRIES) {
|
|
106
|
+
return { ok: false, ...identity, error: "Delegation skill supports at most 256 entries." };
|
|
107
|
+
}
|
|
108
|
+
if (skillEntries.some((entry) => Buffer.byteLength(entry, "utf8") > MAX_SHORT_TEXT_BYTES)) {
|
|
109
|
+
return { ok: false, ...identity, error: "Delegation skill entry exceeds 1 KiB when UTF-8 encoded." };
|
|
110
|
+
}
|
|
111
|
+
if (skillEntries.reduce((total, entry) => total + Buffer.byteLength(entry, "utf8"), 0) > MAX_SKILL_AGGREGATE_BYTES) {
|
|
112
|
+
return { ok: false, ...identity, error: "Delegation skill entries exceed 64 KiB in aggregate when UTF-8 encoded." };
|
|
113
|
+
}
|
|
114
|
+
if (value.thinking !== undefined && (typeof value.thinking !== "string" || !thinkingLevels.has(value.thinking))) {
|
|
115
|
+
return { ok: false, ...identity, error: "thinking must be one of off, minimal, low, medium, high, xhigh, or max." };
|
|
116
|
+
}
|
|
117
|
+
if (!value.result || typeof value.result !== "object" || Array.isArray(value.result)) {
|
|
118
|
+
return { ok: false, ...identity, error: 'result must be { kind: "text" } or { kind: "structured", schema: object }.' };
|
|
119
|
+
}
|
|
120
|
+
const result = value.result;
|
|
121
|
+
let structuredSchema;
|
|
122
|
+
if (result.kind === "text") {
|
|
123
|
+
const unsupportedResultField = Object.keys(result).find((key) => key !== "kind");
|
|
124
|
+
if (unsupportedResultField)
|
|
125
|
+
return { ok: false, ...identity, error: `result.${unsupportedResultField} is not supported for text results.` };
|
|
126
|
+
} else if (result.kind === "structured") {
|
|
127
|
+
const unsupportedResultField = Object.keys(result).find((key) => key !== "kind" && key !== "schema");
|
|
128
|
+
if (unsupportedResultField)
|
|
129
|
+
return { ok: false, ...identity, error: `result.${unsupportedResultField} is not supported for structured results.` };
|
|
130
|
+
if (!result.schema || typeof result.schema !== "object" || Array.isArray(result.schema)) {
|
|
131
|
+
return { ok: false, ...identity, error: "result.schema must be a JSON Schema object." };
|
|
132
|
+
}
|
|
133
|
+
const inspectedSchema = cloneJsonWithinByteLimit(result.schema, MAX_SCHEMA_BYTES);
|
|
134
|
+
if (inspectedSchema.ok === false) {
|
|
135
|
+
return {
|
|
136
|
+
ok: false,
|
|
137
|
+
...identity,
|
|
138
|
+
error: inspectedSchema.reason === "too_large" ? "result.schema exceeds 64 KiB when encoded." : "result.schema must be plain JSON data."
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
structuredSchema = inspectedSchema.value;
|
|
142
|
+
} else {
|
|
143
|
+
return { ok: false, ...identity, error: "result.kind must be text or structured." };
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
ok: true,
|
|
147
|
+
request: {
|
|
148
|
+
...value,
|
|
149
|
+
result: structuredSchema ? { kind: "structured", schema: structuredSchema } : { kind: "text" }
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|