#11104: feat(agent): add Ralph persistence loop for autonomous continuation
stale
## Summary
- Add configurable Ralph persistence loop that allows the agent to continue working autonomously after each reply
- When `ralph.enabled` is true in `openclaw.json`, the agent re-dispatches with a continuation prompt after each reply, up to `maxIterations` times
- Trigger internal hook `agent:reply-complete` for hook-based loop control
- Assign unique `MessageSid` per continuation to bypass inbound dedup
## Config Example
```json
{
"ralph": {
"enabled": true,
"maxIterations": 5,
"continuationPrompt": "Continue working. Complete the remaining tasks."
}
}
```
## Files Changed
- `src/config/types.openclaw.ts` - Add `ralph` config type
- `src/config/zod-schema.ts` - Add `ralph` to validation schema
- `src/auto-reply/dispatch.ts` - Add continuation loop in `dispatchInboundMessage`
- `src/auto-reply/reply/dispatch-from-config.ts` - Add `ralphContinue` flag and hook trigger
## Test plan
- [x] TypeScript compilation passes
- [x] Config validation accepts `ralph` key
- [x] Gateway API test: ralph loop runs for maxIterations
- [x] Discord channel test: bot sends continuation replies
- [x] Inbound dedup bypass verified with unique MessageSid
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR adds a new optional `ralph` config section (types + Zod schema) and wires a persistence loop into the inbound dispatch path. When enabled, `dispatchReplyFromConfig` can signal `ralphContinue` after a reply completes; `dispatchInboundMessage` then re-dispatches with an injected continuation prompt and a fresh `MessageSid` to bypass inbound de-duplication. It also introduces an internal `agent:reply-complete` hook event intended to let hooks control whether the loop continues.
Key behavior change is that a single inbound message may now cause multiple reply cycles (up to `maxIterations`) when Ralph continuation is active.
<h3>Confidence Score: 3/5</h3>
- This PR is close to safe, but has a functional gap in the new hook-driven continuation flow.
- Core changes are localized (config schema/types + dispatch loop) and the loop trigger is guarded by `cfg.ralph?.enabled` in `dispatchReplyFromConfig`. However, the new `agent:reply-complete` hook event exposes a `messages` channel that is currently never dispatched when the loop triggers, which will break expected hook behaviors. There’s also a maintainability hazard where the loop in `dispatchInboundMessage` is not itself gated on `cfg.ralph.enabled`, relying on downstream behavior.
- src/auto-reply/reply/dispatch-from-config.ts; src/auto-reply/dispatch.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#14274: feat: add collapseReplyPayloads to collapse multi-message replies
by Henry-Roff-AI · 2026-02-11
73.8%
#15732: [AI-assisted] feat: emit agent:response internal hook after replies
by zontasticality · 2026-02-13
73.6%
#11788: feat: inter-agent communication via CLI scripts
by jingkang0822 · 2026-02-08
72.7%
#3045: [AI-Assisted] fix: preserve pending tasks when subagent completes
by sid1943 · 2026-01-28
72.1%
#7580: feat: add message:received internal hook with prompt injection
by rodrigoschott · 2026-02-03
72.1%
#8086: feat(security): Add prompt injection guard rail
by bobbythelobster · 2026-02-03
72.1%
#19923: feat: track held messages during compaction gate and split verifica...
by PrivacySmurf · 2026-02-18
71.5%
#20081: feat: post-compaction triage UX — fuzzy ok + stage-2 gate + Discord...
by PrivacySmurf · 2026-02-18
71.1%
#6630: feat(hooks): add agent:turn_start and agent:turn_end lifecycle events
by drdigital13 · 2026-02-01
70.9%
#14222: core: add needsApproval to before_tool_call; move AgentShield to ex...
by Eventedge · 2026-02-11
70.8%