Repository navigation
Start server-run automations' agents through the launch executor - #26820
Conversation
Server-run automations, both the new-workspace and existing-workspace runs, now start their agent through executeAgentLaunch as a terminal-only launch with automation-owned factories. argv agents keep the prompt folded into their command; agents that read the prompt after start get it from the executor's own terminal writer once their composer is ready. The run is recorded as soon as the terminal exists, as before.
… starts out of run completion - Headless automations pass the write guard's write-unless-shell policy, as worker briefs do, so a host that cannot find the agent in front (Windows) still gets the prompt; only a proven shell refuses. agent.launch keeps refusing by default. - judgeIdleRun ignores session-boundary status rows: a SessionStart row lands before the prompt and must not settle the run completed. - A launch failure after the terminal was published is logged instead of dropped.
…iter QA found the executor's composer-readiness writer drops the prompt of a slow-starting post-start agent (aider): it watches the input-box signal only ~8 s, then tui-idle, which those agents never satisfy. Main's follow-up writer (wait for the agent process, type the prompt) delivered it. - Extract the follow-up writer into an awaitable deliverWorktreeStartupFollowup (same waits, write and log lines); sendWorktreeStartupFollowupWhenReady wraps it. The runtime exposes it as deliverStartupFollowup, and the headless launch's deliverTerminalPrompt uses it, so the executor still sequences the launch with main's delivery. - Revert the round-1 write-guard option and the judgeIdleRun session-boundary rule, which existed only because of the executor's writer.
Review and QA summary (head 9c7be59)The problem. When Orca runs as a server, scheduled automations started their agent through their own two code paths, a new-workspace path and an existing-workspace path, instead of through the shared launch executor that every other fresh launch uses. That meant one more place where the order of launch steps had to be kept in sync by hand. What changes for the user: nothing. Automations now start their agent through the executor. The tab title, background behaviour, prompt bytes, when the run is recorded, completion detection and run records are the same as on main. ReviewThree review rounds ran, plus an independent architecture check and a pre-release checklist.
QARun on hidden laptop test servers (serve mode) with stand-in agents, main vs this PR. The driver was opencode.
Checks
|
📝 WalkthroughWalkthroughThe runtime automation service now delegates headless launches to a new launcher that handles existing and new-per-run workspaces. The launcher trims prompts, starts agent terminals, and delivers post-start prompts through an awaited startup follow-up. The readiness helper reports whether delivery succeeded. Tests cover launch modes, prompt handling, missing workspaces, and startup failures. Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to Server-run automations now launch through the shared executor with their prompt delivery unchanged. No concrete defect was found in this change. SSH and Windows hosts were not verified by the author. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/main/automations/headless-automation-agent-launch.ts (1)
148-163: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winSettle the promise when the executor resolves without publishing a surface.
launchUntilPublishedresolves only fromonSurfacePublished. It rejects only from.catch. SupposeexecuteAgentLaunchresolves normally but never callsonSurfacePublished. The returned promise then stays pending. The headless dispatcher then waits indefinitely, and the run never reaches the "did not report its terminal" error on Line 128. The visible executor paths currently publish before they return, so this case cannot happen today. However, nothing in the type contract enforces that ordering. To guard against a future executor branch, add a.thenthat resolves or rejects when the launch did not publish.Proposed fix
- }).catch((error: unknown) => { + }).then( + (result) => { + if (!published) { + reject(new Error('Automation agent launch did not report its terminal.')) + } + return result + } + ).catch((error: unknown) => {
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
f238d6f8-1575-4e16-91be-0c41d4a1fa1c
📒 Files selected for processing (11)
src/main/agent-launch/agent-launch-executor.tssrc/main/agent-launch/agent-launch-legacy-host.tssrc/main/agent-launch/startup-agent-worktree-create.tssrc/main/automations/headless-automation-agent-launch.test.tssrc/main/automations/headless-automation-agent-launch.tssrc/main/automations/runtime-automation-service.test.tssrc/main/automations/runtime-automation-service.tssrc/main/runtime/launch-agent-terminal-followup.test.tssrc/main/runtime/orca-runtime-activate-managed-worktree.tssrc/main/runtime/runtime-worktree-startup-readiness.test.tssrc/main/runtime/runtime-worktree-startup-readiness.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
Rebase adaptation for upstream stablyai#26820: WorktreeStartupFollowup now carries the TUI agent (used to pick the composer-ready signal and the submit settle delay), so the headless automation's deliverTerminalPrompt passes it and the launch tests assert the full call shape. Generated-by: GLM-5.3-Flash (ZCode)
ELI5
When Orca runs as a server, it runs your scheduled automations itself. It starts the agent you picked, either in a fresh workspace made for that run or in an existing workspace, and gives it the automation's prompt. Orca has one shared host operation that starts agents (the launch executor), but server-run automations still started their agent their own way, beside it. This PR sends them through the executor too. Nothing you see changes.
What Changed
The problem. A server-run automation started its agent through two separate code paths. A new-workspace run created the workspace with the agent already in it. An existing-workspace run called a dedicated terminal launcher. Neither went through the launch executor that the other fresh launches (
agent.launch,worktree.create, orchestration workers) now use, so the order of steps in a launch had to be kept in step by hand in one more place.What is different for the user: nothing, by design.
The mechanism.
launchHeadlessAutomationAgentrunsexecuteAgentLaunchfor both kinds of run as a terminal-only launch (the input Start worktree.create's agent through the launch executor #26709 added). Automations detect completion from the terminal, so the chat default never applies.deliverWorktreeStartupFollowup), and the existing fire-and-forget call wraps it, so there is one writer, not two.Why
This is phase 1b, step 2 of moving every fresh agent start onto one executor. After it, only launches from the desktop window (later steps) start fresh agents outside it.
Why main's prompt writer and not the executor's own: the first version of this PR used the executor's writer for agents that read the prompt after start. That writer waits for the agent's input box, sends a multi-line prompt as one paste, and keeps waiting past the old writer's roughly 4.5 s limit. Testing showed it gives up on an agent whose input box appears more than about 8 seconds after start. Main delivers in that case, because it types early and the terminal holds the text until the agent reads it. So this PR keeps main's writer exactly. Making the executor's writer handle slow starts is a separate follow-up, because it also changes phone and CLI launches.
Labeled differences:
Linked Issue
Maintainer change, part of the launch-unification work (no separate issue). Follows #26703, #26709 and #26724.
Visual Proof
No visual change by design. Server-run automations have no window of their own. This is a hidden desktop app paired to a hidden test server with stand-in agents, before (main) and after (this PR), around a "new workspace per run" automation run. In both, the run's workspace appears in the sidebar with background activity, and the desktop stays on its start screen without switching workspace. These shots were taken on the PR's earlier head, 74bb7a7. Its later change touched only how a post-start prompt is typed, which these screens don't show.
The prompt evidence is text from the stand-in agents' logs (see the review comment). For each row it shows the bytes received and the number of submits, which were identical between main and this PR.
Testing
headless-automation-agent-launch.test.ts. For each kind of run it checks:deliverWorktreeStartupFollowupwrites once when the agent is in front, and writes nothing when it never appears.launchAgentTerminalwith an empty prompt sends no follow-up.runtime-automation-service.test.ts,runtime-automation-service-retention.test.ts,headless-workspace-create.test.ts,launch-agent-terminal-followup.test.ts,orcad-automations.test.ts.tc:nodetypecheck and CI static checks pass.Agent skill upstream boundary