Skip to content

feat: sub-agent session viewing#1383

Open
dobesv wants to merge 4 commits intokagent-dev:mainfrom
dobesv:feat/sub-agent-session-view
Open

feat: sub-agent session viewing#1383
dobesv wants to merge 4 commits intokagent-dev:mainfrom
dobesv:feat/sub-agent-session-view

Conversation

@dobesv
Copy link
Contributor

@dobesv dobesv commented Feb 26, 2026

  • Parent agent assigns session IDs and stores in the event, for linking.
  • UI can see child contextId stored in the event and show a link to it.
  • Allow anyone who knows the ID of a session to access it

Note that this does kind of remove a permission check. This seems OK to me because in its current state kagent does not have multi-user support anyway. Later if multi-user becomes a thing, the permission check could be adjusted somehow.

@dobesv dobesv force-pushed the feat/sub-agent-session-view branch 3 times, most recently from 65a9776 to 75f59e8 Compare February 26, 2026 01:26
@dobesv dobesv marked this pull request as ready for review February 26, 2026 01:39
@dobesv dobesv requested a review from peterj as a code owner February 26, 2026 01:39
Copilot AI review requested due to automatic review settings February 26, 2026 01:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request implements sub-agent session viewing by enabling parent agents to assign session IDs to child agents and linking them in the UI. When a parent agent invokes a child agent, the child's context_id is captured and stored in the event metadata, allowing the UI to display clickable links to the child agent's session.

Changes:

  • Added contextId field to track child session IDs in tool execution events
  • Implemented metadata extraction to move a2a:context_id from function response data to part metadata
  • Created clickable links in the UI that navigate to child agent sessions

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
ui/src/lib/messageHandlers.ts Added optional contextId field to ProcessedToolResultData interface; whitespace cleanup
ui/src/components/chat/ToolCallDisplay.tsx Extract and pass contextId from A2A metadata to AgentCallDisplay component; whitespace cleanup
ui/src/components/chat/AgentCallDisplay.tsx Display contextId as clickable link to child agent session using parsed tool name
python/packages/kagent-adk/tests/unittests/test_agent_tool.py Comprehensive test coverage for metadata extraction from function responses
python/packages/kagent-adk/src/kagent/adk/converters/part_converter.py Extract a2a:context_id and a2a:task_id from function response data to DataPart metadata
go/internal/mcp/mcp_handler.go Always generate context_id for child agent sessions to enable deterministic session IDs
Comments suppressed due to low confidence (1)

python/packages/kagent-adk/src/kagent/adk/converters/part_converter.py:179

  • The code uses response.pop() to extract metadata keys from the response dict, which mutates the original dictionary. However, data is created from part.function_response.model_dump() which creates a new dict, so this mutation affects the converted data dict but not the original part object. This should be fine but could be clearer. Consider adding a comment explaining that pop() is used intentionally to both extract and remove these internal metadata keys from the response data.
            sub_ctx_id = response.pop("a2a:context_id", None)
            sub_task_id = response.pop("a2a:task_id", None)
            if sub_ctx_id:
                metadata["a2a:context_id"] = sub_ctx_id
            if sub_task_id:
                metadata["a2a:task_id"] = sub_task_id

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Parent agents now pre-assign the child session ID via context_id. The UI links directly
to child sessions via the pre-assigned context_id.

Signed-off-by: Dobes Vandermeer <dobes.vandermeer@newsela.com>
Signed-off-by: Dobes Vandermeer <dobes.vandermeer@newsela.com>
Signed-off-by: Dobes Vandermeer <dobes.vandermeer@newsela.com>
@dobesv dobesv force-pushed the feat/sub-agent-session-view branch from 6b8ebac to 5746efa Compare February 26, 2026 02:27
Copy link
Contributor

@EItanya EItanya left a comment

Choose a reason for hiding this comment

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

Why do we need to remove the user_id from the session? Is it because sub-agents don't have the correct user_id set? I don't think we should remove it, I'd prefer to figure out how to make sure it's always present if that's the issue.

@dobesv
Copy link
Contributor Author

dobesv commented Feb 26, 2026

I don't think I removed it from the session. I just changed the session lookup not to require a match on user ID. This is because the sub agent sessions don't have the user's ID.

The session ID should be unique enough to identify the session, we don't need to scope it to the user as well.

An alternative might be to somehow figure out the right user ID to use for the lookup, maybe we know it's a sub-agent session and calculate the user ID based on the session ID.

I also looked at propagation of the user ID to sub-agent sessions but it was getting complex and I wanted to keep the change small. I could attempt that again, though, if you prefer.

@dobesv
Copy link
Contributor Author

dobesv commented Feb 26, 2026

Propagating the user's ID to the sub agent sessions does have the side effect that you can see the sub agent sessions along with your own chats in your chat history. I couldn't quite decide if that's a good thing or not, but my feeling is that it would be a bit noisy as a default.

@dobesv
Copy link
Contributor Author

dobesv commented Feb 26, 2026

Oh to clarify your question... The sub-agent calls have user_id set to a string based on the session ID, so it's a new user every session. It's not blank, but it's also not the user's actual ID. So it doesn't match if the user requests that session by ID.

@EItanya
Copy link
Contributor

EItanya commented Feb 26, 2026

Ok, those are all very good points. Let's step back for 2 seconds and think about the data model from first principles. If you could organize them however you want what do you think you would do. 1 requirement is that it's still important for sessions to be user-scoped, even if that's just the root

@dobesv
Copy link
Contributor Author

dobesv commented Feb 26, 2026

Where does the user scoped session requirement come from? Do you think two users would generate the same session ID?

@EItanya
Copy link
Contributor

EItanya commented Feb 26, 2026

Where does the user scoped session requirement come from? Do you think two users would generate the same session ID?

No, but we need to be able to separate the sessions by the user who created them, otherwise users will be able to see other users sessions

@dobesv
Copy link
Contributor Author

dobesv commented Feb 26, 2026

Another trick I could do here is match a session if the user ID matches OR the user_id on the session is a generated A2A session user_id.

Personally I think that if you know a session ID you can see the session, at least for now since kagent is effectively single user and session IDs are hard enough to guess.

The logic to get a list of sessions is still scoped to the user, you can only search for your own chat sessions.

Fully solving the question of access control to sub-agent sessions might blow up the pull request.

@dobesv
Copy link
Contributor Author

dobesv commented Feb 26, 2026

Where does the user scoped session requirement come from? Do you think two users would generate the same session ID?

No, but we need to be able to separate the sessions by the user who created them, otherwise users will be able to see other users sessions

That part is not affected by this change, I only changed it so when you look by session ID you don't have to match by user ID as well. Getting a list of chats by user ID still matches by user.

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.

3 participants