Hmbown / Hmbown/Codewhale

Mid-turn guidance: deliver a committed queued follow-up as a steer at the next checkpoint (peek tool rejected)

Open
#5,625 2 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
41k
Forks
3.6k
Avg merge
13h 59m
Merged PRs (30d)
299

Description

# Enhancement: non-blocking "pending user input" peek tool for mid-turn guidance

**Type:** feature request / enhancement
**Area:** agent runtime · tool surface · human-in-the-loop collaboration
**Status:** proposal — feedback requested

---

## Summary

Add a lightweight, non-blocking tool that lets the agent **check whether the user has queued input** during a turn, and **read that input without ending the turn**.

Concretely: `check_pending_input()` (or similar) returns **both** a boolean (`has_input`) and a **peek** at the pending text. The agent calls it at natural checkpoints between steps. If nothing is queued, it continues without an expensive yield. If something is queued, it can read and act on the guidance immediately — instead of discovering it only when the turn ends, by which point it is often stale.

---

## Background / problem

The agent frequently runs **long chains of action inside a single turn**: multi-step refactors, porting an endpoint file-by-file, running a test harness and triaging diffs, or executing a sequence of build → test → fix → rebuild steps. Each chain may involve many tool calls and produce a large amount of streamed output over minutes.

Meanwhile, the user is **watching that output stream in real time** and will often spot something that would benefit from immediate guidance:

- "that's the wrong approach, stop and reconsider"
- "pause — I need to give you a decision on X"
- "the file at `/path` is the authoritative source, not what you assumed"
- "don't mutate the database yet"

Today, that input is **queued but not delivered until the agent yields** (ends the turn). The agent, busy mid-chain, is blind to it. It keeps producing work — often hundreds of lines of output and significant token spend — before it finally stops and receives the message.

By the time the queued input arrives, it is frequently **stale**: it refers to a state or an intermediate result that has since been superseded, or it corrects work the agent has already completed incorrectly. This produces:

- **Wasted work and tokens** — the agent completes a path the user already wanted to redirect.
- **Rework** — the agent must unwind decisions made on the now-obsolete assumption.
- **Confusion** — a guidance message that arrives at turn-end references an earlier context the agent has to reconstruct ("what was I looking at when the user said this?").

The user has explicitly flagged this as a recurring problem: guidance typed mid-turn arrives too late to be useful, and is "often stale, irrelevant, and confuses" the agent.

---

## Why "just yield more often" is not sufficient

The current mitigation is purely behavioural: "pause frequently between steps so pending input can surface." This is necessary but insufficient, for three reasons:

1. **The agent cannot see whether there is pending input without yielding.** It has no way to know if the user is typing. So it must choose between yielding too often (wasteful when there is nothing to say) and too rarely (input goes stale).
2. **Yielding has real cost.** Ending a turn interrupts a correct, in-progress chain. The agent must re-establish context on resume, and the user must re-read where things stand before the next instruction.
3. **Neither party wants to cancel a good chain.** When the work is correct and on-track, forcing a yield to check for input is pure overhead. When the work is wrong, the user wants to intervene *before* it goes further — not after the agent has burned through the remaining steps.

The core asymmetry is: **the user can see the agent's output as it streams, but the agent cannot see the user's pending input until it stops.** This proposal closes that asymmetry with a cheap, opt-in "peek".

---

## Proposed solution

A non-blocking tool on the agent's tool surface:

```
check_pending_input() -> { "has_input": bool, "input": string | null }
```

- **`has_input`** — whether any user message is currently queued.
- **`input`** — a **peek** at the queued text (`null`/empty when `has_input` is false).

Behavioural properties:

- **Non-blocking.** It must return immediately regardless of whether input is present. The agent can call it as cheaply as a read-only probe.
- **Peek, not consume.** It must not dequeue or otherwise disturb the input; the message is still delivered normally at the next turn boundary. The agent reads it opportunistically and, if it chooses to act, the message is still there for the normal flow. (Consume-vs-peek semantics can be refined, but peek is the least surprising starting point.)
- **Idempotent / side-effect-free.** Calling it has no effect on the conversation state, so the agent can call it liberally.

### Why the peek (text) matters, not just the boolean

A boolean-only "is input pending?" would only tell the agent *to yield* — but yielding is exactly what it is trying to avoid, and it would still have to end the turn to *read* what the user said. The value of the tool is in returning the **content**, so that:

```
has_input == false → continue the chain (no wasteful yield)
has_input == true → read `input`, fold it into the work immediately
```

Returning the text lets the agent respond to "pause, use option (b)" *in place*, without surrendering the turn.

---

## Discipline: how the behaviour is instilled

The tool only helps if the agent actually calls it at the right moments. In this project, such behaviours are **not left to chance** — they are encoded in the standing instruction files the agent re-reads and obeys:

- **`AGENTS.md`** — the project's standing rules (e.g., the "genuine design decision / judgment call → hard stop and ask" rule, the gate list for `commit` / `push` / `amend` / irreversible actions, the "pause for input" guidance).
- **`~/.codewhale/notes.txt`** — accumulated workflow lessons and corrections, which already contains the lesson "pause frequently between steps and tool-calls… check for [queued input] before proceeding."
- **`~/.codewhale/memory.md`** — durable preferences (e.g., "consult the user on design/scope/trade-off decisions rather than investigate to a self-decided answer").

The enhancement would add a rule of the same kind, for example:

> **Rule — Check for pending input at checkpoints.** Before any consequential or irreversible action (database mutation, commit/push, writing outside the workspace, a "genuine design decision"), and at each step boundary in a multi-step chain, call `check_pending_input()`. If `has_input` is true, read `input` and apply it before proceeding.

This slots cleanly into the **existing** checkpoint moments the project already defines — the hard-stop list, the commit/push gates, the "escalate judgment calls" rule. The tool makes those checkpoints cheap to honour instead of forcing a full turn yield each time.

---

## How this improves collaboration

- **Guidance arrives while it is still actionable.** The user can redirect the agent *before* it commits to the wrong path, rather than after.
- **Less wasted work and token spend.** The agent stops producing output that the queued guidance would have short-circuited.
- **Cheaper intervention.** The user can steer without waiting for a full yield and without the ceremony of a new turn.
- **Preserves momentum on correct work.** When nothing is queued, the agent continues with zero overhead — it no longer has to guess between "yield wastefully" and "go stale."
- **Closes the visibility asymmetry.** The user already watches the agent's stream in real time; the agent gains a real-time, opt-in view of the user's pending intent. Collaboration becomes a true two-way loop.
- **Safety net for gated actions.** The agent can peek immediately before a destructive/irreversible operation, catching "no, don't do that" where it matters most.

---

## Concrete example (before / after)

**Before (today):**

1. Agent begins a long port: many files, build → test → fix loops.
2. At step 4 of 20 the user sees a wrong assumption and types "use the shared helper, not a duplicate."
3. That message sits in the queue.
4. The agent finishes all 20 steps, produces a large diff, then yields.
5. The message arrives, but it refers to step 4; the agent has to unwind and redo steps 5–20.

**After (with the tool):**

1. Agent begins the same port.
2. At each step boundary it calls `check_pending_input()`.
3. After step 4 the call returns `{"has_input": true, "input": "use the shared helper, not a duplicate"}`.
4. The agent reads it, switches to the shared helper from step 5 onward, and mentions the redirect in its next checkpoint.
5. No unwinding, no stale input, no wasted steps.

---

## Non-goals

- **Not** automatic/async push of user input into the middle of the agent's stream (that would be disruptive and harder to reason about). This is an explicit, agent-initiated *pull*.
- **Not** a blocking "wait for input" primitive.
- **Not** a substitute for the existing hard-stop / yield discipline — it complements it by making the *check* cheap, while the existing rules still govern *when* the agent must stop and ask.
- **Not** proposing to consume the queued message; the peek leaves the normal delivery intact unless/until we decide otherwise.

---

## Acceptance criteria

1. `check_pending_input()` is callable from the agent tool surface and returns `{ has_input, input }` **without blocking**.
2. Calling it is side-effect-free and does not consume or reorder queued input.
3. The agent can read and act on the peeked text mid-turn, before yielding.
4. `AGENTS.md` (and, where appropriate, `notes.txt` / `memory.md`) gains a rule describing the checkpoint discipline above.
5. Observable reduction in "stale input delivered at turn-end" incidents and in rework caused by mid-turn guidance arriving late.

---

*Filed by the workbench-go project team. Reference: recurring "check for input / pause frequently" lessons in `~/.codewhale/notes.txt` and `AGENTS.md`.*

Contributor guide

Open the contributing guide

Research direction

Start by locating the agent tool surface and reading AGENTS.md, then compare the existing queued-input, yield, and checkpoint behavior. Review the proposed updates for AGENTS.md, ~/.codewhale/notes.txt, and ~/.codewhale/memory.md. Done means a non-blocking check_pending_input() exposes queued text without consuming it and the checkpoint discipline is documented and verified against the acceptance criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
ai, cli, devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.