Skip to content

fix(followup): route CLI runtime drains through CLI runner (#82847)#82857

Merged
steipete merged 2 commits into
openclaw:mainfrom
hclsys:fix-followup-cli-runtime-82847
May 17, 2026
Merged

fix(followup): route CLI runtime drains through CLI runner (#82847)#82857
steipete merged 2 commits into
openclaw:mainfrom
hclsys:fix-followup-cli-runtime-82847

Conversation

@hclsys

@hclsys hclsys commented May 17, 2026

Copy link
Copy Markdown

Summary

Fixes #82847.

Queued followup drains now mirror the primary reply path's runtime split:

  • resolve the configured CLI runtime for the selected provider/model
  • route CLI-backed followup attempts through runCliAgent
  • keep the existing runEmbeddedPiAgent path for embedded/runtime-default attempts
  • preserve existing followup delivery, session usage persistence, and model fallback handling

Why

The followup queue previously always called runEmbeddedPiAgent. For sessions whose selected model maps to a CLI runtime such as claude-cli, that can pass the CLI runtime id into embedded harness selection and fail with Requested agent harness "claude-cli" is not registered.

Real behavior proof

  • Behavior or issue addressed: A queued followup for an Anthropic model configured with agentRuntime.id = "claude-cli" must dispatch to the CLI backend instead of the embedded Pi harness selector.
  • Real environment tested: Local OpenClaw checkout at PR head 29ce366db53fd0714a2d29c07a1469677a3bf128 on Linux, Node runtime from the repo toolchain, using the real runtime-selection helpers imported through tsx.
  • Exact steps or command run after this patch:
$ node --import tsx -e "import { resolveCliRuntimeExecutionProvider } from './src/agents/model-runtime-aliases.ts'; import { isCliProvider } from './src/agents/model-selection-cli.ts'; const cfg={agents:{defaults:{cliBackends:{'claude-cli':{command:'claude'}},models:{'anthropic/claude-opus-4-7':{agentRuntime:{id:'claude-cli'}}}}}}; const provider=resolveCliRuntimeExecutionProvider({provider:'anthropic',modelId:'claude-opus-4-7',cfg}); console.log(JSON.stringify({provider,isCli:isCliProvider(provider??'',cfg)}));"
  • Evidence after fix: Copied terminal output from the command above:
{"provider":"claude-cli","isCli":true}

The focused followup-runner regression then exercises that same selected CLI provider through a queued followup and asserts runCliAgent is called while runEmbeddedPiAgent is not called.

$ node scripts/run-vitest.mjs src/auto-reply/reply/followup-runner.test.ts

Test Files  1 passed (1)
Tests       36 passed (36)
Start at    11:06:53
Duration    5.29s (transform 2.00s, setup 114ms, import 263ms, tests 4.82s, environment 0ms)
  • Observed result after fix: The runtime-selection probe resolves the queued followup's canonical anthropic/claude-opus-4-7 selection to claude-cli, and the regression test confirms the followup runner now dispatches that case through runCliAgent instead of embedded harness selection.
  • What was not tested: I did not run a live Claude CLI process against a real account in this environment; the after-fix proof is local runtime-selection output plus the focused queued-followup dispatch regression.

Audits

  • Existing helper: reused resolveCliRuntimeExecutionProvider, isCliProvider, runCliAgent, and getCliSessionBinding; no new runtime abstraction.
  • Shared callers: primary reply execution already uses the same CLI-runtime decision before embedded Pi dispatch; this patch only applies that split to queued followups.
  • Broader rival scan: fix: route remaining cli-backed helper runs through CLI paths #72499 is an older broad/conflicting PR covering several CLI helper paths. This PR is intentionally narrower: followup queue only, two files, no cron/probe/slug changes, so it avoids the security-sensitive cron policy blocker on fix: route remaining cli-backed helper runs through CLI paths #72499.

Tests

$ pnpm exec oxfmt --check --threads=1 src/auto-reply/reply/followup-runner.ts src/auto-reply/reply/followup-runner.test.ts
Checking formatting...
All matched files use the correct format.
Finished in 7ms on 2 files using 1 threads.

$ git diff --check
# no output

$ pnpm check:changed
[check:changed] lanes=core, coreTests
[check:changed] src/auto-reply/reply/followup-runner.test.ts: core test
[check:changed] src/auto-reply/reply/followup-runner.ts: core production
...
Found 0 warnings and 0 errors.
Import cycle check: 0 runtime value cycle(s).
# command exited 0

Note: a full tsc --noEmit --project tsconfig.json --incremental false OOMed locally even with --max-old-space-size=8192; pnpm check:changed completed the relevant core/core-test typechecks through the repo's tsgo lane.

@openclaw-barnacle openclaw-barnacle Bot added size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 17, 2026
@clawsweeper

clawsweeper Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Summary
The PR routes queued followup runs whose selected model resolves to a CLI backend through a shared CLI runner lifecycle helper, adds focused followup regression coverage, updates Telegram message-cache types, and adds a changelog entry.

Reproducibility: yes. Source inspection on current main gives a high-confidence path: configure a queued followup model whose runtime resolves to claude-cli or another CLI backend, and the followup runner still reaches runEmbeddedPiAgent instead of the CLI runner.

Real behavior proof
Needs stronger real behavior proof before merge: Insufficient: add a redacted terminal log, live output, linked artifact, or recording of an actual queued followup using a CLI backend; after updating the PR body ClawSweeper should re-review automatically, or ask a maintainer to comment @clawsweeper re-review.

Next step before merge
Human merge handling is needed because the remaining blocker is real behavior proof or a maintainer proof waiver, not a narrow code repair ClawSweeper can produce for the contributor.

Security
Cleared: Cleared: the diff changes TypeScript routing/tests, a Telegram cache type repair, and the changelog, with no concrete security or supply-chain concern found.

Review details

Best possible solution:

Land the narrow followup-runner CLI routing fix after real queued-followup CLI proof or an explicit maintainer proof waiver, while leaving broader helper-path work to #72499.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection on current main gives a high-confidence path: configure a queued followup model whose runtime resolves to claude-cli or another CLI backend, and the followup runner still reaches runEmbeddedPiAgent instead of the CLI runner.

Is this the best way to solve the issue?

Yes for the code shape. The PR applies the existing primary-reply CLI dispatch contract to queued followups and keeps embedded fallback behavior, but merge should wait for real behavior proof or an explicit maintainer waiver.

Acceptance criteria:

  • Real queued-followup CLI backend proof, redacted as needed.
  • node scripts/run-vitest.mjs src/auto-reply/reply/followup-runner.test.ts
  • pnpm test src/auto-reply/reply/followup-runner.test.ts src/auto-reply/reply/agent-runner-execution.test.ts -- --reporter=verbose
  • pnpm check:changed

What I checked:

  • current-main source repro: Current main enters queued followup fallback and calls runEmbeddedPiAgent for every candidate, so a model whose configured runtime resolves to a CLI backend can still be sent to embedded harness selection. (src/auto-reply/reply/followup-runner.ts:356, ee10fe17f063)
  • direct reply contract: The primary reply path on main already resolves session/runtime CLI overrides and checks isCliProvider before dispatching through runCliAgent, which is the behavior the PR mirrors for followups. (src/auto-reply/reply/agent-runner-execution.ts:1731, ee10fe17f063)
  • PR followup routing shape: At the PR head, createFollowupRunner resolves the CLI execution provider, skips reusable CLI sessions for room events, calls runCliAgentWithLifecycle for CLI providers, and leaves embedded Pi dispatch for non-CLI candidates. (src/auto-reply/reply/followup-runner.ts:388, 66fe61e4c91b)
  • shared CLI lifecycle helper: The PR factors the existing direct-reply CLI lifecycle, assistant text bridge, final assistant event, and terminal lifecycle handling into a shared helper without adding dependencies or workflow changes. (src/auto-reply/reply/agent-runner-cli-dispatch.ts:57, 66fe61e4c91b)
  • regression coverage: The PR adds focused tests that assert queued CLI-runtime followups call runCliAgent rather than runEmbeddedPiAgent and that terminal lifecycle events are deferred while fallback settles. (src/auto-reply/reply/followup-runner.test.ts:681, 66fe61e4c91b)
  • proof assessment: The PR body and later maintainer comments show runtime-selection terminal output plus targeted tests/checks, but they do not show an actual queued followup executing through a real CLI backend after the fix. (66fe61e4c91b)

Likely related people:

  • vincentkoc: Current-main blame for the queued followup fallback dispatch region points to Vincent Koc's commit that currently carries the unconditional embedded dispatch path. (role: recent area contributor; confidence: high; commits: 817f0cd6c838; files: src/auto-reply/reply/followup-runner.ts)
  • joshavant: Recent current-main history for the direct reply execution path includes adjacent work in agent-runner-execution, where the CLI dispatch contract already exists. (role: recent adjacent contributor; confidence: medium; commits: 39a9a3478f11; files: src/auto-reply/reply/agent-runner-execution.ts)
  • steipete: The PR history includes maintainer fixup commits and verification comments by steipete, and current-main history shows recent adjacent CLI/auto-reply work by the same person. (role: PR fixup and adjacent contributor; confidence: medium; commits: 0cc4d882e5e7, 66fe61e4c91b, 89d7a24a3523; files: src/auto-reply/reply/followup-runner.ts, src/auto-reply/reply/agent-runner-cli-dispatch.ts, extensions/telegram/src/message-cache.ts)

Remaining risk / open question:

  • After-fix proof still does not demonstrate a real queued followup using a live CLI backend, so the highest-risk user path remains unproven outside tests and helper probes.

Codex review notes: model gpt-5.5, reasoning high; reviewed against ee10fe17f063.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 17, 2026
@clawsweeper clawsweeper Bot added P1 High-priority user-facing bug, regression, or broken workflow. impact:message-loss Channel message delivery can be lost, duplicated, or misrouted. impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. impact:auth-provider Auth, provider routing, model choice, or SecretRef resolution may break. labels May 17, 2026
@steipete
steipete force-pushed the fix-followup-cli-runtime-82847 branch from 29ce366 to d986dfa Compare May 17, 2026 04:28
@steipete

Copy link
Copy Markdown
Contributor

Verification for the maintainer fixup on this PR:

Behavior addressed: queued followup turns now route CLI runtime selections (claude-cli, google-gemini-cli) through the CLI runner instead of falling into embedded harness lookup.
Real environment tested: local normal source checkout on macOS after rebasing PR #82857 onto origin/main (5c02b72413).
Exact steps or command run after this patch: pnpm test src/auto-reply/reply/followup-runner.test.ts src/auto-reply/reply/agent-runner-execution.test.ts -- --reporter=verbose
Evidence after fix: 2 files passed, 135 tests passed.
Exact steps or command run after this patch: env -u OPENCLAW_TESTBOX -u OPENCLAW_TESTBOX_REMOTE_RUN pnpm check:changed
Evidence after fix: lanes were core, coreTests, and docs; conflict-marker, changelog attribution, dependency pin, patch guard, core typecheck, core test typecheck, core lint, runtime sidecar loader, import-cycle, webhook, and pairing guards completed successfully.
Exact steps or command run after this patch: /Users/steipete/Projects/agent-scripts/skills/codex-review/scripts/codex-review --mode local
Evidence after fix: codex-review reported no accepted/actionable findings.
Observed result after fix: added regression coverage for CLI-runtime queued followups and for deferring CLI terminal lifecycle events until fallback settles.
What was not tested: Blacksmith Testbox pnpm check:changed did not start because two fresh leases were shut down during warmup before repo commands ran (tbx_01krt2wt43xy2y5msbpajrmzqa, tbx_01krt2xn8kx55phyk91yctzqd7).

@steipete
steipete force-pushed the fix-followup-cli-runtime-82847 branch from d986dfa to 0cc4d88 Compare May 17, 2026 04:35
@steipete

Copy link
Copy Markdown
Contributor

Verification update for latest SHA 66fe61e4c9:

Behavior addressed: queued followup turns now use the selected CLI runtime backend, so claude-cli / google-gemini-cli followups do not fall back into embedded harness lookup before delivery.
Real environment tested: local OpenClaw checkout on macOS; GitHub Actions pending on this pushed SHA.
Exact steps or command run after this patch:

  • pnpm test src/auto-reply/reply/followup-runner.test.ts src/auto-reply/reply/agent-runner-execution.test.ts -- --reporter=verbose
  • pnpm tsgo:extensions
  • pnpm test extensions/telegram/src/message-cache.test.ts -- --reporter=dot
  • env -u OPENCLAW_TESTBOX -u OPENCLAW_TESTBOX_REMOTE_RUN pnpm check:changed
  • codex-review on followup runtime patch, then again on the Telegram CI-unblock patch
    Evidence after fix: followup/agent-runner test command passed 2 files / 135 tests; Telegram cache test passed 1 file / 12 tests; extensions typecheck passed; changed gate passed lanes core, coreTests, extensions, extensionTests, docs; codex-review reported no accepted/actionable findings.
    Observed result after fix: CLI-backed queued followups preserve the CLI session binding and defer terminal lifecycle until fallback settles; the rebased Telegram reply-chain cache compiles against grammy reply message types.
    What was not tested: full remote Testbox proof; two Testbox attempts failed before command execution because the warm worker shut down (tbx_01krt2wt43xy2y5msbpajrmzqa, tbx_01krt2xn8kx55phyk91yctzqd7).

@openclaw-barnacle openclaw-barnacle Bot added the channel: telegram Channel integration: telegram label May 17, 2026
@steipete
steipete force-pushed the fix-followup-cli-runtime-82847 branch from 66fe61e to d2a5a32 Compare May 17, 2026 05:01
@steipete

Copy link
Copy Markdown
Contributor

Verification update for latest SHA d2a5a32db0 after rebasing onto origin/main (422a1374e0):

Behavior addressed: queued followup turns now use the selected CLI runtime backend, so claude-cli / google-gemini-cli followups do not fall back into embedded harness lookup before delivery.
Real environment tested: local OpenClaw checkout on macOS; GitHub Actions pending on this pushed SHA.
Exact steps or command run after this patch:

  • pnpm test src/auto-reply/reply/followup-runner.test.ts src/auto-reply/reply/agent-runner-execution.test.ts -- --reporter=verbose
  • env -u OPENCLAW_TESTBOX -u OPENCLAW_TESTBOX_REMOTE_RUN pnpm check:changed
  • codex-review on the followup runtime patch
    Evidence after fix: focused followup/agent-runner tests passed 2 files / 135 tests; changed gate passed lanes core, coreTests, docs; codex-review reported no accepted/actionable findings.
    Observed result after fix: CLI-backed queued followups preserve the CLI session binding and defer terminal lifecycle until fallback settles.
    What was not tested: full remote Testbox proof; earlier Testbox attempts failed before command execution because the warm worker shut down (tbx_01krt2wt43xy2y5msbpajrmzqa, tbx_01krt2xn8kx55phyk91yctzqd7).

@openclaw-barnacle openclaw-barnacle Bot removed the channel: telegram Channel integration: telegram label May 17, 2026
@steipete
steipete merged commit f2d8f38 into openclaw:main May 17, 2026
114 of 116 checks passed
galiniliev pushed a commit to galiniliev/openclaw that referenced this pull request May 20, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
galiniliev pushed a commit to galiniliev/openclaw that referenced this pull request May 25, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
…82847) (openclaw#82857)

* fix(followup): route CLI runtime drains through CLI runner

* fix(followup): route queued CLI runtimes

---------

Co-authored-by: hclsys <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

impact:auth-provider Auth, provider routing, model choice, or SecretRef resolution may break. impact:message-loss Channel message delivery can be lost, duplicated, or misrouted. impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. P1 High-priority user-facing bug, regression, or broken workflow. proof: supplied External PR includes structured after-fix real behavior proof. size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Followup queue drain crashes on CLI runtimes (claude-cli/codex-cli/gemini-cli): "Requested agent harness ... is not registered"

2 participants