Description
Part of the Oz cloud-agent startup latency work (workstream C3). worker_container_ready -> shared_session_started is a near-constant ~2.9s for every run of every harness. It is a chain of server round trips in AgentDriverRunner::setup_and_run_driver that were awaited one after another even though most of them only need the task id and the workload token. This PR issues the independent ones together.
Dependency map of the chain (cloud --task-id --execution-id launch)
Serial before this PR, in order:
set_ambient_agent_task_id(local)worker_container_readytimeline POST (1 RTT, telemetry only)issue_workload_token+ExecutionBootstrapGraphQL (1 RTT with retry) — needs task id, execution id, workload tokenrefresh_team_metadata(1 RTT, up to 30s retry budget) — needs auth only- Warp Drive wait — waits for the initial load that began at login; no request of its own
build_driver_options_and_task, which starts withbootstrap_git_credentials_for_task(issue_workload_token+TaskGitCredentialsGraphQL, 1 RTT) — needs task id, workload token, anduse_factory_repositories, which is computed locally from the task id, theFactoryDeferredRepositoriescapability, andWARP_FACTORY_ID- then skill repo clones (need git credentials),
build_execution_task_and_options, attachment downloads (need the bootstrap's attachment list), cloud provider load AgentDriver::createspawns the PTY;run()PATCHesInProgress(already overlapping the shell bootstrap);run_internalwaits for bootstrap, then the session-sharing handshake.
What now runs concurrently
Steps 2, 3, 4, and 6a are issued with one try_join!:
- the
ExecutionBootstrapfetch, - the git credentials bootstrap (hoisted out of
build_driver_options_and_task; it ran there only because that was the first place withuse_factory_repositories, which is now captured once up front asRepositoryContract::for_taskand passed to both the fetch and the credentials call, preserving the "capability captured at launch" guarantee the existing subprocess test checks), - the team metadata refresh,
- the
worker_container_readyPOST.
None of the four reads anything another one produces: the bootstrap and git credentials each issue their own workload token (a local read on the self-hosted worker), the team refresh only needs auth, and the timeline POST is fire-and-record. try_join! keeps today's failure semantics in the single-failure case: a fast bootstrap failure still surfaces as ConfigBuildFailed without waiting for the team refresh's retry budget, and a team refresh timeout still surfaces as TeamMetadataRefreshFailed (the existing paused-time test for that path still passes). Dropping the team refresh future on another future's error stops its retries, which dropping_cloud_startup_metadata_refresh_stops_retries already covers.
Expected effect: three round trips removed from the critical path (container-ready POST, team refresh, git credentials), i.e. roughly half of the ~6 serialized round trips in this phase, for every harness.
What stays serial, and why
- Warp Drive wait stays after the join and the team-scope resolution. It waits on a load that started at login, so there is no round trip to overlap; joining it would also make the legacy launch path touch
UpdateManagerbefore the team refresh resolves, which the paused-time test does not register. - Team scope resolution (legacy path) reads
UserWorkspaces, so it needs the team refresh. - Skill repo clones need the git credentials; attachment downloads need the bootstrap's attachment list; both stay inside
build_driver_options_and_taskafter the join. InProgressPATCH mutates server state and already overlaps the shell bootstrap (the PTY spawn starts inAgentDriver::create, beforerun()issues the PATCH). Unchanged.- PTY spawn was not moved earlier. The shell's environment must be complete at spawn (secrets, cloud-provider variables, task variables, the deferred-repository policy file), and that is only known after the bootstrap fetch,
build_execution_task_and_options,prepare_execution_task_data, andload_providers. The only remaining pre-spawn work after that point is the attachment/handoff fetch, Bedrock credential minting (which feeds the environment), and resume loading. Overlapping the spawn with those would require splittingAgentDriver::createso the terminal is created before options are final and then re-spawned or re-exported into, which is what the standby path does withreplace_shell_with_resolved_envat the cost of a second shell spawn. Not worth it for one round trip here; noted as a follow-up if the handoff fetch shows up in the A1 breakdown.
Setup events
Two new, run-scoped events make the join measurable: setup_execution_bootstrap_fetch and setup_git_credentials_bootstrap. Neither call was instrumented before. No existing names were changed; setup_team_metadata_refresh and setup_warp_drive_sync keep their meaning. The server does not allowlist setup-metric names, so nothing needs to land first.
Linked Issue
- The linked issue is labeled
ready-to-specorready-to-implement. - Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes).
Testing
cargo check -p warp --tests— clean, no warningscargo nextest run -p warp -E 'test(/agent_sdk::tests/) | test(/agent_sdk::setup_observability/) | test(/agent_sdk::driver::prewarmed/)'— 56 passed, 0 failed, includinglegacy_execution_launch_skips_bootstrap_and_reports_team_metadata_refresh_failure(team refresh timeout still reported after 30s with the join) andpaired_execution_keeps_captured_capability_after_runtime_flag_changes(the capability captured before the bootstrap still governs the git credentials request and the options build)cargo clippy -p warp --all-targets --tests -- -D warnings— cleancargo fmt -p warpwith the repo's import config
Test changes: the subprocess bootstrap test now builds RepositoryContract::for_task itself and calls bootstrap_git_credentials_for_task explicitly, mirroring the new call structure; the legacy launch test's client-event expectation widened from 1..=2 to 1..=3 for the new git-credentials setup metric, which posts from the background and may or may not land before exit.
Not done: an end-to-end timing comparison against a local or staging Oz stack. Recommend comparing worker_container_ready -> shared_session_started on staging before/after, using the two new setup events to confirm the fetches overlap.
- I have manually tested my changes locally with
./script/run
Agent Mode
- Warp Agent Mode - This PR was created via Warp's AI Agent Mode
CHANGELOG-OZ: Cloud agent runs fetch their configuration, git credentials, and team metadata concurrently at startup instead of one after another.
Activity
1This pull request is a draft
Merging is unavailable until it is marked ready for review.