Skip to content

Stage C: let the agent pause and ask the user a question#5

Closed
Anmolnoor wants to merge 1 commit into
stage-b/decoupled-writesfrom
stage-c/user-questions
Closed

Stage C: let the agent pause and ask the user a question#5
Anmolnoor wants to merge 1 commit into
stage-b/decoupled-writesfrom
stage-c/user-questions

Conversation

@Anmolnoor
Copy link
Copy Markdown
Owner

Context

First half of the "make fcli ask me" feature. Adds a model-initiated clarifying-question mechanism so the agent can pause and ask instead of guessing when a request is ambiguous.

Note: based on stage-b/decoupled-writes so the diff shows only Stage C. Merge order: #3#4 → this. GitHub retargets automatically as bases merge.

What changed

  • New ActionKind.QUESTION + QuestionAction (prompt, options, allow_free_text); PlannedAction.question with shape validation. Question actions bypass policy like explanations.
  • Executor handles a question via an injected question_callback: interactive runs prompt synchronously and returns EXECUTED with the answer; with no callback (non-interactive / dismissed) it returns the new ExecutionStatus.AWAITING_INPUT.
  • Orchestrator: AWAITING_INPUT stops the loop with the new LoopStopReason.AWAITING_USER_INPUT; an answer is surfaced into the next iteration's observation so the planner acts on it. (Maps to COMPLETED_INCONCLUSIVE — no history schema change needed.)
  • CLI: _prompt_for_question (numbered options + free text, pauses the live widget), wired into _build_orchestrator; _awaiting_input_notice surfaces an unanswered question. Live widget shows an "awaiting your answer" state.
  • Planner prompt + schema outline document the question action (use sparingly).
  • Events: EVENT_QUESTION_ASKED / EVENT_QUESTION_ANSWERED.

Tests

6 new (393 total, ruff clean): answer flows into the next iteration; non-interactive stops with AWAITING_USER_INPUT; option-by-number and free-text prompt parsing; the awaiting-input notice fires (and doesn't without the stop reason).

Sequencing

Stage C of A→B→C→D. Stage D (out-of-scope escalation) reuses this prompt/event plumbing.

🤖 Generated with Claude Code

Adds a model-initiated clarifying-question mechanism so the agent can stop
and ask instead of guessing when a request is ambiguous.

- New ActionKind.QUESTION + QuestionAction model (prompt, options,
  allow_free_text); PlannedAction.question with validation. Question actions
  bypass policy like explanations.
- Executor handles QUESTION via an injected question_callback: interactive
  runs prompt synchronously (EXECUTED with the answer); without a callback
  (non-interactive / dismissed) the action returns AWAITING_INPUT.
- Orchestrator: AWAITING_INPUT results stop the loop with the new
  LoopStopReason.AWAITING_USER_INPUT; an answer is surfaced into the next
  iteration's observation so the planner acts on it. AWAITING maps to
  COMPLETED_INCONCLUSIVE (no schema change).
- CLI: _prompt_for_question (numbered options + free text, pauses the live
  widget); wired into _build_orchestrator; _awaiting_input_notice surfaces
  an unanswered question. Live widget shows an "awaiting your answer" state.
- Planner prompt + schema outline document the question action (use sparingly).
- Events: EVENT_QUESTION_ASKED / EVENT_QUESTION_ANSWERED.

Tests: answer flows into the next iteration; non-interactive stops with
AWAITING_USER_INPUT; option-by-number and free-text prompt parsing; the
awaiting-input notice.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Anmolnoor
Copy link
Copy Markdown
Owner Author

Merged into main via commit 27c97b0 (stages A–G landed as one merge). See the summary on #9.

@Anmolnoor Anmolnoor closed this May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant