Skip to content

Display delegate sub agents logs in UI#7519

Merged
jamadeo merged 7 commits intomainfrom
zane/delegate-tool-call-display
Mar 23, 2026
Merged

Display delegate sub agents logs in UI#7519
jamadeo merged 7 commits intomainfrom
zane/delegate-tool-call-display

Conversation

@zanesq
Copy link
Copy Markdown
Contributor

@zanesq zanesq commented Feb 25, 2026

Summary

Improved the desktop app's UX for delegate/subagent tool calls.

Problem:
When goose delegates tasks to subagents, the UI had no visual distinction
for these tool calls, they used generic icons, had no descriptions, and
there was no way to navigate to the subagent's session to see what it did.

Addressed it by:

  1. Created a dedicated delegate tool icon (indigo with arrow+dot motif)
    and added icon mappings for both "delegate" and "load" tools.

  2. Added descriptive labels for delegate/load tool calls in the collapsed
    view (e.g. "delegating: Read and summarize the README").

  3. Added a "View subagent session" button on completed delegate tool calls
    that opens the subagent's full conversation in a new window.

  4. Improved subagent activity log rendering during live delegation — logs
    now show "Activity (N)" with formatted entries like "shell · developer"
    instead of raw notification strings.

image image

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d89fd922aa

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

When a delegate call is cancelled or fails, the subagent session still
exists with partial work. Previously the session ID was only set on
success, so the 'View subagent session' link wouldn't appear for
cancelled delegates. Now we always include the session ID in meta
regardless of outcome.
@zanesq
Copy link
Copy Markdown
Contributor Author

zanesq commented Feb 26, 2026

@tlongwell-block added displaying the sub agent session link when cancelled also. I also tried to show it mid stream but it doesn't work well because we don't auto refresh the stream when opened in a new window (no realtime push mechanism) so I gated it only on tool call finished for now (includes cancelled state)

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e73e8e3007

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@jamadeo jamadeo self-assigned this Mar 6, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98dfc38fb3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

toolResponse?: ToolResponseMessageContent,
notifications?: NotificationEvent[]
): string | null {
const sessionId = toolResponse?.metadata?.subagent_session_id;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Read subagent session id from tool result _meta

handle_load/handle_delegate now attach subagent_session_id via CallToolResult::with_meta (crates/goose/src/agents/platform_extensions/summon.rs lines 887-893 and 1302-1316), and this component already reads MCP response metadata from toolResponse.toolResult.value._meta for resource URIs a few lines below. Looking on toolResponse.metadata here points at the provider-metadata field instead, so the new “View subagent session” button never appears for normal completed delegate/load calls unless a streamed subagent_tool_request notification happens to be present.

Useful? React with 👍 / 👎.

const sessionId = toolResponse?.metadata?.subagent_session_id;
if (typeof sessionId === 'string') return sessionId;

// Fallback: extract from subagent notifications (e.g. when delegate was cancelled mid-stream)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

toolResponse?.metadata is the provider metadata (from the LLM request), not the CallToolResult._meta where the Rust code puts subagent_session_id. The correct path to reach the _meta set via CallToolResult::with_meta is through the serialized tool result value, e.g. toolResponse.toolResult{status: "success", value: {content: [...], _meta: {subagent_session_id: "..."}}}.

You can see the existing pattern at line ~106 of this same file: resultWithMeta.value._meta?.ui?.resourceUri. This should be something like:

const result = toolResponse?.toolResult as { status?: string; value?: { _meta?: Record<string, unknown> } };
const sessionId = result?.status === 'success' ? result?.value?._meta?.subagent_session_id : undefined;
if (typeof sessionId === 'string') return sessionId;

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

const parts = toolCallName.split('__').reverse();
const toolName = parts[0] || 'unknown';
const extensionName = parts.slice(1).reverse().join('__') || '';

P2 Badge Parse subagent tool names using the last __ delimiter

formatSubagentToolCall splits the full tool name on every "__", but this component already documents that normalized extension names can themselves contain extra underscores and must be parsed with lastIndexOf('__'). For names like my_server(local)___get_time, this code reports the delegated tool as _get_time under extension my_server_local, so the new Activity view mislabels MCP calls from any server whose normalized name includes the delimiter pattern.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +1242 to +1244
if params.r#async {
return self.handle_async_delegate(session_id, params).await;
let content = self.handle_async_delegate(session_id, params).await?;
return Ok(CallToolResult::success(content));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Carry async delegate session ids into the initial tool result

When params.async is true, this branch returns a plain CallToolResult::success(content) even though handle_async_delegate uses the spawned subagent session id as the task id. The new UI can only show “View subagent session” from _meta.subagent_session_id or from notifications, and tool_stream stops forwarding notifications once the result is emitted, so the common async-delegate case gets neither live activity nor a clickable way to inspect the running subagent from the original delegate(async: true) call.

Useful? React with 👍 / 👎.

@jamadeo jamadeo enabled auto-merge March 23, 2026 18:32
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

const parts = toolCallName.split('__').reverse();
const toolName = parts[0] || 'unknown';
const extensionName = parts.slice(1).reverse().join('__') || '';

P2 Badge Split delegated tool names on the last __ delimiter

This parser regresses delegated activity logs for MCP extensions whose sanitized name ends with _ (the same file already documents the my_server(local)my_server_local___get_time case at lines 138-145). Using split('__') here turns that tool call into _get_time from extension my_server_local, so the new subagent log UI mislabels both the tool and extension exactly in the environments where name normalization adds a trailing underscore.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +846 to +848
window.electron.createChatWindow({
resumeSessionId: subagentSessionId,
viewType: 'pair',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pass the subagent working dir into createChatWindow

When the delegated session belongs to a different repo than the most recent directory, this new button opens the window against the wrong project because create-chat-window falls back to loadRecentDirs()[0] whenever dir is omitted (ui/desktop/src/main.ts:2123-2126). The existing “open session in new window” flow already passes session.working_dir for that reason (ui/desktop/src/components/sessions/SessionListView.tsx:539-543), so clicking “View subagent session” can resume the right session ID but boot the window with the wrong GOOSE_WORKING_DIR and project-scoped UI state.

Useful? React with 👍 / 👎.

@jamadeo jamadeo added this pull request to the merge queue Mar 23, 2026
Merged via the queue into main with commit ed5e130 Mar 23, 2026
23 checks passed
@jamadeo jamadeo deleted the zane/delegate-tool-call-display branch March 23, 2026 18:45
wpfleger96 added a commit that referenced this pull request Mar 23, 2026
* origin/main:
  fix: handle reasoning content blocks in OpenAI-compat streaming parser (#8078)
  chore(acp): build native packages on latest mac (#8075)
  Display delegate sub agents logs in UI (#7519)
  Update tar version to avoid CVE-2026-33056 (#8073)
  refactor: consolidate duplicated dependencies into workspace (#8041)
  tui: set up for publishing via github actions (#8020)
  feat: feature-gate local inference dependencies (#7976)
  feat: ability to manage sub recipes in desktop ui (#6360)
lifeizhou-ap added a commit that referenced this pull request Mar 24, 2026
* main: (37 commits)
  fix: handle reasoning content blocks in OpenAI-compat streaming parser (#8078)
  chore(acp): build native packages on latest mac (#8075)
  Display delegate sub agents logs in UI (#7519)
  Update tar version to avoid CVE-2026-33056 (#8073)
  refactor: consolidate duplicated dependencies into workspace (#8041)
  tui: set up for publishing via github actions (#8020)
  feat: feature-gate local inference dependencies (#7976)
  feat: ability to manage sub recipes in desktop ui (#6360)
  Tweak the release process: no more merge to main (#7994)
  fix: gemini models via databricks (#8042)
  feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506)
  fix: remove configured marker when deleting oauth provider configuration (#7887)
  docs: add vmware-aiops MCP extension documentation (#8055)
  Show setup instructions for ACP providers in settings modal (#8065)
  deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064)
  feat(acp): add session/set_config and stabilize list, delete and close (#7984)
  docs: Correct `gosoe` typo to `goose` (#8062)
  fix: use default provider and model when provider in session no longer exists (#8035)
  feat: add GOOSE_SHELL env var to configure preferred shell (#7909)
  fix(desktop): fullscreen header bar + always-visible close controls (#8033)
  ...
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.

2 participants