[QUALITY-569] Orchestrate tool client implementation#9490
Closed
cephalonaut wants to merge 7 commits intomasterfrom
Closed
[QUALITY-569] Orchestrate tool client implementation#9490cephalonaut wants to merge 7 commits intomasterfrom
cephalonaut wants to merge 7 commits intomasterfrom
Conversation
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>
Contributor
Author
|
Superseded by rewrite on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Client-side implementation of the
orchestratetool call (Linear: QUALITY-569).When the LLM emits an
orchestratetool call, the client now renders anOrchestrateConfigCardwith:Launch dispatches N parallel
CreateAgentTasks through the existingStartAgentExecutorpath. Per-agent outcomes are aggregated back intoagent_run_configs[]input order regardless of completion order. The M=0 case (every per-agent dispatch failed) still emitsLaunched;Failureis reserved strictly for the pre-dispatch case where noCreateAgentTaskwas issued. Reject maps toOrchestrateActionResult::Cancelled, which converts toConvertToAPITypeError::Ignoreso nothing reaches the wire — the server's input interceptor synthesizes the genericToolCallResult.Cancelmarker on the next user input.Spec sources (in the warp-server worktree):
specs/orchestration-tool/PRODUCT.mdspecs/orchestration-tool/TECH.mdCommits:
1f10c4dScaffold orchestrate tool client plumbing10d46fbPhase A: action plumbing for orchestrate (AIAgentActionType::Orchestrate,OrchestrateActionResult,OrchestrateAgentOutcome)5d23e4dPhase B (skeleton): routeOrchestrateActionto a render stube433a07Phase B: wire OrchestrateConfigCard buttons2c177c3Phase C: parallel Launch flow forOrchestrateExecutore3f8c1fPhase B backfill: interactive dropdowns, validation, auto-reset, in-flight state47d9bacPhase D: orchestrate tests + clippy fixTesting
OrchestrateActionResult→ API conversion (Cancelled→Ignore, per-agent ordering preserved through Launched, LaunchDenied, Failure carrying error message) incrates/ai/src/agent/action_result/convert_tests.rs.compute_validation_errors(Local valid, Remote valid, Remote-without-env, OpenCode+Remote, both errors simultaneously) anddisplay_label_for_option(known + unknown values fall back gracefully) inapp/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:
Server API dependencies
This change wires up the existing
OrchestrateAction/OrchestrateResultAPI on the client side; no new server API is introduced.Agent Mode
Conversation: https://staging.warp.dev/conversation/c8ae6e3a-29db-4078-86d7-5fc7c60c0f7a
Co-Authored-By: Oz oz-agent@warp.dev