diff --git a/site/src/pages/AgentsPage/components/ChatConversation/StreamingOutput.tsx b/site/src/pages/AgentsPage/components/ChatConversation/StreamingOutput.tsx
index 56cb79014d..ba894a3eb0 100644
--- a/site/src/pages/AgentsPage/components/ChatConversation/StreamingOutput.tsx
+++ b/site/src/pages/AgentsPage/components/ChatConversation/StreamingOutput.tsx
@@ -23,7 +23,7 @@ const LiveActivitySlot: FC = () => (
data-testid="live-activity-slot"
className="flex h-6 items-center gap-2 text-content-secondary"
>
-
+
Thinking
diff --git a/site/src/pages/AgentsPage/components/ChatConversation/messageParsing.test.ts b/site/src/pages/AgentsPage/components/ChatConversation/messageParsing.test.ts
index 7d3fa92bd8..53356484d7 100644
--- a/site/src/pages/AgentsPage/components/ChatConversation/messageParsing.test.ts
+++ b/site/src/pages/AgentsPage/components/ChatConversation/messageParsing.test.ts
@@ -1151,30 +1151,4 @@ describe("getSubagentDescriptor", () => {
});
}
});
-
- it("renders list_agents with a fixed generic affordance", () => {
- const descriptor = getSubagentDescriptor({
- name: "list_agents",
- args: {},
- result: {
- agents: [
- { chat_id: "agent-1", type: "explore", status: "completed" },
- { chat_id: "agent-2", type: "computer_use", status: "running" },
- ],
- total: 2,
- returned: 2,
- offset: 0,
- has_more: false,
- },
- });
-
- // The list result has no single top-level type, so the descriptor
- // must not derive a variant from per-agent types.
- expect(descriptor).toMatchObject({
- action: "list",
- variant: "general",
- iconKind: "bot",
- supportsDesktopAffordance: false,
- });
- });
});
diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/CreateWorkspaceTool.tsx b/site/src/pages/AgentsPage/components/ChatElements/tools/CreateWorkspaceTool.tsx
index 970ed61de2..ece7f4ff17 100644
--- a/site/src/pages/AgentsPage/components/ChatElements/tools/CreateWorkspaceTool.tsx
+++ b/site/src/pages/AgentsPage/components/ChatElements/tools/CreateWorkspaceTool.tsx
@@ -2,7 +2,7 @@ import { ExternalLinkIcon } from "lucide-react";
import type React from "react";
import { Link } from "react-router";
import { ToolCall } from "./ToolCall";
-import { asRecord, asString, type ToolStatus } from "./utils";
+import { asString, parseArgs, type ToolStatus } from "./utils";
import { WorkspaceBuildLogSection } from "./WorkspaceBuildLogSection";
/**
@@ -32,15 +32,7 @@ export const CreateWorkspaceTool: React.FC<{
labelOverride,
}) => {
const isRunning = status === "running";
- let rec: Record | null = null;
- if (resultJson) {
- try {
- const parsed = JSON.parse(resultJson);
- rec = asRecord(parsed);
- } catch {
- rec = asRecord(resultJson);
- }
- }
+ const rec = parseArgs(resultJson);
const ownerName = rec ? asString(rec.owner_name) : "";
const wsName = rec ? asString(rec.workspace_name) : workspaceName;
const workspaceLink = ownerName && wsName ? `/@${ownerName}/${wsName}` : null;
diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/ExecuteTool.stories.tsx b/site/src/pages/AgentsPage/components/ChatElements/tools/ExecuteTool.stories.tsx
index f30e469874..bae1044512 100644
--- a/site/src/pages/AgentsPage/components/ChatElements/tools/ExecuteTool.stories.tsx
+++ b/site/src/pages/AgentsPage/components/ChatElements/tools/ExecuteTool.stories.tsx
@@ -35,14 +35,6 @@ export const ShortCommand: Story = {
},
};
-export const RunningWithoutCommand: Story = {
- args: {
- command: "",
- status: "running",
- transcriptBlocks: [],
- },
-};
-
export const LongCommand: Story = {
decorators: [
(Story) => (
diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/ExecuteTool.tsx b/site/src/pages/AgentsPage/components/ChatElements/tools/ExecuteTool.tsx
index 329773e056..2e6add7289 100644
--- a/site/src/pages/AgentsPage/components/ChatElements/tools/ExecuteTool.tsx
+++ b/site/src/pages/AgentsPage/components/ChatElements/tools/ExecuteTool.tsx
@@ -56,7 +56,6 @@ export const ExecuteTool: React.FC = ({
parsedCommands,
shellToolDisplayMode,
}) => {
- const hasCommand = command.trim().length > 0;
const hasTranscriptBlocks = transcriptBlocks.length > 0;
const autoDisplayState: AgentDisplayState =
hasTranscriptBlocks ||
@@ -78,10 +77,6 @@ export const ExecuteTool: React.FC = ({
autoDisplayState,
);
- if (!hasCommand) {
- return null;
- }
-
return (
{
- const Renderer =
- isSubagentToolName(name) && name !== "list_agents"
- ? SubagentRenderer
- : (toolRenderers[name] ?? GenericToolRenderer);
+ const Renderer = isSubagentToolName(name)
+ ? SubagentRenderer
+ : (toolRenderers[name] ?? GenericToolRenderer);
const isShellTool = name === "execute" || name === "process_output";
if (!shouldRenderTool({ name, status, args, result })) {
return null;
diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/ToolCall.tsx b/site/src/pages/AgentsPage/components/ChatElements/tools/ToolCall.tsx
index cd51f618b0..d9023d6f87 100644
--- a/site/src/pages/AgentsPage/components/ChatElements/tools/ToolCall.tsx
+++ b/site/src/pages/AgentsPage/components/ChatElements/tools/ToolCall.tsx
@@ -15,7 +15,6 @@ import {
import { cn } from "#/utils/cn";
import { Shimmer } from "../Shimmer";
import { TranscriptRow } from "../TranscriptRow";
-import type { SubagentIconKind } from "./subagentDescriptor";
import { ToolIcon } from "./ToolIcon";
import type { ToolStatus } from "./utils";
@@ -208,7 +207,6 @@ type ToolCallLeadingIconProps = {
children?: ReactNode;
iconUrl?: string;
serverName?: string;
- subagentIconKind?: SubagentIconKind;
};
const LeadingIcon: FC = ({
@@ -216,9 +214,8 @@ const LeadingIcon: FC = ({
children,
iconUrl,
serverName,
- subagentIconKind,
}) => {
- const { active, failed } = useToolCallContext();
+ const { active } = useToolCallContext();
if (children) {
return <>{children}>;
}
@@ -229,11 +226,9 @@ const LeadingIcon: FC = ({
return (
);
};
@@ -267,16 +262,11 @@ const Label: FC = ({
type ToolCallStatusProps = {
className?: string;
- errorMessage?: string;
};
-const Status: FC = ({ className, errorMessage }) => {
- const {
- active,
- errorMessage: contextErrorMessage,
- failed,
- } = useToolCallContext();
- const message = errorMessage || contextErrorMessage || "Tool call failed";
+const Status: FC = ({ className }) => {
+ const { active, errorMessage, failed } = useToolCallContext();
+ const message = errorMessage || "Tool call failed";
return (
<>
{active && (
@@ -367,7 +357,6 @@ type ToolCallHeaderProps = {
label: ReactNode;
iconUrl?: string;
serverName?: string;
- subagentIconKind?: SubagentIconKind;
secondaryLabel?: ReactNode;
trailing?: ReactNode;
showStatus?: boolean;
@@ -388,7 +377,6 @@ const Header: FC = ({
label,
iconUrl,
serverName,
- subagentIconKind,
secondaryLabel,
trailing,
showStatus = true,
@@ -396,12 +384,7 @@ const Header: FC = ({
}) => {
return (
-
+
{secondaryLabel}
{showStatus && }
diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/ToolIcon.tsx b/site/src/pages/AgentsPage/components/ChatElements/tools/ToolIcon.tsx
index c2ff74debb..6db7eb5604 100644
--- a/site/src/pages/AgentsPage/components/ChatElements/tools/ToolIcon.tsx
+++ b/site/src/pages/AgentsPage/components/ChatElements/tools/ToolIcon.tsx
@@ -22,19 +22,13 @@ import {
TooltipTrigger,
} from "#/components/Tooltip/Tooltip";
import { cn } from "#/utils/cn";
-import {
- isSubagentToolName,
- type SubagentIconKind,
-} from "./subagentDescriptor";
export const ToolIcon: React.FC<{
name: string;
- isError: boolean;
iconUrl?: string;
isRunning?: boolean;
serverName?: string;
- subagentIconKind?: SubagentIconKind;
-}> = ({ name, iconUrl, isRunning, serverName, subagentIconKind }) => {
+}> = ({ name, iconUrl, isRunning, serverName }) => {
const [imgError, setImgError] = useState(false);
const color = "text-current";
const base = cn(
@@ -80,20 +74,6 @@ export const ToolIcon: React.FC<{
return img;
}
- if (isSubagentToolName(name)) {
- // This name-based fallback only exists for legacy callers that do
- // not pass a descriptor. The descriptor path should provide
- // subagentIconKind for new subagent types instead of extending it.
- const iconKind =
- subagentIconKind ||
- (name === "spawn_computer_use_agent" ? "monitor" : "bot");
- return iconKind === "monitor" ? (
-
- ) : (
-
- );
- }
-
switch (name) {
case "execute":
case "process_output":
@@ -116,6 +96,7 @@ export const ToolIcon: React.FC<{
case "start_workspace":
return ;
case "chat_summarized":
+ case "list_agents":
return ;
case "thinking":
return ;
diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/ToolLabel.tsx b/site/src/pages/AgentsPage/components/ChatElements/tools/ToolLabel.tsx
index b8babecf7a..078aa5d9ae 100644
--- a/site/src/pages/AgentsPage/components/ChatElements/tools/ToolLabel.tsx
+++ b/site/src/pages/AgentsPage/components/ChatElements/tools/ToolLabel.tsx
@@ -1,58 +1,7 @@
import type React from "react";
import { getPathBasename } from "../../../utils/path";
-import {
- getProvidedSubagentTitle,
- getSubagentDescriptor,
-} from "./subagentDescriptor";
import { asRecord, asString, humanizeMCPToolName, parseArgs } from "./utils";
-const renderSubagentLabel = (
- name: string,
- args: unknown,
- result: unknown,
-): React.ReactNode | null => {
- const descriptor = getSubagentDescriptor({ name, args, result });
- if (!descriptor) {
- return null;
- }
-
- const providedTitle = getProvidedSubagentTitle({ args, result });
- const fallbackTitle = descriptor.fallbackTitle;
- const text = (() => {
- switch (descriptor.action) {
- case "spawn":
- if (providedTitle) {
- return `Spawning ${providedTitle}`;
- }
- if (descriptor.variant === "explore") {
- return "Spawning Explore agent…";
- }
- if (descriptor.variant === "computer_use") {
- return "Spawning computer use sub-agent…";
- }
- return `Spawning ${fallbackTitle}…`;
- case "wait":
- return providedTitle
- ? `Waiting for ${providedTitle}`
- : `Waiting for ${fallbackTitle}…`;
- case "message":
- return providedTitle
- ? `Messaging ${providedTitle}`
- : `Messaging ${fallbackTitle}…`;
- case "interrupt":
- return providedTitle
- ? `Interrupting ${providedTitle}`
- : `Interrupting ${fallbackTitle}`;
- case "list":
- return providedTitle
- ? `Listing ${providedTitle}`
- : `Listing ${fallbackTitle}`;
- }
- })();
-
- return {text};
-};
-
export const ToolLabel: React.FC<{
name: string;
args: unknown;
@@ -61,14 +10,6 @@ export const ToolLabel: React.FC<{
}> = ({ name, args, result, mcpSlug }) => {
const parsed = parseArgs(args);
const parsedResult = asRecord(result);
- const subagentLabel = renderSubagentLabel(
- name,
- parsed ?? args,
- parsedResult ?? result,
- );
- if (subagentLabel) {
- return subagentLabel;
- }
switch (name) {
case "execute": {
diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/subagentDescriptor.ts b/site/src/pages/AgentsPage/components/ChatElements/tools/subagentDescriptor.ts
index 8011c4a642..8d954b830a 100644
--- a/site/src/pages/AgentsPage/components/ChatElements/tools/subagentDescriptor.ts
+++ b/site/src/pages/AgentsPage/components/ChatElements/tools/subagentDescriptor.ts
@@ -1,14 +1,9 @@
import { asString } from "../runtimeTypeUtils";
import { parseArgs } from "./utils";
-export type SubagentAction =
- | "spawn"
- | "wait"
- | "message"
- | "interrupt"
- | "list";
+export type SubagentAction = "spawn" | "wait" | "message" | "interrupt";
export type SubagentVariant = "general" | "explore" | "computer_use";
-export type SubagentIconKind = "bot" | "monitor";
+type SubagentIconKind = "bot" | "monitor";
export type SubagentDescriptor = {
action: SubagentAction;
@@ -59,11 +54,6 @@ const actionByToolName: Record = {
// Legacy persisted tool name kept so old chat histories still render.
close_agent: "interrupt",
interrupt_agent: "interrupt",
- // list_agents is a subagent tool but renders through
- // ListAgentsRenderer, not SubagentRenderer. The "list" action
- // exists for isSubagentToolName classification and ToolIcon
- // dispatch, not for the SubagentRenderer label machinery.
- list_agents: "list",
};
const variantBySpawnToolName: Record = {
diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/toolVisibility.test.ts b/site/src/pages/AgentsPage/components/ChatElements/tools/toolVisibility.test.ts
index 31f68826e0..077a626468 100644
--- a/site/src/pages/AgentsPage/components/ChatElements/tools/toolVisibility.test.ts
+++ b/site/src/pages/AgentsPage/components/ChatElements/tools/toolVisibility.test.ts
@@ -136,7 +136,7 @@ describe("toolVisibility", () => {
).toBe(false);
});
- it("renders list_agents rows even without a chat_id", () => {
+ it("renders list_agents rows regardless of chat_id", () => {
expect(
shouldRenderTool({
name: "list_agents",