From 8f10f182f87b3d13860b2cf8ce278ccb757dfeab Mon Sep 17 00:00:00 2001 From: Ammar Date: Sat, 2 May 2026 13:52:59 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20refactor:=20rip=20out=20the=20Or?= =?UTF-8?q?chestrator=20agent=20feature?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the Orchestrator built-in agent and its surrounding plumbing wholesale, with no backward-compat migration: - Delete src/node/builtinAgents/orchestrator.md and the planExecutorRouter LLM auto-router (and its tests + the planAutoRoutingStatus constants module). - Drop the planSubagentExecutorRouting + planSubagentDefaultsToOrchestrator task settings (and their migration), the corresponding Settings UI selector, and the on-disk schema entries. - taskService: collapse the propose_plan auto-handoff target to "exec" unconditionally; drop resolvePlanAutoHandoffTargetAgentId, isAgentEnabledForTaskWorkspace, canAgentSpawnTasksInWorkspace, and the getTaskWorkspaceAgentResolutionContext helper used only by them. - Remove the Start Orchestrator button + handler in ProposePlanToolCall and the Workflow icon entry in AgentModePicker. - Strip orchestrator branches from streamContextBuilder, modelMessageTransform, and the FALLBACK_AGENTS list. - Prune orchestrator-specific tests (taskService.test.ts plan-handoff tests, builtInAgentDefinitions.test.ts, modelMessageTransform.test.ts, ProposePlanToolCall.test.tsx, listOrchestratorAlwaysSelectable.test.ts, picker.test.ts entry). - Remove the OrchestrateAgents README screenshot story + capture entry + docs/img asset, and delete the Orchestrator section from docs/agents/index.mdx and the Orchestrator-mode notes from docs/AGENTS.md. - Regenerate builtInAgentContent.generated.ts and builtInSkillContent.generated.ts. forkOrchestrator (the unrelated workspace-fork helper) is preserved. --- docs/AGENTS.md | 8 +- docs/agents/index.mdx | 175 ---------- docs/img/orchestrate-agents.webp | Bin 167320 -> 0 bytes scripts/capture-readme-screenshots.ts | 8 - .../AgentModePicker/AgentModePicker.tsx | 3 +- .../Settings/Sections/TasksSection.agents.ts | 10 - .../Settings/Sections/TasksSection.tsx | 43 +-- .../ProposePlanToolCall.stories.tsx | 83 +---- .../Tools/ProposePlanToolCall.test.tsx | 194 ----------- .../features/Tools/ProposePlanToolCall.tsx | 108 +----- .../stories/App.readmeScreenshots.stories.tsx | 191 ----------- src/browser/stories/mocks/orpc.ts | 11 - src/browser/utils/fuzzySearch.test.ts | 2 +- .../applyWorkspaceChatEventToAggregator.ts | 2 +- .../messages/modelMessageTransform.test.ts | 49 --- .../utils/messages/modelMessageTransform.ts | 25 +- src/browser/utils/workspaceModeAi.ts | 2 +- src/common/config/schemas/appConfigOnDisk.ts | 4 +- src/common/config/schemas/taskSettings.ts | 6 - src/common/constants/planAutoRoutingStatus.ts | 4 - src/common/types/tasks.test.ts | 33 -- src/common/types/tasks.ts | 49 +-- src/common/utils/agentTools.test.ts | 8 +- src/common/utils/agentTools.ts | 2 +- src/node/builtinAgents/orchestrator.md | 164 --------- src/node/orpc/router.ts | 2 +- .../builtInAgentContent.generated.ts | 1 - .../builtInAgentDefinitions.test.ts | 20 +- .../builtInAgentDefinitions.ts | 1 - src/node/services/agentSession.ts | 2 +- .../builtInSkillContent.generated.ts | 183 +--------- src/node/services/planExecutorRouter.test.ts | 107 ------ src/node/services/planExecutorRouter.ts | 147 -------- src/node/services/streamContextBuilder.ts | 6 +- src/node/services/taskService.test.ts | 226 +------------ src/node/services/taskService.ts | 314 +----------------- .../listOrchestratorAlwaysSelectable.test.ts | 101 ------ tests/ui/agents/picker.test.ts | 18 - 38 files changed, 50 insertions(+), 2262 deletions(-) delete mode 100644 docs/img/orchestrate-agents.webp delete mode 100644 src/common/constants/planAutoRoutingStatus.ts delete mode 100644 src/node/builtinAgents/orchestrator.md delete mode 100644 src/node/services/planExecutorRouter.test.ts delete mode 100644 src/node/services/planExecutorRouter.ts delete mode 100644 tests/ipc/agents/listOrchestratorAlwaysSelectable.test.ts diff --git a/docs/AGENTS.md b/docs/AGENTS.md index 2d05b31fe6..6e7e1e6ab0 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -69,8 +69,6 @@ Core workflow: - If a PR has Codex review comments, address + resolve them, then re-request review by commenting `@codex review` on the PR. - Prefer `gh` CLI for GitHub interactions over manual web/curl flows. -- In Orchestrator mode, delegate implementation/verification commands to `exec` or `explore` sub-agents and integrate their patches; do not bypass delegation with direct local edits. -- In Orchestrator mode, route higher-complexity implementation tasks to `plan` sub-agents so they can research and produce a precise plan before auto-handoff to implementation. - User preference: when work is already on an open PR, push branch updates at the end of each completed change set so the PR stays current. - **PR creation gate:** Do **not** open/create a pull request unless the user explicitly asks (e.g., "open a PR", "create PR", "submit this"). By default, complete local validation, commit/push branch updates as requested, and let the user review before deciding whether to open a PR. @@ -82,11 +80,11 @@ Core workflow: When a PR exists, you MUST remain in this loop until the PR is fully ready: 1. Push your latest fixes. -2. Run local validation (`make static-check` and targeted tests as needed); in Orchestrator mode, delegate command execution to sub-agents. +2. Run local validation (`make static-check` and targeted tests as needed). 3. Request review with `@codex review`. 4. Run `./scripts/wait_pr_ready.sh ` (which must execute `./scripts/wait_pr_checks.sh --once` while checks are pending). -5. If Codex leaves comments, address them (delegate fixes in Orchestrator mode), resolve threads with `./scripts/resolve_pr_comment.sh `, push, and repeat. -6. If checks/mergeability fail, fix issues locally (delegate fixes in Orchestrator mode), push, and repeat. +5. If Codex leaves comments, address them, resolve threads with `./scripts/resolve_pr_comment.sh `, push, and repeat. +6. If checks/mergeability fail, fix issues locally, push, and repeat. The only early-stop exception is when the reviewer is clearly misunderstanding the intended change and further churn would be counterproductive. In that case, leave a clarifying PR comment and pause for human direction. diff --git a/docs/agents/index.mdx b/docs/agents/index.mdx index 6cdfa9914a..f5f7a75610 100644 --- a/docs/agents/index.mdx +++ b/docs/agents/index.mdx @@ -315,181 +315,6 @@ When a task involves repeated screenshot/action/verify loops for desktop GUI int -### Orchestrator - -**Coordinate sub-agent implementation and apply patches** - - - -```md ---- -name: Orchestrator -description: Coordinate sub-agent implementation and apply patches -base: exec -subagent: - runnable: false - append_prompt: | - You are running as a sub-agent orchestrator in a child workspace. - - - Your parent workspace handles all PR management. - Do NOT create pull requests, push to remote branches, or run any - `gh pr` / `git push` commands. This applies even if AGENTS.md or - other instructions say otherwise — those PR instructions target the - top-level workspace only. - - Orchestrate your delegated subtasks (spawn, await, apply patches, - verify locally), then call `agent_report` exactly once with: - - What changed (paths / key details) - - What you ran (tests, typecheck, lint) - - Any follow-ups / risks - - Do not expand scope beyond the delegated task. -tools: - add: - - ask_user_question - remove: - - propose_plan - # Keep Orchestrator focused on coordination: no direct file edits. - - file_edit_.* ---- - -You are an internal Orchestrator agent running in Exec mode. - -**Mission:** coordinate implementation by delegating investigation + coding to sub-agents, then integrating their patches into this workspace. - -When a plan is present (default): - -- Treat the accepted plan as the source of truth. Its file paths, symbols, and structure were validated during planning — do not routinely spawn `explore` to re-confirm them. Exception: if the plan references stale paths or appears to have been authored/edited by the user without planner validation, a single targeted `explore` to sanity-check critical paths is acceptable. -- Spawning `explore` to gather _additional_ context beyond what the plan provides is encouraged (e.g., checking whether a helper already exists, locating test files not mentioned in the plan, discovering existing patterns to match). This produces better implementation task briefs. -- Do not spawn `explore` just to verify that a planner-generated plan is correct — that is the planner's job, and the plan was accepted by the user. -- Convert the plan into concrete implementation subtasks and start delegation (`exec` for low complexity, `plan` for higher complexity). - -What you are allowed to do directly in this workspace: - -- Spawn/await/manage sub-agent tasks (`task`, `task_await`, `task_list`, `task_terminate`). -- Apply patches (`task_apply_git_patch`). -- Use `bash` for orchestration workflows: repo coordination via `git`/`gh`, targeted post-apply verification runs, and waiting on review/CI completion after PR updates (for example: `git push`, `gh pr comment`, `gh pr view`, `gh pr checks --watch`). Only run `gh pr create` when the user explicitly asks you to open a PR. -- Ask clarifying questions with `ask_user_question` when blocked. -- Coordinate targeted verification after integrating patches by running focused checks directly (when appropriate) or delegating runs to `explore`/`exec`. -- Delegate patch-conflict reconciliation to `exec` sub-agents. - -Hard rules (delegate-first): - -- Trust `explore` sub-agent reports as authoritative for repo facts (paths/symbols/callsites). Do not redo the same investigation yourself; only re-check if the report is ambiguous or contradicts other evidence. -- For correctness claims, an `explore` sub-agent report counts as having read the referenced files. -- **Do not do broad repo investigation here.** If you need context, spawn an `explore` sub-agent with a narrow prompt (keeps this agent focused on coordination). -- **Do not implement features/bugfixes directly here.** Spawn `exec` (simple) or `plan` (complex) sub-agents and have them complete the work end-to-end. -- **Do not use `bash` for file reads/writes, manual code editing, or broad repo exploration.** `bash` in this workspace is for orchestration-only operations: `git`/`gh` repo management, targeted post-apply verification checks, and waiting for PR review/CI outcomes. If direct checks fail due to code issues, delegate fixes to `exec`/`plan` sub-agents instead of implementing changes here. -- **Never read or scan session storage.** This includes `~/.mux/sessions/**` and `~/.mux/sessions/subagent-patches/**`. Treat session storage as an internal implementation detail; do not shell out to locate patch artifacts on disk. Only use `task_apply_git_patch` to access patches. - -Delegation guide: - -- Use `explore` for narrowly-scoped read-only questions (confirm an assumption, locate a symbol/callsite, find relevant tests). Avoid "scan the repo" prompts. -- Use `exec` for straightforward, low-complexity work where the implementation path is obvious from the task brief. - - Good fit: single-file edits, localized wiring to existing helpers, straightforward command execution, or narrowly scoped follow-ups with clear acceptance. - - Provide a compact task brief (so the sub-agent can act without reading the full plan) with: - - Task: one sentence - - Background (why this matters): 1–3 bullets - - Scope / non-goals: what to change, and what not to change - - Starting points: relevant files/symbols/paths (from prior exploration) - - Acceptance: bullets / checks - - Deliverables: commits + verification commands to run - - Constraints: - - Do not expand scope. - - Prefer `explore` tasks for repo investigation (paths/symbols/tests/patterns) to preserve your context window for implementation. - Trust Explore reports as authoritative; do not re-verify unless ambiguous/contradictory. - If starting points + acceptance are already clear, skip initial explore and only explore when blocked. - - Create one or more git commits before `agent_report`. -- Use `plan` for higher-complexity subtasks that touch multiple files/locations, require non-trivial investigation, or have an unclear implementation approach. - - Default to `plan` when a subtask needs coordinated updates across multiple locations, unless the edits are mechanical and already fully specified. - - For higher-complexity implementation work, prefer `plan` over `exec` so the sub-agent can do targeted research and produce a precise plan before implementation begins. - - Good fit: multi-file refactors, cross-module behavior changes, unfamiliar subsystems, or work where sequencing/dependencies need discovery. - - Plan subtasks automatically hand off to implementation after a successful `propose_plan`; expect the usual task completion output once implementation finishes. - - For `plan` briefs, prioritize goal + constraints + acceptance criteria over file-by-file diff instructions. -- Use `desktop` for GUI-heavy desktop automation that requires repeated screenshot → act → verify loops (for example, interacting with application windows, clicking through UI flows, or visual verification). The desktop agent enforces a grounding discipline that keeps visual context local. - -Recommended Orchestrator → Exec task brief template: - -- Task: -- Background (why this matters): - - -- Scope / non-goals: - - Scope: - - Non-goals: -- Starting points: -- Dependencies / assumptions: - - Assumes: - - If unmet: stop and report back; do not expand scope to create prerequisites. -- Acceptance: -- Deliverables: - - Commits: - - Verification: -- Constraints: - - Do not expand scope. - - Prefer `explore` tasks for repo investigation (paths/symbols/tests/patterns) to preserve your context window for implementation. - Trust Explore reports as authoritative; do not re-verify unless ambiguous/contradictory. - If starting points + acceptance are already clear, skip initial explore and only explore when blocked. - - Create one or more git commits before `agent_report`. - -Dependency analysis (required before spawning implementation tasks — `exec` or `plan`): - -- For each candidate subtask, write: - - Outputs: files/targets/artifacts introduced/renamed/generated - - Inputs / prerequisites (including for verification): what must already exist -- A subtask is "independent" only if its patch can be applied + verified on the current parent workspace HEAD, without any other pending patch. -- Parallelism is the default: maximize the size of each independent batch and run it in parallel. - Use the sequential protocol only when a subtask has a concrete prerequisite on another subtask's outputs. -- If task B depends on outputs from task A: - - Do not spawn B until A has completed and A's patch is applied in the parent workspace. - - If the dependency chain is tight (download → generate → wire-up), prefer one `exec` task rather than splitting. - -Example dependency chain (schema download → generation): - -- Task A outputs: a new download target + new schema files. -- Task B inputs: those schema files; verifies by running generation. -- Therefore: run Task A (await + apply patch) before spawning Task B. - -Patch integration loop (default): - -1. Identify a batch of independent subtasks. -2. Spawn one implementation sub-agent task per subtask with `run_in_background: true` (`exec` for low complexity, `plan` for higher complexity). -3. Await the batch via `task_await`. -4. For each successful implementation task (`exec` directly, or `plan` after auto-handoff to implementation), integrate patches one at a time: - - Treat every successful child task with a `taskId` as pending patch integration, whether the completion arrived inline from `task` or later from `task_await`. - - Complete each dry-run + real-apply pair before starting the next patch. Applying one patch changes `HEAD`, which can invalidate later dry-run results. - - Dry-run apply: `task_apply_git_patch` with `dry_run: true`. - - If dry-run succeeds, immediately apply for real: `task_apply_git_patch` with `dry_run: false`. - - Do not assume an inline `status: completed` result means the child changes are already present in this workspace. - - If dry-run fails, treat it as a patch conflict and delegate reconciliation: - 1. Do not attempt a real apply for that patch in this workspace. - 2. Spawn a dedicated `exec` task. In the brief, include the original failing `task_id` and instruct the sub-agent to replay that patch via `task_apply_git_patch`, resolve conflicts in its own workspace, run `git am --continue`, commit the resolved result, and report back with a new patch to apply cleanly. - - If real apply fails unexpectedly: - 1. Restore a clean working tree before delegating: run `git am --abort` via `bash` only when a git-am session is in progress; if abort reports no operation in progress, continue. - 2. Then follow the same delegated reconciliation flow above. -5. Verify + review: - - Run focused verification directly with `bash` when practical (for example: targeted tests or the repo's standard full-validation command), or delegate verification to `explore`/`exec` when investigation/fixes are likely. - - Use `git`/`gh` directly for PR orchestration when a PR already exists (pushes, review-request comments, replies to review remarks, and CI/check-status waiting loops). Create a new PR only when the user explicitly asks. - - PASS: summary-only (no long logs). - - FAIL: include the failing command + key error lines; then delegate a fix to `exec`/`plan` and re-verify. - -Sequential protocol (only for dependency chains): - -1. Spawn the prerequisite implementation task (`exec` or `plan`, based on complexity) with `run_in_background: false`. -2. If step 1 returns `queued`/`running` without a completed report, call `task_await` with the returned `taskId` before attempting any patch apply. If step 1 returns `status: completed` inline, that same `taskId` still requires patch application. -3. Dry-run apply its patch (`dry_run: true`); then apply for real (`dry_run: false`). If either step fails, follow the conflict playbook above (including `git am --abort` only when a real apply leaves a git-am session in progress). -4. Only after the patch is applied, spawn the dependent implementation task. -5. Repeat until the dependency chain is complete. - -Note: child workspaces are created at spawn time. Spawning dependents too early means they work from the wrong repo snapshot and get forced into scope expansion. - -Keep context minimal: - -- Do not request, paste, or restate large plans. -- Prefer short, actionable prompts, but include enough context that the sub-agent does not need your plan file. - - Child workspaces do not automatically have access to the parent's plan file; summarize just the relevant slice or provide file pointers. -- Prefer file paths/symbols over long prose. -``` - - - ### Plan **Create a plan before coding** diff --git a/docs/img/orchestrate-agents.webp b/docs/img/orchestrate-agents.webp deleted file mode 100644 index 1f8a18503a306422facda722132e315dc15994d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167320 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 z%0D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

@n&31R}7G=3L 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�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 z�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

VLk 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 z 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 R00000000005O47S001D11wa4* diff --git a/scripts/capture-readme-screenshots.ts b/scripts/capture-readme-screenshots.ts index 2ce3068535..a70fe60785 100644 --- a/scripts/capture-readme-screenshots.ts +++ b/scripts/capture-readme-screenshots.ts @@ -155,14 +155,6 @@ const STORIES: StoryDef[] = [ postProcess: async (pngBuffer: Buffer) => sharp(pngBuffer).webp({ quality: WEBP_QUALITY }).toBuffer(), }, - { - exportName: "OrchestrateAgents", - storyId: `${STORY_ID_PREFIX}orchestrate-agents`, - outputFile: "orchestrate-agents.webp", - // Narrower viewport makes the plan card + "Start Orchestrator" button more prominent - viewport: { width: 1200, height: 1188 }, - clip: { x: 0, y: 0, width: 1200, height: 1000 }, - }, ]; // --------------------------------------------------------------------------- diff --git a/src/browser/components/AgentModePicker/AgentModePicker.tsx b/src/browser/components/AgentModePicker/AgentModePicker.tsx index 46cb151d76..834c9b8635 100644 --- a/src/browser/components/AgentModePicker/AgentModePicker.tsx +++ b/src/browser/components/AgentModePicker/AgentModePicker.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import { Bot, ChevronDown, Route, SquareCode, Workflow } from "lucide-react"; +import { Bot, ChevronDown, Route, SquareCode } from "lucide-react"; import type { LucideIcon } from "lucide-react"; import { useAgent } from "@/browser/contexts/AgentContext"; @@ -47,7 +47,6 @@ interface AgentOption { const AGENT_ICONS: Record = { plan: Route, exec: SquareCode, - orchestrator: Workflow, }; const DEFAULT_AGENT_ICON: LucideIcon = Bot; diff --git a/src/browser/features/Settings/Sections/TasksSection.agents.ts b/src/browser/features/Settings/Sections/TasksSection.agents.ts index 23f08e372f..b7c6217fa8 100644 --- a/src/browser/features/Settings/Sections/TasksSection.agents.ts +++ b/src/browser/features/Settings/Sections/TasksSection.agents.ts @@ -91,16 +91,6 @@ export const FALLBACK_AGENTS: AgentDefinitionDescriptor[] = [ require: ["propose_name"], }, }, - { - id: "orchestrator", - scope: "built-in", - name: "Orchestrator", - description: "Coordinate sub-agent implementation and apply patches", - uiSelectable: true, - uiRoutable: true, - subagentRunnable: false, - base: "exec", - }, ]; function compareAgentsByName(a: AgentDefinitionDescriptor, b: AgentDefinitionDescriptor): number { diff --git a/src/browser/features/Settings/Sections/TasksSection.tsx b/src/browser/features/Settings/Sections/TasksSection.tsx index 770ee7d0b4..0f04d19f8b 100644 --- a/src/browser/features/Settings/Sections/TasksSection.tsx +++ b/src/browser/features/Settings/Sections/TasksSection.tsx @@ -34,11 +34,9 @@ import { import { DEFAULT_TASK_SETTINGS, TASK_SETTINGS_LIMITS, - isPlanSubagentExecutorRouting, normalizeSubagentAiDefaults, shouldMirrorAgentDefaultToLegacySubagent, normalizeTaskSettings, - type PlanSubagentExecutorRouting, type SubagentAiDefaults, type SubagentAiDefaultsEntry, type TaskSettings, @@ -280,9 +278,7 @@ function areTaskSettingsEqual(a: TaskSettings, b: TaskSettings): boolean { a.maxParallelAgentTasks === b.maxParallelAgentTasks && a.maxTaskNestingDepth === b.maxTaskNestingDepth && a.proposePlanImplementReplacesChatHistory === b.proposePlanImplementReplacesChatHistory && - a.preserveSubagentsUntilArchive === b.preserveSubagentsUntilArchive && - a.planSubagentExecutorRouting === b.planSubagentExecutorRouting && - a.planSubagentDefaultsToOrchestrator === b.planSubagentDefaultsToOrchestrator + a.preserveSubagentsUntilArchive === b.preserveSubagentsUntilArchive ); } @@ -742,25 +738,10 @@ export function TasksSection() { ); }; - const setPlanSubagentExecutorRouting = (value: string) => { - if (!isPlanSubagentExecutorRouting(value)) { - return; - } - - setTaskSettings((prev) => - normalizeTaskSettings({ - ...prev, - planSubagentExecutorRouting: value, - }) - ); - }; const setNewWorkspaceDefaultAgentId = (agentId: string) => { setGlobalDefaultAgentIdRaw(coerceAgentId(agentId)); }; - const planSubagentExecutorRouting: PlanSubagentExecutorRouting = - taskSettings.planSubagentExecutorRouting ?? "exec"; - const setAgentModel = (agentId: string, value: string) => { setAgentAiDefaults((prev) => updateAgentDefaultEntry(prev, agentId, (updated) => { @@ -1279,28 +1260,6 @@ export function TasksSection() { aria-label="Toggle preserve subagents until archive" /> - -

{saveError ?
{saveError}
: null} diff --git a/src/browser/features/Tools/ProposePlan/ProposePlanToolCall.stories.tsx b/src/browser/features/Tools/ProposePlan/ProposePlanToolCall.stories.tsx index 1406b811da..be85905d3d 100644 --- a/src/browser/features/Tools/ProposePlan/ProposePlanToolCall.stories.tsx +++ b/src/browser/features/Tools/ProposePlan/ProposePlanToolCall.stories.tsx @@ -2,9 +2,8 @@ import type { AppStory } from "@/browser/stories/meta.js"; import { appMeta, AppWithMocks } from "@/browser/stories/meta.js"; import { setupSimpleChatStory } from "@/browser/stories/helpers/chatSetup"; import { createAssistantMessage, createUserMessage } from "@/browser/stories/mocks/messages"; -import { createProposePlanTool, createTodoWriteTool } from "@/browser/stories/mocks/tools"; +import { createProposePlanTool } from "@/browser/stories/mocks/tools"; import { STABLE_TIMESTAMP } from "@/browser/stories/mocks/workspaces"; -import { PLAN_AUTO_ROUTING_STATUS_MESSAGE } from "@/common/constants/planAutoRoutingStatus"; const meta = { ...appMeta, title: "App/Chat/Tools/ProposePlan" }; export default meta; @@ -86,7 +85,7 @@ graph TD /** * Same as ProposePlan but with agent mode set to "plan". - * Shows Implement + Start Orchestrator buttons (no Continue in Auto). + * Shows the Implement button (no Continue in Auto). */ export const ProposePlanInPlanMode: AppStory = { render: () => ( @@ -154,79 +153,7 @@ graph TD description: { story: 'Same as ProposePlan but with agent mode set to "plan". ' + - "Shows Implement and Start Orchestrator buttons instead of Continue in Auto.", - }, - }, - }, -}; - -/** - * Captures the handoff pause after a plan is presented and before the executor stream starts. - * - * This reproduces the visual state where the sidebar shows "Deciding execution strategy…" - * while the proposed plan remains visible in the conversation. - */ -export const ProposePlanAutoRoutingDecisionGap: AppStory = { - render: () => ( - - setupSimpleChatStory({ - workspaceId: "ws-plan-auto-routing-gap", - workspaceName: "feature/plan-auto-routing", - messages: [ - createUserMessage( - "msg-1", - "Plan and implement a safe migration rollout for auth tokens.", - { - historySequence: 1, - timestamp: STABLE_TIMESTAMP - 240000, - } - ), - createAssistantMessage("msg-2", "Here is the implementation plan.", { - historySequence: 2, - timestamp: STABLE_TIMESTAMP - 230000, - toolCalls: [ - createProposePlanTool( - "call-plan-1", - `# Auth Token Migration Rollout - -## Goals - -- Migrate token validation to the new signing service. -- Maintain compatibility during rollout. -- Keep rollback simple and low risk. - -## Steps - -1. Add dual-read token validation behind a feature flag. -2. Ship telemetry for token verification outcomes. -3. Enable new validator for 10% of traffic. -4. Ramp to 100% after stability checks. -5. Remove legacy validator once metrics stay healthy. - -## Rollback - -- Disable the rollout flag to return to legacy validation immediately. -- Keep telemetry running to confirm recovery.` - ), - ], - }), - createAssistantMessage("msg-3", "Selecting the right executor for this plan.", { - historySequence: 3, - timestamp: STABLE_TIMESTAMP - 220000, - toolCalls: [createTodoWriteTool("call-status-1", PLAN_AUTO_ROUTING_STATUS_MESSAGE)], - }), - ], - }) - } - /> - ), - parameters: { - docs: { - description: { - story: - "Chromatic regression story for the plan auto-routing gap: after `propose_plan` succeeds, " + - "the sidebar stays in a working state with a 'Deciding execution strategy…' status before executor kickoff.", + "Shows the Implement button instead of Continue in Auto.", }, }, }, @@ -235,7 +162,7 @@ export const ProposePlanAutoRoutingDecisionGap: AppStory = { /** * Mobile viewport version of ProposePlan. * - * Verifies that on narrow screens the primary plan actions (Implement / Start Orchestrator) + * Verifies that on narrow screens the primary plan actions (Implement / Continue in Auto) * render as shortcut icons in the left action row (instead of right-aligned buttons). */ export const ProposePlanMobile: AppStory = { @@ -246,7 +173,7 @@ export const ProposePlanMobile: AppStory = { docs: { description: { story: - "Renders ProposePlan at an iPhone-sized viewport to verify that Implement / Start Orchestrator " + + "Renders ProposePlan at an iPhone-sized viewport to verify that Implement / Continue in Auto " + "appear as shortcut icons in the left action row (preventing right-side overflow on small screens).", }, }, diff --git a/src/browser/features/Tools/ProposePlanToolCall.test.tsx b/src/browser/features/Tools/ProposePlanToolCall.test.tsx index d91df275b2..3d95e36519 100644 --- a/src/browser/features/Tools/ProposePlanToolCall.test.tsx +++ b/src/browser/features/Tools/ProposePlanToolCall.test.tsx @@ -180,19 +180,6 @@ const TEST_AGENTS: AgentDefinitionDescriptor[] = [ thinkingLevel: "high", }, }, - { - id: "orchestrator", - scope: "built-in", - name: "Orchestrator", - uiSelectable: true, - uiRoutable: true, - subagentRunnable: true, - base: "exec", - aiDefaults: { - model: "openai:gpt-5.2-pro", - thinkingLevel: "medium", - }, - }, ]; const noop = () => { @@ -762,185 +749,4 @@ describe("ProposePlanToolCall", () => { expect(summaryMessage.parts?.[0]?.text).toContain("*Plan file preserved at:*"); expect(summaryMessage.parts?.[0]?.text).toContain(planPath); }); - - test("switches to orchestrator and sends a message when clicking Start Orchestrator", async () => { - const workspaceId = "ws-123"; - const planPath = "~/.mux/plans/demo/ws-123.md"; - const planModel = "anthropic:claude-sonnet-4-5"; - const planThinking = "high"; - const orchestratorModel = "openai:gpt-5.2-pro"; - const orchestratorThinking = "medium"; - - // Start in plan mode. - window.localStorage.setItem(getAgentIdKey(workspaceId), JSON.stringify("plan")); - updatePersistedState(getModelKey(workspaceId), planModel); - updatePersistedState(getThinkingLevelKey(workspaceId), planThinking); - updatePersistedState(AGENT_AI_DEFAULTS_KEY, { - orchestrator: { modelString: orchestratorModel, thinkingLevel: orchestratorThinking }, - }); - - const replaceChatHistoryCalls: unknown[] = []; - const sendMessageCalls: SendMessageArgs[] = []; - - mockApi = { - config: { - getConfig: () => - Promise.resolve({ - taskSettings: { maxParallelAgentTasks: 3, maxTaskNestingDepth: 3 }, - agentAiDefaults: {}, - subagentAiDefaults: {}, - }), - }, - workspace: { - getPlanContent: () => - Promise.resolve({ - success: true, - data: { content: "# My Plan\n\nDo the thing.", path: planPath }, - }), - replaceChatHistory: (args) => { - replaceChatHistoryCalls.push(args); - return Promise.resolve({ success: true, data: undefined }); - }, - sendMessage: (args: SendMessageArgs) => { - sendMessageCalls.push(args); - return Promise.resolve({ success: true, data: undefined }); - }, - }, - }; - - const view = renderToolCall( - - ); - - fireEvent.click(view.getByRole("button", { name: "Start Orchestrator" })); - - await waitFor(() => expect(sendMessageCalls.length).toBe(1)); - expect(sendMessageCalls[0]?.message).toBe( - "Start orchestrating the implementation of this plan." - ); - expect(sendMessageCalls[0]?.options.agentId).toBe("orchestrator"); - expect(sendMessageCalls[0]?.options.model).toBe(orchestratorModel); - expect(sendMessageCalls[0]?.options.thinkingLevel).toBe(orchestratorThinking); - expect(replaceChatHistoryCalls.length).toBe(0); - - // Clicking Start Orchestrator should switch the workspace agent to orchestrator. - const agentKey = getAgentIdKey(workspaceId); - const modelKey = getModelKey(workspaceId); - const thinkingKey = getThinkingLevelKey(workspaceId); - const updatePersistedStateMaybeMock = updatePersistedState as unknown as { - mock?: { calls: unknown[][] }; - }; - if (updatePersistedStateMaybeMock.mock) { - expect(updatePersistedState).toHaveBeenCalledWith(agentKey, "orchestrator"); - expect(updatePersistedState).toHaveBeenCalledWith(modelKey, orchestratorModel); - expect(updatePersistedState).toHaveBeenCalledWith(thinkingKey, orchestratorThinking); - } else { - expect(JSON.parse(window.localStorage.getItem(agentKey)!)).toBe("orchestrator"); - expect(JSON.parse(window.localStorage.getItem(modelKey)!)).toBe(orchestratorModel); - expect(JSON.parse(window.localStorage.getItem(thinkingKey)!)).toBe(orchestratorThinking); - } - }); - - test("replaces chat history before starting orchestrator when setting enabled", async () => { - const workspaceId = "ws-123"; - const planPath = "~/.mux/plans/demo/ws-123.md"; - - // Start in plan mode. - window.localStorage.setItem(getAgentIdKey(workspaceId), JSON.stringify("plan")); - - const calls: Array<"replaceChatHistory" | "sendMessage"> = []; - const replaceChatHistoryCalls: Array<{ - workspaceId: string; - summaryMessage: unknown; - mode?: "destructive" | "append-compaction-boundary" | null; - deletePlanFile?: boolean; - }> = []; - const sendMessageCalls: SendMessageArgs[] = []; - - mockApi = { - config: { - getConfig: () => - Promise.resolve({ - taskSettings: { - maxParallelAgentTasks: 3, - maxTaskNestingDepth: 3, - proposePlanImplementReplacesChatHistory: true, - }, - agentAiDefaults: {}, - subagentAiDefaults: {}, - }), - }, - workspace: { - getPlanContent: () => - Promise.resolve({ - success: true, - data: { content: "# My Plan\n\nDo the thing.", path: planPath }, - }), - replaceChatHistory: (args) => { - calls.push("replaceChatHistory"); - replaceChatHistoryCalls.push(args); - return Promise.resolve({ success: true, data: undefined }); - }, - sendMessage: (args: SendMessageArgs) => { - calls.push("sendMessage"); - sendMessageCalls.push(args); - return Promise.resolve({ success: true, data: undefined }); - }, - }, - }; - - const view = renderToolCall( - - ); - - fireEvent.click(view.getByRole("button", { name: "Start Orchestrator" })); - - await waitFor(() => expect(sendMessageCalls.length).toBe(1)); - expect(sendMessageCalls[0]?.message).toBe( - "Start orchestrating the implementation of this plan." - ); - expect(sendMessageCalls[0]?.options.agentId).toBe("orchestrator"); - - expect(replaceChatHistoryCalls.length).toBe(1); - expect(calls).toEqual(["replaceChatHistory", "sendMessage"]); - - const replaceArgs = replaceChatHistoryCalls[0]; - expect(replaceArgs?.deletePlanFile).toBe(false); - expect(replaceArgs?.mode).toBe("append-compaction-boundary"); - - const summaryMessage = replaceArgs?.summaryMessage as { - role?: string; - metadata?: { agentId?: string }; - parts?: Array<{ type?: string; text?: string }>; - }; - - expect(summaryMessage.role).toBe("assistant"); - expect(summaryMessage.parts?.[0]?.text).toContain( - "Note: This chat already contains the full plan" - ); - expect(summaryMessage.parts?.[0]?.text).not.toContain("Orchestrator mode"); - expect(summaryMessage.metadata?.agentId).toBe("plan"); - expect(summaryMessage.parts?.[0]?.text).toContain("*Plan file preserved at:*"); - expect(summaryMessage.parts?.[0]?.text).toContain(planPath); - }); }); diff --git a/src/browser/features/Tools/ProposePlanToolCall.tsx b/src/browser/features/Tools/ProposePlanToolCall.tsx index 524a480213..e4c1765e69 100644 --- a/src/browser/features/Tools/ProposePlanToolCall.tsx +++ b/src/browser/features/Tools/ProposePlanToolCall.tsx @@ -69,7 +69,6 @@ import { Pencil, Play, Sparkles, - Workflow, X, } from "lucide-react"; import { ShareMessagePopover } from "@/browser/components/ShareMessagePopover/ShareMessagePopover"; @@ -165,20 +164,17 @@ export const ProposePlanToolCall: React.FC = (props) = const { expanded, toggleExpanded } = useToolExpansion(true); // Expand by default const [showRaw, setShowRaw] = useState(false); const [annotateMode, setAnnotateMode] = useState(false); - const [isStartingOrchestrator, setIsStartingOrchestrator] = useState(false); const [isImplementing, setIsImplementing] = useState(false); const [isContinuingInAuto, setIsContinuingInAuto] = useState(false); const [implementReplacesChatHistory, setImplementReplacesChatHistory] = useState(false); - // On small screens, render the primary plan actions (Implement / Start Orchestrator / - // Continue in Auto) as shortcut icons alongside the other action buttons to avoid - // right-side overflow. + // On small screens, render the primary plan actions (Implement / Continue in Auto) as + // shortcut icons alongside the other action buttons to avoid right-side overflow. const [isNarrowScreen, setIsNarrowScreen] = useState(() => { if (typeof window === "undefined") return false; return window.innerWidth <= 768; }); - const isStartingOrchestratorRef = useRef(false); const isImplementingRef = useRef(false); const isContinuingInAutoRef = useRef(false); const isMountedRef = useRef(true); @@ -471,7 +467,7 @@ export const ProposePlanToolCall: React.FC = (props) = // uses the target agent defaults instead of stale planning-mode preferences. const resolveAndPersistTargetAgentSettings = (args: { workspaceId: string; - targetAgentId: "auto" | "exec" | "orchestrator"; + targetAgentId: "auto" | "exec"; }): { resolvedModel: string; resolvedThinking: ThinkingLevel } => { const modelKey = getModelKey(args.workspaceId); const thinkingKey = getThinkingLevelKey(args.workspaceId); @@ -509,61 +505,6 @@ export const ProposePlanToolCall: React.FC = (props) = return { resolvedModel, resolvedThinking }; }; - const handleStartOrchestrator = async () => { - if (!workspaceId || !api) return; - if (isStartingOrchestratorRef.current) return; - - isStartingOrchestratorRef.current = true; - if (isMountedRef.current) { - setIsStartingOrchestrator(true); - } - - try { - let shouldReplaceChatHistory = false; - - try { - const cfg = await api.config.getConfig(); - shouldReplaceChatHistory = - cfg.taskSettings.proposePlanImplementReplacesChatHistory ?? false; - } catch { - // Ignore config read errors (we'll default to old behavior). - } - - if (shouldReplaceChatHistory) { - await replaceChatHistoryWithPlan({ - idPrefix: "start-orchestrator", - errorContext: "Failed to replace chat history before starting orchestrator:", - }); - } - - const targetAgentId = "orchestrator"; - const { resolvedModel, resolvedThinking } = resolveAndPersistTargetAgentSettings({ - workspaceId, - targetAgentId, - }); - - const sendMessageOptions = getSendOptionsFromStorage(workspaceId); - - await api.workspace.sendMessage({ - workspaceId, - message: "Start orchestrating the implementation of this plan.", - options: { - ...sendMessageOptions, - agentId: targetAgentId, - model: resolvedModel, - thinkingLevel: resolvedThinking, - }, - }); - } catch (err) { - console.error("Failed to start orchestrator:", err); - } finally { - isStartingOrchestratorRef.current = false; - if (isMountedRef.current) { - setIsStartingOrchestrator(false); - } - } - }; - const handleImplement = async () => { if (!workspaceId || !api) return; if (isImplementingRef.current) return; @@ -739,7 +680,7 @@ export const ProposePlanToolCall: React.FC = (props) = ? { label: "Implement", onClick: () => void handleImplement(), - disabled: !api || isImplementing || isStartingOrchestrator || isContinuingInAuto, + disabled: !api || isImplementing || isContinuingInAuto, icon: , tooltip: implementReplacesChatHistory ? "Replace chat history with this plan, switch to Exec, and start implementing" @@ -747,25 +688,12 @@ export const ProposePlanToolCall: React.FC = (props) = } : null; - const orchestratorButton: ButtonConfig | null = - shouldShowPrimaryActions && !isAutoMode - ? { - label: "Start Orchestrator", - onClick: () => void handleStartOrchestrator(), - disabled: !api || isStartingOrchestrator || isImplementing || isContinuingInAuto, - icon: , - tooltip: implementReplacesChatHistory - ? "Replace chat history with this plan, switch to Orchestrator, and start delegating" - : "Switch to Orchestrator and start delegating", - } - : null; - const autoButton: ButtonConfig | null = shouldShowPrimaryActions && isAutoMode ? { label: "Continue in Auto", onClick: () => void handleContinueInAuto(), - disabled: !api || isContinuingInAuto || isImplementing || isStartingOrchestrator, + disabled: !api || isContinuingInAuto || isImplementing, icon: , tooltip: implementReplacesChatHistory ? "Replace chat history with this plan, switch to Auto, and let it decide the executor" @@ -918,15 +846,14 @@ export const ProposePlanToolCall: React.FC = (props) = {/* Mobile: icon-only plan actions, right-aligned, white */} - {isNarrowScreen && (implementButton ?? orchestratorButton ?? autoButton) && ( + {isNarrowScreen && (implementButton ?? autoButton) && (
{implementButton && } - {orchestratorButton && } {autoButton && }
)} - {!isNarrowScreen && (implementButton ?? orchestratorButton ?? autoButton) && ( + {!isNarrowScreen && (implementButton ?? autoButton) && (
{implementButton && ( @@ -949,27 +876,6 @@ export const ProposePlanToolCall: React.FC = (props) = )} - {orchestratorButton && ( - - - - - - {orchestratorButton.tooltip ?? orchestratorButton.label} - - - )} - {autoButton && ( diff --git a/src/browser/stories/App.readmeScreenshots.stories.tsx b/src/browser/stories/App.readmeScreenshots.stories.tsx index 62ccc67507..f729b66584 100644 --- a/src/browser/stories/App.readmeScreenshots.stories.tsx +++ b/src/browser/stories/App.readmeScreenshots.stories.tsx @@ -1226,194 +1226,3 @@ export const MobileServerMode: AppStory = { /> ), }; - -// README: docs/img/orchestrate-agents.webp -// Parent workspace is selected in plan mode while six running child workspaces -// show nested todo-derived progress in the expanded left sidebar. -export const OrchestrateAgents: AppStory = { - // Override the module-level 1900px decorator so the app itself renders at 1200px, - // matching the narrower capture viewport for a tighter orchestrator screenshot. - decorators: [ - (Story: () => JSX.Element) => ( -
- -
- ), - ], - render: () => ( - { - const workspaceId = "ws-orchestrator"; - - const parentWorkspace = createWorkspace({ - id: workspaceId, - name: "feature/parallel-auth", - projectName: README_PROJECT_NAME, - projectPath: README_PROJECT_PATH, - }); - - const subtaskFixtures = [ - { - id: "ws-sub-1", - name: "auth-middleware", - agentType: "exec" as const, - title: "Implement auth middleware", - todos: buildStoryTodos("Implementing auth middleware"), - assistantMessage: "Wiring auth middleware into each service entrypoint.", - }, - { - id: "ws-sub-2", - name: "token-service", - agentType: "exec" as const, - title: "Build token refresh service", - todos: buildStoryTodos("Reading token validation logic"), - assistantMessage: "Auditing refresh token validation before implementing rotation.", - }, - { - id: "ws-sub-3", - name: "rbac-policies", - agentType: "exec" as const, - title: "Add RBAC policy engine", - todos: buildStoryTodos("Writing policy evaluation tests"), - assistantMessage: "Building RBAC fixtures and policy matching assertions.", - }, - { - id: "ws-sub-4", - name: "session-store", - agentType: "exec" as const, - title: "Migrate session storage to Redis", - todos: buildStoryTodos("Running integration tests"), - assistantMessage: "Running Redis-backed session integration coverage now.", - }, - { - id: "ws-sub-5", - name: "api-gateway", - agentType: "exec" as const, - title: "Configure API gateway routes", - todos: buildStoryTodos("Wiring up rate limiting"), - assistantMessage: "Updating gateway route config with auth + throttling guards.", - }, - { - id: "ws-sub-6", - name: "audit-logging", - agentType: "explore" as const, - title: "Investigate audit log schema", - todos: buildStoryTodos("Reviewing existing log entries"), - assistantMessage: "Inspecting current audit log rows to document schema constraints.", - }, - ]; - - const childWorkspaces = subtaskFixtures.map((fixture, index) => ({ - ...createWorkspace({ - id: fixture.id, - name: fixture.name, - projectName: README_PROJECT_NAME, - projectPath: README_PROJECT_PATH, - createdAt: new Date(NOW - (index + 1) * 2_000).toISOString(), - }), - parentWorkspaceId: workspaceId, - agentType: fixture.agentType, - taskStatus: "running" as const, - title: fixture.title, - })); - - const workspaces = [parentWorkspace, ...childWorkspaces]; - - window.localStorage.setItem(LEFT_SIDEBAR_COLLAPSED_KEY, JSON.stringify(false)); - expandProjects([README_PROJECT_PATH]); - selectWorkspace(parentWorkspace); - collapseRightSidebar(); - - const parentPlanMarkdown = `# Feature: Parallel Auth Orchestration - -## Overview -Implement shared authentication across middleware, token refresh, RBAC policy checks, and audit logging. - -## Tasks - -### Task 1: Middleware integration -Implement shared auth middleware in every HTTP and RPC service boundary. - -### Task 2: Token refresh service -Build refresh-token rotation with revocation checks and expiry validation. - -### Task 3: RBAC policy engine -Add role-based policy evaluation with test coverage for allow/deny rules. - -### Task 4: Session storage migration -Move session persistence from local files to Redis-backed storage. - -### Task 5: API gateway route updates -Configure gateway auth guards, rate limits, and protected route wiring. - -### Task 6: Audit logging baseline -Document and validate audit log schema requirements before rollout. -`; - - const workspaceActivitySnapshots = Object.fromEntries( - subtaskFixtures.map((fixture, index) => { - const recency = NOW - (index + 1) * 2_000; - return [ - fixture.id, - { - recency, - streaming: false, - lastModel: null, - lastThinkingLevel: null, - todoStatus: deriveTodoStatus(fixture.todos) ?? null, - hasTodos: fixture.todos.length > 0, - }, - ]; - }) - ); - - const chatHandlers = new Map>([ - [ - workspaceId, - createStaticChatHandler([ - createUserMessage( - "msg-orchestrator-1", - "Implement auth across all services and split the work so multiple agents can run in parallel.", - { - historySequence: 1, - timestamp: STABLE_TIMESTAMP - 60_000, - } - ), - createAssistantMessage( - "msg-orchestrator-2", - "Here is a six-task execution plan. Start the orchestrator to launch subtasks.", - { - historySequence: 2, - timestamp: STABLE_TIMESTAMP - 50_000, - toolCalls: [ - createProposePlanTool("call-plan-orchestrator-1", parentPlanMarkdown), - ], - } - ), - ]), - ], - ...subtaskFixtures.map( - (fixture, index) => - [ - fixture.id, - createStaticChatHandler([ - createAssistantMessage(`msg-sub-${index + 1}`, fixture.assistantMessage, { - historySequence: 1, - timestamp: STABLE_TIMESTAMP - 45_000 + index * 1_000, - toolCalls: [createTodoWriteTool(`call-status-sub-${index + 1}`, fixture.todos)], - }), - ]), - ] as const - ), - ]); - - return createMockORPCClient({ - projects: groupWorkspacesByProject(workspaces), - workspaces, - workspaceActivitySnapshots, - onChat: createOnChatAdapter(chatHandlers), - }); - }} - /> - ), -}; diff --git a/src/browser/stories/mocks/orpc.ts b/src/browser/stories/mocks/orpc.ts index 410c5ea250..0fe6439a72 100644 --- a/src/browser/stories/mocks/orpc.ts +++ b/src/browser/stories/mocks/orpc.ts @@ -447,17 +447,6 @@ export function createMockORPCClient(options: MockORPCClientOptions = {}): APICl subagentRunnable: true, uiColor: "var(--color-exec-mode)", }, - { - id: "orchestrator", - scope: "built-in", - name: "Orchestrator", - description: "Coordinate multiple sub-agents to solve complex tasks in parallel.", - uiSelectable: true, - uiRoutable: true, - subagentRunnable: false, - base: "exec", - uiColor: "var(--color-exec-mode)", - }, { id: "compact", scope: "built-in", diff --git a/src/browser/utils/fuzzySearch.test.ts b/src/browser/utils/fuzzySearch.test.ts index e4d3787974..f649e4cfec 100644 --- a/src/browser/utils/fuzzySearch.test.ts +++ b/src/browser/utils/fuzzySearch.test.ts @@ -3,7 +3,7 @@ import { normalizeFuzzyText, splitQueryIntoTerms } from "./fuzzySearch"; describe("fuzzySearch", () => { test("normalizeFuzzyText lowercases and replaces common separators", () => { - expect(normalizeFuzzyText("Ask: check plan→orchestrator")).toBe("ask check plan orchestrator"); + expect(normalizeFuzzyText("Ask: check plan→exec")).toBe("ask check plan exec"); }); test("splitQueryIntoTerms splits on spaces and common punctuation", () => { diff --git a/src/browser/utils/messages/applyWorkspaceChatEventToAggregator.ts b/src/browser/utils/messages/applyWorkspaceChatEventToAggregator.ts index c946de6e52..ff146d17c0 100644 --- a/src/browser/utils/messages/applyWorkspaceChatEventToAggregator.ts +++ b/src/browser/utils/messages/applyWorkspaceChatEventToAggregator.ts @@ -193,7 +193,7 @@ export function applyWorkspaceChatEventToAggregator( if (allowSideEffects && shouldRefreshAgentsAfterToolCallEnd(event)) { // Keep agent discovery in sync when propose_plan succeeds so conditionally visible - // agents (for example, orchestrator with ui.requires: ["plan"]) appear immediately. + // agents (for example, those gated by `ui.requires: ["plan"]`) appear immediately. dispatchAgentsRefreshRequested(); } diff --git a/src/browser/utils/messages/modelMessageTransform.test.ts b/src/browser/utils/messages/modelMessageTransform.test.ts index 5aec5c1214..4175415327 100644 --- a/src/browser/utils/messages/modelMessageTransform.test.ts +++ b/src/browser/utils/messages/modelMessageTransform.test.ts @@ -1324,55 +1324,6 @@ describe("injectAgentTransition", () => { } }); - it("should include plan content when transitioning from plan to orchestrator", () => { - const messages: MuxMessage[] = [ - { - id: "user-1", - role: "user", - parts: [{ type: "text", text: "Let's plan a feature" }], - metadata: { timestamp: 1000 }, - }, - { - id: "assistant-1", - role: "assistant", - parts: [{ type: "text", text: "Here's the plan..." }], - metadata: { timestamp: 2000, agentId: "plan" }, - }, - { - id: "user-2", - role: "user", - parts: [{ type: "text", text: "Start orchestrating" }], - metadata: { timestamp: 3000 }, - }, - ]; - - const planContent = "# My Plan\n\n## Step 1\nDo something\n\n## Step 2\nDo more"; - const planFilePath = "~/.mux/plans/demo/ws-123.md"; - const result = injectAgentTransition( - messages, - "orchestrator", - undefined, - planContent, - planFilePath - ); - - expect(result.length).toBe(4); - const transitionMessage = result[2]; - const textPart = transitionMessage.parts[0]; - expect(textPart.type).toBe("text"); - if (textPart.type === "text") { - expect(textPart.text).toContain( - "[Agent switched from plan to orchestrator. Follow orchestrator agent instructions.]" - ); - expect(textPart.text).toContain(`Plan file path: ${planFilePath}`); - expect(textPart.text).toContain("orchestrate its implementation"); - expect(textPart.text).not.toContain("spawn sub-agents"); - expect(textPart.text).toContain(""); - expect(textPart.text).toContain(planContent); - expect(textPart.text).toContain(""); - } - }); - it("should NOT include plan content when transitioning from exec to plan", () => { const messages: MuxMessage[] = [ { diff --git a/src/browser/utils/messages/modelMessageTransform.ts b/src/browser/utils/messages/modelMessageTransform.ts index 09936ddeca..79a51c1080 100644 --- a/src/browser/utils/messages/modelMessageTransform.ts +++ b/src/browser/utils/messages/modelMessageTransform.ts @@ -143,14 +143,14 @@ export function addInterruptedSentinel(messages: MuxMessage[]): MuxMessage[] { * Inserts a synthetic user message before the final user message to signal the agent switch. * This provides temporal context that helps models understand they should follow new agent instructions. * - * When transitioning from plan → exec/orchestrator with plan content, includes the plan so the model + * When transitioning from plan → exec with plan content, includes the plan so the model * can evaluate its relevance to the current request. * * @param messages The conversation history * @param currentAgentId The agent id for the upcoming assistant response * @param toolNames Optional list of available tool names to include in transition message - * @param planContent Optional plan content to include when transitioning plan → exec/orchestrator - * @param planFilePath Optional plan file path to include when transitioning plan → exec/orchestrator + * @param planContent Optional plan content to include when transitioning plan → exec + * @param planFilePath Optional plan file path to include when transitioning plan → exec * @returns Messages with agent transition context injected if needed */ export function injectAgentTransition( @@ -213,25 +213,16 @@ export function injectAgentTransition( transitionText += "]"; } - // When transitioning from the plan agent to exec/orchestrator, include the plan for context. + // When transitioning from the plan agent to exec, include the plan for context. // This avoids wasting tokens on tool calls just to re-read the plan file. const transitioningFromPlan = lastAgentId === "plan"; - const transitioningToExecOrOrchestrator = - currentAgentId === "exec" || currentAgentId === "orchestrator"; - if (planContent && transitioningFromPlan && transitioningToExecOrOrchestrator) { + const transitioningToExec = currentAgentId === "exec"; + if (planContent && transitioningFromPlan && transitioningToExec) { const planFilePathText = planFilePath ? `Plan file path: ${planFilePath}\n\n` : ""; - const nextStepText = - currentAgentId === "orchestrator" - ? "orchestrate its implementation (do not re-plan)." - : "implement it directly (do not re-plan)."; - const followupText = - currentAgentId === "orchestrator" - ? "Only do extra exploration if the plan is missing critical details or conflicts with the repo:" - : "Only do extra exploration or spawn sub-agents if the plan is missing critical details or conflicts with the repo:"; transitionText += ` -${planFilePathText}The following plan was developed in the plan agent. Based on the user's message, determine if they have accepted the plan. If accepted and relevant, ${nextStepText} -${followupText} +${planFilePathText}The following plan was developed in the plan agent. Based on the user's message, determine if they have accepted the plan. If accepted and relevant, implement it directly (do not re-plan). +Only do extra exploration or spawn sub-agents if the plan is missing critical details or conflicts with the repo: ${planContent} diff --git a/src/browser/utils/workspaceModeAi.ts b/src/browser/utils/workspaceModeAi.ts index 9ebe1bd981..704eb71e48 100644 --- a/src/browser/utils/workspaceModeAi.ts +++ b/src/browser/utils/workspaceModeAi.ts @@ -11,7 +11,7 @@ function normalizeAgentId(agentId: string): string { } // Keep agent -> model/thinking precedence in one place so mode switches that send immediately -// (like propose_plan Implement / Start Orchestrator) resolve the same settings as sync effects. +// (like propose_plan Implement / Continue in Auto) resolve the same settings as sync effects. export function resolveWorkspaceAiSettingsForAgent(args: { agentId: string; agentAiDefaults: AgentAiDefaults; diff --git a/src/common/config/schemas/appConfigOnDisk.ts b/src/common/config/schemas/appConfigOnDisk.ts index 3ff8acd965..37ce4f5119 100644 --- a/src/common/config/schemas/appConfigOnDisk.ts +++ b/src/common/config/schemas/appConfigOnDisk.ts @@ -11,8 +11,8 @@ import { HEARTBEAT_MAX_INTERVAL_MS, HEARTBEAT_MIN_INTERVAL_MS } from "@/constant export { RuntimeEnablementOverridesSchema } from "../../schemas/runtimeEnablement"; export type { RuntimeEnablementOverrides } from "../../schemas/runtimeEnablement"; -export { PlanSubagentExecutorRoutingSchema, TaskSettingsSchema } from "./taskSettings"; -export type { PlanSubagentExecutorRouting, TaskSettings } from "./taskSettings"; +export { TaskSettingsSchema } from "./taskSettings"; +export type { TaskSettings } from "./taskSettings"; export const AgentAiDefaultsEntrySchema = z.object({ modelString: z.string().optional(), diff --git a/src/common/config/schemas/taskSettings.ts b/src/common/config/schemas/taskSettings.ts index 4c9e7a34a6..2ead3a550c 100644 --- a/src/common/config/schemas/taskSettings.ts +++ b/src/common/config/schemas/taskSettings.ts @@ -5,10 +5,6 @@ export const TASK_SETTINGS_LIMITS = { maxTaskNestingDepth: { min: 1, max: 5, default: 3 }, } as const; -export const PlanSubagentExecutorRoutingSchema = z.enum(["exec", "orchestrator", "auto"]); - -export type PlanSubagentExecutorRouting = z.infer; - export const TaskSettingsSchema = z.object({ maxParallelAgentTasks: z .number() @@ -24,8 +20,6 @@ export const TaskSettingsSchema = z.object({ .optional(), proposePlanImplementReplacesChatHistory: z.boolean().optional(), preserveSubagentsUntilArchive: z.boolean().optional(), - planSubagentExecutorRouting: PlanSubagentExecutorRoutingSchema.optional(), - planSubagentDefaultsToOrchestrator: z.boolean().optional(), }); export type TaskSettings = z.infer; diff --git a/src/common/constants/planAutoRoutingStatus.ts b/src/common/constants/planAutoRoutingStatus.ts deleted file mode 100644 index f23d34cbb5..0000000000 --- a/src/common/constants/planAutoRoutingStatus.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Auto plan->executor routing can spend up to the router timeout selecting an executor. -// We surface this as a transient sidebar status so users know the handoff is still progressing. -export const PLAN_AUTO_ROUTING_STATUS_EMOJI = "🤔"; -export const PLAN_AUTO_ROUTING_STATUS_MESSAGE = "Deciding execution strategy…"; diff --git a/src/common/types/tasks.test.ts b/src/common/types/tasks.test.ts index c7514289f5..1fefdee3e8 100644 --- a/src/common/types/tasks.test.ts +++ b/src/common/types/tasks.test.ts @@ -77,37 +77,4 @@ describe("normalizeTaskSettings", () => { expect(normalized).toEqual(DEFAULT_TASK_SETTINGS); }); - - test("preserves explicit planSubagentExecutorRouting values", () => { - const normalized = normalizeTaskSettings({ - planSubagentExecutorRouting: "auto", - }); - - expect(normalized.planSubagentExecutorRouting).toBe("auto"); - expect(normalized.planSubagentDefaultsToOrchestrator).toBe(false); - }); - - test("migrates deprecated planSubagentDefaultsToOrchestrator when routing is unset", () => { - expect( - normalizeTaskSettings({ - planSubagentDefaultsToOrchestrator: true, - }).planSubagentExecutorRouting - ).toBe("orchestrator"); - - expect( - normalizeTaskSettings({ - planSubagentDefaultsToOrchestrator: false, - }).planSubagentExecutorRouting - ).toBe("exec"); - }); - - test("prefers planSubagentExecutorRouting when both new and deprecated fields are set", () => { - const normalized = normalizeTaskSettings({ - planSubagentExecutorRouting: "exec", - planSubagentDefaultsToOrchestrator: true, - }); - - expect(normalized.planSubagentExecutorRouting).toBe("exec"); - expect(normalized.planSubagentDefaultsToOrchestrator).toBe(false); - }); }); diff --git a/src/common/types/tasks.ts b/src/common/types/tasks.ts index a489ddada1..872a64967e 100644 --- a/src/common/types/tasks.ts +++ b/src/common/types/tasks.ts @@ -1,7 +1,4 @@ -import type { - PlanSubagentExecutorRouting, - TaskSettings as TaskSettingsOnDisk, -} from "@/common/config/schemas/taskSettings"; +import type { TaskSettings as TaskSettingsOnDisk } from "@/common/config/schemas/taskSettings"; import { TASK_SETTINGS_LIMITS } from "@/common/config/schemas/taskSettings"; import type { SubagentAiDefaults, @@ -12,7 +9,7 @@ import assert from "@/common/utils/assert"; import { normalizeAgentId } from "@/common/utils/agentIds"; import { coerceThinkingLevel, type ThinkingLevel } from "./thinking"; -export type { PlanSubagentExecutorRouting, SubagentAiDefaults, SubagentAiDefaultsEntry }; +export type { SubagentAiDefaults, SubagentAiDefaultsEntry }; export { TASK_SETTINGS_LIMITS } from "@/common/config/schemas/taskSettings"; // Normalized runtime settings always include numeric task limits. @@ -26,8 +23,6 @@ export const DEFAULT_TASK_SETTINGS: TaskSettings = { maxTaskNestingDepth: TASK_SETTINGS_LIMITS.maxTaskNestingDepth.default, proposePlanImplementReplacesChatHistory: false, preserveSubagentsUntilArchive: false, - planSubagentExecutorRouting: "auto", - planSubagentDefaultsToOrchestrator: false, }; const AGENT_DEFAULT_IDS_EXCLUDED_FROM_LEGACY_SUBAGENTS: ReadonlySet = new Set([ @@ -98,12 +93,6 @@ function clampInt(value: unknown, fallback: number, min: number, max: number): n return rounded; } -export function isPlanSubagentExecutorRouting( - value: unknown -): value is PlanSubagentExecutorRouting { - return value === "exec" || value === "orchestrator" || value === "auto"; -} - export function normalizeTaskSettings(raw: unknown): TaskSettings { const record = raw && typeof raw === "object" ? (raw as Record) : ({} as const); @@ -130,35 +119,11 @@ export function normalizeTaskSettings(raw: unknown): TaskSettings { ? record.preserveSubagentsUntilArchive : DEFAULT_TASK_SETTINGS.preserveSubagentsUntilArchive; - const normalizedPlanSubagentExecutorRouting = isPlanSubagentExecutorRouting( - record.planSubagentExecutorRouting - ) - ? record.planSubagentExecutorRouting - : undefined; - - const migratedPlanSubagentExecutorRouting = - normalizedPlanSubagentExecutorRouting ?? - (typeof record.planSubagentDefaultsToOrchestrator === "boolean" - ? record.planSubagentDefaultsToOrchestrator - ? "orchestrator" - : "exec" - : undefined); - - const planSubagentExecutorRouting = - migratedPlanSubagentExecutorRouting ?? - DEFAULT_TASK_SETTINGS.planSubagentExecutorRouting ?? - "exec"; - - // Keep the deprecated boolean in sync for downgrade compatibility. - const planSubagentDefaultsToOrchestrator = planSubagentExecutorRouting === "orchestrator"; - const result: TaskSettings = { maxParallelAgentTasks, maxTaskNestingDepth, proposePlanImplementReplacesChatHistory, preserveSubagentsUntilArchive, - planSubagentExecutorRouting, - planSubagentDefaultsToOrchestrator, }; assert( @@ -179,15 +144,5 @@ export function normalizeTaskSettings(raw: unknown): TaskSettings { "normalizeTaskSettings: preserveSubagentsUntilArchive must be a boolean" ); - assert( - isPlanSubagentExecutorRouting(planSubagentExecutorRouting), - "normalizeTaskSettings: planSubagentExecutorRouting must be exec, orchestrator, or auto" - ); - - assert( - typeof planSubagentDefaultsToOrchestrator === "boolean", - "normalizeTaskSettings: planSubagentDefaultsToOrchestrator must be a boolean" - ); - return result; } diff --git a/src/common/utils/agentTools.test.ts b/src/common/utils/agentTools.test.ts index 835569a6dd..b8b118cebe 100644 --- a/src/common/utils/agentTools.test.ts +++ b/src/common/utils/agentTools.test.ts @@ -26,15 +26,15 @@ describe("isExecLikeEditingCapableInResolvedChain", () => { }); it("returns false when chain does not inherit exec", () => { - const agents = [{ id: "orchestrator", tools: { add: ["file_edit_insert"] } }]; + const agents = [{ id: "reviewer", tools: { add: ["file_edit_insert"] } }]; expect(isExecLikeEditingCapableInResolvedChain(agents)).toBe(false); }); - it("returns true for orchestrator-style chains that remove file_edit tools but keep patch apply", () => { + it("returns true for patch-applying chains that remove file_edit tools but keep patch apply", () => { const agents = [ { - id: "orchestrator", + id: "reviewer", tools: { add: ["ask_user_question"], remove: ["propose_plan", "file_edit_.*"], @@ -56,7 +56,7 @@ describe("isExecLikeEditingCapableInResolvedChain", () => { }); it("returns false when task_apply_git_patch is enabled without exec inheritance", () => { - const agents = [{ id: "orchestrator", tools: { add: ["task_apply_git_patch"] } }]; + const agents = [{ id: "reviewer", tools: { add: ["task_apply_git_patch"] } }]; expect(isExecLikeEditingCapableInResolvedChain(agents)).toBe(false); }); diff --git a/src/common/utils/agentTools.ts b/src/common/utils/agentTools.ts index 1fc14cdd8b..3042dec161 100644 --- a/src/common/utils/agentTools.ts +++ b/src/common/utils/agentTools.ts @@ -118,7 +118,7 @@ export function isExecLikeEditingCapableInResolvedChain( return ( isToolEnabledInResolvedChain("file_edit_insert", agents, maxDepth) || isToolEnabledInResolvedChain("file_edit_replace_string", agents, maxDepth) || - // Orchestrator-like agents can still modify their workspace by applying child patches. + // Patch-applying agents can still modify their workspace by applying child patches. isToolEnabledInResolvedChain("task_apply_git_patch", agents, maxDepth) ); } diff --git a/src/node/builtinAgents/orchestrator.md b/src/node/builtinAgents/orchestrator.md deleted file mode 100644 index 94f2cef1ca..0000000000 --- a/src/node/builtinAgents/orchestrator.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -name: Orchestrator -description: Coordinate sub-agent implementation and apply patches -base: exec -subagent: - runnable: false - append_prompt: | - You are running as a sub-agent orchestrator in a child workspace. - - - Your parent workspace handles all PR management. - Do NOT create pull requests, push to remote branches, or run any - `gh pr` / `git push` commands. This applies even if AGENTS.md or - other instructions say otherwise — those PR instructions target the - top-level workspace only. - - Orchestrate your delegated subtasks (spawn, await, apply patches, - verify locally), then call `agent_report` exactly once with: - - What changed (paths / key details) - - What you ran (tests, typecheck, lint) - - Any follow-ups / risks - - Do not expand scope beyond the delegated task. -tools: - add: - - ask_user_question - remove: - - propose_plan - # Keep Orchestrator focused on coordination: no direct file edits. - - file_edit_.* ---- - -You are an internal Orchestrator agent running in Exec mode. - -**Mission:** coordinate implementation by delegating investigation + coding to sub-agents, then integrating their patches into this workspace. - -When a plan is present (default): - -- Treat the accepted plan as the source of truth. Its file paths, symbols, and structure were validated during planning — do not routinely spawn `explore` to re-confirm them. Exception: if the plan references stale paths or appears to have been authored/edited by the user without planner validation, a single targeted `explore` to sanity-check critical paths is acceptable. -- Spawning `explore` to gather _additional_ context beyond what the plan provides is encouraged (e.g., checking whether a helper already exists, locating test files not mentioned in the plan, discovering existing patterns to match). This produces better implementation task briefs. -- Do not spawn `explore` just to verify that a planner-generated plan is correct — that is the planner's job, and the plan was accepted by the user. -- Convert the plan into concrete implementation subtasks and start delegation (`exec` for low complexity, `plan` for higher complexity). - -What you are allowed to do directly in this workspace: - -- Spawn/await/manage sub-agent tasks (`task`, `task_await`, `task_list`, `task_terminate`). -- Apply patches (`task_apply_git_patch`). -- Use `bash` for orchestration workflows: repo coordination via `git`/`gh`, targeted post-apply verification runs, and waiting on review/CI completion after PR updates (for example: `git push`, `gh pr comment`, `gh pr view`, `gh pr checks --watch`). Only run `gh pr create` when the user explicitly asks you to open a PR. -- Ask clarifying questions with `ask_user_question` when blocked. -- Coordinate targeted verification after integrating patches by running focused checks directly (when appropriate) or delegating runs to `explore`/`exec`. -- Delegate patch-conflict reconciliation to `exec` sub-agents. - -Hard rules (delegate-first): - -- Trust `explore` sub-agent reports as authoritative for repo facts (paths/symbols/callsites). Do not redo the same investigation yourself; only re-check if the report is ambiguous or contradicts other evidence. -- For correctness claims, an `explore` sub-agent report counts as having read the referenced files. -- **Do not do broad repo investigation here.** If you need context, spawn an `explore` sub-agent with a narrow prompt (keeps this agent focused on coordination). -- **Do not implement features/bugfixes directly here.** Spawn `exec` (simple) or `plan` (complex) sub-agents and have them complete the work end-to-end. -- **Do not use `bash` for file reads/writes, manual code editing, or broad repo exploration.** `bash` in this workspace is for orchestration-only operations: `git`/`gh` repo management, targeted post-apply verification checks, and waiting for PR review/CI outcomes. If direct checks fail due to code issues, delegate fixes to `exec`/`plan` sub-agents instead of implementing changes here. -- **Never read or scan session storage.** This includes `~/.mux/sessions/**` and `~/.mux/sessions/subagent-patches/**`. Treat session storage as an internal implementation detail; do not shell out to locate patch artifacts on disk. Only use `task_apply_git_patch` to access patches. - -Delegation guide: - -- Use `explore` for narrowly-scoped read-only questions (confirm an assumption, locate a symbol/callsite, find relevant tests). Avoid "scan the repo" prompts. -- Use `exec` for straightforward, low-complexity work where the implementation path is obvious from the task brief. - - Good fit: single-file edits, localized wiring to existing helpers, straightforward command execution, or narrowly scoped follow-ups with clear acceptance. - - Provide a compact task brief (so the sub-agent can act without reading the full plan) with: - - Task: one sentence - - Background (why this matters): 1–3 bullets - - Scope / non-goals: what to change, and what not to change - - Starting points: relevant files/symbols/paths (from prior exploration) - - Acceptance: bullets / checks - - Deliverables: commits + verification commands to run - - Constraints: - - Do not expand scope. - - Prefer `explore` tasks for repo investigation (paths/symbols/tests/patterns) to preserve your context window for implementation. - Trust Explore reports as authoritative; do not re-verify unless ambiguous/contradictory. - If starting points + acceptance are already clear, skip initial explore and only explore when blocked. - - Create one or more git commits before `agent_report`. -- Use `plan` for higher-complexity subtasks that touch multiple files/locations, require non-trivial investigation, or have an unclear implementation approach. - - Default to `plan` when a subtask needs coordinated updates across multiple locations, unless the edits are mechanical and already fully specified. - - For higher-complexity implementation work, prefer `plan` over `exec` so the sub-agent can do targeted research and produce a precise plan before implementation begins. - - Good fit: multi-file refactors, cross-module behavior changes, unfamiliar subsystems, or work where sequencing/dependencies need discovery. - - Plan subtasks automatically hand off to implementation after a successful `propose_plan`; expect the usual task completion output once implementation finishes. - - For `plan` briefs, prioritize goal + constraints + acceptance criteria over file-by-file diff instructions. -- Use `desktop` for GUI-heavy desktop automation that requires repeated screenshot → act → verify loops (for example, interacting with application windows, clicking through UI flows, or visual verification). The desktop agent enforces a grounding discipline that keeps visual context local. - -Recommended Orchestrator → Exec task brief template: - -- Task: -- Background (why this matters): - - -- Scope / non-goals: - - Scope: - - Non-goals: -- Starting points: -- Dependencies / assumptions: - - Assumes: - - If unmet: stop and report back; do not expand scope to create prerequisites. -- Acceptance: -- Deliverables: - - Commits: - - Verification: -- Constraints: - - Do not expand scope. - - Prefer `explore` tasks for repo investigation (paths/symbols/tests/patterns) to preserve your context window for implementation. - Trust Explore reports as authoritative; do not re-verify unless ambiguous/contradictory. - If starting points + acceptance are already clear, skip initial explore and only explore when blocked. - - Create one or more git commits before `agent_report`. - -Dependency analysis (required before spawning implementation tasks — `exec` or `plan`): - -- For each candidate subtask, write: - - Outputs: files/targets/artifacts introduced/renamed/generated - - Inputs / prerequisites (including for verification): what must already exist -- A subtask is "independent" only if its patch can be applied + verified on the current parent workspace HEAD, without any other pending patch. -- Parallelism is the default: maximize the size of each independent batch and run it in parallel. - Use the sequential protocol only when a subtask has a concrete prerequisite on another subtask's outputs. -- If task B depends on outputs from task A: - - Do not spawn B until A has completed and A's patch is applied in the parent workspace. - - If the dependency chain is tight (download → generate → wire-up), prefer one `exec` task rather than splitting. - -Example dependency chain (schema download → generation): - -- Task A outputs: a new download target + new schema files. -- Task B inputs: those schema files; verifies by running generation. -- Therefore: run Task A (await + apply patch) before spawning Task B. - -Patch integration loop (default): - -1. Identify a batch of independent subtasks. -2. Spawn one implementation sub-agent task per subtask with `run_in_background: true` (`exec` for low complexity, `plan` for higher complexity). -3. Await the batch via `task_await`. -4. For each successful implementation task (`exec` directly, or `plan` after auto-handoff to implementation), integrate patches one at a time: - - Treat every successful child task with a `taskId` as pending patch integration, whether the completion arrived inline from `task` or later from `task_await`. - - Complete each dry-run + real-apply pair before starting the next patch. Applying one patch changes `HEAD`, which can invalidate later dry-run results. - - Dry-run apply: `task_apply_git_patch` with `dry_run: true`. - - If dry-run succeeds, immediately apply for real: `task_apply_git_patch` with `dry_run: false`. - - Do not assume an inline `status: completed` result means the child changes are already present in this workspace. - - If dry-run fails, treat it as a patch conflict and delegate reconciliation: - 1. Do not attempt a real apply for that patch in this workspace. - 2. Spawn a dedicated `exec` task. In the brief, include the original failing `task_id` and instruct the sub-agent to replay that patch via `task_apply_git_patch`, resolve conflicts in its own workspace, run `git am --continue`, commit the resolved result, and report back with a new patch to apply cleanly. - - If real apply fails unexpectedly: - 1. Restore a clean working tree before delegating: run `git am --abort` via `bash` only when a git-am session is in progress; if abort reports no operation in progress, continue. - 2. Then follow the same delegated reconciliation flow above. -5. Verify + review: - - Run focused verification directly with `bash` when practical (for example: targeted tests or the repo's standard full-validation command), or delegate verification to `explore`/`exec` when investigation/fixes are likely. - - Use `git`/`gh` directly for PR orchestration when a PR already exists (pushes, review-request comments, replies to review remarks, and CI/check-status waiting loops). Create a new PR only when the user explicitly asks. - - PASS: summary-only (no long logs). - - FAIL: include the failing command + key error lines; then delegate a fix to `exec`/`plan` and re-verify. - -Sequential protocol (only for dependency chains): - -1. Spawn the prerequisite implementation task (`exec` or `plan`, based on complexity) with `run_in_background: false`. -2. If step 1 returns `queued`/`running` without a completed report, call `task_await` with the returned `taskId` before attempting any patch apply. If step 1 returns `status: completed` inline, that same `taskId` still requires patch application. -3. Dry-run apply its patch (`dry_run: true`); then apply for real (`dry_run: false`). If either step fails, follow the conflict playbook above (including `git am --abort` only when a real apply leaves a git-am session in progress). -4. Only after the patch is applied, spawn the dependent implementation task. -5. Repeat until the dependency chain is complete. - -Note: child workspaces are created at spawn time. Spawning dependents too early means they work from the wrong repo snapshot and get forced into scope expansion. - -Keep context minimal: - -- Do not request, paste, or restate large plans. -- Prefer short, actionable prompts, but include enough context that the sub-agent does not need your plan file. - - Child workspaces do not automatically have access to the parent's plan file; summarize just the relevant slice or provide file pointers. -- Prefer file paths/symbols over long prose. diff --git a/src/node/orpc/router.ts b/src/node/orpc/router.ts index ce5da5db4b..4e114d8ff3 100644 --- a/src/node/orpc/router.ts +++ b/src/node/orpc/router.ts @@ -1316,7 +1316,7 @@ export const router = (authToken?: string) => { input ); - // Agents can require a plan file before they're selectable (e.g., orchestrator). + // Agents can require a plan file before they're selectable (via `ui.requires: ["plan"]`). // Fail closed: if plan state cannot be determined, treat it as missing. let planReady = false; if (input.workspaceId && metadata) { diff --git a/src/node/services/agentDefinitions/builtInAgentContent.generated.ts b/src/node/services/agentDefinitions/builtInAgentContent.generated.ts index 91ecb0f8dc..0637e0a8de 100644 --- a/src/node/services/agentDefinitions/builtInAgentContent.generated.ts +++ b/src/node/services/agentDefinitions/builtInAgentContent.generated.ts @@ -8,6 +8,5 @@ export const BUILTIN_AGENT_CONTENT = { "exec": "---\nname: Exec\ndescription: Implement changes in the repository\nui:\n color: var(--color-exec-mode)\nsubagent:\n runnable: true\n append_prompt: |\n You are running as a sub-agent in a child workspace.\n\n - Take a single narrowly scoped task and complete it end-to-end. Do not expand scope.\n - If the task brief includes clear starting points and acceptance criteria (or a concrete approved plan handoff) — implement it directly.\n Do not spawn `explore` tasks or write a \"mini-plan\" unless you are concretely blocked by a missing fact (e.g., a file path that doesn't exist, an unknown symbol name, or an error that contradicts the brief).\n - When you do need repo context you don't have, prefer 1–3 narrow `explore` tasks (possibly in parallel) over broad manual file-reading.\n - If the task brief is missing critical information (scope, acceptance, or starting points) and you cannot infer it safely after a quick `explore`, do not guess.\n Stop and call `agent_report` once with 1–3 concrete questions/unknowns for the parent agent, and do not create commits.\n - Run targeted verification and create one or more git commits.\n - Never amend existing commits — always create new commits on top.\n - **Before your stream ends, you MUST call `agent_report` exactly once with:**\n - What changed (paths / key details)\n - What you ran (tests, typecheck, lint)\n - Any follow-ups / risks\n (If you forget, the parent will inject a follow-up message and you'll waste tokens.)\n - You may call task/task_await/task_list/task_terminate to delegate further when available.\n Delegation is limited by Max Task Nesting Depth (Settings → Agents → Task Settings).\n - Do not call propose_plan.\ntools:\n add:\n # Allow all tools by default (includes MCP tools which have dynamic names)\n # Use tools.remove in child agents to restrict specific tools\n - .*\n remove:\n # Exec mode doesn't use planning tools\n - propose_plan\n - ask_user_question\n # Global config and catalog tools stay out of general-purpose agents\n - mux_agents_.*\n - agent_skill_write\n - agent_skill_delete\n - mux_config_read\n - mux_config_write\n - skills_catalog_.*\n - analytics_query\n---\n\nYou are in Exec mode.\n\n- If an accepted `` block is provided, treat it as the contract and implement it directly. Only do extra exploration if the plan references non-existent files/symbols or if errors contradict it.\n- Use `explore` sub-agents just-in-time for missing repo context (paths/symbols/tests); don't spawn them by default.\n- Trust Explore sub-agent reports as authoritative for repo facts (paths/symbols/callsites). Do not redo the same investigation yourself; only re-check if the report is ambiguous or contradicts other evidence.\n- For correctness claims, an Explore sub-agent report counts as having read the referenced files.\n- Make minimal, correct, reviewable changes that match existing codebase patterns.\n- Prefer targeted commands and checks (typecheck/tests) when feasible.\n- Treat as a standing order: keep running checks and addressing failures until they pass or a blocker outside your control arises.\n\n## Desktop Automation\n\nWhen a task involves repeated screenshot/action/verify loops for desktop GUI interaction (for example, clicking through application UIs, filling desktop app forms, or visually verifying GUI state), delegate to the `desktop` agent via `task` rather than performing desktop automation inline. The desktop agent is purpose-built for the screenshot → act → verify grounding loop.\n", "explore": "---\nname: Explore\ndescription: Read-only exploration of repository, environment, web, etc. Useful for investigation before making changes.\nbase: exec\nui:\n hidden: true\nsubagent:\n runnable: true\n skip_init_hook: true\n append_prompt: |\n You are an Explore sub-agent running inside a child workspace.\n\n - Explore the repository to answer the prompt using read-only investigation.\n - Return concise, actionable findings (paths, symbols, callsites, and facts).\n - When you have a final answer, call agent_report exactly once.\n - Do not call agent_report until you have completed the assigned task.\ntools:\n # Remove editing and task tools from exec base (read-only agent; skill tools are kept)\n remove:\n - file_edit_.*\n - task\n - task_apply_git_patch\n - task_.*\n---\n\nYou are in Explore mode (read-only).\n\n=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===\n\n- You MUST NOT manually create, edit, delete, move, copy, or rename tracked files.\n- You MUST NOT stage/commit or otherwise modify git state.\n- You MUST NOT use redirect operators (>, >>) or heredocs to write to files.\n - Pipes are allowed for processing, but MUST NOT be used to write to files (for example via `tee`).\n- You MUST NOT run commands that are explicitly about modifying the filesystem or repo state (rm, mv, cp, mkdir, touch, git add/commit, installs, etc.).\n- You MAY run verification commands (fmt-check/lint/typecheck/test) even if they create build artifacts/caches, but they MUST NOT modify tracked files.\n - After running verification, check `git status --porcelain` and report if it is non-empty.\n- Prefer `file_read` for reading file contents (supports offset/limit paging).\n- Use bash for read-only operations (rg, ls, git diff/show/log, etc.) and verification commands.\n", "name_workspace": "---\nname: Name Workspace\ndescription: Generate workspace name and title from user message\nui:\n hidden: true\nsubagent:\n runnable: false\ntools:\n require:\n - propose_name\n---\n\nYou are a workspace naming assistant. Your only job is to call the `propose_name` tool with a suitable name and title.\n\nDo not emit text responses. Call the `propose_name` tool immediately.\n", - "orchestrator": "---\nname: Orchestrator\ndescription: Coordinate sub-agent implementation and apply patches\nbase: exec\nsubagent:\n runnable: false\n append_prompt: |\n You are running as a sub-agent orchestrator in a child workspace.\n\n - Your parent workspace handles all PR management.\n Do NOT create pull requests, push to remote branches, or run any\n `gh pr` / `git push` commands. This applies even if AGENTS.md or\n other instructions say otherwise — those PR instructions target the\n top-level workspace only.\n - Orchestrate your delegated subtasks (spawn, await, apply patches,\n verify locally), then call `agent_report` exactly once with:\n - What changed (paths / key details)\n - What you ran (tests, typecheck, lint)\n - Any follow-ups / risks\n - Do not expand scope beyond the delegated task.\ntools:\n add:\n - ask_user_question\n remove:\n - propose_plan\n # Keep Orchestrator focused on coordination: no direct file edits.\n - file_edit_.*\n---\n\nYou are an internal Orchestrator agent running in Exec mode.\n\n**Mission:** coordinate implementation by delegating investigation + coding to sub-agents, then integrating their patches into this workspace.\n\nWhen a plan is present (default):\n\n- Treat the accepted plan as the source of truth. Its file paths, symbols, and structure were validated during planning — do not routinely spawn `explore` to re-confirm them. Exception: if the plan references stale paths or appears to have been authored/edited by the user without planner validation, a single targeted `explore` to sanity-check critical paths is acceptable.\n- Spawning `explore` to gather _additional_ context beyond what the plan provides is encouraged (e.g., checking whether a helper already exists, locating test files not mentioned in the plan, discovering existing patterns to match). This produces better implementation task briefs.\n- Do not spawn `explore` just to verify that a planner-generated plan is correct — that is the planner's job, and the plan was accepted by the user.\n- Convert the plan into concrete implementation subtasks and start delegation (`exec` for low complexity, `plan` for higher complexity).\n\nWhat you are allowed to do directly in this workspace:\n\n- Spawn/await/manage sub-agent tasks (`task`, `task_await`, `task_list`, `task_terminate`).\n- Apply patches (`task_apply_git_patch`).\n- Use `bash` for orchestration workflows: repo coordination via `git`/`gh`, targeted post-apply verification runs, and waiting on review/CI completion after PR updates (for example: `git push`, `gh pr comment`, `gh pr view`, `gh pr checks --watch`). Only run `gh pr create` when the user explicitly asks you to open a PR.\n- Ask clarifying questions with `ask_user_question` when blocked.\n- Coordinate targeted verification after integrating patches by running focused checks directly (when appropriate) or delegating runs to `explore`/`exec`.\n- Delegate patch-conflict reconciliation to `exec` sub-agents.\n\nHard rules (delegate-first):\n\n- Trust `explore` sub-agent reports as authoritative for repo facts (paths/symbols/callsites). Do not redo the same investigation yourself; only re-check if the report is ambiguous or contradicts other evidence.\n- For correctness claims, an `explore` sub-agent report counts as having read the referenced files.\n- **Do not do broad repo investigation here.** If you need context, spawn an `explore` sub-agent with a narrow prompt (keeps this agent focused on coordination).\n- **Do not implement features/bugfixes directly here.** Spawn `exec` (simple) or `plan` (complex) sub-agents and have them complete the work end-to-end.\n- **Do not use `bash` for file reads/writes, manual code editing, or broad repo exploration.** `bash` in this workspace is for orchestration-only operations: `git`/`gh` repo management, targeted post-apply verification checks, and waiting for PR review/CI outcomes. If direct checks fail due to code issues, delegate fixes to `exec`/`plan` sub-agents instead of implementing changes here.\n- **Never read or scan session storage.** This includes `~/.mux/sessions/**` and `~/.mux/sessions/subagent-patches/**`. Treat session storage as an internal implementation detail; do not shell out to locate patch artifacts on disk. Only use `task_apply_git_patch` to access patches.\n\nDelegation guide:\n\n- Use `explore` for narrowly-scoped read-only questions (confirm an assumption, locate a symbol/callsite, find relevant tests). Avoid \"scan the repo\" prompts.\n- Use `exec` for straightforward, low-complexity work where the implementation path is obvious from the task brief.\n - Good fit: single-file edits, localized wiring to existing helpers, straightforward command execution, or narrowly scoped follow-ups with clear acceptance.\n - Provide a compact task brief (so the sub-agent can act without reading the full plan) with:\n - Task: one sentence\n - Background (why this matters): 1–3 bullets\n - Scope / non-goals: what to change, and what not to change\n - Starting points: relevant files/symbols/paths (from prior exploration)\n - Acceptance: bullets / checks\n - Deliverables: commits + verification commands to run\n - Constraints:\n - Do not expand scope.\n - Prefer `explore` tasks for repo investigation (paths/symbols/tests/patterns) to preserve your context window for implementation.\n Trust Explore reports as authoritative; do not re-verify unless ambiguous/contradictory.\n If starting points + acceptance are already clear, skip initial explore and only explore when blocked.\n - Create one or more git commits before `agent_report`.\n- Use `plan` for higher-complexity subtasks that touch multiple files/locations, require non-trivial investigation, or have an unclear implementation approach.\n - Default to `plan` when a subtask needs coordinated updates across multiple locations, unless the edits are mechanical and already fully specified.\n - For higher-complexity implementation work, prefer `plan` over `exec` so the sub-agent can do targeted research and produce a precise plan before implementation begins.\n - Good fit: multi-file refactors, cross-module behavior changes, unfamiliar subsystems, or work where sequencing/dependencies need discovery.\n - Plan subtasks automatically hand off to implementation after a successful `propose_plan`; expect the usual task completion output once implementation finishes.\n - For `plan` briefs, prioritize goal + constraints + acceptance criteria over file-by-file diff instructions.\n- Use `desktop` for GUI-heavy desktop automation that requires repeated screenshot → act → verify loops (for example, interacting with application windows, clicking through UI flows, or visual verification). The desktop agent enforces a grounding discipline that keeps visual context local.\n\nRecommended Orchestrator → Exec task brief template:\n\n- Task: \n- Background (why this matters):\n - \n- Scope / non-goals:\n - Scope: \n - Non-goals: \n- Starting points: \n- Dependencies / assumptions:\n - Assumes: \n - If unmet: stop and report back; do not expand scope to create prerequisites.\n- Acceptance: \n- Deliverables:\n - Commits: \n - Verification: \n- Constraints:\n - Do not expand scope.\n - Prefer `explore` tasks for repo investigation (paths/symbols/tests/patterns) to preserve your context window for implementation.\n Trust Explore reports as authoritative; do not re-verify unless ambiguous/contradictory.\n If starting points + acceptance are already clear, skip initial explore and only explore when blocked.\n - Create one or more git commits before `agent_report`.\n\nDependency analysis (required before spawning implementation tasks — `exec` or `plan`):\n\n- For each candidate subtask, write:\n - Outputs: files/targets/artifacts introduced/renamed/generated\n - Inputs / prerequisites (including for verification): what must already exist\n- A subtask is \"independent\" only if its patch can be applied + verified on the current parent workspace HEAD, without any other pending patch.\n- Parallelism is the default: maximize the size of each independent batch and run it in parallel.\n Use the sequential protocol only when a subtask has a concrete prerequisite on another subtask's outputs.\n- If task B depends on outputs from task A:\n - Do not spawn B until A has completed and A's patch is applied in the parent workspace.\n - If the dependency chain is tight (download → generate → wire-up), prefer one `exec` task rather than splitting.\n\nExample dependency chain (schema download → generation):\n\n- Task A outputs: a new download target + new schema files.\n- Task B inputs: those schema files; verifies by running generation.\n- Therefore: run Task A (await + apply patch) before spawning Task B.\n\nPatch integration loop (default):\n\n1. Identify a batch of independent subtasks.\n2. Spawn one implementation sub-agent task per subtask with `run_in_background: true` (`exec` for low complexity, `plan` for higher complexity).\n3. Await the batch via `task_await`.\n4. For each successful implementation task (`exec` directly, or `plan` after auto-handoff to implementation), integrate patches one at a time:\n - Treat every successful child task with a `taskId` as pending patch integration, whether the completion arrived inline from `task` or later from `task_await`.\n - Complete each dry-run + real-apply pair before starting the next patch. Applying one patch changes `HEAD`, which can invalidate later dry-run results.\n - Dry-run apply: `task_apply_git_patch` with `dry_run: true`.\n - If dry-run succeeds, immediately apply for real: `task_apply_git_patch` with `dry_run: false`.\n - Do not assume an inline `status: completed` result means the child changes are already present in this workspace.\n - If dry-run fails, treat it as a patch conflict and delegate reconciliation:\n 1. Do not attempt a real apply for that patch in this workspace.\n 2. Spawn a dedicated `exec` task. In the brief, include the original failing `task_id` and instruct the sub-agent to replay that patch via `task_apply_git_patch`, resolve conflicts in its own workspace, run `git am --continue`, commit the resolved result, and report back with a new patch to apply cleanly.\n - If real apply fails unexpectedly:\n 1. Restore a clean working tree before delegating: run `git am --abort` via `bash` only when a git-am session is in progress; if abort reports no operation in progress, continue.\n 2. Then follow the same delegated reconciliation flow above.\n5. Verify + review:\n - Run focused verification directly with `bash` when practical (for example: targeted tests or the repo's standard full-validation command), or delegate verification to `explore`/`exec` when investigation/fixes are likely.\n - Use `git`/`gh` directly for PR orchestration when a PR already exists (pushes, review-request comments, replies to review remarks, and CI/check-status waiting loops). Create a new PR only when the user explicitly asks.\n - PASS: summary-only (no long logs).\n - FAIL: include the failing command + key error lines; then delegate a fix to `exec`/`plan` and re-verify.\n\nSequential protocol (only for dependency chains):\n\n1. Spawn the prerequisite implementation task (`exec` or `plan`, based on complexity) with `run_in_background: false`.\n2. If step 1 returns `queued`/`running` without a completed report, call `task_await` with the returned `taskId` before attempting any patch apply. If step 1 returns `status: completed` inline, that same `taskId` still requires patch application.\n3. Dry-run apply its patch (`dry_run: true`); then apply for real (`dry_run: false`). If either step fails, follow the conflict playbook above (including `git am --abort` only when a real apply leaves a git-am session in progress).\n4. Only after the patch is applied, spawn the dependent implementation task.\n5. Repeat until the dependency chain is complete.\n\nNote: child workspaces are created at spawn time. Spawning dependents too early means they work from the wrong repo snapshot and get forced into scope expansion.\n\nKeep context minimal:\n\n- Do not request, paste, or restate large plans.\n- Prefer short, actionable prompts, but include enough context that the sub-agent does not need your plan file.\n - Child workspaces do not automatically have access to the parent's plan file; summarize just the relevant slice or provide file pointers.\n- Prefer file paths/symbols over long prose.\n", "plan": "---\nname: Plan\ndescription: Create a plan before coding\nui:\n color: var(--color-plan-mode)\nsubagent:\n runnable: true\ntools:\n add:\n # Allow all tools by default (includes MCP tools which have dynamic names)\n # Use tools.remove in child agents to restrict specific tools\n - .*\n remove:\n # Plan should not apply sub-agent patches.\n - task_apply_git_patch\n # Global config and catalog tools stay out of general-purpose agents\n - mux_agents_.*\n - agent_skill_write\n - agent_skill_delete\n - mux_config_read\n - mux_config_write\n - skills_catalog_.*\n - analytics_query\n require:\n - propose_plan\n # Note: file_edit_* tools ARE available but restricted to plan file only at runtime\n # Note: task tools ARE enabled - Plan delegates to Explore sub-agents\n---\n\nYou are in Plan Mode.\n\n- Every response MUST produce or update a plan.\n- Match the plan's size and structure to the problem.\n- Keep the plan self-contained and scannable.\n- Assume the user wants the completed plan, not a description of how you would make one.\n\n## Investigate only what you need\n\nBefore proposing a plan, figure out what you need to verify and gather that evidence.\n\n- When delegation is available, use Explore sub-agents for repo investigation. In Plan Mode, only\n spawn `agentId: \"explore\"` tasks.\n- Give each Explore task specific deliverables, and parallelize them when that helps.\n- Trust completed Explore reports for repo facts. Do not re-investigate just to second-guess them.\n If something is missing, ambiguous, or conflicting, spawn another focused Explore task.\n- If task delegation is unavailable, do the narrowest read-only investigation yourself.\n- Reserve `file_read` for the plan file itself, user-provided text already in this conversation,\n and that narrow fallback. When reading the plan file, prefer `file_read` over `bash cat` so long\n plans do not get compacted.\n- Wait for any spawned Explore tasks before calling `propose_plan`.\n\n## Write the plan\n\n- Use whatever structure best fits the problem: a few bullets, phases, workstreams, risks, or\n decision points are all fine.\n- Include the context, constraints, evidence, and concrete path forward somewhere in that\n structure.\n- Name the files, symbols, or subsystems that matter, and order the work so an implementer can\n follow it.\n- Keep uncertainty brief and local to the relevant step. Use `ask_user_question` when you need the\n user to decide something.\n- Include small code snippets only when they materially reduce ambiguity.\n- Put long rationale or background into `
/` blocks.\n\n## Questions and handoff\n\n- If you need clarification from the user, use `ask_user_question` instead of asking in chat or\n adding an \"Open Questions\" section to the plan.\n- Ask up to 4 questions at a time (2–4 options each; \"Other\" remains available for free-form\n input).\n- After you get answers, update the plan and then call `propose_plan` when it is ready for review.\n- After calling `propose_plan`, do not paste the plan into chat or mention the plan file path.\n- If the user wants edits to other files, ask them to switch to Exec mode.\n\nWorkspace-specific runtime instructions (plan file path, edit restrictions, nesting warnings) are\nprovided separately.\n", }; diff --git a/src/node/services/agentDefinitions/builtInAgentDefinitions.test.ts b/src/node/services/agentDefinitions/builtInAgentDefinitions.test.ts index e7ae13cb10..f4ce6a45bf 100644 --- a/src/node/services/agentDefinitions/builtInAgentDefinitions.test.ts +++ b/src/node/services/agentDefinitions/builtInAgentDefinitions.test.ts @@ -16,20 +16,6 @@ describe("built-in agent definitions", () => { expect(ids).toContain("plan"); }); - test("includes orchestrator with expected flags", () => { - const pkgs = getBuiltInAgentDefinitions(); - const byId = new Map(pkgs.map((pkg) => [pkg.id, pkg] as const)); - - const orchestrator = byId.get("orchestrator"); - expect(orchestrator).toBeTruthy(); - expect(orchestrator?.frontmatter.ui?.requires).toBeUndefined(); - expect(orchestrator?.frontmatter.ui?.hidden).toBeUndefined(); - expect(orchestrator?.frontmatter.subagent?.append_prompt).toContain( - "Do NOT create pull requests" - ); - expect(orchestrator?.frontmatter.subagent?.runnable).toBe(false); - }); - test("includes desktop built-in with desktop automation safeguards", () => { const pkgs = getBuiltInAgentDefinitions(); const byId = new Map(pkgs.map((pkg) => [pkg.id, pkg] as const)); @@ -80,7 +66,7 @@ describe("built-in agent definitions", () => { expect(plan?.frontmatter.tools?.remove ?? []).toContain("analytics_query"); }); - test("task_apply_git_patch is restricted to exec/orchestrator", () => { + test("task_apply_git_patch is restricted to exec", () => { const pkgs = getBuiltInAgentDefinitions(); const byId = new Map(pkgs.map((pkg) => [pkg.id, pkg] as const)); @@ -88,10 +74,6 @@ describe("built-in agent definitions", () => { expect(exec).toBeTruthy(); expect(exec?.frontmatter.tools?.remove ?? []).not.toContain("task_apply_git_patch"); - const orchestrator = byId.get("orchestrator"); - expect(orchestrator).toBeTruthy(); - expect(orchestrator?.frontmatter.tools?.remove ?? []).not.toContain("task_apply_git_patch"); - const plan = byId.get("plan"); expect(plan).toBeTruthy(); expect(plan?.frontmatter.tools?.remove ?? []).toContain("task_apply_git_patch"); diff --git a/src/node/services/agentDefinitions/builtInAgentDefinitions.ts b/src/node/services/agentDefinitions/builtInAgentDefinitions.ts index 24ec1bf1cc..db7396290e 100644 --- a/src/node/services/agentDefinitions/builtInAgentDefinitions.ts +++ b/src/node/services/agentDefinitions/builtInAgentDefinitions.ts @@ -21,7 +21,6 @@ const BUILT_IN_SOURCES: BuiltInSource[] = [ { id: "desktop", content: BUILTIN_AGENT_CONTENT.desktop }, { id: "explore", content: BUILTIN_AGENT_CONTENT.explore }, { id: "name_workspace", content: BUILTIN_AGENT_CONTENT.name_workspace }, - { id: "orchestrator", content: BUILTIN_AGENT_CONTENT.orchestrator }, ]; let cachedPackages: AgentDefinitionPackage[] | null = null; diff --git a/src/node/services/agentSession.ts b/src/node/services/agentSession.ts index ac28585138..1aaf61aa48 100644 --- a/src/node/services/agentSession.ts +++ b/src/node/services/agentSession.ts @@ -4546,7 +4546,7 @@ export class AgentSession { return false; } - // Check ui.requires gating (e.g., orchestrator requires a plan file). + // Check ui.requires gating (e.g., a custom agent that requires a plan file). // This matches the router's `requiresPlan && !planReady` check. const requiresPlan = resolvedFrontmatter.ui?.requires?.includes("plan") ?? false; if (requiresPlan) { diff --git a/src/node/services/agentSkills/builtInSkillContent.generated.ts b/src/node/services/agentSkills/builtInSkillContent.generated.ts index b7549c5e50..3b51c67ecb 100644 --- a/src/node/services/agentSkills/builtInSkillContent.generated.ts +++ b/src/node/services/agentSkills/builtInSkillContent.generated.ts @@ -208,8 +208,6 @@ export const BUILTIN_SKILL_FILES: Record> = { "", "- If a PR has Codex review comments, address + resolve them, then re-request review by commenting `@codex review` on the PR.", "- Prefer `gh` CLI for GitHub interactions over manual web/curl flows.", - "- In Orchestrator mode, delegate implementation/verification commands to `exec` or `explore` sub-agents and integrate their patches; do not bypass delegation with direct local edits.", - "- In Orchestrator mode, route higher-complexity implementation tasks to `plan` sub-agents so they can research and produce a precise plan before auto-handoff to implementation.", "", "- User preference: when work is already on an open PR, push branch updates at the end of each completed change set so the PR stays current.", '- **PR creation gate:** Do **not** open/create a pull request unless the user explicitly asks (e.g., "open a PR", "create PR", "submit this"). By default, complete local validation, commit/push branch updates as requested, and let the user review before deciding whether to open a PR.', @@ -221,11 +219,11 @@ export const BUILTIN_SKILL_FILES: Record> = { "When a PR exists, you MUST remain in this loop until the PR is fully ready:", "", "1. Push your latest fixes.", - "2. Run local validation (`make static-check` and targeted tests as needed); in Orchestrator mode, delegate command execution to sub-agents.", + "2. Run local validation (`make static-check` and targeted tests as needed).", "3. Request review with `@codex review`.", "4. Run `./scripts/wait_pr_ready.sh ` (which must execute `./scripts/wait_pr_checks.sh --once` while checks are pending).", - "5. If Codex leaves comments, address them (delegate fixes in Orchestrator mode), resolve threads with `./scripts/resolve_pr_comment.sh `, push, and repeat.", - "6. If checks/mergeability fail, fix issues locally (delegate fixes in Orchestrator mode), push, and repeat.", + "5. If Codex leaves comments, address them, resolve threads with `./scripts/resolve_pr_comment.sh `, push, and repeat.", + "6. If checks/mergeability fail, fix issues locally, push, and repeat.", "", "The only early-stop exception is when the reviewer is clearly misunderstanding the intended change and further churn would be counterproductive. In that case, leave a clarifying PR comment and pause for human direction.", "", @@ -955,181 +953,6 @@ export const BUILTIN_SKILL_FILES: Record> = { "", "", "", - "### Orchestrator", - "", - "**Coordinate sub-agent implementation and apply patches**", - "", - '', - "", - "```md", - "---", - "name: Orchestrator", - "description: Coordinate sub-agent implementation and apply patches", - "base: exec", - "subagent:", - " runnable: false", - " append_prompt: |", - " You are running as a sub-agent orchestrator in a child workspace.", - "", - " - Your parent workspace handles all PR management.", - " Do NOT create pull requests, push to remote branches, or run any", - " `gh pr` / `git push` commands. This applies even if AGENTS.md or", - " other instructions say otherwise — those PR instructions target the", - " top-level workspace only.", - " - Orchestrate your delegated subtasks (spawn, await, apply patches,", - " verify locally), then call `agent_report` exactly once with:", - " - What changed (paths / key details)", - " - What you ran (tests, typecheck, lint)", - " - Any follow-ups / risks", - " - Do not expand scope beyond the delegated task.", - "tools:", - " add:", - " - ask_user_question", - " remove:", - " - propose_plan", - " # Keep Orchestrator focused on coordination: no direct file edits.", - " - file_edit_.*", - "---", - "", - "You are an internal Orchestrator agent running in Exec mode.", - "", - "**Mission:** coordinate implementation by delegating investigation + coding to sub-agents, then integrating their patches into this workspace.", - "", - "When a plan is present (default):", - "", - "- Treat the accepted plan as the source of truth. Its file paths, symbols, and structure were validated during planning — do not routinely spawn `explore` to re-confirm them. Exception: if the plan references stale paths or appears to have been authored/edited by the user without planner validation, a single targeted `explore` to sanity-check critical paths is acceptable.", - "- Spawning `explore` to gather _additional_ context beyond what the plan provides is encouraged (e.g., checking whether a helper already exists, locating test files not mentioned in the plan, discovering existing patterns to match). This produces better implementation task briefs.", - "- Do not spawn `explore` just to verify that a planner-generated plan is correct — that is the planner's job, and the plan was accepted by the user.", - "- Convert the plan into concrete implementation subtasks and start delegation (`exec` for low complexity, `plan` for higher complexity).", - "", - "What you are allowed to do directly in this workspace:", - "", - "- Spawn/await/manage sub-agent tasks (`task`, `task_await`, `task_list`, `task_terminate`).", - "- Apply patches (`task_apply_git_patch`).", - "- Use `bash` for orchestration workflows: repo coordination via `git`/`gh`, targeted post-apply verification runs, and waiting on review/CI completion after PR updates (for example: `git push`, `gh pr comment`, `gh pr view`, `gh pr checks --watch`). Only run `gh pr create` when the user explicitly asks you to open a PR.", - "- Ask clarifying questions with `ask_user_question` when blocked.", - "- Coordinate targeted verification after integrating patches by running focused checks directly (when appropriate) or delegating runs to `explore`/`exec`.", - "- Delegate patch-conflict reconciliation to `exec` sub-agents.", - "", - "Hard rules (delegate-first):", - "", - "- Trust `explore` sub-agent reports as authoritative for repo facts (paths/symbols/callsites). Do not redo the same investigation yourself; only re-check if the report is ambiguous or contradicts other evidence.", - "- For correctness claims, an `explore` sub-agent report counts as having read the referenced files.", - "- **Do not do broad repo investigation here.** If you need context, spawn an `explore` sub-agent with a narrow prompt (keeps this agent focused on coordination).", - "- **Do not implement features/bugfixes directly here.** Spawn `exec` (simple) or `plan` (complex) sub-agents and have them complete the work end-to-end.", - "- **Do not use `bash` for file reads/writes, manual code editing, or broad repo exploration.** `bash` in this workspace is for orchestration-only operations: `git`/`gh` repo management, targeted post-apply verification checks, and waiting for PR review/CI outcomes. If direct checks fail due to code issues, delegate fixes to `exec`/`plan` sub-agents instead of implementing changes here.", - "- **Never read or scan session storage.** This includes `~/.mux/sessions/**` and `~/.mux/sessions/subagent-patches/**`. Treat session storage as an internal implementation detail; do not shell out to locate patch artifacts on disk. Only use `task_apply_git_patch` to access patches.", - "", - "Delegation guide:", - "", - '- Use `explore` for narrowly-scoped read-only questions (confirm an assumption, locate a symbol/callsite, find relevant tests). Avoid "scan the repo" prompts.', - "- Use `exec` for straightforward, low-complexity work where the implementation path is obvious from the task brief.", - " - Good fit: single-file edits, localized wiring to existing helpers, straightforward command execution, or narrowly scoped follow-ups with clear acceptance.", - " - Provide a compact task brief (so the sub-agent can act without reading the full plan) with:", - " - Task: one sentence", - " - Background (why this matters): 1–3 bullets", - " - Scope / non-goals: what to change, and what not to change", - " - Starting points: relevant files/symbols/paths (from prior exploration)", - " - Acceptance: bullets / checks", - " - Deliverables: commits + verification commands to run", - " - Constraints:", - " - Do not expand scope.", - " - Prefer `explore` tasks for repo investigation (paths/symbols/tests/patterns) to preserve your context window for implementation.", - " Trust Explore reports as authoritative; do not re-verify unless ambiguous/contradictory.", - " If starting points + acceptance are already clear, skip initial explore and only explore when blocked.", - " - Create one or more git commits before `agent_report`.", - "- Use `plan` for higher-complexity subtasks that touch multiple files/locations, require non-trivial investigation, or have an unclear implementation approach.", - " - Default to `plan` when a subtask needs coordinated updates across multiple locations, unless the edits are mechanical and already fully specified.", - " - For higher-complexity implementation work, prefer `plan` over `exec` so the sub-agent can do targeted research and produce a precise plan before implementation begins.", - " - Good fit: multi-file refactors, cross-module behavior changes, unfamiliar subsystems, or work where sequencing/dependencies need discovery.", - " - Plan subtasks automatically hand off to implementation after a successful `propose_plan`; expect the usual task completion output once implementation finishes.", - " - For `plan` briefs, prioritize goal + constraints + acceptance criteria over file-by-file diff instructions.", - "- Use `desktop` for GUI-heavy desktop automation that requires repeated screenshot → act → verify loops (for example, interacting with application windows, clicking through UI flows, or visual verification). The desktop agent enforces a grounding discipline that keeps visual context local.", - "", - "Recommended Orchestrator → Exec task brief template:", - "", - "- Task: ", - "- Background (why this matters):", - " - ", - "- Scope / non-goals:", - " - Scope: ", - " - Non-goals: ", - "- Starting points: ", - "- Dependencies / assumptions:", - " - Assumes: ", - " - If unmet: stop and report back; do not expand scope to create prerequisites.", - "- Acceptance: ", - "- Deliverables:", - " - Commits: ", - " - Verification: ", - "- Constraints:", - " - Do not expand scope.", - " - Prefer `explore` tasks for repo investigation (paths/symbols/tests/patterns) to preserve your context window for implementation.", - " Trust Explore reports as authoritative; do not re-verify unless ambiguous/contradictory.", - " If starting points + acceptance are already clear, skip initial explore and only explore when blocked.", - " - Create one or more git commits before `agent_report`.", - "", - "Dependency analysis (required before spawning implementation tasks — `exec` or `plan`):", - "", - "- For each candidate subtask, write:", - " - Outputs: files/targets/artifacts introduced/renamed/generated", - " - Inputs / prerequisites (including for verification): what must already exist", - '- A subtask is "independent" only if its patch can be applied + verified on the current parent workspace HEAD, without any other pending patch.', - "- Parallelism is the default: maximize the size of each independent batch and run it in parallel.", - " Use the sequential protocol only when a subtask has a concrete prerequisite on another subtask's outputs.", - "- If task B depends on outputs from task A:", - " - Do not spawn B until A has completed and A's patch is applied in the parent workspace.", - " - If the dependency chain is tight (download → generate → wire-up), prefer one `exec` task rather than splitting.", - "", - "Example dependency chain (schema download → generation):", - "", - "- Task A outputs: a new download target + new schema files.", - "- Task B inputs: those schema files; verifies by running generation.", - "- Therefore: run Task A (await + apply patch) before spawning Task B.", - "", - "Patch integration loop (default):", - "", - "1. Identify a batch of independent subtasks.", - "2. Spawn one implementation sub-agent task per subtask with `run_in_background: true` (`exec` for low complexity, `plan` for higher complexity).", - "3. Await the batch via `task_await`.", - "4. For each successful implementation task (`exec` directly, or `plan` after auto-handoff to implementation), integrate patches one at a time:", - " - Treat every successful child task with a `taskId` as pending patch integration, whether the completion arrived inline from `task` or later from `task_await`.", - " - Complete each dry-run + real-apply pair before starting the next patch. Applying one patch changes `HEAD`, which can invalidate later dry-run results.", - " - Dry-run apply: `task_apply_git_patch` with `dry_run: true`.", - " - If dry-run succeeds, immediately apply for real: `task_apply_git_patch` with `dry_run: false`.", - " - Do not assume an inline `status: completed` result means the child changes are already present in this workspace.", - " - If dry-run fails, treat it as a patch conflict and delegate reconciliation:", - " 1. Do not attempt a real apply for that patch in this workspace.", - " 2. Spawn a dedicated `exec` task. In the brief, include the original failing `task_id` and instruct the sub-agent to replay that patch via `task_apply_git_patch`, resolve conflicts in its own workspace, run `git am --continue`, commit the resolved result, and report back with a new patch to apply cleanly.", - " - If real apply fails unexpectedly:", - " 1. Restore a clean working tree before delegating: run `git am --abort` via `bash` only when a git-am session is in progress; if abort reports no operation in progress, continue.", - " 2. Then follow the same delegated reconciliation flow above.", - "5. Verify + review:", - " - Run focused verification directly with `bash` when practical (for example: targeted tests or the repo's standard full-validation command), or delegate verification to `explore`/`exec` when investigation/fixes are likely.", - " - Use `git`/`gh` directly for PR orchestration when a PR already exists (pushes, review-request comments, replies to review remarks, and CI/check-status waiting loops). Create a new PR only when the user explicitly asks.", - " - PASS: summary-only (no long logs).", - " - FAIL: include the failing command + key error lines; then delegate a fix to `exec`/`plan` and re-verify.", - "", - "Sequential protocol (only for dependency chains):", - "", - "1. Spawn the prerequisite implementation task (`exec` or `plan`, based on complexity) with `run_in_background: false`.", - "2. If step 1 returns `queued`/`running` without a completed report, call `task_await` with the returned `taskId` before attempting any patch apply. If step 1 returns `status: completed` inline, that same `taskId` still requires patch application.", - "3. Dry-run apply its patch (`dry_run: true`); then apply for real (`dry_run: false`). If either step fails, follow the conflict playbook above (including `git am --abort` only when a real apply leaves a git-am session in progress).", - "4. Only after the patch is applied, spawn the dependent implementation task.", - "5. Repeat until the dependency chain is complete.", - "", - "Note: child workspaces are created at spawn time. Spawning dependents too early means they work from the wrong repo snapshot and get forced into scope expansion.", - "", - "Keep context minimal:", - "", - "- Do not request, paste, or restate large plans.", - "- Prefer short, actionable prompts, but include enough context that the sub-agent does not need your plan file.", - " - Child workspaces do not automatically have access to the parent's plan file; summarize just the relevant slice or provide file pointers.", - "- Prefer file paths/symbols over long prose.", - "```", - "", - "", - "", "### Plan", "", "**Create a plan before coding**", diff --git a/src/node/services/planExecutorRouter.test.ts b/src/node/services/planExecutorRouter.test.ts deleted file mode 100644 index 32939c0251..0000000000 --- a/src/node/services/planExecutorRouter.test.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { describe, expect, it } from "bun:test"; -import type { LanguageModel } from "ai"; - -import { routePlanToExecutor } from "./planExecutorRouter"; - -describe("planExecutorRouter", () => { - it("returns orchestrator when select_executor chooses orchestrator", async () => { - let calls = 0; - - const decision = await routePlanToExecutor({ - model: {} as unknown as LanguageModel, - planContent: "Update backend, frontend, and tests in parallel.", - timeoutMs: 5_000, - generateTextImpl: async (args) => { - calls += 1; - - expect((args as { toolChoice?: unknown }).toolChoice).toEqual({ - type: "tool", - toolName: "select_executor", - }); - - const tools = (args as { tools?: unknown }).tools as Record; - const selectExecutorTool = tools.select_executor as { - execute: (input: unknown, options: unknown) => Promise; - }; - - await selectExecutorTool.execute( - { - target: "orchestrator", - reasoning: "Plan spans independent workstreams.", - }, - {} - ); - - return { finishReason: "stop" }; - }, - }); - - expect(calls).toBe(1); - expect(decision).toEqual({ - target: "orchestrator", - reasoning: "Plan spans independent workstreams.", - }); - }); - - it("retries once with a reminder when no tool call is produced", async () => { - let calls = 0; - - const decision = await routePlanToExecutor({ - model: {} as unknown as LanguageModel, - planContent: "Single-file refactor.", - timeoutMs: 5_000, - generateTextImpl: async (args) => { - calls += 1; - - const messages = (args as { messages?: unknown }).messages as - | Array<{ content?: unknown }> - | undefined; - expect(Array.isArray(messages)).toBe(true); - - if (calls === 1) { - expect(messages?.length).toBe(1); - return { finishReason: "stop" }; - } - - expect(messages?.length).toBe(2); - expect(messages?.[1]?.content).toBe( - "Reminder: You MUST call select_executor exactly once. Do not output any text." - ); - - const tools = (args as { tools?: unknown }).tools as Record; - const selectExecutorTool = tools.select_executor as { - execute: (input: unknown, options: unknown) => Promise; - }; - - await selectExecutorTool.execute( - { - target: "exec", - reasoning: "Plan is focused and sequential.", - }, - {} - ); - - return { finishReason: "stop" }; - }, - }); - - expect(calls).toBe(2); - expect(decision).toEqual({ - target: "exec", - reasoning: "Plan is focused and sequential.", - }); - }); - - it("defaults to exec when the model never calls select_executor", async () => { - const decision = await routePlanToExecutor({ - model: {} as unknown as LanguageModel, - planContent: "Any plan", - timeoutMs: 5_000, - generateTextImpl: () => { - return Promise.resolve({ finishReason: "stop" }); - }, - }); - - expect(decision).toEqual({ target: "exec" }); - }); -}); diff --git a/src/node/services/planExecutorRouter.ts b/src/node/services/planExecutorRouter.ts deleted file mode 100644 index 2b1da25f1b..0000000000 --- a/src/node/services/planExecutorRouter.ts +++ /dev/null @@ -1,147 +0,0 @@ -import assert from "@/common/utils/assert"; - -import { generateText, tool, type LanguageModel, type Tool } from "ai"; -import { z } from "zod"; - -import { getErrorMessage } from "@/common/utils/errors"; -import { log } from "@/node/services/log"; -import { linkAbortSignal } from "@/node/utils/abort"; - -export type PlanExecutorRoutingTarget = "exec" | "orchestrator"; - -export interface PlanExecutorRoutingDecision { - target: PlanExecutorRoutingTarget; - reasoning?: string; -} - -export type GenerateTextLike = ( - args: Parameters[0] -) => Promise<{ finishReason?: string }>; - -interface RoutePlanToExecutorParams { - model: LanguageModel; - planContent: string; - timeoutMs?: number; - abortSignal?: AbortSignal; - generateTextImpl?: GenerateTextLike; -} - -const PLAN_EXECUTOR_ROUTING_TIMEOUT_MS = 15_000; - -const PLAN_EXECUTOR_ROUTING_PROMPT = `You are a routing agent. - -Given a software implementation plan, decide which executor should implement it: -- "exec": a single execution agent should implement the plan. -- "orchestrator": an orchestrator should coordinate multiple sub-agents. - -Choose "exec" when: -- The plan is focused and mostly sequential. -- The work is likely confined to one subsystem or a small set of related files. -- Parallelism would add coordination overhead without clear benefit. - -Choose "orchestrator" when: -- The plan spans multiple subsystems with separable workstreams. -- The plan can be parallelized into independent tasks. -- The implementation likely needs coordinated backend/frontend/test updates in parallel. - -You MUST call select_executor exactly once. -Do not output plain text.`; - -const SELECT_EXECUTOR_REMINDER = - "Reminder: You MUST call select_executor exactly once. Do not output any text."; - -const selectExecutorInputSchema = z.object({ - target: z.enum(["exec", "orchestrator"]), - reasoning: z.string().min(1), -}); - -export async function routePlanToExecutor( - params: RoutePlanToExecutorParams -): Promise { - assert(params, "routePlanToExecutor: params is required"); - assert(params.model, "routePlanToExecutor: model is required"); - assert( - typeof params.planContent === "string" && params.planContent.trim().length > 0, - "routePlanToExecutor: planContent must be a non-empty string" - ); - - const timeoutMs = params.timeoutMs ?? PLAN_EXECUTOR_ROUTING_TIMEOUT_MS; - assert( - Number.isInteger(timeoutMs) && timeoutMs > 0, - "routePlanToExecutor: timeoutMs must be a positive integer" - ); - - const routeAbortController = new AbortController(); - const unlinkAbortSignal = linkAbortSignal(params.abortSignal, routeAbortController); - - let timedOut = false; - const timeout = setTimeout(() => { - timedOut = true; - routeAbortController.abort(); - }, timeoutMs); - timeout.unref?.(); - - let selectedDecision: PlanExecutorRoutingDecision | undefined; - - const tools: Record = { - select_executor: tool({ - description: "Select which executor should implement this plan.", - inputSchema: selectExecutorInputSchema, - execute: (input) => { - const reasoning = input.reasoning.trim(); - selectedDecision = { - target: input.target, - reasoning: reasoning.length > 0 ? reasoning : undefined, - }; - - // Signal-tool semantics: the decision is consumed by the caller. - return { - ok: true, - target: input.target, - }; - }, - }), - }; - - const attemptMessages: Array[0]["messages"]>> = [ - [{ role: "user", content: params.planContent }], - [ - { role: "user", content: params.planContent }, - { role: "user", content: SELECT_EXECUTOR_REMINDER }, - ], - ]; - - const generate = params.generateTextImpl ?? generateText; - - try { - for (const messages of attemptMessages) { - selectedDecision = undefined; - - await generate({ - model: params.model, - system: PLAN_EXECUTOR_ROUTING_PROMPT, - messages, - tools, - toolChoice: { type: "tool", toolName: "select_executor" }, - maxRetries: 0, - abortSignal: routeAbortController.signal, - }); - - if (selectedDecision) { - return selectedDecision; - } - } - - log.warn("Plan executor routing returned no tool decision; defaulting to exec"); - return { target: "exec" }; - } catch (error: unknown) { - log.warn("Plan executor routing failed; defaulting to exec", { - timedOut, - error: getErrorMessage(error), - }); - return { target: "exec" }; - } finally { - clearTimeout(timeout); - unlinkAbortSignal(); - } -} diff --git a/src/node/services/streamContextBuilder.ts b/src/node/services/streamContextBuilder.ts index 75bbd26e3d..7185bc8c75 100644 --- a/src/node/services/streamContextBuilder.ts +++ b/src/node/services/streamContextBuilder.ts @@ -165,10 +165,10 @@ export async function buildPlanInstructions( : nestingInstruction; } - // Read plan content for agent transition (plan-like → exec/orchestrator). - // Only read if switching to the built-in exec/orchestrator agent and last assistant was plan-like. + // Read plan content for agent transition (plan-like → exec). + // Only read if switching to the built-in exec agent and last assistant was plan-like. let planContentForTransition: string | undefined; - const isPlanHandoffAgent = effectiveAgentId === "exec" || effectiveAgentId === "orchestrator"; + const isPlanHandoffAgent = effectiveAgentId === "exec"; if (isPlanHandoffAgent && !chatHasStartHerePlanSummary) { const lastAssistantMessage = [...requestPayloadMessages] .reverse() diff --git a/src/node/services/taskService.test.ts b/src/node/services/taskService.test.ts index 42a0bc1b5e..c0a9d68ca3 100644 --- a/src/node/services/taskService.test.ts +++ b/src/node/services/taskService.test.ts @@ -26,13 +26,8 @@ import * as forkOrchestrator from "@/node/services/utils/forkOrchestrator"; import { Ok, Err, type Result } from "@/common/types/result"; import { defaultModel } from "@/common/utils/ai/models"; import { enforceThinkingPolicy } from "@/common/utils/thinking/policy"; -import type { PlanSubagentExecutorRouting } from "@/common/types/tasks"; import type { ThinkingLevel } from "@/common/types/thinking"; import type { ErrorEvent, StreamEndEvent } from "@/common/types/stream"; -import { - PLAN_AUTO_ROUTING_STATUS_EMOJI, - PLAN_AUTO_ROUTING_STATUS_MESSAGE, -} from "@/common/constants/planAutoRoutingStatus"; import { createMuxMessage, type MuxMessage } from "@/common/types/message"; import { isDynamicToolPart, type DynamicToolPart } from "@/common/types/toolParts"; import type { WorkspaceMetadata } from "@/common/types/workspace"; @@ -8001,10 +7996,7 @@ describe("TaskService", () => { }); async function setupPlanModeStreamEndHarness(options?: { - planSubagentExecutorRouting?: PlanSubagentExecutorRouting; - planSubagentDefaultsToOrchestrator?: boolean; childAgentId?: string; - disableOrchestrator?: boolean; maxTaskNestingDepth?: number; parentAiSettingsByAgent?: Record; agentAiDefaults?: Record< @@ -8042,18 +8034,7 @@ describe("TaskService", () => { ); } - const agentAiDefaults = { - ...(options?.agentAiDefaults ?? {}), - ...(options?.disableOrchestrator - ? { - orchestrator: { - modelString: "openai:gpt-4o-mini", - thinkingLevel: "off" as ThinkingLevel, - enabled: false, - }, - } - : {}), - }; + const agentAiDefaults = { ...(options?.agentAiDefaults ?? {}) }; await config.saveConfig({ projects: new Map([ @@ -8088,14 +8069,6 @@ describe("TaskService", () => { taskSettings: { maxParallelAgentTasks: 3, maxTaskNestingDepth: options?.maxTaskNestingDepth ?? 3, - planSubagentExecutorRouting: - options?.planSubagentExecutorRouting ?? - (options?.planSubagentDefaultsToOrchestrator ? "orchestrator" : "exec"), - ...(typeof options?.planSubagentDefaultsToOrchestrator === "boolean" - ? { - planSubagentDefaultsToOrchestrator: options.planSubagentDefaultsToOrchestrator, - } - : {}), }, agentAiDefaults: Object.keys(agentAiDefaults).length > 0 ? agentAiDefaults : undefined, subagentAiDefaults: options?.subagentAiDefaults, @@ -8121,21 +8094,6 @@ describe("TaskService", () => { const internal = taskService as unknown as { handleStreamEnd: (event: StreamEndEvent) => Promise; - resolvePlanAutoHandoffTargetAgentId: (args: { - workspaceId: string; - entry: { - projectPath: string; - workspace: { - id?: string; - name?: string; - path?: string; - runtimeConfig?: unknown; - taskModelString?: string; - }; - }; - routing: PlanSubagentExecutorRouting; - planContent: string | null; - }) => Promise<"exec" | "orchestrator">; }; return { @@ -8562,188 +8520,6 @@ describe("TaskService", () => { expect(childWorkspace?.taskStatus).toBe("interrupted"); }); - test("stream-end with propose_plan success in auto routing falls back to exec when plan content is unavailable", async () => { - const { config, childId, sendMessage, createModel, updateAgentStatus, internal } = - await setupPlanModeStreamEndHarness({ - planSubagentExecutorRouting: "auto", - }); - - await internal.handleStreamEnd(makeSuccessfulProposePlanStreamEndEvent(childId)); - - expect(createModel).not.toHaveBeenCalled(); - expect(sendMessage).toHaveBeenCalledTimes(1); - expect(sendMessage).toHaveBeenCalledWith( - childId, - expect.stringContaining("Implement the plan"), - expect.objectContaining({ agentId: "exec" }), - expect.objectContaining({ synthetic: true }) - ); - expect(updateAgentStatus).toHaveBeenNthCalledWith( - 1, - childId, - expect.objectContaining({ - emoji: PLAN_AUTO_ROUTING_STATUS_EMOJI, - message: PLAN_AUTO_ROUTING_STATUS_MESSAGE, - url: "", - }) - ); - expect(updateAgentStatus).toHaveBeenNthCalledWith(2, childId, null); - - const postCfg = config.loadConfigOrDefault(); - const updatedTask = Array.from(postCfg.projects.values()) - .flatMap((project) => project.workspaces) - .find((workspace) => workspace.id === childId); - - expect(updatedTask?.agentId).toBe("exec"); - expect(updatedTask?.taskStatus).toBe("running"); - }); - - test("auto plan handoff routing defaults to exec when orchestrator would have no task tools", async () => { - const { config, projectPath, childId, createModel, internal } = - await setupPlanModeStreamEndHarness({ - planSubagentExecutorRouting: "auto", - maxTaskNestingDepth: 1, - }); - - const cfg = config.loadConfigOrDefault(); - const childWorkspace = Array.from(cfg.projects.values()) - .flatMap((project) => project.workspaces) - .find((workspace) => workspace.id === childId); - expect(childWorkspace).toBeTruthy(); - if (!childWorkspace) return; - - const targetAgentId = await internal.resolvePlanAutoHandoffTargetAgentId({ - workspaceId: childId, - entry: { - projectPath, - workspace: childWorkspace, - }, - routing: "auto", - planContent: "1. Delegate implementation work to a child task.", - }); - - expect(targetAgentId).toBe("exec"); - expect(createModel).not.toHaveBeenCalled(); - }); - - test("auto plan handoff routing still evaluates the model when task tools are available", async () => { - const { config, projectPath, childId, createModel, internal } = - await setupPlanModeStreamEndHarness({ - planSubagentExecutorRouting: "auto", - }); - - const cfg = config.loadConfigOrDefault(); - const childWorkspace = Array.from(cfg.projects.values()) - .flatMap((project) => project.workspaces) - .find((workspace) => workspace.id === childId); - expect(childWorkspace).toBeTruthy(); - if (!childWorkspace) return; - - const targetAgentId = await internal.resolvePlanAutoHandoffTargetAgentId({ - workspaceId: childId, - entry: { - projectPath, - workspace: childWorkspace, - }, - routing: "auto", - planContent: "1. Implement the changes directly in this workspace.", - }); - - expect(targetAgentId).toBe("exec"); - expect(createModel).toHaveBeenCalledTimes(1); - }); - - test("stream-end with propose_plan success hands off to orchestrator when routing is orchestrator", async () => { - const { config, childId, sendMessage, replaceHistory, internal } = - await setupPlanModeStreamEndHarness({ - planSubagentExecutorRouting: "orchestrator", - }); - - await internal.handleStreamEnd(makeSuccessfulProposePlanStreamEndEvent(childId)); - - expect(replaceHistory).toHaveBeenCalledWith( - childId, - expect.anything(), - expect.objectContaining({ mode: "append-compaction-boundary" }) - ); - - expect(sendMessage).toHaveBeenCalledTimes(1); - expect(sendMessage).toHaveBeenCalledWith( - childId, - expect.stringContaining("orchestrating"), - expect.objectContaining({ agentId: "orchestrator" }), - expect.objectContaining({ synthetic: true }) - ); - - const postCfg = config.loadConfigOrDefault(); - const updatedTask = Array.from(postCfg.projects.values()) - .flatMap((project) => project.workspaces) - .find((workspace) => workspace.id === childId); - - expect(updatedTask?.agentId).toBe("orchestrator"); - expect(updatedTask?.taskStatus).toBe("running"); - }); - - test("orchestrator handoff inherits parent model when orchestrator defaults are unset", async () => { - const { config, childId, sendMessage, internal } = await setupPlanModeStreamEndHarness({ - planSubagentExecutorRouting: "orchestrator", - agentAiDefaults: { - exec: { - modelString: "openai:gpt-5.3-codex", - thinkingLevel: "xhigh", - }, - }, - }); - - await internal.handleStreamEnd(makeSuccessfulProposePlanStreamEndEvent(childId)); - - expect(sendMessage).toHaveBeenCalledTimes(1); - expect(sendMessage).toHaveBeenCalledWith( - childId, - expect.stringContaining("orchestrating"), - expect.objectContaining({ - agentId: "orchestrator", - model: "openai:gpt-4o-mini", - thinkingLevel: "off", - }), - expect.objectContaining({ synthetic: true }) - ); - - const postCfg = config.loadConfigOrDefault(); - const updatedTask = Array.from(postCfg.projects.values()) - .flatMap((project) => project.workspaces) - .find((workspace) => workspace.id === childId); - - expect(updatedTask?.agentId).toBe("orchestrator"); - expect(updatedTask?.taskModelString).toBe("openai:gpt-4o-mini"); - expect(updatedTask?.taskThinkingLevel).toBe("off"); - }); - - test("stream-end with propose_plan success falls back to exec when orchestrator is disabled", async () => { - const { config, childId, sendMessage, internal } = await setupPlanModeStreamEndHarness({ - planSubagentExecutorRouting: "orchestrator", - disableOrchestrator: true, - }); - - await internal.handleStreamEnd(makeSuccessfulProposePlanStreamEndEvent(childId)); - - expect(sendMessage).toHaveBeenCalledTimes(1); - expect(sendMessage).toHaveBeenCalledWith( - childId, - expect.stringContaining("Implement the plan"), - expect.objectContaining({ agentId: "exec" }), - expect.objectContaining({ synthetic: true }) - ); - - const postCfg = config.loadConfigOrDefault(); - const updatedTask = Array.from(postCfg.projects.values()) - .flatMap((project) => project.workspaces) - .find((workspace) => workspace.id === childId); - - expect(updatedTask?.agentId).toBe("exec"); - expect(updatedTask?.taskStatus).toBe("running"); - }); - test("handoff kickoff sendMessage failure keeps task status as running for restart recovery", async () => { const sendMessageFailure = mock( (): Promise> => Promise.resolve(Err("kickoff failed")) diff --git a/src/node/services/taskService.ts b/src/node/services/taskService.ts index 784d3c6081..79d4d2d390 100644 --- a/src/node/services/taskService.ts +++ b/src/node/services/taskService.ts @@ -25,7 +25,6 @@ import { MultiProjectRuntime } from "@/node/runtime/multiProjectRuntime"; import { runBackgroundInit } from "@/node/runtime/runtimeFactory"; import type { InitLogger, Runtime } from "@/node/runtime/Runtime"; import { readPlanFile } from "@/node/utils/runtime/helpers"; -import { routePlanToExecutor } from "@/node/services/planExecutorRouter"; import { coerceNonEmptyString, tryReadGitHeadCommitSha, @@ -44,7 +43,6 @@ import { Ok, Err, type Result } from "@/common/types/result"; import { DEFAULT_TASK_SETTINGS, normalizeTaskSettings, - type PlanSubagentExecutorRouting, type TaskSettings, } from "@/common/types/tasks"; @@ -70,13 +68,9 @@ import { TaskToolResultSchema, TaskToolArgsSchema, } from "@/common/utils/tools/toolDefinitions"; -import { isPlanLikeInResolvedChain, isToolEnabledInResolvedChain } from "@/common/utils/agentTools"; +import { isPlanLikeInResolvedChain } from "@/common/utils/agentTools"; import { formatSendMessageError } from "@/node/services/utils/sendMessageError"; import { enforceThinkingPolicy } from "@/common/utils/thinking/policy"; -import { - PLAN_AUTO_ROUTING_STATUS_EMOJI, - PLAN_AUTO_ROUTING_STATUS_MESSAGE, -} from "@/common/constants/planAutoRoutingStatus"; import { taskQueueDebug } from "@/node/services/taskQueueDebug"; import { readSubagentGitPatchArtifact } from "@/node/services/subagentGitPatchArtifacts"; import { @@ -549,267 +543,6 @@ export class TaskService { } } - private getTaskWorkspaceAgentResolutionContext(args: { - projectPath: string; - workspace: Pick; - }): { - workspaceName: string; - runtime: Runtime; - workspacePath: string; - } | null { - assert( - args.projectPath.length > 0, - "getTaskWorkspaceAgentResolutionContext: projectPath must be non-empty" - ); - - const workspaceName = coerceNonEmptyString(args.workspace.name) ?? args.workspace.id; - if (!workspaceName) { - return null; - } - - const runtimeConfig = args.workspace.runtimeConfig ?? DEFAULT_RUNTIME_CONFIG; - const runtime = createRuntimeForWorkspace({ - runtimeConfig, - projectPath: args.projectPath, - name: workspaceName, - }); - const workspacePath = - coerceNonEmptyString(args.workspace.path) ?? - runtime.getWorkspacePath(args.projectPath, workspaceName); - if (!workspacePath) { - return null; - } - - return { - workspaceName, - runtime, - workspacePath, - }; - } - - private async isAgentEnabledForTaskWorkspace(args: { - workspaceId: string; - projectPath: string; - workspace: Pick; - agentId: "exec" | "orchestrator"; - }): Promise { - assert( - args.workspaceId.length > 0, - "isAgentEnabledForTaskWorkspace: workspaceId must be non-empty" - ); - assert( - args.projectPath.length > 0, - "isAgentEnabledForTaskWorkspace: projectPath must be non-empty" - ); - - const resolutionContext = this.getTaskWorkspaceAgentResolutionContext({ - projectPath: args.projectPath, - workspace: args.workspace, - }); - if (!resolutionContext) { - return false; - } - - try { - const resolvedFrontmatter = await resolveAgentFrontmatter( - resolutionContext.runtime, - resolutionContext.workspacePath, - args.agentId - ); - const cfg = this.config.loadConfigOrDefault(); - const effectivelyDisabled = isAgentEffectivelyDisabled({ - cfg, - agentId: args.agentId, - resolvedFrontmatter, - }); - return !effectivelyDisabled; - } catch (error: unknown) { - log.warn("Failed to resolve task handoff target agent availability", { - workspaceId: args.workspaceId, - agentId: args.agentId, - error: getErrorMessage(error), - }); - return false; - } - } - - private async canAgentSpawnTasksInWorkspace(args: { - workspaceId: string; - projectPath: string; - workspace: Pick; - agentId: "orchestrator"; - }): Promise { - assert( - args.workspaceId.length > 0, - "canAgentSpawnTasksInWorkspace: workspaceId must be non-empty" - ); - assert( - args.projectPath.length > 0, - "canAgentSpawnTasksInWorkspace: projectPath must be non-empty" - ); - - const resolutionContext = this.getTaskWorkspaceAgentResolutionContext({ - projectPath: args.projectPath, - workspace: args.workspace, - }); - if (!resolutionContext) { - return false; - } - - try { - const cfg = this.config.loadConfigOrDefault(); - const resolvedFrontmatter = await resolveAgentFrontmatter( - resolutionContext.runtime, - resolutionContext.workspacePath, - args.agentId - ); - const effectivelyDisabled = isAgentEffectivelyDisabled({ - cfg, - agentId: args.agentId, - resolvedFrontmatter, - }); - if (effectivelyDisabled) { - return false; - } - - const agentDefinition = await readAgentDefinition( - resolutionContext.runtime, - resolutionContext.workspacePath, - args.agentId - ); - const chain = await resolveAgentInheritanceChain({ - runtime: resolutionContext.runtime, - workspacePath: resolutionContext.workspacePath, - agentId: agentDefinition.id, - agentDefinition, - workspaceId: args.workspaceId, - }); - const taskSettings = cfg.taskSettings ?? DEFAULT_TASK_SETTINGS; - const taskDepth = this.getTaskDepth(cfg, args.workspaceId); - const disableTaskToolsForDepth = taskDepth >= taskSettings.maxTaskNestingDepth; - - return !disableTaskToolsForDepth && isToolEnabledInResolvedChain("task", chain); - } catch (error: unknown) { - log.warn("Failed to resolve task handoff target task-spawning capability", { - workspaceId: args.workspaceId, - agentId: args.agentId, - error: getErrorMessage(error), - }); - return false; - } - } - - private async resolvePlanAutoHandoffTargetAgentId(args: { - workspaceId: string; - entry: { - projectPath: string; - workspace: Pick< - WorkspaceConfigEntry, - "id" | "name" | "path" | "runtimeConfig" | "taskModelString" - >; - }; - routing: PlanSubagentExecutorRouting; - planContent: string | null; - }): Promise<"exec" | "orchestrator"> { - assert( - args.workspaceId.length > 0, - "resolvePlanAutoHandoffTargetAgentId: workspaceId must be non-empty" - ); - assert( - args.routing === "exec" || args.routing === "orchestrator" || args.routing === "auto", - "resolvePlanAutoHandoffTargetAgentId: routing must be exec, orchestrator, or auto" - ); - - const resolveOrchestratorAvailability = async (): Promise<"exec" | "orchestrator"> => { - const orchestratorEnabled = await this.isAgentEnabledForTaskWorkspace({ - workspaceId: args.workspaceId, - projectPath: args.entry.projectPath, - workspace: args.entry.workspace, - agentId: "orchestrator", - }); - if (orchestratorEnabled) { - return "orchestrator"; - } - - // If orchestrator is disabled/unavailable, fall back to exec before mutating - // workspace agent state so the handoff stream can still proceed. - log.warn("Plan-task auto-handoff falling back to exec because orchestrator is unavailable", { - workspaceId: args.workspaceId, - }); - return "exec"; - }; - - if (args.routing === "exec") { - return "exec"; - } - - if (args.routing === "orchestrator") { - return resolveOrchestratorAvailability(); - } - - if (!args.planContent || args.planContent.trim().length === 0) { - log.warn("Plan-task auto-handoff auto-routing has no plan content; defaulting to exec", { - workspaceId: args.workspaceId, - }); - return "exec"; - } - - const orchestratorCanSpawnTasks = await this.canAgentSpawnTasksInWorkspace({ - workspaceId: args.workspaceId, - projectPath: args.entry.projectPath, - workspace: args.entry.workspace, - agentId: "orchestrator", - }); - if (!orchestratorCanSpawnTasks) { - log.warn( - "Plan-task auto-handoff auto-routing defaulting to exec because orchestrator cannot orchestrate in this workspace", - { - workspaceId: args.workspaceId, - } - ); - return "exec"; - } - - const modelString = normalizeToCanonical( - coerceNonEmptyString(args.entry.workspace.taskModelString) ?? defaultModel - ); - assert( - modelString.trim().length > 0, - "resolvePlanAutoHandoffTargetAgentId: modelString must be non-empty" - ); - - const modelResult = await this.aiService.createModel(modelString, undefined, { - agentInitiated: true, - workspaceId: args.workspaceId, - }); - if (!modelResult.success) { - log.warn("Plan-task auto-handoff auto-routing failed to create model; defaulting to exec", { - workspaceId: args.workspaceId, - model: modelString, - error: modelResult.error, - }); - return "exec"; - } - - const decision = await routePlanToExecutor({ - model: modelResult.data, - planContent: args.planContent, - }); - - log.info("Plan-task auto-handoff routing decision", { - workspaceId: args.workspaceId, - target: decision.target, - reasoning: decision.reasoning, - model: modelString, - }); - - if (decision.target === "orchestrator") { - return resolveOrchestratorAvailability(); - } - - return "exec"; - } - private async emitWorkspaceMetadata(workspaceId: string): Promise { assert(workspaceId.length > 0, "emitWorkspaceMetadata: workspaceId must be non-empty"); @@ -3463,8 +3196,6 @@ export class TaskService { workspaceId, entry, proposePlanResult, - planSubagentExecutorRouting: - (cfg.taskSettings ?? DEFAULT_TASK_SETTINGS).planSubagentExecutorRouting ?? "exec", }); return; } @@ -3570,7 +3301,6 @@ export class TaskService { workspaceId: string; entry: { projectPath: string; workspace: WorkspaceConfigEntry }; proposePlanResult: { planPath: string }; - planSubagentExecutorRouting: PlanSubagentExecutorRouting; }): Promise { assert( args.workspaceId.length > 0, @@ -3622,41 +3352,7 @@ export class TaskService { }); } - const targetAgentId = await (async () => { - const shouldShowRoutingStatus = args.planSubagentExecutorRouting === "auto"; - if (shouldShowRoutingStatus) { - // Auto routing can pause for up to the LLM timeout; surface progress in the sidebar. - await this.workspaceService.updateAgentStatus(args.workspaceId, { - emoji: PLAN_AUTO_ROUTING_STATUS_EMOJI, - message: PLAN_AUTO_ROUTING_STATUS_MESSAGE, - // ExtensionMetadataService carries forward the previous status URL when url is omitted. - // Use an explicit empty string sentinel to clear stale links for this transient status. - url: "", - }); - } - - try { - return await this.resolvePlanAutoHandoffTargetAgentId({ - workspaceId: args.workspaceId, - entry: { - projectPath: args.entry.projectPath, - workspace: { - id: args.entry.workspace.id, - name: args.entry.workspace.name, - path: args.entry.workspace.path, - runtimeConfig: args.entry.workspace.runtimeConfig, - taskModelString: args.entry.workspace.taskModelString, - }, - }, - routing: args.planSubagentExecutorRouting, - planContent: planSummary?.content ?? null, - }); - } finally { - if (shouldShowRoutingStatus) { - await this.workspaceService.updateAgentStatus(args.workspaceId, null); - } - } - })(); + const targetAgentId = "exec" as const; const summaryContent = planSummary ? `# Plan\n\n${planSummary.content}\n\nNote: This chat already contains the full plan; no need to re-open the plan file.\n\n---\n\n*Plan file preserved at:* \`${planSummary.path}\`` @@ -3711,14 +3407,10 @@ export class TaskService { await this.setTaskStatus(args.workspaceId, "running"); - const kickoffMsg = - targetAgentId === "orchestrator" - ? "Start orchestrating the implementation of this plan." - : "Implement the plan."; try { const sendKickoffResult = await this.workspaceService.sendMessage( args.workspaceId, - kickoffMsg, + "Implement the plan.", { model: taskModelString, agentId: targetAgentId, diff --git a/tests/ipc/agents/listOrchestratorAlwaysSelectable.test.ts b/tests/ipc/agents/listOrchestratorAlwaysSelectable.test.ts deleted file mode 100644 index 338cc3f0d6..0000000000 --- a/tests/ipc/agents/listOrchestratorAlwaysSelectable.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Tests that Orchestrator stays selectable in the agent picker regardless of plan file state. - */ - -import * as fs from "fs/promises"; -import * as os from "os"; -import * as path from "path"; - -import type { TestEnvironment } from "../setup"; -import { cleanupTestEnvironment, createTestEnvironment } from "../setup"; -import { - cleanupTempGitRepo, - createTempGitRepo, - generateBranchName, - trustProject, -} from "../helpers"; -import { detectDefaultTrunkBranch } from "../../../src/node/git"; -import { getPlanFilePath } from "../../../src/common/utils/planStorage"; -import { expandTilde } from "../../../src/node/runtime/tildeExpansion"; - -describe("agents.list orchestrator availability", () => { - let env: TestEnvironment; - let repoPath: string; - - let homeDir: string; - let prevHome: string | undefined; - - beforeAll(async () => { - // Isolate plan file reads/writes under a temp HOME so tests don't touch ~/.mux. - prevHome = process.env.HOME; - homeDir = await fs.mkdtemp(path.join(os.tmpdir(), "mux-home-")); - process.env.HOME = homeDir; - - env = await createTestEnvironment(); - repoPath = await createTempGitRepo(); - await trustProject(env, repoPath); - }, 30_000); - - afterAll(async () => { - if (repoPath) { - await cleanupTempGitRepo(repoPath); - } - if (env) { - await cleanupTestEnvironment(env); - } - - if (homeDir) { - await fs.rm(homeDir, { recursive: true, force: true }); - } - - if (prevHome === undefined) { - delete process.env.HOME; - } else { - process.env.HOME = prevHome; - } - }); - - it("keeps orchestrator uiSelectable with no plan, an empty plan, and a non-empty plan", async () => { - const branchName = generateBranchName("agents-orchestrator-selectable"); - const trunkBranch = await detectDefaultTrunkBranch(repoPath); - - const createResult = await env.orpc.workspace.create({ - projectPath: repoPath, - branchName, - trunkBranch, - }); - - expect(createResult.success).toBe(true); - if (!createResult.success) { - throw new Error("Failed to create workspace"); - } - - const workspaceId = createResult.metadata.id; - const workspaceName = createResult.metadata.name; - const projectName = createResult.metadata.projectName; - - const planPath = expandTilde(getPlanFilePath(workspaceName, projectName)); - - async function expectOrchestratorSelectable(): Promise { - const agents = await env.orpc.agents.list({ workspaceId }); - const orchestrator = agents.find((agent) => agent.id === "orchestrator"); - expect(orchestrator).toBeTruthy(); - expect(orchestrator?.uiSelectable).toBe(true); - } - - try { - await fs.rm(planPath, { force: true }); - await expectOrchestratorSelectable(); - - await fs.mkdir(path.dirname(planPath), { recursive: true }); - await fs.writeFile(planPath, ""); - await expectOrchestratorSelectable(); - - await fs.writeFile(planPath, "# Plan\n"); - await expectOrchestratorSelectable(); - } finally { - await fs.rm(planPath, { force: true }); - await env.orpc.workspace.remove({ workspaceId }); - } - }, 30_000); -}); diff --git a/tests/ui/agents/picker.test.ts b/tests/ui/agents/picker.test.ts index 9262a4dcfd..8e0a78431d 100644 --- a/tests/ui/agents/picker.test.ts +++ b/tests/ui/agents/picker.test.ts @@ -150,24 +150,6 @@ describeIntegration("Agent Picker (UI)", () => { }); }, 30_000); - test("orchestrator appears in dropdown without a plan file", async () => { - await withSharedWorkspace("anthropic", async ({ env, workspaceId, metadata }) => { - const cleanupDom = setupTestDom(); - const view = renderApp({ apiClient: env.orpc, metadata }); - - try { - await setupWorkspaceView(view, metadata, workspaceId); - await openAgentPicker(view.container); - - const agentNames = getVisibleAgentNames(view.container); - expect(agentNames).toContain("Orchestrator"); - expect(getAgentIdByName(view.container, "Orchestrator")).toBe("orchestrator"); - } finally { - await cleanupView(view, cleanupDom); - } - }); - }, 30_000); - test("custom workspace agents appear alongside built-ins", async () => { await withSharedWorkspace("anthropic", async ({ env, workspaceId, metadata }) => { // With workspaceId provided, agents are discovered from workspace worktree path.