Skip to content

[QUALITY-569] Orchestrate tool client implementation#9490

Closed
cephalonaut wants to merge 7 commits intomasterfrom
matthew/orchestration-tool
Closed

[QUALITY-569] Orchestrate tool client implementation#9490
cephalonaut wants to merge 7 commits intomasterfrom
matthew/orchestration-tool

Conversation

@cephalonaut
Copy link
Copy Markdown
Contributor

Description

Client-side implementation of the orchestrate tool call (Linear: QUALITY-569).

When the LLM emits an orchestrate tool call, the client now renders an OrchestrateConfigCard with:

  • Interactive Model / Harness / Execution mode / Environment dropdowns (Environment shown only in Remote)
  • Inline validation: "Choose an environment before launching." (Remote without env), "OpenCode is not supported in remote mode."
  • OpenCode → Oz auto-reset on Local → Remote toggle, with an inline notice the user can dismiss
  • Three terminal buttons: Reject, Launch without orchestration, Launch
  • Six post-action terminal states: Launching N / Started N / Started M of N (M=0 included) / Failed to start orchestration / Launch denied / Cancelled

Launch dispatches N parallel CreateAgentTasks through the existing StartAgentExecutor path. Per-agent outcomes are aggregated back into agent_run_configs[] input order regardless of completion order. The M=0 case (every per-agent dispatch failed) still emits Launched; Failure is reserved strictly for the pre-dispatch case where no CreateAgentTask was issued. Reject maps to OrchestrateActionResult::Cancelled, which converts to ConvertToAPITypeError::Ignore so nothing reaches the wire — the server's input interceptor synthesizes the generic ToolCallResult.Cancel marker on the next user input.

Spec sources (in the warp-server worktree):

  • specs/orchestration-tool/PRODUCT.md
  • specs/orchestration-tool/TECH.md

Commits:

  • 1f10c4d Scaffold orchestrate tool client plumbing
  • 10d46fb Phase A: action plumbing for orchestrate (AIAgentActionType::Orchestrate, OrchestrateActionResult, OrchestrateAgentOutcome)
  • 5d23e4d Phase B (skeleton): route OrchestrateAction to a render stub
  • e433a07 Phase B: wire OrchestrateConfigCard buttons
  • 2c177c3 Phase C: parallel Launch flow for OrchestrateExecutor
  • e3f8c1f Phase B backfill: interactive dropdowns, validation, auto-reset, in-flight state
  • 47d9bac Phase D: orchestrate tests + clippy fix

Testing

  • Added unit tests for OrchestrateActionResult → API conversion (Cancelled→Ignore, per-agent ordering preserved through Launched, LaunchDenied, Failure carrying error message) in crates/ai/src/agent/action_result/convert_tests.rs.
  • Added unit tests for compute_validation_errors (Local valid, Remote valid, Remote-without-env, OpenCode+Remote, both errors simultaneously) and display_label_for_option (known + unknown values fall back gracefully) in app/src/ai/blocklist/block/view_impl/orchestration_tests.rs.
  • cargo nextest run -p warp -p ai --lib — 3748 passed, 6 skipped.
  • cargo clippy --workspace --all-targets --all-features --tests -- -D warnings — clean.
  • cargo fmt --all -- --check — clean.

Pending: manual screen recordings (user task)

An agent cannot capture screen recordings. Please attach recordings of:

  1. All-succeed Launch flow against a local warp-server build
  2. Mid-batch failure (one or more children fail; outcome ordering preserved)
  3. Launch without orchestration (decision passes through; lead agent continues)
  4. Reject (Cancelled marker; nothing reaches the wire)
  5. Local ↔ Remote toggling with OpenCode auto-reset notice and Environment defaults
  6. Remote-without-environment failure path (Launch disabled, inline error visible)

Server API dependencies

This change wires up the existing OrchestrateAction / OrchestrateResult API on the client side; no new server API is introduced.

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Conversation: https://staging.warp.dev/conversation/c8ae6e3a-29db-4078-86d7-5fc7c60c0f7a

Co-Authored-By: Oz oz-agent@warp.dev

cephalonaut and others added 7 commits April 29, 2026 14:57
Foundational scaffolding for the new `orchestrate` client tool:

- Pin warp_multi_agent_api to the local warp-proto-apis worktree via a
  Cargo path override so the new `Orchestrate`, `OrchestrateAction`,
  `OrchestrateResult`, and `SupportsOrchestrate` symbols are available
  while the proto release is unpublished.
- Add the `OrchestrateTool` feature flag (in DOGFOOD_FLAGS).
- Advertise `RequestSettings.SupportsOrchestrate` to the server when the
  flag is on.
- Register `ToolType::Orchestrate` as the only spawn-related tool when
  both `orchestration_enabled` and `OrchestrateTool` are true; otherwise
  the existing v1/v2 `StartAgent` selection runs unchanged.
- Add minimal arms for `Tool::Orchestrate` and
  `ToolCallResultType::OrchestrateResult` in the conversation_yaml
  serializer (used by conversation search) and the helper.rs tool-name
  table so the existing matches stay exhaustive.
- Stub `OrchestrateResult` and `Tool::Orchestrate` arms in
  convert_conversation so that legacy AIAgentInput conversion does not
  attempt to synthesize results for orchestrate calls. The actual replay
  path will be fleshed out alongside the OrchestrateConfigCard and
  AIAgentActionType::Orchestrate work in follow-up commits.

This commit does not yet introduce the OrchestrateConfigCard component,
the AIAgentActionType::Orchestrate variant, or the parallel
CreateAgentTask / OrchestrateResult emission paths — those are the
substantive UI and action-plumbing pieces that follow.

Refs QUALITY-569.

Co-Authored-By: Oz <oz-agent@warp.dev>
Adds the AIAgentActionType::Orchestrate variant and
OrchestrateActionResult conversion path so that the orchestrate tool
call can flow through the existing action / action-result pipeline.

* New `AIAgentActionType::Orchestrate { tool_call_id, summary,
  model_id, harness, execution_mode, skills, agents }` variant in
  `crates/ai/src/agent/action/mod.rs` with Display, cancelled_result,
  user_friendly_name, and exhaustive match coverage at all call sites.
* New `OrchestrateExecutionMode` (Local / Remote { environment_id })
  and `OrchestrateAgentRunConfig { name, prompt }` helpers; the
  `action_result` module re-exports `OrchestrateExecutionMode` from
  `action` so the two modules share one definition under the app's
  glob re-exports.
* New `OrchestrateActionResult { Launched | LaunchDenied | Failure |
  Cancelled }` enum in `crates/ai/src/agent/action_result/mod.rs`
  with Display, plus `OrchestrateAgentOutcome` / `OrchestrateAgentOutcomeEntry`
  for the per-agent outcome list.
* `TryFrom<OrchestrateActionResult> for tool_call_result::Result` in
  `action_result/convert.rs`. Launched / LaunchDenied / Failure map
  to the corresponding `OrchestrateResult` proto outcomes; Cancelled
  returns `ConvertToAPITypeError::Ignore` (matching the pattern
  ReadFiles / Grep / etc. use), so that Reject does NOT emit a result
  on the wire — the server-side input interceptor's
  `cancelledResultsForIncompleteToolCallsInLastResponse` path
  synthesizes the generic `Message_ToolCallResult.Cancel` marker on
  the next user input. No orchestrate-specific cancellation variant is
  introduced, per spec.
* `Tool::Orchestrate -> AIAgentActionType::Orchestrate` decoder in
  `convert_from.rs` that reconstructs the resolved per-child prompt
  (`base_prompt + "\n\n" + agent.prompt`) when restoring a
  conversation from the raw tool-call shape.
* `AIAgentActionResultType::Orchestrate(...)` arm wired through
  `convert_to.rs` so the new result type round-trips into
  `request::input::ToolCallResult`.
* Stub Orchestrate arms in eight other exhaustive match sites in the
  app (redaction, agent_sdk text/json formatters, action executor's
  preprocess / try_to_execute / should_autoexecute, persistence) so
  the workspace builds. Each arm carries a comment explaining that
  Phase B / C will replace the stub with the real OrchestrateConfigCard
  flow.

`cargo check -p ai -p warp` passes; `cargo fmt` clean.

Refs QUALITY-569.

Co-Authored-By: Oz <oz-agent@warp.dev>
… stub

Wires the routing of `AIAgentActionType::Orchestrate` through the
existing tool-call card pipeline so that an orchestrate tool call now
renders its own card in the conversation. Phase B skeleton only —
the full interactive card (Model / Harness / Execution mode /
Environment dropdowns, three terminal buttons, six post-action
states with M=0 partial-failure handling, inline validation messages)
is left as the phase-B follow-up TODO documented inline.

* Adds the dispatch arm in
  `app/src/ai/blocklist/block/view_impl/output.rs` so that an
  orchestrate action with the `OrchestrateTool` feature flag enabled
  is routed to the new `orchestration::render_orchestrate_config_card`.
* Adds `render_orchestrate_config_card` in
  `app/src/ai/blocklist/block/view_impl/orchestration.rs` next to
  `render_start_agent`. The skeleton:
  * surfaces the resolved run-wide config (model, harness, execution
    mode with environment_id when remote) and the per-agent name list
    in the body so the routing is observable end-to-end against a
    local server build,
  * handles the post-action terminal states for the
    `OrchestrateActionResult` (`Launched` with full and partial
    success — including the M=0 case rendered under "Started 0 of N"
    per spec — `LaunchDenied`, `Failure`, and `Cancelled`),
  * uses the same status-row visual language as
    `render_start_agent` so the post-action card stays in
    conversation history with appropriate icons.

The skeleton intentionally does NOT implement the interactive parts:
no Model / Harness / Execution mode / Environment dropdowns, no
inline validation gating, no Launch / Launch without orchestration /
Reject buttons, and no parallel `CreateAgentTask` flow. Those are
the substantive Phase B follow-up + Phase C deliverables.

`cargo check -p warp` clean.

Refs QUALITY-569.

Co-Authored-By: Oz <oz-agent@warp.dev>
Adds OrchestrateExecutor, the AIBlockAction::OrchestrateActionDecision

variant + handler, and the three terminal buttons (Reject / Launch

without orchestration / Launch) inside render_orchestrate_config_card.

Reject and LaunchWithoutOrchestration are fully functional. Launch

currently resolves with an empty agents slice (M=0 placeholder per

PRODUCT.md); Phase C will expand this into N parallel CreateAgentTask

calls.

Co-Authored-By: Oz <oz-agent@warp.dev>
Implements the parallel CreateAgentTask dispatch path for the orchestrate
tool action. The OrchestrateExecutor now subscribes to BlocklistAIHistoryModel
events, tracks per-agent slots through Pending -> InFlight -> resolved
states, and aggregates Launched/Failed outcomes in the input order of
agent_run_configs[] regardless of completion order.

- Pre-dispatch validation (zero agents, Remote without env, Remote+OpenCode,
  OrchestrationV2 disabled, missing parent_run_id) emits Failure.
- Mid-batch failures and the M=0 all-fail case both emit Launched with
  per-agent outcomes preserved in input order.
- TerminalView re-emits each StartAgentRequest in the CreateAgentBatch as
  Event::StartAgentConversation so the workspace can spawn child panes.

Co-Authored-By: Oz <oz-agent@warp.dev>
…-reset, in-flight state

Replaces the static OrchestrateConfigCard skeleton with the four spec-required
behaviors that block the draft PR per the lead agent:

1. Interactive Model / Harness / Execution-mode / Environment dropdowns
   (TECH.md §6). Click the dropdown header to expand an inline option list;
   selecting an option closes the dropdown and updates the per-action
   OrchestrateConfigSelections state.
2. Inline validation messages above the buttons (TECH.md §6):
   "Choose an environment before launching." when Remote without env, and
   "OpenCode is not supported in remote mode." when the LLM directly proposes
   the OpenCode + Remote combination. Launch is rendered in a disabled
   visual treatment when validation errors are active.
3. OpenCode→Oz auto-reset on Local→Remote toggle with notice (TECH.md
   Risks). The OrchestrateSelectExecutionMode handler resets harness to
   `oz` when toggling Local→Remote with harness=opencode, and the card
   renders a dismissible inline notice explaining the reset.
4. "Launching N agents…" in-flight transitional state (PRODUCT.md
   §post-action). When the action moves to RunningAsync, the dropdowns
   become read-only and the buttons are removed; the body shows the
   in-flight status line.

State plumbing:
- New OrchestrateConfigSelections + OrchestrateConfigDropdown +
  OrchestrateDropdownHandles in AIBlockStateHandles, seeded from the
  LLM-proposed action values when the Orchestrate action is first
  observed in handle_updated_output.
- New AIBlockAction variants: OrchestrateToggleDropdown,
  OrchestrateSelect{Model,Harness,ExecutionMode,Environment},
  OrchestrateDismissOpenCodeNotice, OrchestrateLaunchClicked. Each is
  handled in TypedActionView::handle_action with ctx.notify().
- Launch click dispatches OrchestrateLaunchClicked (the prior closure
  could not read state at render time); the handler reads
  OrchestrateConfigSelections, builds the resolved
  OrchestrateDecision::Launch payload, and forwards it to
  OrchestrateExecutor::submit_decision.
- Environment options are sourced from
  CloudAmbientAgentEnvironment::get_all so the dropdown reflects the
  user's available cloud environments.

Co-Authored-By: Oz <oz-agent@warp.dev>
Add unit tests covering:
- OrchestrateActionResult::Cancelled -> ConvertToAPITypeError::Ignore
- Per-agent outcome ordering preserved through Launched conversion
- LaunchDenied + Failure conversions
- compute_validation_errors: Local valid / Remote valid / Remote-without-env /
  OpenCode+Remote / both errors simultaneously
- display_label_for_option: known + unknown values fall back gracefully

Fixes clippy too_many_arguments warning on dispatch_launch with #[allow]
since all 7 args are necessary state for the Launch dispatch path.

Co-Authored-By: Oz <oz-agent@warp.dev>
@cla-bot cla-bot Bot added the cla-signed label Apr 29, 2026
@cephalonaut
Copy link
Copy Markdown
Contributor Author

Superseded by rewrite on matthew/orchestration-tool-2. The architecture (parallel ClientAction.OrchestrateAction and the inline-dropdown card layout) and confirmation-card UX from this PR are being redone against an updated unified PRODUCT.md / TECH.md spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant