Skip to content

improve extensions management and usage context#8926

Open
morgmart wants to merge 13 commits intomainfrom
extensions-followup
Open

improve extensions management and usage context#8926
morgmart wants to merge 13 commits intomainfrom
extensions-followup

Conversation

@morgmart
Copy link
Copy Markdown
Collaborator

@morgmart morgmart commented Apr 30, 2026

🤖 Category: improvement
User Impact: Users get a dedicated Extensions view and clearer chat context about which extensions were actually used, while agent-enabled MCP extensions are now scoped to the current chat/session instead of silently changing future chats.

Problem: Extension management was split across settings, config defaults, chat-time extension usage, and agent-managed MCP enablement. The previous branch behavior blurred those boundaries: when the Extension Manager enabled an MCP extension from chat, it persisted that as a global config change for future chats. We also had a temporary special case that kept global toggles for three default-off Goose capabilities (chatrecall, summarize, and code_execution), which is no longer the right model.

Solution: This PR separates extension defaults from session state:

  • The Extensions page manages configured extensions and global defaults for future chats.
  • User-managed external extensions (stdio / streamable_http) can still be added, edited, and deleted from the Extensions view, but they no longer have global enable/disable toggles.
  • Built-in/platform Goose capabilities no longer get the old special-case global toggles for chatrecall, summarize, and code_execution.
  • When the agent uses the Extension Manager to enable or disable an extension, that change updates the live extension manager and persists only to the current session's extension_data.enabled_extensions.
  • Resuming a session restores that session-specific extension set; starting a different chat falls back to the global defaults unless that chat has its own saved session extension state.
  • The chat context panel now uses typed session extension status data to show only extensions actually used by tool requests in that conversation, including connection state and tool counts.
Notable implementation details

Session-scoped agent extension management

  • crates/goose/src/agents/platform_extensions/ext_manager.rs now treats manage_extensions as a session operation.
  • Enable looks up the configured extension, adds it to the live ExtensionManager, upserts it into the current session's saved extension list, and reports that it was enabled "for this session."
  • Disable removes the extension from the current session's desired extension list and from the live manager when present. This also handles the case where an extension was saved on the session but failed to connect.
  • The extension manager no longer writes agent-managed enable/disable actions back to global config.

Session status API and generated types

  • crates/goose-sdk/src/custom_requests.rs adds typed DTOs for session extension status, including ExtensionConfigDto, SessionExtensionStatusDto, and ExtensionConnectionStatusDto.
  • crates/goose/src/acp/server/extensions.rs returns typed status records instead of ad hoc JSON, redacts secret env/header values, and includes tool inventory for connected extensions.
  • Generated ACP schema and TypeScript SDK files were regenerated for the new typed status response.

Global config and settings behavior

  • crates/goose/src/config/extensions.rs resolves extension lookup through normalized config keys, so display names and config keys line up more reliably.
  • ui/goose2/src/features/extensions/ui/ExtensionItem.tsx no longer renders global enable/disable toggles; user-managed external extensions remain configurable via the settings button.
  • ui/goose2/src/features/extensions/hooks/useExtensionsSettings.ts preserves an existing extension's enabled value when editing its config.
  • The previous special-case toggle list for chatrecall, summarize, and code_execution was removed.

Chat extension usage

  • ui/goose2/src/features/chat/ui/widgets/ExtensionsWidget.tsx fetches _goose/session/extensions/status, merges in configured extension metadata for historical/unavailable usage, and displays only extensions used by tool requests in the current chat.
  • The widget refreshes when a new tool owner appears, so newly enabled/used extensions do not stay stale.
  • ui/goose2/src/shared/api/acpNotificationHandler.ts now reads tool identity from the actual _meta.goose.mcpApp metadata shape, keeps the older _meta.goose.toolCall path as a fallback, and attaches toolName / extensionName in both live and replay flows.

Navigation and UI

  • Extensions now has a top-level sidebar entry and dedicated page shell.
  • The settings modal no longer owns extension management.
  • Extension rows, filters, usage helpers, and i18n copy were updated for the new management model.

Reproduction Steps

  1. Open Goose desktop and confirm the sidebar includes an Extensions navigation item.
  2. Navigate to Extensions and verify configured extensions are searchable and grouped between apps/services and Goose capabilities.
  3. Confirm user-managed stdio / streamable_http extensions can be configured, edited, and deleted, but do not show global enable/disable controls.
  4. Confirm built-in/platform Goose capabilities, including chatrecall, summarize, and code_execution, do not get special global enable/disable controls.
  5. From chat, ask Goose to use an extension that is not active in the current session.
  6. Confirm the Extension Manager can enable it for that chat and that the response says it was enabled for the session.
  7. Start or open another chat and confirm that agent-enabled extension does not become globally enabled there unless it is part of that chat's own saved session state.
  8. Open a chat that has used extension-backed tools and check the context panel Details tab.
  9. Confirm the Extensions used widget lists only extensions used in that chat, with connection status and tool counts.
  10. Add, edit, disable, or delete a configurable external extension and confirm the list refreshes without reopening the page.

Verification

  • cargo fmt
  • just generate-acp-types
  • pnpm test src/features/extensions/lib/__tests__/extensionUsage.test.ts src/features/extensions/lib/__tests__/extensionCategories.test.ts
  • pnpm test src/features/extensions/ui/__tests__/ExtensionsSettings.test.tsx
  • pnpm test src/shared/api/__tests__/acpNotificationHandler.test.ts
  • pnpm typecheck
  • git diff --check
  • Commit/pre-commit hooks passed their configured formatting, file-size, i18n, and typecheck steps. They emitted existing non-fatal warnings about broken local skill symlinks and platform/engine mismatches.
Screen.Recording.2026-04-29.at.7.27.54.PM.mov

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: 1adcc39885

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/goose2/src/features/chat/ui/widgets/ExtensionsWidget.tsx Outdated
chatgpt-codex-connector[bot]

This comment was marked as resolved.

@morgmart morgmart force-pushed the extensions-followup branch from 8d9b1d3 to 08f6a41 Compare April 30, 2026 02:23
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: 9313b4309b

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/goose/src/acp/server.rs Outdated
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: e79bd7facc

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/goose/src/acp/server.rs Outdated
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: 82fda94231

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/goose2/src/features/extensions/ui/ExtensionItem.tsx Outdated
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: 2cd62a80a4

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/goose2/src/features/sidebar/ui/SidebarRecentsSection.tsx
Comment thread crates/goose-sdk/src/custom_requests.rs Outdated
Comment thread crates/goose/src/config/extensions.rs Outdated
Comment thread crates/goose/src/config/extensions.rs Outdated
Comment thread crates/goose/src/acp/server.rs Outdated
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: ab85f69863

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/goose2/src/features/extensions/api/extensions.ts Outdated
Comment thread ui/goose2/src/features/extensions/hooks/useExtensionsSettings.ts Outdated
morgmart added 11 commits April 30, 2026 11:27
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
@morgmart morgmart force-pushed the extensions-followup branch from ab85f69 to 61d82aa Compare April 30, 2026 21:27
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: 61d82aa14d

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/goose2/src/shared/api/acpNotificationHandler.ts Outdated
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
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: 9150ad1965

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +124 to +128
owners.add(toolRequestOwnerKey(content));
}
}
}
return Array.from(owners).sort().join("|");
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 Refresh extension status on repeated owner activity

The status fetch is keyed off toolOwnerSignature, but this signature is built from a deduplicated owner set, so it does not change when more tool calls arrive from owners already seen. In practice, if the first fetch fails or an extension transitions state later (for example after reconnect/auth), the widget can keep stale failed/unavailable data indefinitely because the effect never reruns for same-owner activity. Use a signature that changes per tool request (count or latest timestamp) or trigger periodic/focus refreshes.

Useful? React with 👍 / 👎.

Comment on lines +119 to +121
item.config_key === configKey
? { ...item, enabled: extension.enabled }
: item,
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 Restore toggle state from authoritative source on errors

The error rollback writes enabled: extension.enabled from the callback argument, which can be an intermediate optimistic value during rapid consecutive toggles. If multiple toggle requests fail, version gating suppresses earlier rollbacks and the final rollback may preserve the wrong optimistic state, leaving UI and backend out of sync until a later full reload. Capture the pre-toggle value from current state per request or force a fetchExtensions() on failure to realign.

Useful? React with 👍 / 👎.

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
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: 46f7464055

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +119 to +124
const toolOwnerSignature = useMemo(() => {
const owners = new Set<string>();
for (const message of messages) {
for (const content of message.content) {
if (content.type === "toolRequest") {
owners.add(toolRequestOwnerKey(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 Trigger extension-status refresh for repeated tool activity

Build the refresh key from all tool requests (or include a monotonic counter/timestamp), not just a deduplicated owner set. As written, once an owner appears once, additional calls from that same owner do not change toolOwnerSignature, so the effect never refetches status; if the first fetch failed or the extension later reconnects/authenticates, the widget can stay stale indefinitely for that chat.

Useful? React with 👍 / 👎.

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