openclaw - ✅(Solved) Fix memory/dreaming: CLI-backed agents (Claude CLI, Codex CLI, Gemini CLI) silently fail to dream [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#70940Fetched 2026-04-24 10:37:34
View on GitHub
Comments
0
Participants
1
Timeline
14
Reactions
0
Participants
Timeline (top)
referenced ×6labeled ×3mentioned ×2closed ×1

Error Message

Adjacent options if the above is too invasive: docs caveat in docs/concepts/dreaming.md, or a startup warn log when the dreaming cron is reconciled against a CLI-backed default agent.

Root Cause

Memory-core's promotion runs inside a before_agent_reply hook. That hook is only fired by runEmbeddedPiAgent. The CLI runner (src/agents/cli-runner/*.ts) fires before_prompt_build and before_agent_start but not before_agent_reply, so the cron's isolated agent turn skips the hook entirely (src/cron/isolated-agent/run-executor.ts:123 branches on isCliProvider).

Fix Action

Fixed

PR fix notes

PR #70950: fix(cli-runner): fire before_agent_reply on cron-triggered turns

Description (problem / solution / changelog)

Summary

Adds a before_agent_reply call site to runPreparedCliAgent so plugin-managed cron jobs can short-circuit a CLI-backed agent turn before the codex/claude/gemini subprocess is spawned. Mirrors the embedded PI runner gate at src/agents/pi-embedded-runner/run.ts:326.

Without this, configuring a default agent's model to a CLI backend silently broke memory-core dreaming: the cron sentinel was sent to the underlying LLM as a literal user prompt and the dreaming hook never executed.

Closes #70940.

TDD trail

  • 8998e9b5c6 — RED: 4-case test mirroring pi-embedded-runner/run.before-agent-reply-cron.test.ts. Two cases fail without the gate; two pass trivially.
  • 9dc1cfbfb6 — GREEN: hook gate added to runPreparedCliAgent. 4/4 pass.

Empirical validation (manual e2e)

Reran the same isolated-gateway repro from #70940 against this branch (OPENCLAW_HOME=/tmp/dream-test-cli, model: { primary: "codex-cli/gpt-5.5" }, dreaming enabled at */2 * * * *).

SignalPre-fix (#70940 repro)This branch
memory-core: dreaming promotion complete lines0 in 5 min3 (manual + 2 natural firings)
Dream-sentinel sent to LLM as literal promptYes (promptChars=217)No
Hook short-circuit duration (natural firings)n/a140ms / 148ms

The fast natural firings are the unambiguous proof: hook fires, returns handled: true, cli subprocess is skipped entirely.

Test plan

  • pnpm test src/agents/cli-runner.before-agent-reply-cron.test.ts — 4/4
  • pnpm test src/agents/cli-runner — 21/21
  • Lint clean on touched files
  • Manual e2e against codex-cli backend (above)

Note

buildHandledReplyPayloads is now duplicated in cli-runner.ts and pi-embedded-runner/run.ts. Worth a follow-up to extract; out of scope here to keep the diff tight.

Changed files

  • src/agents/cli-runner.before-agent-reply-cron.test.ts (added, +167/-0)
  • src/agents/cli-runner.ts (modified, +54/-0)

Code Example

[gateway] agent model: codex-cli/gpt-5.5
[gateway] ready (6 plugins:, memory-core,)
[agent/cli-backend] cli exec: provider=codex-cli model=gpt-5.5 promptChars=217
RAW_BUFFERClick to expand / collapse

Bug

When the default agent's resolved provider is a CLI backend (Claude CLI, Codex CLI, Gemini CLI, or any registerCliBackend provider), the managed dreaming cron fires but the promotion sweep never runs. The dream-sentinel token is sent to the underlying LLM as a literal user prompt — wasted tokens, no MEMORY.md write, no diary entry.

Pre-existing (heartbeat path had the same gap); surfaced by #70737.

Root cause

Memory-core's promotion runs inside a before_agent_reply hook. That hook is only fired by runEmbeddedPiAgent. The CLI runner (src/agents/cli-runner/*.ts) fires before_prompt_build and before_agent_start but not before_agent_reply, so the cron's isolated agent turn skips the hook entirely (src/cron/isolated-agent/run-executor.ts:123 branches on isCliProvider).

Repro (verified 2026-04-23 against PR #70737)

Isolated OPENCLAW_HOME with default agent model: { primary: "codex-cli/gpt-5.5" } and dreaming enabled at */2 * * * *. Trigger via openclaw cron run <jobId>.

Gateway log:

[gateway] agent model: codex-cli/gpt-5.5
[gateway] ready (6 plugins: …, memory-core, …)
[agent/cli-backend] cli exec: provider=codex-cli model=gpt-5.5 promptChars=217

pgrep -af "codex exec" confirmed a codex subprocess actively talking to OpenAI with the dream-sentinel as the user prompt. No memory-core: dreaming promotion complete line ever appeared. Same config with model: { primary: "openai/gpt-5.5" } (non-CLI) routes to runEmbeddedPiAgent, fires the hook, and produces the expected promotion-complete line.

Suggested fix

Mirror the before_agent_reply block from src/agents/pi-embedded-runner/run.ts:326 into the CLI runner (gated on trigger === "cron" at minimum). Small follow-up PR.

Adjacent options if the above is too invasive: docs caveat in docs/concepts/dreaming.md, or a startup warn log when the dreaming cron is reconciled against a CLI-backed default agent.

Identified by

@chatgpt-codex-connector during PR #70737 review.

extent analysis

TL;DR

The most likely fix is to mirror the before_agent_reply block from src/agents/pi-embedded-runner/run.ts:326 into the CLI runner, gated on trigger === "cron".

Guidance

  • Verify that the before_agent_reply hook is not being fired when using a CLI backend by checking the gateway log for the memory-core: dreaming promotion complete line.
  • Check the src/cron/isolated-agent/run-executor.ts:123 line to confirm that the isCliProvider branch is causing the hook to be skipped.
  • Consider adding a warn log when the dreaming cron is reconciled against a CLI-backed default agent to alert users to this issue.
  • Review the docs/concepts/dreaming.md documentation to determine if a caveat is needed to inform users of this limitation.

Example

No code snippet is provided as the issue does not require a specific code change, but rather a modification to the existing codebase.

Notes

This fix may require additional testing to ensure that it does not introduce any new issues, particularly with the runEmbeddedPiAgent and before_agent_reply hook.

Recommendation

Apply workaround: Mirror the before_agent_reply block into the CLI runner, as this is the most direct solution to the issue and has been identified as a potential fix.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix memory/dreaming: CLI-backed agents (Claude CLI, Codex CLI, Gemini CLI) silently fail to dream [1 pull requests, 1 participants]