Skip to content

feat(agents): add the agent details panel - #243

Open
marekdano wants to merge 4 commits into
mainfrom
7518-agent-details-panel
Open

marekdano wants to merge 4 commits into
mainfrom
7518-agent-details-panel

Conversation

@marekdano

@marekdano marekdano commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds the agent details panel from the Figma design. It opens from View details in an agent card's ⋮ menu and follows the existing details panels (ResourceDetailsPanel, ToolDetailsPanel).

Closes IBM/mcp-context-forge#7518. Part of IBM/mcp-context-forge#7023.

What it shows

  • Main column: name, description, skills, capabilities, input/output modes, authentication type, and the plugins bound to the agent.
  • Sidebar: status, visibility, protocol, agent type, endpoint, agent ID, team, tags, owner, created, last modified, last used.
  • The panel only reads the authentication type. A test confirms a token on the agent never appears.

Behaviour

  • Reads GET /v1/a2a/{id} and GET /v1/a2a/{id}/card on open. The card supplies skills and modes; if it fails, the rest still renders.
  • Plugins: GET /v1/a2a-agents/plugin-bindings/{team_id}, filtered to this agent and team-wide (*) bindings. Removal uses DELETE .../plugin-bindings/{id}.
  • Tags are added inline with the shared InlineTagAdd, saved with PUT /v1/a2a/{id} and { tags }, as on the other pages.
  • Enabled state and tags come from the list entry, so the panel updates as soon as Enable/Disable or an added tag is saved, and rolls back with the list.
  • Permissions: a2a.update (enable/disable, add tag), a2a.delete (delete), tools.read (show plugins), tools.manage_plugins (remove a binding).
  • List card: the description is removed and clicking the card does nothing. The panel opens only from the menu, which now always has View details.

Notes

  • Agent type shows the stored value ("generic" by default). The design shows "JSON-RPC", which is a protocol binding the gateway does not store yet. TODO(IBM/mcp-context-forge#7383).
  • Adding a plugin binding is not included. It needs a plugin picker that the design does not show. Listing and removal are.
  • Escape, the close button and focus restore match the other panels.

Testing

  • Unit: AgentDetailsPanel.test.tsx, Agents.test.tsx, agents.test.ts (panel content, no credential shown, card failure, plugin list/remove/permissions, tag add, enabled state following the list, menu behaviour). The translation parity test passes.
  • Playwright: 8 new tests in e2e/agents.spec.ts. The agents spec passes (41 tests).
  • Full unit suite passes (3,641 tests). Typecheck, ESLint and Prettier are clean.

Screenshot

Screenshot 2026-11-13 at 13 19 49

  Open a details panel from "View details" in an agent card's menu. The panel
  shows the agent's configuration, skills, capabilities, input/output modes and
  authentication type, and the plugins bound to it. Follows the Figma design and
  the existing details panels.

  - Read the agent (GET /v1/a2a/{id}) and its card (GET /v1/a2a/{id}/card) on
    open; the card supplies skills and modes, and the panel still renders if it
    fails. Show only the authentication type, never a credential value.
  - List the plugin bindings for the agent's team that name this agent or are
    team-wide, and remove one with DELETE /v1/a2a-agents/plugin-bindings/{id}.
  - Add tags inline with the shared InlineTagAdd (PUT /v1/a2a/{id} with tags).
  - Gate actions on permissions: a2a.update (enable/disable, add tag), a2a.delete,
    tools.read (show plugins), tools.manage_plugins (remove a binding).
  - Take enabled state and tags from the list entry so the panel follows a toggle
    or tag add straight away.
  - Remove the description from the list card; clicking a card does nothing.
  - Show the stored agent type ("generic" by default) until the gateway stores
    the protocol binding. TODO(IBM/mcp-context-forge#7383).
  - Add en-US, es-ES and pt-BR strings, unit tests and Playwright tests.

Signed-off-by: Marek Dano <mk.dano@gmail.com>
  Open a details panel from "View details" in an agent card's menu. The panel
  shows the agent's configuration, skills, capabilities, input/output modes and
  authentication type, and the plugins bound to it. Follows the Figma design and
  the existing details panels.

  - Read the agent (GET /v1/a2a/{id}) and its card (GET /v1/a2a/{id}/card) on
    open; the card supplies skills and modes, and the panel still renders if it
    fails. Show only the authentication type, never a credential value.
  - List the plugin bindings for the agent's team that name this agent or are
    team-wide, and remove one with DELETE /v1/a2a-agents/plugin-bindings/{id}.
  - Add tags inline with the shared InlineTagAdd (PUT /v1/a2a/{id} with tags).
  - Gate actions on permissions: a2a.update (enable/disable, add tag), a2a.delete,
    tools.read (show plugins), tools.manage_plugins (remove a binding).
  - Take enabled state and tags from the list entry so the panel follows a toggle
    or tag add straight away. Ignore fetched data when no agent is selected.
  - Remove the description from the list card; clicking a card does nothing.
  - Show the stored agent type ("generic" by default) until the gateway stores
    the protocol binding. TODO(IBM/mcp-context-forge#7383).
  - Add en-US, es-ES and pt-BR strings, unit tests and Playwright tests.

Signed-off-by: Marek Dano <mk.dano@gmail.com>

@gcgoncalves gcgoncalves 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.

Solid PR, found nits only.

Comment thread src/i18n/locales/en-US/agents.json Outdated
"agents.connect.manual.description.label": "Description",
"agents.connect.manual.description.placeholder": "Add an optional description..."
"agents.connect.manual.description.placeholder": "Add an optional description...",
"agents.details.region": "Details of {name}",

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.

Translation added, but not used.

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.

Fixed!

Comment on lines +158 to +165
const current: AgentDetailsFields | null =
agent && fetched
? {
...fetched,
enabled: agent?.enabled ?? fetched.enabled,
tags: agent?.tags ?? fetched.tags,
}
: agent;

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.

useQuery keeps data when its path changes (it only sets isLoading/error; it never clears data). <AgentDetailsPanel> is mounted once in Agents.tsx and re-used for every agent, and the path goes A → null (closed) → B. So after opening agent A and then agent B:

const current = agent && fetched
  ? { ...fetched, enabled: agent?.enabled ?? fetched.enabled, tags: agent?.tags ?? fetched.tags }
  : agent;                                   // ❌ `fetched` is still agent A's until B's request returns
  • Until B's response arrives, the panel renders A's name, description, endpoint, ID, team, owner, protocol and dates, with B's enabled/tags.
  • If B's GET /v1/a2a/{id} fails, A's data stays on screen alongside the "Couldn't load the agent details." message; the test reports a failed read but keeps showing the list entry only passes because it renders a single agent.
  • card (skills, modes, capabilities) and bindingList are stale in the same way; bindings are then filtered by B's name, and the team-wide * bindings of A's team would be shown for B if teams differ.
  • removeBinding could then delete a binding id belonging to the other team's list.

Recommendation: guard on identity and clear on switch. Smallest fix:

const fetchedForThisAgent = fetched?.id === agentId ? fetched : undefined;
const cardForThisAgent = ... // include id in RegisteredAgentCard or key by agentId

or, simpler and more robust, remount the content per agent:

<AgentDetailsPanel key={detailsId ?? "none"} ... />   // in Agents.tsx

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.

Done!

Comment on lines +37 to +61
// Only what the panel renders. `Agent` also carries credential fields
// (authToken, authPassword, ...) that must never reach the UI, so the panel
// accepts this narrower `Pick`: a stray `{agent.authToken}` is a type error.
// `authType` is the kind of credential, never its value.
export type AgentDetailsFields = Pick<
Agent,
| "id"
| "name"
| "description"
| "endpointUrl"
| "agentType"
| "protocolVersion"
| "capabilities"
| "enabled"
| "reachable"
| "tags"
| "authType"
| "visibility"
| "team"
| "teamId"
| "ownerEmail"
| "createdAt"
| "updatedAt"
| "lastInteraction"
>;

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.

Will this list get replaced by Orval generated types after the backend for A2A is complete? If not, the section below tells the user the agent is unauthenticated when it is not.:

const authType: AuthType | "none" = AUTH_TYPES.includes(current?.authType as AuthType)
    ? (current?.authType as AuthType)
    : "none";

It'd be better to fall back to showing something like "Not available" for unknown auth types.

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.

Good point! Fixed!

marekdano and others added 2 commits November 13, 2026 15:03
  - Remount the panel per agent so the previous agent's details, card and
    plugin bindings never show while the next one loads or fails to load
  - Report an unrecognised authentication type as unknown instead of
    presenting it as "No authentication"
  - Remove the unused agents.details.region translation

Signed-off-by: Marek Dano <mk.dano@gmail.com>
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.

[UI-REWRITE]: Build the agent details panel

2 participants