Skip to content

feat: forward ask_user_question from nested subagents to root session via pi-intercom#1

Open
avtc wants to merge 1 commit into
ghoseb:mainfrom
avtc:feature/forward-question-to-root-session
Open

feat: forward ask_user_question from nested subagents to root session via pi-intercom#1
avtc wants to merge 1 commit into
ghoseb:mainfrom
avtc:feature/forward-question-to-root-session

Conversation

@avtc
Copy link
Copy Markdown

@avtc avtc commented May 11, 2026

What

Adds the ability for subagents at any nesting depth to interactively ask the user questions through the existing ask_user_question TUI — even though those subagent sessions have no UI of their own.

Questions are forwarded over pi-intercom to the root session (which has a TUI), rendered as the familiar interactive component, and the user's answer is relayed back to the subagent.

Why

When a subagent calls ask_user_question today, it hits the !ctx.hasUI path and the tool is deregistered — the subagent is told not to ask questions and must guess or skip. This is a poor experience when the agent genuinely needs clarification (e.g., ambiguous requirements, design choices, error recovery).

Subagents are increasingly used for complex workflows where user input is valuable. Silently disabling the ability to ask defeats the purpose of interactive tooling.

How

Enabled by pi-intercom#21, which exposes sendAndWait and registerHandler through the intercom:ready event — allowing extensions to build request/response patterns between sessions without a direct import dependency.

The forwarding works in two parts:

  1. Root session (has TUI): On intercom:ready, registers a handler for the "ask_user_question" content type. When a subagent sends a question, the handler renders it via AskUserQuestionComponent and returns the user's answer as JSON.

  2. Subagent session (no TUI): When ask_user_question is invoked and !ctx.hasUI, the tool checks for a subagent context (PI_SUBAGENT_ORCHESTRATOR_TARGET). If present, it calls sendAndWait to forward the questions to root and awaits the reply. The answer is returned to the LLM in the same format it would have received locally.

Additional details:

  • No hard dependency on pi-intercom — hooks are registered lazily via the intercom:ready event. If pi-intercom is not installed, the extension works exactly as before (deregisters the tool in non-interactive sessions).
  • Extracted renderQuestionsViaUI helper from the inline closure so both the tool handler and the intercom handler share the same rendering logic.
  • Message renderer registered in the root session displays answered questions in conversation history with a green-bordered summary box.
  • Graceful fallback — if intercom is unavailable or the user cancels, the subagent receives a clear response ("User cancelled") instead of hanging or crashing.

Flow diagram

Subagent (no UI)                     Root session (has TUI)
      │                                      │
      │  ask_user_question invoked           │
      │  !ctx.hasUI → forward path           │
      │                                      │
      │  sendAndWait("ask_user_question") ──►│  handler renders
      │                                      │  AskUserQuestionComponent
      │                                      │  user picks answer
      │  ◄── reply (JSON Result) ────────────│
      │                                      │
      │  returns answer to LLM               │

… via pi-intercom

Enables subagents at any nesting depth to interactively ask the user
questions by forwarding them through pi-intercom to the root session
that has a TUI.

- Add intercom-forwarding module with root-side handler (renders
  questions via AskUserQuestionComponent) and child-side forwarding
  (uses sendAndWait to relay questions up to root)
- Extract renderQuestionsViaUI helper for shared use by tool handler
  and intercom handler
- Register hooks lazily via intercom:ready event (no hard dependency)
- Add message renderer for answered questions in root session history
- Fall back to tool deregistration only when intercom is unavailable
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