Skip to content

fix(go-adk): surface the sub-agent's ask_user question in RemoteHitlHint - #2475

Open
vramahandry wants to merge 5 commits into
kagent-dev:mainfrom
vramahandry:fix/remote-hitl-hint-ask-user-question
Open

fix(go-adk): surface the sub-agent's ask_user question in RemoteHitlHint#2475
vramahandry wants to merge 5 commits into
kagent-dev:mainfrom
vramahandry:fix/remote-hitl-hint-ask-user-question

Conversation

@vramahandry

Copy link
Copy Markdown
Contributor

Summary

RemoteHitlHint() builds the hint text shown to a human when a sub-agent's own HITL pause bubbles up to the parent agent. Today it only lists the paused tool's name (e.g. ask_user) — never the actual question — even though AskUserRequest.Questions (already threaded through VisibleTools() into HitlTool.Args["questions"]) has the real content right there.

  • Before: "Remote agent 'github_agent' requires approval for tool(s): ask_user"
  • After: "Remote agent 'github_agent' asks: What is the GitHub owner/org for the repo?"

Real tool-approval hints (the non-ask_user case) are unaffected — same wording as before, existing TestBuildRemoteHitlStateAndHint still passes unchanged.

Discovered while building an external A2A chat bridge that correctly renders every other kagent HITL flow (direct tool approval, direct ask_user) from the same session — this was the one case where the confirmation card reaching a downstream A2A client carried no actionable information, because the hint itself never had it. Confirmed by inspecting the sub-agent's own ADK session directly (GET /api/sessions/<id>), where the real question is visible in adk_request_confirmation — it's just discarded before reaching RemoteHitlHint.

Fixes #2473

Changes

  • go/adk/pkg/a2a/hitl.go: new askUserQuestionText() helper extracts question text from an ask_user HitlTool's args; RemoteHitlHint() uses it when present, falling back to the existing tool-name-only wording otherwise.
  • go/adk/pkg/a2a/hitl_test.go: new TestBuildRemoteHitlStateAndHintAskUser covering the fixed behavior.

Test plan

  • go build ./adk/... — clean
  • go test ./adk/... — all packages pass (a2a, agent, app, tools, etc.)
  • gofmt -l / go vet ./adk/pkg/a2a/... — clean
  • Existing TestBuildRemoteHitlStateAndHint (tool-approval case) passes unchanged

@vramahandry
vramahandry force-pushed the fix/remote-hitl-hint-ask-user-question branch from be0a702 to eb714e3 Compare August 18, 2026 12:52
@github-actions github-actions Bot added the bug Something isn't working label Aug 18, 2026

@supreme-gg-gg supreme-gg-gg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix makes sense to me, two comments and this is ready to go

Comment thread go/adk/pkg/a2a/hitl.go Outdated
Comment thread go/adk/pkg/a2a/hitl_test.go
RemoteHitlHint() only listed the paused tool's name ('ask_user'), never
the actual question text, even though HitlTool.Args already carries it
via VisibleTools(). A human relayed a bubbled-up sub-agent HITL pause
saw 'requires approval for tool(s): ask_user' with no way to know what
was actually being asked.

Fixes kagent-dev#2473

Signed-off-by: Vivien Ramahandry <56304555+vramahandry@users.noreply.github.com>
askUserQuestionText() type-asserted a nested ask_user HitlTool's
Args["questions"] as []map[string]any, but Args round-trips through
JSON into a plain map[string]any, which decodes "questions" as []any
instead — silently dropping the question for nested (two-level)
ask_user pauses. AskUserRequest.Questions is already correctly typed
in both the direct and nested case (see BuildHITLStatusMessage), so
read it directly instead of re-deriving from VisibleTools() output.

Addresses review feedback from supreme-gg-gg on kagent-dev#2475.

Signed-off-by: Vivien Ramahandry <56304555+vramahandry@users.noreply.github.com>
supreme-gg-gg
supreme-gg-gg previously approved these changes Aug 19, 2026

@supreme-gg-gg supreme-gg-gg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks!

Comment thread go/adk/pkg/a2a/hitl.go Outdated
if state == nil {
return "Remote agent requires human input before continuing."
}
// AskUserRequest.Questions carries the real question text whether or not

@supreme-gg-gg supreme-gg-gg Aug 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this inline comment seems a bit too long (but not worth blocking on this)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trimmed in 40bec6b, along with the similarly verbose comments added alongside it.

EItanya pushed a commit that referenced this pull request Aug 19, 2026
…hitl_hint (#2495)

## Summary

`remote_hitl_hint()` in the Python `kagent-adk` runtime builds the hint
text shown to a human when a sub-agent's own HITL pause bubbles up to
the parent agent. Unlike the Go runtime's `RemoteHitlHint()`, it only
ever lists the paused tool's *name* (e.g. `ask_user`) — never the actual
question — even though `AskUserRequest.questions` (set directly on the
request in `build_hitl_status_message`, whether or not `nested` is
populated) has the real content right there.

- Before: `"Remote agent 'github_agent' requires approval for tool(s):
ask_user"`
- After: `"Remote agent 'github_agent' asks: What is the GitHub
owner/org for the repo?"`

Real tool-approval hints (the non-`ask_user` case) are unaffected.

This is the Python-runtime counterpart to #2475, which fixed the same
class of bug in `go/adk/pkg/a2a/hitl.go`. The Go and Python runtimes
maintain independent implementations of this HITL hint logic, and the
Python side never had question-surfacing added — so a parent agent built
on `kagent-adk` still drops the question today even after #2475 merges.

Unlike the Go fix, there's no `[]any` vs `[]map[string]any]` JSON-decode
subtlety to worry about here: Pydantic's `HitlTool.args: dict[str, Any]`
keeps nested question dicts intact, so reading
`AskUserRequest.questions` directly is straightforward in both the
direct and nested case.

Fixes #2473

## Changes

- `python/packages/kagent-adk/src/kagent/adk/_hitl.py`:
`remote_hitl_hint()` now checks `AskUserRequest.questions` first and
returns `"Remote agent '{name}' asks: {question}"` when present, falling
back to the existing tool-name-only wording otherwise.
- `python/packages/kagent-adk/tests/unittests/test_hitl.py`: adds
`test_remote_hitl_hint_tool_approval`, `test_remote_hitl_hint_ask_user`,
and `test_remote_hitl_hint_ask_user_nested` (the last covering a
two-level nested `ask_user` pause).

## Test plan

- [x] `uv run pytest packages/kagent-adk/tests/unittests/test_hitl.py` —
18 passed (3 new)
- [x] `uv run ruff format --diff` / `uv run ruff check` — clean
- [x] Existing tests unaffected — no changes to tool-approval hint
wording

Signed-off-by: Vivien Ramahandry <56304555+vramahandry@users.noreply.github.com>
supreme-gg-gg and others added 2 commits August 19, 2026 11:40
supreme-gg-gg flagged the inline comment as too long; tightened it and
the similarly verbose doc/test comments added in the same change while
keeping the JSON round-trip explanation.
@supreme-gg-gg

Copy link
Copy Markdown
Contributor

@vramahandry this commit is not properly signed off: 40bec6b you need to do that for DCO to pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] RemoteHitlHint drops the sub-agent's actual ask_user question, only names the tool

2 participants