@duckmind/dm-windows-x64 0.61.4 → 0.61.9
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 +211 -67
- 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/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,245 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import * as fs from "node:fs";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { writePrivateAtomicJson } from "../shared/atomic-json.js";
|
|
6
|
+
import { DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS, isRetryableFileSystemError, waitForFileSystemRetry } from "../shared/file-system-retry.js";
|
|
7
|
+
import { assertWorkflowJsonValue } from "../workflows/scripted-workflow.js";
|
|
8
|
+
import { validateMissionId } from "./store.js";
|
|
9
|
+
const STATE_KEY_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
10
|
+
const STATE_LOCK_STALE_MS = 60000;
|
|
11
|
+
export const MISSION_STATE_MAX_BYTES = 256 * 1024;
|
|
12
|
+
export function missionStatePath(location, missionId) {
|
|
13
|
+
return path.join(location.missionDir, validateMissionId(missionId), "state.json");
|
|
14
|
+
}
|
|
15
|
+
function isProcessAlive(pid) {
|
|
16
|
+
try {
|
|
17
|
+
process.kill(pid, 0);
|
|
18
|
+
return true;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
return error.code === "EPERM";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function linuxProcessStartKey(pid) {
|
|
24
|
+
try {
|
|
25
|
+
const raw = fs.readFileSync(`/proc/${pid}/stat`, "utf-8");
|
|
26
|
+
const tail = raw.slice(raw.lastIndexOf(")") + 2).trim().split(/\s+/);
|
|
27
|
+
return tail[19] ? `linux:${tail[19]}` : undefined;
|
|
28
|
+
} catch {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function psProcessStartKey(pid) {
|
|
33
|
+
try {
|
|
34
|
+
const raw = execFileSync("ps", ["-p", String(pid), "-o", "lstart="], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 1000 }).trim();
|
|
35
|
+
return raw ? `ps:${raw}` : undefined;
|
|
36
|
+
} catch {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function windowsProcessStartKey(pid) {
|
|
41
|
+
try {
|
|
42
|
+
const raw = execFileSync("powershell.exe", ["-NoProfile", "-Command", `(Get-CimInstance Win32_Process -Filter "ProcessId=${pid}").CreationDate`], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 1000, windowsHide: true }).trim();
|
|
43
|
+
return raw ? `win:${raw}` : undefined;
|
|
44
|
+
} catch {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function processStartKey(pid) {
|
|
49
|
+
if (process.platform === "linux")
|
|
50
|
+
return linuxProcessStartKey(pid) ?? psProcessStartKey(pid);
|
|
51
|
+
if (process.platform === "win32")
|
|
52
|
+
return windowsProcessStartKey(pid);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const CURRENT_PROCESS_KEY = processStartKey(process.pid);
|
|
56
|
+
function readStateLockOwner(lockPath) {
|
|
57
|
+
try {
|
|
58
|
+
const owner = JSON.parse(fs.readFileSync(path.join(lockPath, "owner.json"), "utf-8"));
|
|
59
|
+
if (Number.isSafeInteger(owner.pid) && owner.pid > 0 && typeof owner.token === "string" && owner.token && Number.isSafeInteger(owner.createdAt)) {
|
|
60
|
+
return {
|
|
61
|
+
pid: owner.pid,
|
|
62
|
+
token: owner.token,
|
|
63
|
+
createdAt: owner.createdAt,
|
|
64
|
+
...typeof owner.processKey === "string" && owner.processKey ? { processKey: owner.processKey } : {}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
function stateLockIsStale(lockPath, now = Date.now()) {
|
|
73
|
+
const owner = readStateLockOwner(lockPath);
|
|
74
|
+
if (owner) {
|
|
75
|
+
if (!isProcessAlive(owner.pid))
|
|
76
|
+
return true;
|
|
77
|
+
if (owner.processKey) {
|
|
78
|
+
const currentProcessKey = owner.pid === process.pid ? CURRENT_PROCESS_KEY : processStartKey(owner.pid);
|
|
79
|
+
if (currentProcessKey)
|
|
80
|
+
return owner.processKey !== currentProcessKey;
|
|
81
|
+
if (owner.pid === process.pid)
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
return now - fs.statSync(lockPath).mtimeMs > STATE_LOCK_STALE_MS;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error.code === "ENOENT")
|
|
90
|
+
return false;
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function removeOwnedStateLock(lockPath, owner) {
|
|
95
|
+
const current = readStateLockOwner(lockPath);
|
|
96
|
+
if (current?.token !== owner.token)
|
|
97
|
+
return;
|
|
98
|
+
fs.rmSync(lockPath, { recursive: true, force: true });
|
|
99
|
+
}
|
|
100
|
+
function staleDirectoryExists(dirPath, now = Date.now()) {
|
|
101
|
+
try {
|
|
102
|
+
return now - fs.statSync(dirPath).mtimeMs > STATE_LOCK_STALE_MS;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if (error.code === "ENOENT")
|
|
105
|
+
return false;
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function tryMakeDirectory(dirPath, mode) {
|
|
110
|
+
try {
|
|
111
|
+
fs.mkdirSync(dirPath, { mode });
|
|
112
|
+
return true;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error.code === "EEXIST")
|
|
115
|
+
return false;
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function waitForStateLock(delayMs, lockPath) {
|
|
120
|
+
if (delayMs === undefined)
|
|
121
|
+
throw new Error(`Timed out acquiring mission state lock '${lockPath}'.`);
|
|
122
|
+
waitForFileSystemRetry(delayMs);
|
|
123
|
+
}
|
|
124
|
+
function reclaimStaleStateLock(lockPath, reclaimPath) {
|
|
125
|
+
if (!stateLockIsStale(lockPath))
|
|
126
|
+
return false;
|
|
127
|
+
if (!tryMakeDirectory(reclaimPath, 448))
|
|
128
|
+
return false;
|
|
129
|
+
try {
|
|
130
|
+
if (!stateLockIsStale(lockPath))
|
|
131
|
+
return false;
|
|
132
|
+
fs.rmSync(lockPath, { recursive: true, force: true });
|
|
133
|
+
return true;
|
|
134
|
+
} finally {
|
|
135
|
+
fs.rmSync(reclaimPath, { recursive: true, force: true });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function withStateFileLock(filePath, operation) {
|
|
139
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
140
|
+
const lockPath = `${filePath}.lock`;
|
|
141
|
+
const reclaimPath = `${lockPath}.reclaim`;
|
|
142
|
+
let owner;
|
|
143
|
+
for (let attempt = 0;; attempt++) {
|
|
144
|
+
if (fs.existsSync(reclaimPath)) {
|
|
145
|
+
if (staleDirectoryExists(reclaimPath)) {
|
|
146
|
+
fs.rmSync(reclaimPath, { recursive: true, force: true });
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
let acquired = false;
|
|
153
|
+
try {
|
|
154
|
+
acquired = tryMakeDirectory(lockPath, 448);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
if (isRetryableFileSystemError(error)) {
|
|
157
|
+
waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
throw new Error(`Failed to acquire mission state lock '${lockPath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
161
|
+
}
|
|
162
|
+
if (!acquired) {
|
|
163
|
+
if (reclaimStaleStateLock(lockPath, reclaimPath))
|
|
164
|
+
continue;
|
|
165
|
+
waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
owner = { pid: process.pid, token: randomUUID(), createdAt: Date.now(), ...CURRENT_PROCESS_KEY ? { processKey: CURRENT_PROCESS_KEY } : {} };
|
|
169
|
+
try {
|
|
170
|
+
fs.writeFileSync(path.join(lockPath, "owner.json"), JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
|
|
171
|
+
} catch (error) {
|
|
172
|
+
fs.rmSync(lockPath, { recursive: true, force: true });
|
|
173
|
+
owner = undefined;
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
return operation();
|
|
180
|
+
} finally {
|
|
181
|
+
if (owner)
|
|
182
|
+
removeOwnedStateLock(lockPath, owner);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function validateStateKey(value) {
|
|
186
|
+
if (typeof value !== "string" || !STATE_KEY_PATTERN.test(value)) {
|
|
187
|
+
throw new Error("state key must be 1-128 characters using letters, numbers, '.', '_' or '-', and start with a letter or number.");
|
|
188
|
+
}
|
|
189
|
+
return value;
|
|
190
|
+
}
|
|
191
|
+
export function createMissionWorkflowState(location, missionId) {
|
|
192
|
+
const filePath = missionStatePath(location, missionId);
|
|
193
|
+
let loaded = false;
|
|
194
|
+
let values = Object.create(null);
|
|
195
|
+
const readStateFile = () => {
|
|
196
|
+
let raw;
|
|
197
|
+
try {
|
|
198
|
+
raw = fs.readFileSync(filePath, "utf-8");
|
|
199
|
+
} catch (error) {
|
|
200
|
+
if (error.code === "ENOENT")
|
|
201
|
+
return Object.create(null);
|
|
202
|
+
throw new Error(`Failed to read mission state '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
203
|
+
}
|
|
204
|
+
const bytes = Buffer.byteLength(raw);
|
|
205
|
+
if (bytes > MISSION_STATE_MAX_BYTES)
|
|
206
|
+
throw new Error(`Mission state file '${filePath}' exceeds the 256 KiB limit (${bytes} bytes).`);
|
|
207
|
+
try {
|
|
208
|
+
const parsed = JSON.parse(raw);
|
|
209
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
210
|
+
throw new Error("root must be a JSON object");
|
|
211
|
+
assertWorkflowJsonValue(parsed, "mission state");
|
|
212
|
+
return Object.assign(Object.create(null), parsed);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
throw new Error(`Invalid mission state file '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
const load = () => {
|
|
218
|
+
if (loaded)
|
|
219
|
+
return values;
|
|
220
|
+
values = readStateFile();
|
|
221
|
+
loaded = true;
|
|
222
|
+
return values;
|
|
223
|
+
};
|
|
224
|
+
return {
|
|
225
|
+
path: filePath,
|
|
226
|
+
get(key) {
|
|
227
|
+
const validKey = validateStateKey(key);
|
|
228
|
+
const current = load();
|
|
229
|
+
return Object.hasOwn(current, validKey) ? current[validKey] : undefined;
|
|
230
|
+
},
|
|
231
|
+
set(key, value) {
|
|
232
|
+
const validKey = validateStateKey(key);
|
|
233
|
+
assertWorkflowJsonValue(value, `state.set('${validKey}') value`);
|
|
234
|
+
withStateFileLock(filePath, () => {
|
|
235
|
+
const next = Object.assign(Object.create(null), readStateFile(), { [validKey]: value });
|
|
236
|
+
const bytes = Buffer.byteLength(JSON.stringify(next, null, 2));
|
|
237
|
+
if (bytes > MISSION_STATE_MAX_BYTES)
|
|
238
|
+
throw new Error(`Mission state exceeds the 256 KiB limit (${bytes} bytes; maximum ${MISSION_STATE_MAX_BYTES} bytes).`);
|
|
239
|
+
writePrivateAtomicJson(filePath, next);
|
|
240
|
+
values = next;
|
|
241
|
+
loaded = true;
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const AUTHORITY_ACTIONS = [
|
|
2
|
+
"discardWorktree",
|
|
3
|
+
"destructiveCleanup",
|
|
4
|
+
"spawnBudgetGrant",
|
|
5
|
+
"scheduleCreate",
|
|
6
|
+
"stopRun",
|
|
7
|
+
"steerRun"
|
|
8
|
+
];
|
|
9
|
+
const DEFAULT_AUTHORITY_POLICY = {
|
|
10
|
+
discardWorktree: "confirm",
|
|
11
|
+
destructiveCleanup: "confirm",
|
|
12
|
+
spawnBudgetGrant: "confirm",
|
|
13
|
+
scheduleCreate: "auto",
|
|
14
|
+
stopRun: "auto",
|
|
15
|
+
steerRun: "auto"
|
|
16
|
+
};
|
|
17
|
+
export function resolveAuthorityDecision(input) {
|
|
18
|
+
return input.policy?.[input.action] ?? DEFAULT_AUTHORITY_POLICY[input.action];
|
|
19
|
+
}
|
|
20
|
+
export function validateAuthorityPolicy(value, label = "config.authorityPolicy") {
|
|
21
|
+
if (value === undefined)
|
|
22
|
+
return;
|
|
23
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
24
|
+
throw new Error(`${label} must be a JSON object`);
|
|
25
|
+
}
|
|
26
|
+
const policy = value;
|
|
27
|
+
const allowedActions = new Set(AUTHORITY_ACTIONS);
|
|
28
|
+
for (const [action, decision] of Object.entries(policy)) {
|
|
29
|
+
if (!allowedActions.has(action)) {
|
|
30
|
+
throw new Error(`${label}.${action} is unknown; expected one of ${AUTHORITY_ACTIONS.join(", ")}`);
|
|
31
|
+
}
|
|
32
|
+
if (decision !== "auto" && decision !== "confirm" && decision !== "forbid") {
|
|
33
|
+
throw new Error(`${label}.${action} must be "auto", "confirm", or "forbid"`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return policy;
|
|
37
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import { getPiSpawnCommand } from "../runs/shared/dm-spawn.js";
|
|
4
5
|
import { findModelInfo, getSupportedThinkingLevels, splitKnownThinkingSuffix, toModelInfo } from "../shared/model-info.js";
|
|
5
6
|
import { getAgentDir } from "../shared/utils.js";
|
|
6
7
|
export const DEFAULT_PROVIDER_MODELS_MAX_AGE_DAYS = 7;
|
|
@@ -48,10 +49,23 @@ function validateSubagentProfile(filePath, parsed) {
|
|
|
48
49
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
49
50
|
throw new Error(`Profile '${filePath}' has invalid override '${name}'; expected an object.`);
|
|
50
51
|
}
|
|
51
|
-
const
|
|
52
|
+
const override = value;
|
|
53
|
+
const model = override.model;
|
|
52
54
|
if (model !== undefined && typeof model !== "string") {
|
|
53
55
|
throw new Error(`Profile '${filePath}' has invalid model for '${name}'; expected a string.`);
|
|
54
56
|
}
|
|
57
|
+
const thinking = override.thinking;
|
|
58
|
+
if (thinking !== undefined && thinking !== false && typeof thinking !== "string") {
|
|
59
|
+
throw new Error(`Profile '${filePath}' has invalid thinking for '${name}'; expected a string or false.`);
|
|
60
|
+
}
|
|
61
|
+
const fallbackModels = override.fallbackModels;
|
|
62
|
+
if (fallbackModels !== undefined && fallbackModels !== false && (!Array.isArray(fallbackModels) || fallbackModels.some((item) => typeof item !== "string"))) {
|
|
63
|
+
throw new Error(`Profile '${filePath}' has invalid fallbackModels for '${name}'; expected an array of strings or false.`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const disableBuiltins = subagents.disableBuiltins;
|
|
67
|
+
if (disableBuiltins !== undefined && typeof disableBuiltins !== "boolean") {
|
|
68
|
+
throw new Error(`Profile '${filePath}' has invalid subagents.disableBuiltins; expected a boolean.`);
|
|
55
69
|
}
|
|
56
70
|
return parsed;
|
|
57
71
|
}
|
|
@@ -137,7 +151,7 @@ function agentsForRoleTier(roleTier) {
|
|
|
137
151
|
if (roleTier === "cheap")
|
|
138
152
|
return ["scout", "delegate"];
|
|
139
153
|
if (roleTier === "medium")
|
|
140
|
-
return ["
|
|
154
|
+
return ["researcher", "reviewer"];
|
|
141
155
|
return ["worker", "reviewer", "oracle"];
|
|
142
156
|
}
|
|
143
157
|
function classifyModel(input, context) {
|
|
@@ -192,11 +206,12 @@ function resolveProbeStatus(text, timedOut) {
|
|
|
192
206
|
return "unavailable";
|
|
193
207
|
return "error";
|
|
194
208
|
}
|
|
195
|
-
async function probeModel(
|
|
196
|
-
if (typeof
|
|
197
|
-
return { status: "skipped", message: "
|
|
209
|
+
async function probeModel(dm, fullId) {
|
|
210
|
+
if (typeof dm.exec !== "function") {
|
|
211
|
+
return { status: "skipped", message: "dm.exec is unavailable in this runtime." };
|
|
198
212
|
}
|
|
199
|
-
const
|
|
213
|
+
const spawnSpec = getPiSpawnCommand(["-p", "--model", fullId, "--no-tools", 'Reply with exactly "OK".']);
|
|
214
|
+
const result = await dm.exec(spawnSpec.command, spawnSpec.args, {
|
|
200
215
|
cwd: os.tmpdir(),
|
|
201
216
|
timeout: 45000
|
|
202
217
|
});
|
|
@@ -250,14 +265,12 @@ function dominatesModel(a, b) {
|
|
|
250
265
|
function filterDominatedModels(models) {
|
|
251
266
|
return models.filter((candidate, index) => !models.some((other, otherIndex) => otherIndex !== index && dominatesModel(other, candidate)));
|
|
252
267
|
}
|
|
253
|
-
function buildProfileFile(
|
|
268
|
+
function buildProfileFile(models) {
|
|
254
269
|
return {
|
|
255
270
|
subagents: {
|
|
256
271
|
agentOverrides: {
|
|
257
272
|
scout: { model: models.cheap },
|
|
258
273
|
delegate: { model: models.cheap },
|
|
259
|
-
planner: { model: models.medium },
|
|
260
|
-
"context-builder": { model: models.medium },
|
|
261
274
|
researcher: { model: models.medium },
|
|
262
275
|
worker: { model: models.strong },
|
|
263
276
|
reviewer: { model: models.strong },
|
|
@@ -319,7 +332,12 @@ export function applySubagentProfile(name) {
|
|
|
319
332
|
const { filePath, profile } = readSubagentProfile(name);
|
|
320
333
|
const settingsPath = getUserSettingsPath();
|
|
321
334
|
const settings = readSettingsFile(settingsPath);
|
|
322
|
-
settings.subagents
|
|
335
|
+
const existing = settings.subagents && typeof settings.subagents === "object" && !Array.isArray(settings.subagents) ? settings.subagents : {};
|
|
336
|
+
settings.subagents = {
|
|
337
|
+
...existing,
|
|
338
|
+
...profile.subagents,
|
|
339
|
+
agentOverrides: profile.subagents.agentOverrides
|
|
340
|
+
};
|
|
323
341
|
writeJsonFile(settingsPath, settings);
|
|
324
342
|
return { filePath, settingsPath };
|
|
325
343
|
}
|
|
@@ -336,7 +354,7 @@ export function isProviderModelCatalogStale(catalog, maxAgeDays = DEFAULT_PROVID
|
|
|
336
354
|
const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
|
|
337
355
|
return Date.now() - refreshedAt > maxAgeMs;
|
|
338
356
|
}
|
|
339
|
-
export async function refreshProviderModelCatalog(
|
|
357
|
+
export async function refreshProviderModelCatalog(dm, ctx, provider, options = {}) {
|
|
340
358
|
const normalizedProvider = normalizeProviderName(provider);
|
|
341
359
|
const maxAgeDays = options.maxAgeDays ?? DEFAULT_PROVIDER_MODELS_MAX_AGE_DAYS;
|
|
342
360
|
const filePath = getProviderModelsPath(normalizedProvider);
|
|
@@ -354,7 +372,7 @@ export async function refreshProviderModelCatalog(pi, ctx, provider, options = {
|
|
|
354
372
|
for (const rawModel of availableModels) {
|
|
355
373
|
const modelRecord = rawModel;
|
|
356
374
|
const fullId = `${modelRecord.provider}/${modelRecord.id}`;
|
|
357
|
-
const probe = options.probe === false ? { status: "skipped", message: "Live probing disabled." } : await probeModel(
|
|
375
|
+
const probe = options.probe === false ? { status: "skipped", message: "Live probing disabled." } : await probeModel(dm, fullId);
|
|
358
376
|
observedModels.push({ rawModel, modelRecord, fullId, probe });
|
|
359
377
|
}
|
|
360
378
|
const classificationContext = buildClassificationContext(observedModels.map(({ modelRecord }) => ({
|
|
@@ -409,9 +427,9 @@ export async function refreshProviderModelCatalog(pi, ctx, provider, options = {
|
|
|
409
427
|
writeJsonFile(filePath, catalog);
|
|
410
428
|
return { filePath, catalog, reused: false, heuristicFallbackCount: countHeuristicFallbackModels(catalog) };
|
|
411
429
|
}
|
|
412
|
-
export async function generateProfilesForProvider(
|
|
430
|
+
export async function generateProfilesForProvider(dm, ctx, provider, options = {}) {
|
|
413
431
|
const normalizedProvider = normalizeProviderName(provider);
|
|
414
|
-
const { filePath: catalogPath, catalog, heuristicFallbackCount } = await refreshProviderModelCatalog(
|
|
432
|
+
const { filePath: catalogPath, catalog, heuristicFallbackCount } = await refreshProviderModelCatalog(dm, ctx, normalizedProvider, {
|
|
415
433
|
maxAgeDays: options.maxAgeDays,
|
|
416
434
|
force: options.forceRefresh,
|
|
417
435
|
probe: options.probe
|
|
@@ -426,13 +444,13 @@ export async function generateProfilesForProvider(pi, ctx, provider, options = {
|
|
|
426
444
|
const dir = ensureSubagentProfilesDir();
|
|
427
445
|
const quotaPath = path.join(dir, `${normalizedProvider}.quota.json`);
|
|
428
446
|
const qualityPath = path.join(dir, `${normalizedProvider}.quality.json`);
|
|
429
|
-
writeJsonFile(quotaPath, buildProfileFile(
|
|
430
|
-
writeJsonFile(qualityPath, buildProfileFile(
|
|
447
|
+
writeJsonFile(quotaPath, buildProfileFile(quotaModels));
|
|
448
|
+
writeJsonFile(qualityPath, buildProfileFile(qualityModels));
|
|
431
449
|
const selectedModels = new Set([...Object.values(quotaModels), ...Object.values(qualityModels)]);
|
|
432
450
|
const selectedHeuristicFallbackCount = profileModels.filter((model) => selectedModels.has(model.fullId) && modelUsesHeuristicClassification(model)).length;
|
|
433
451
|
return { quotaPath, qualityPath, catalogPath, quotaModels, qualityModels, heuristicFallbackCount, selectedHeuristicFallbackCount };
|
|
434
452
|
}
|
|
435
|
-
export async function checkSubagentProfile(
|
|
453
|
+
export async function checkSubagentProfile(dm, ctx, name) {
|
|
436
454
|
const { filePath, profile } = readSubagentProfile(name);
|
|
437
455
|
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
438
456
|
const entries = Object.entries(profile.subagents.agentOverrides).filter(([, value]) => typeof value?.model === "string" && value.model.trim()).map(([agent, value]) => ({ agent, model: value.model.trim() }));
|
|
@@ -444,7 +462,7 @@ export async function checkSubagentProfile(pi, ctx, name) {
|
|
|
444
462
|
const probeModelId = modelInfo ? `${modelInfo.fullId}${thinkingSuffix}` : entry.model;
|
|
445
463
|
let probe = probeCache.get(probeModelId);
|
|
446
464
|
if (!probe) {
|
|
447
|
-
probe = await probeModel(
|
|
465
|
+
probe = await probeModel(dm, probeModelId);
|
|
448
466
|
probeCache.set(probeModelId, probe);
|
|
449
467
|
}
|
|
450
468
|
results.push({
|