Repository navigation
Send scheduled automation prompts to agents that read them after they start - #26703
Conversation
Review and QA summaryProblem. When the Orca server ran a scheduled or "Run now" automation on an existing workspace, agents that take their task after they start (Aider, Goose, Amp, Kiro, Crush, Cline, Claude agent teams and about 17 others) launched but never received the prompt. They sat idle and the run did nothing. The bug predates this PR: it comes from how the server's existing-workspace launch was built (#5071, reshaped in #17605 and #17919). Agents that take the prompt on their command line (Claude, Codex) were never affected. User-facing change. Those agents now receive the automation's prompt once they start, exactly like automations that create a new workspace for each run. What was fixed. The existing-workspace launch now hands the agent's start-up prompt to the same writer that new-workspace runs already use, and adds no new writer. There is a regression test for an agent that takes its prompt after start (fails on main) and one for an agent that takes it on the command line (no extra prompt). Review. Two independent reviewers covered:
A release-readiness checklist also ran. None found a problem caused by this PR. Deferred: older limits of the shared prompt writer. These already affect new-workspace runs, are not changed here, and are planned to go away when server automations move onto the shared agent launcher.
Verified.
Not verified. A live SSH workspace, Windows/WSL hosts, real agent programs (only stand-ins were used), and the other agents of this kind individually. |
📝 WalkthroughWalkthrough
Priority: ➖ Normal Merge Risk: 🔵 Low · up to A slow-starting agent can leave a scheduled run without its prompt. This is a bounded failure, but the follow-up should be preserved or retried. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
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.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
dc0d72a8-3f4b-435e-bb87-f1e9e3e05880
📒 Files selected for processing (2)
src/main/runtime/launch-agent-terminal-followup.test.tssrc/main/runtime/orca-runtime-terminal-create-deduplication.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.
| // Why: agents that read the prompt after they start get it typed in, not on argv. | ||
| if (startup.followup) { | ||
| this.sendStartupFollowupWhenReady(terminal.handle, startup.followup) | ||
| } | ||
| return terminal |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
rg -n 'sendWorktreeStartupFollowupWhenReady|StartupFollowupWhenReady|startup\.followup|followup:' src/main/runtime src/main/automations
sed -n '135,190p' src/main/runtime/orca-runtime-terminal-create-deduplication.ts
sed -n '65,95p' src/main/automations/runtime-automation-service.tsRepository: stablyai/orca
Length of output: 6440
🏁 Script executed:
set -eu
printf '%s\n' '--- readiness helper ---'
nl -ba src/main/runtime/runtime-worktree-startup-readiness.ts | sed -n '1,180p'
printf '%s\n' '--- readiness host and delegator ---'
nl -ba src/main/runtime/orca-runtime-activate-managed-worktree.ts | sed -n '270,305p'
rg -n -F --glob '*.ts' -- 'getWorktreeStartupReadinessHost' src/main/runtime
printf '%s\n' '--- startup follow-up construction ---'
nl -ba src/main/runtime/runtime-worktree-agent-startup.ts | sed -n '150,225p'
printf '%s\n' '--- existing-workspace automation caller ---'
nl -ba src/main/automations/runtime-automation-service.ts | sed -n '1,145p'
printf '%s\n' '--- automation service entrypoints and configuration uses ---'
rg -n -F --glob '*.ts' -- 'runAutomation|schedule|workspaceId|automation.prompt|automation.agentId' src/main/automations src/main | head -160Repository: stablyai/orca
Length of output: 21300
🏁 Script executed:
set -eu
printf '%s\n' '--- dispatcher contract and invocation ---'
rg -n -F --glob '*.ts' -- 'headlessDispatcher' src/main src/shared
rg -n -F --glob '*.ts' -- 'workspaceMode' src/main/automations src/shared | head -120
printf '%s\n' '--- automation run dispatch path ---'
rg -n -E --glob '*.ts' 'dispatch|dispatcher|headless' src/main/automations/service.ts src/main/automations
printf '%s\n' '--- follow-up-producing startup plans/config ---'
rg -n -E --glob '*.ts' 'followupPrompt|expectedProcess|promptCandidate|onPromptCarry' src/main src/shared | head -160Repository: stablyai/orca
Length of output: 9888
🏁 Script executed:
set -eu
printf '%s\n' '--- dispatch request ---'
nl -ba src/main/automations/automation-dispatch-request.ts | sed -n '1,180p'
printf '%s\n' '--- service dispatch call site ---'
nl -ba src/main/automations/service.ts | sed -n '260,340p'
printf '%s\n' '--- startup plan follow-up references ---'
rg -n -F --glob '*.ts' -- 'followupPrompt' src/main src/shared
printf '%s\n' '--- startup plan definitions around follow-up branches ---'
rg -n -F --glob '*.ts' -- 'buildAgentStartupPlan' src/main src/sharedRepository: stablyai/orca
Length of output: 26225
🏁 Script executed:
set -eu
nl -ba src/shared/tui-agent-startup.ts | sed -n '35,200p'Repository: stablyai/orca
Length of output: 7137
Preserve the follow-up when readiness polling expires.
waitForWorktreeStartupFollowup stops after 30 polls with 150 ms delays. If the expected process is still not visible, it returns null. sendWorktreeStartupFollowupWhenReady then only logs a warning and discards followup.prompt.
A scheduled headless automation for an existing workspace reaches this helper through runtime.launchAgentTerminal. The terminal launch returns without waiting for the detached writer. Therefore, a slow agent startup can leave the run with a started terminal but without its prompt. Retry or retain the follow-up after the readiness wait expires.
ELI5
When Orca's server runs a scheduled automation in a workspace that already exists, some agents start up but never receive the task. They sit idle, and the run waits for work that was never handed over. This change types the task into those agents once they are ready, the same way Orca already does when the automation creates a new workspace for each run.
What Changed
Problem. A scheduled automation can run in an existing workspace or create a new workspace per run. When the Orca server (not the desktop window) runs it in an existing workspace, it starts the agent's terminal but never sends the automation's prompt to agents whose command line takes no prompt and expect it to be typed in after they start. That covers about two dozen configured agents, including Aider, Goose, Amp, Kiro, Crush, Cline and Claude agent teams. Agents that take the prompt on their command line, such as Claude and Codex, were never affected.
User-facing change. For those agents, a scheduled run on an existing workspace now actually performs its task: the prompt is typed into the agent once it is ready, instead of the agent starting idle. Nothing changes for Claude, Codex or the other agents that take the prompt on the command line, for automations that create a new workspace per run, or for automations the desktop app runs itself.
Mechanism. The host's
launchAgentTerminal(used only by the server's automation runner, for the existing-workspace case) builds the agent's startup plan. For a type-it-in-after-start agent, that plan returns a bare launch command plus a separate follow-up prompt. The function used the command and dropped the follow-up. It now hands the follow-up to the existingsendStartupFollowupWhenReadywriter, which waits until the agent is running and then types the prompt. That is the same writer and readiness wait the new-workspace-per-run branch already uses (runtime-local-worktree-terminal-startup.ts). No new writer was added.Why
This approach reuses the delivery path the sibling branch already relies on, so both workspace modes now treat these agents the same way.
Alternatives considered:
Where it came from. The bug predates recent changes.
launchAgentTerminalwas added in #5071. Its current form, which builds the startup plan and passes only the command tocreateTerminal, comes from the runtime split in #17605 and the execution-host routing in #17919. The recentextraAgentArgspassthrough only forwards extra arguments and did not cause the bug.Linked Issue
None (maintainer fix).
Visual Proof
Not a UI change, so the proof is a stand-in agent's own log. Orca ran in server mode on an isolated, hidden laptop profile, with an automation on an existing workspace using
aider. A stand-in program took aider's place and loggedSTARTwhen launched andLINEfor every line typed into it.Before (main): the agent starts and never gets the prompt.
After (this PR): each run's prompt arrives exactly once, right after the agent starts.
Testing
New
src/main/runtime/launch-agent-terminal-followup.test.tsuses the real startup builder:agent-terminal-launch-host.test.tsandruntime-automation-service.test.tsstill pass.pnpm tc:nodepasses, as do oxlint and the changed-files code-quality check.Manual check (macOS laptop, hidden isolated profile, stand-in agents only): main and this PR, each in server mode, ran three automations on an existing workspace:
Not checked live: an SSH workspace, Windows/WSL, real agent programs, and the other agents that take their prompt after start.
I manually tested these changes locally
Automated tests added/updated, or explained why not below
Review
Reviewed by two independent reviewers (one on the change itself, one on the run lifecycle and SSH/WSL/Windows hosts), plus a release-readiness checklist. None of them found a problem caused by this change. Older limits of the shared writer are listed in the review comment.
Agent skill upstream boundary
Notes
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)