[GH-ISSUE #148] RFC: CLI and TUI guidance injection for human-in-the-loop steering #56

Closed
opened 2026-02-27 10:21:59 +03:00 by kerem · 3 comments
Owner

Originally created by @LuoAndOrder on GitHub (Feb 2, 2026).
Original GitHub issue: https://github.com/mikeyobrien/ralph-orchestrator/issues/148

The Problem

You're watching Ralph work through a task. You notice it's about to spend three iterations debugging the wrong file, or it's not aware that the v1 API endpoint is deprecated, or you just remembered a critical detail that isn't in the codebase.

Right now, your options are:

  1. Kill the loop and restart with updated instructions (loses progress, wastes tokens)
  2. Set up Telegram and send a message (high friction for a quick nudge)
  3. Wait and hope Ralph figures it out (spoiler: it often doesn't)

What you want to do is just type "check auth.rs not auth_old.rs" and have Ralph pick that up on the next iteration.

Proposal

Add CLI and TUI interfaces for injecting guidance into running loops:

# From any terminal
ralph guidance "the API key is in .env.local, not .env"

Or press g in the TUI to open a guidance modal while watching progress.

The guidance appears as ## ROBOT GUIDANCE in the next iteration's prompt—same as the existing Telegram integration, just without needing Telegram.

Why This Matters

1. Course correction without restart
Nudge Ralph back on track without losing progress. One sentence of guidance can save 5+ wasted iterations.

2. Inject knowledge the agent can't infer

  • "Use the staging database credentials"
  • "The client prefers Tailwind over inline styles"
  • "Skip the migration for now, we'll handle it separately"

3. Real-time collaboration
Instead of "set and forget," you can actively pair with Ralph—watching progress, offering hints when stuck, and steering toward your preferred approach.

4. Lower friction than Telegram
The RObot/Telegram system is powerful for async monitoring and team visibility. But for developers already in a terminal watching Ralph work, switching to a phone app just to say "try the other approach" is unnecessary friction.

Technical Approach

Both interfaces write the same human.guidance events that Telegram already uses:

CLI: ralph guidance "..."          TUI: Press 'g'          Telegram
            │                            │                     │
            └────────────────────────────┼─────────────────────┘
                                         ▼
                                  events.jsonl
                                         │
                                         ▼
                              Event Loop (next iteration)
                                         │
                                         ▼
                              ## ROBOT GUIDANCE in prompt

No changes to core orchestration logic—just new ways to write the same event type.

CLI

ralph guidance "focus on error handling"
ralph guidance --loop feature-auth "check edge cases"  # target worktree

TUI

  • Press g to open guidance modal
  • Type message (Shift+Enter for newlines, Enter to send, Esc to cancel)
  • Confirmation via footer status + inline echo in iteration buffer

Open Questions

  1. Key binding: Is g for guidance intuitive?
  2. Scope: Should we add guidance history/recall (up arrow)? Leaning toward "not in v1"
  3. Anything else this should support?

Implementation

I've drafted a detailed spec and am happy to implement this and submit a PR. The changes touch:

  • ralph-cli: New guidance subcommand (~100 lines)
  • ralph-tui: Guidance modal and state management (~400 lines)
  • ralph-core: Shared event-writing function extracted from telegram handler (~50 lines)

Would love feedback on the approach before diving into implementation.

Originally created by @LuoAndOrder on GitHub (Feb 2, 2026). Original GitHub issue: https://github.com/mikeyobrien/ralph-orchestrator/issues/148 ## The Problem You're watching Ralph work through a task. You notice it's about to spend three iterations debugging the wrong file, or it's not aware that the v1 API endpoint is deprecated, or you just remembered a critical detail that isn't in the codebase. Right now, your options are: 1. **Kill the loop** and restart with updated instructions (loses progress, wastes tokens) 2. **Set up Telegram** and send a message (high friction for a quick nudge) 3. **Wait and hope** Ralph figures it out (spoiler: it often doesn't) What you *want* to do is just type "check `auth.rs` not `auth_old.rs`" and have Ralph pick that up on the next iteration. ## Proposal Add CLI and TUI interfaces for injecting guidance into running loops: ```bash # From any terminal ralph guidance "the API key is in .env.local, not .env" ``` Or press `g` in the TUI to open a guidance modal while watching progress. The guidance appears as `## ROBOT GUIDANCE` in the next iteration's prompt—same as the existing Telegram integration, just without needing Telegram. ## Why This Matters **1. Course correction without restart** Nudge Ralph back on track without losing progress. One sentence of guidance can save 5+ wasted iterations. **2. Inject knowledge the agent can't infer** - "Use the staging database credentials" - "The client prefers Tailwind over inline styles" - "Skip the migration for now, we'll handle it separately" **3. Real-time collaboration** Instead of "set and forget," you can actively pair with Ralph—watching progress, offering hints when stuck, and steering toward your preferred approach. **4. Lower friction than Telegram** The RObot/Telegram system is powerful for async monitoring and team visibility. But for developers already in a terminal watching Ralph work, switching to a phone app just to say "try the other approach" is unnecessary friction. ## Technical Approach Both interfaces write the same `human.guidance` events that Telegram already uses: ``` CLI: ralph guidance "..." TUI: Press 'g' Telegram │ │ │ └────────────────────────────┼─────────────────────┘ ▼ events.jsonl │ ▼ Event Loop (next iteration) │ ▼ ## ROBOT GUIDANCE in prompt ``` No changes to core orchestration logic—just new ways to write the same event type. ### CLI ```bash ralph guidance "focus on error handling" ralph guidance --loop feature-auth "check edge cases" # target worktree ``` ### TUI - Press `g` to open guidance modal - Type message (Shift+Enter for newlines, Enter to send, Esc to cancel) - Confirmation via footer status + inline echo in iteration buffer ## Open Questions 1. **Key binding**: Is `g` for guidance intuitive? 2. **Scope**: Should we add guidance history/recall (up arrow)? Leaning toward "not in v1" 3. **Anything else** this should support? ## Implementation I've drafted a detailed spec and am happy to implement this and submit a PR. The changes touch: - `ralph-cli`: New `guidance` subcommand (~100 lines) - `ralph-tui`: Guidance modal and state management (~400 lines) - `ralph-core`: Shared event-writing function extracted from telegram handler (~50 lines) Would love feedback on the approach before diving into implementation.
kerem closed this issue 2026-02-27 10:21:59 +03:00
Author
Owner

@mikeyobrien commented on GitHub (Feb 3, 2026):

Totally agree with high friction. I was thinking about adding a new ralph chat command, but this might be a better middle-ground. Ralph is not meant to be chat with, it's to be delegated and directed.

In addition to the guidance command/keybind, thoughts on a pop-up modal when the loop requests interaction? The intention was always to have multiple interaction models, telegram being the first due to all the OpenClaw hype and I was curious on how easy it was to setup.

<!-- gh-comment-id:3841514138 --> @mikeyobrien commented on GitHub (Feb 3, 2026): Totally agree with high friction. I was thinking about adding a new `ralph chat` command, but this might be a better middle-ground. Ralph is not meant to be chat with, it's to be delegated and directed. In addition to the `guidance` command/keybind, thoughts on a pop-up modal when the loop requests interaction? The intention was always to have multiple interaction models, telegram being the first due to all the OpenClaw hype and I was curious on how easy it was to setup.
Author
Owner

@LuoAndOrder commented on GitHub (Feb 3, 2026):

I agree that Ralph is not meant to be chat with. I was originally thinking one way communication from the user back to ralph to help steer it in future iterations or get it unstuck.

But I think there's also merit to your idea of Ralph interrupting itself and ask for help. It needs further thought however. For example:

  1. Should it be configurable? I love using Ralph overnight while I sleep and waking up to what progress it's made. I don't want it to get stuck randomly overnight waiting for input from me that it's not going to get. Yet, I can also see it being useful during the day if it gets stuck (missing an API key) that requires human input for it to prompt me.
  2. If it gets stuck should it be stuck forever? Or is it just blocked on a subset of tasks and it can make progress on other tasks asynchronously until it gets input from the human?
  3. Should there be a configurable timeout? If ralph doesn't get input from human within X minutes, it should just use its own judgement?

My recommendation is to start with the User -> Ralph guidance first and then have a discussion on what the Ralph -> User flow should look like. Interested in others' thoughts.

<!-- gh-comment-id:3842683573 --> @LuoAndOrder commented on GitHub (Feb 3, 2026): I agree that Ralph is not meant to be chat with. I was originally thinking one way communication from the user back to ralph to help steer it in future iterations or get it unstuck. But I think there's also merit to your idea of Ralph interrupting itself and ask for help. It needs further thought however. For example: 1. Should it be configurable? I love using Ralph overnight while I sleep and waking up to what progress it's made. I don't want it to get stuck randomly overnight waiting for input from me that it's not going to get. Yet, I can also see it being useful during the day if it gets stuck (missing an API key) that requires human input for it to prompt me. 2. If it gets stuck should it be stuck forever? Or is it just blocked on a subset of tasks and it can make progress on other tasks asynchronously until it gets input from the human? 3. Should there be a configurable timeout? If ralph doesn't get input from human within X minutes, it should just use its own judgement? My recommendation is to start with the User -> Ralph guidance first and then have a discussion on what the Ralph -> User flow should look like. Interested in others' thoughts.
Author
Owner

@mikeyobrien commented on GitHub (Feb 3, 2026):

  1. This is configurable under the RObot namespace, under timeout_seconds, it will continue the loop if no response is given.
  2. That's a matter of prompting imo. I think it's up to the user to decide what the loop does when no response is received. We could bake in some guardrails so it's not spinning all night doing nothing.
  3. See response 1.

This is a collection I used over the weekend to push the boundaries of what could be done autonomously which worked pretty well. I need more time with it before I decide if I make a generic preset. In short, it's prompted such that the user is only engaged when blocked or the top-level task is complete and is waiting for the new direction.

https://gist.github.com/mikeyobrien/b15d22d7979ecae7cdd3f8f9e34d7337

<!-- gh-comment-id:3843731346 --> @mikeyobrien commented on GitHub (Feb 3, 2026): 1. This is configurable under the RObot namespace, under `timeout_seconds`, it will continue the loop if no response is given. 2. That's a matter of prompting imo. I think it's up to the user to decide what the loop does when no response is received. We could bake in some guardrails so it's not spinning all night doing nothing. 3. See response 1. This is a collection I used over the weekend to push the boundaries of what could be done autonomously which worked pretty well. I need more time with it before I decide if I make a generic preset. In short, it's prompted such that the user is only engaged when blocked or the top-level task is complete and is waiting for the new direction. https://gist.github.com/mikeyobrien/b15d22d7979ecae7cdd3f8f9e34d7337
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ralph-orchestrator#56
No description provided.