Skip to content

fix(orchestration): settle agent TUI before worker-start inject - #13571

Open
bbingz wants to merge 2 commits into
stablyai:mainfrom
bbingz:fix/13488-worker-start-tui-idle-settle
Open

fix(orchestration): settle agent TUI before worker-start inject#13571
bbingz wants to merge 2 commits into
stablyai:mainfrom
bbingz:fix/13488-worker-start-tui-idle-settle

Conversation

@bbingz

@bbingz bbingz commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • worker-start --worktree new-child --agent waited for a single tui-idle then paste+Enter.
  • Claude can report idle during MCP/skills boot while the composer still ignores submit, so the task sat unsubmitted while the receipt claimed input_accepted.
  • For Orca-created agent terminals: settle after the first idle and re-wait for tui-idle before inject. External --terminal reuse is unchanged.
  • Scale paste→Enter delay with payload size so multi-KB preambles get enough render time (especially non-Windows).

Test plan

  • vitest agent-prompt-injection, worker-agent-readiness, workers-new-worktree
  • Manual: worker-start --worktree new-child --agent claude with a setup hook + MCP-heavy agent; receipt ready should mean the turn actually started

Fixes #13488

worker-start already waited for tui-idle, but Claude can report idle during
MCP boot before the composer accepts submit. Re-confirm idle after a short
settle for Orca-created agents, and scale the paste→Enter delay with payload
size so multi-KB preambles are not left unsubmitted.

Fixes stablyai#13488
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The runtime now calculates bracketed-paste submission delays from the platform and UTF-8 payload size, with a 5-second maximum. Worker orchestration now uses waitForWorkerAgentTuiReady. The helper performs an initial TUI idle wait and, for Orca-created agents, a settle delay followed by a second idle confirmation. Tests cover delay scaling and readiness behavior.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the bug and tests but omits the required Screenshots, AI Review Report, Security Audit, and Notes sections. Add all required template sections, including no-visual-change confirmation, completed testing status, cross-platform AI review, and security audit details.
Linked Issues check ⚠️ Warning The PR adds readiness reconfirmation and timeout handling, but it does not show receipt semantics requiring an observed turn or retry-only submission behavior [#13488]. Ensure success requires evidence that the turn started, preserve pending state on timeout, and retry only submission when the prompt is already in the composer.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary change: settling the agent TUI before injecting work.
Out of Scope Changes check ✅ Passed The readiness helper, payload-size delay, and related tests directly support the linked issue and stated PR objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6db61997-37ef-4598-90dd-5aaba7eba433

📥 Commits

Reviewing files that changed from the base of the PR and between a63df91 and b4000ba.

📒 Files selected for processing (6)
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.test.ts
  • src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.ts
  • src/main/runtime/rpc/methods/orchestration-workers.ts
  • src/shared/agent-prompt-injection.test.ts
  • src/shared/agent-prompt-injection.ts

Comment thread src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.ts Outdated
stablyai#13488 preambles were ~8–10KB; bytes/20 still floored at 500ms on macOS.
Use bytes/5 so those pastes wait ~1.6–2s before Enter, and fail closed when
settle exhausts the caller readiness budget.

Addresses review on stablyai#13571

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1211524d-c4d9-49fb-95ce-57d2286f8143

📥 Commits

Reviewing files that changed from the base of the PR and between b4000ba and 703e3f4.

📒 Files selected for processing (4)
  • src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.test.ts
  • src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.ts
  • src/shared/agent-prompt-injection.test.ts
  • src/shared/agent-prompt-injection.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.ts
  • src/shared/agent-prompt-injection.ts
  • src/shared/agent-prompt-injection.test.ts

Comment on lines +93 to +107
vi.useFakeTimers()
vi.setSystemTime(0)

await expect(
waitForWorkerAgentTuiReady({
runtime: { waitForTerminal },
terminalHandle: 'term_worker',
timeoutMs: 1_000,
externalTerminal: false
})
).rejects.toThrow('timeout')

expect(waitForTerminal).toHaveBeenCalledTimes(1)
vi.useRealTimers()
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

rg -n "setTimeout|WORKER_AGENT_TUI_IDLE_SETTLE_MS|useFakeTimers|setSystemTime|runAllTimersAsync|advanceTimersToNextTimerAsync" src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.ts src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.test.ts

Repository: stablyai/orca

Length of output: 894


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file sizes =="
wc -l src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.ts src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.test.ts

echo
echo "== implementation outline and relevant lines =="
ast-grep outline src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.ts --view expanded || true
sed -n '1,130p' src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.ts

echo
echo "== test relevant lines =="
sed -n '1,140p' src/main/runtime/rpc/methods/orchestration-worker-agent-readiness.test.ts

echo
echo "== deterministic timer behavior probe for fake timers =="
node - <<'JS'
let timers = []
const fakeSetTimeout = (cb, delay) => { timers.push({ cb, delay: Number(delay) }) }
setTimeout = fakeSetTimeout

fakeSetTimeout(() => {} , 1000)
const afterSetSystemTime = timers.length
const resolvedWithoutAdvancing = timers.length === afterSetSystemTime
timers.forEach(t => t.cb())
const resolvedAfterAdvancing = afterSetSystemTime > 0 && timers.length === afterSetSystemTime
console.log(JSON.stringify({ afterSetSystemTime, resolvedWithoutAdvancing, resolvedAfterAdvancing }))
JS

Repository: stablyai/orca

Length of output: 5544


🌐 Web query:

Vitest vitest.dev API vi useFakeTimers setSystemTime runAllTimersAsync does setSystemTime run timers

💡 Result:

No, vi.setSystemTime does not run timers [1][2]. While vi.setSystemTime updates the system clock observed by date-related APIs (such as new Date, Date.now, performance.now, and hrtime), it does not trigger any timers scheduled via setTimeout or setInterval [1][3][2]. To execute timers in Vitest, you must use timer advancement methods such as: vi.runAllTimers or vi.runAllTimersAsync: These methods invoke all queued timers until the timer queue is empty [1][2]. vi.advanceTimersByTime(ms) or vi.advanceTimersByTimeAsync(ms): These advance the clock by a specified duration, triggering any timers that fall within that time window [4][3]. In summary, vi.setSystemTime is used to control time-based logic (like date formatting or expiration checks) [3][5], while timer execution is managed separately via the timer advancement API [5].

Citations:


Advance the fake settle timer before asserting the timeout.

Set mock time to 0 after the first waitForTerminal returns: set the second waitForTerminal timestamp past the budget, schedule it with a fake timer, advance with await vi.runAllTimersAsync(), then assert rejects.toThrow('timeout'). Restore real timers in finally so assertion failures do not leave fake timers enabled.

@AmethystLiang
AmethystLiang requested a review from OrcaWin August 10, 2026 18:10
@AmethystLiang AmethystLiang added the P1 High priority: bug or day-to-day user frustration label Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P1 High priority: bug or day-to-day user frustration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: worker-start --worktree new-child --agent injects the task before the agent TUI is ready, and settles it as success

3 participants