authorgravatar for 76637177+SunkenInTime@users.noreply.github.comDara Adedeji <76637177+SunkenInTime@users.noreply.github.com> 2026-10-04 01:41:52-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-04 02:41:52-03:00
logdaa1d0ed947c276cb74b08025b5903e2ffe31278
tree1009f4db3e413f9dfce82b90ae85d1c09fa6824a
parenta92c43b80ba307f112e0ae03bf64d841475cf326
signature Signed by PGP key B5690EEEBB952194

fix(web): subagent cards name the provider account (#15493)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

6 files changed, 34 insertions(+), 3 deletions(-)

apps/mobile/src/features/threads/SubagentRow.tsx+2-1
......@@ -1,4 +1,5 @@
11import { scopeProjectRef, scopeThreadRef } from "@t3tools/client-runtime/environment";
2import { resolveProviderInstanceDisplayName } from "@t3tools/client-runtime/state/provider-instance-display";
23import { resolveSubagentMetadata } from "@t3tools/client-runtime/state/subagent-display";
34import type { EnvironmentId, OrchestrationV2Subagent } from "@t3tools/contracts";
45import type { ReactNode } from "react";
......@@ -125,7 +126,7 @@ function SubagentMetadata(props: {
125126 size={12}
126127 />
127128 <Text className="min-w-0 shrink text-xs text-foreground-muted" numberOfLines={1}>
128 {provider?.displayName ? `${provider.displayName} · ` : ""}
129 {provider ? `${resolveProviderInstanceDisplayName(provider)} · ` : ""}
129130 {modelLabel}
130131 </Text>
131132 {workspace.map(({ label, value }) => (
apps/web/src/components/ChatView.tsx+8
......@@ -315,6 +315,7 @@ import {
315315 applyProviderInstanceSettings,
316316 deriveProviderInstanceEntries,
317317 NO_PROVIDER_MODEL_SELECTION,
318 shouldShowInstanceBadge,
318319 sortProviderInstanceEntries,
319320} from "../providerInstances";
320321import {
......@@ -11111,6 +11112,13 @@ export default function ChatView(props: ChatViewProps) {
1111111112 {showProviderSubagentBar ? (
1111211113 <ProviderSubagentBar
1111311114 provider={selectedProviderEntry ?? null}
11115 showInstanceBadge={
11116 selectedProviderEntry !== undefined &&
11117 shouldShowInstanceBadge(
11118 selectedProviderEntry,
11119 providerInstanceEntries,
11120 )
11121 }
1111411122 modelLabel={providerSubagentModelLabel}
1111511123 effortLabel={providerSubagentEffortLabel}
1111611124 status={providerSubagentStatus}
apps/web/src/components/chat/ProviderSubagentBar.tsx+4
......@@ -18,6 +18,8 @@ import { ProviderInstanceIcon } from "./ProviderInstanceIcon";
1818export function ProviderSubagentBar(props: {
1919 /** The provider running the subagent; no icon while its catalog loads. */
2020 readonly provider: ProviderInstanceEntry | null;
21 /** Several accounts on this provider: badge the glyph, as the composer does. */
22 readonly showInstanceBadge: boolean;
2123 readonly modelLabel: string;
2224 /** Reasoning effort as the composer names it, when the subagent has one. */
2325 readonly effortLabel: string | null;
......@@ -60,8 +62,10 @@ export function ProviderSubagentBar(props: {
6062 accentColor={props.provider.accentColor}
6163 acpRegistryAgentId={props.provider.acpRegistryAgentId}
6264 acpRegistryIconUrl={props.provider.acpRegistryIconUrl}
65 showBadge={props.showInstanceBadge}
6366 className="size-4 shrink-0"
6467 iconClassName="size-4"
68 badgeClassName="right-[-0.125rem] bottom-[-0.125rem] h-3 min-w-3 px-0.5 text-5xs"
6569 />
6670 ) : null}
6771 <span className="min-w-0 truncate font-medium text-foreground">{props.modelLabel}</span>
apps/web/src/components/chat/SubagentTooltipContent.tsx+15-2
......@@ -23,12 +23,15 @@ import { ThreadHoverCard } from "../ThreadHoverCard";
2323import { MiddleTruncate } from "../ui/middle-truncate";
2424import { ProviderInstanceIcon } from "./ProviderInstanceIcon";
2525import { cn } from "~/lib/utils";
26import { deriveProviderInstanceEntries, shouldShowInstanceBadge } from "../../providerInstances";
2627
2728/** Geometry and preview limits stay identical in lineage and timeline tooltips. */
2829export function SubagentTooltipContent(props: {
2930 title: string;
3031 model: string | null;
3132 provider?: ServerProvider | undefined;
33 /** The environment's instances; with several accounts on one provider, the card names this one. */
34 providers?: ReadonlyArray<ServerProvider> | undefined;
3235 driver?: ProviderDriverKind | undefined;
3336 elapsed?: ReactNode;
3437 parentThread?: Pick<OrchestrationV2ThreadShell, "projectId" | "worktreePath"> | undefined;
......@@ -42,6 +45,9 @@ export function SubagentTooltipContent(props: {
4245 const { modelLabel, workspace: metadata } = resolveSubagentMetadata(props);
4346 const preview = subagentDetailPreview(props);
4447 const driver = props.provider?.driver ?? props.driver;
48 const entries = deriveProviderInstanceEntries(props.providers ?? []);
49 const entry = entries.find((candidate) => candidate.instanceId === props.provider?.instanceId);
50 const showInstanceBadge = entry !== undefined && shouldShowInstanceBadge(entry, entries);
4551 const working = ["running", "in_progress", "pending", "waiting"].includes(props.status);
4652 const failed = ["failed", "error"].includes(props.status);
4753 const StatusIcon = working
......@@ -57,14 +63,21 @@ export function SubagentTooltipContent(props: {
5763 {driver ? (
5864 <ProviderInstanceIcon
5965 driverKind={driver}
60 displayName={props.provider?.displayName ?? driver}
66 displayName={entry?.displayName ?? props.provider?.displayName ?? driver}
67 accentColor={entry?.accentColor}
6168 acpRegistryIconUrl={props.provider?.iconUrl}
69 // Same treatment as the sidebar card: accent dot, account in the label.
70 showBadge={showInstanceBadge && entry?.accentColor !== undefined}
71 badgeContent="none"
72 badgeClassName="h-2 min-w-2 px-0"
6273 iconClassName="size-3 shrink-0 grayscale opacity-60"
6374 />
6475 ) : (
6576 <BotIcon className="size-3 shrink-0" />
6677 )}
67 <span className="min-w-0 truncate text-foreground/75">{modelLabel}</span>
78 <span className="min-w-0 truncate text-foreground/75">
79 {showInstanceBadge ? `${modelLabel} · ${entry.displayName}` : modelLabel}
80 </span>
6881 </div>
6982 <div className="flex min-w-0 items-center justify-between gap-4">
7083 <span
apps/web/src/components/chat/ThreadRelationshipsControl.tsx+1
......@@ -384,6 +384,7 @@ export function ThreadRelationshipsPanel(props: {
384384 title={threadTitle}
385385 model={agent.model}
386386 provider={provider}
387 providers={providers}
387388 driver={providerDriver}
388389 elapsed={<AgentElapsed agent={agent} />}
389390 status={agent.status}
apps/web/src/components/chat/V2LifecycleRow.tsx+4
......@@ -217,6 +217,7 @@ export function V2LifecycleRow(props: {
217217 provider={props.providerStatuses.find(
218218 (provider) => provider.instanceId === item.providerInstanceId,
219219 )}
220 providers={props.providerStatuses}
220221 title={formatSubagentDisplayTitle(item.title ?? "Subagent")}
221222 result={item.result}
222223 progress={item.progress}
......@@ -374,6 +375,7 @@ export function SubagentNotificationLink(props: {
374375 provider={props.providerStatuses.find(
375376 (provider) => provider.instanceId === agent.providerInstanceId,
376377 )}
378 providers={props.providerStatuses}
377379 title={formatSubagentDisplayTitle(agent.title ?? "Subagent")}
378380 result={agent.result}
379381 progress={agent.progress}
......@@ -395,6 +397,7 @@ function SubagentTimelineLink(props: {
395397 readonly subagentId: NodeId;
396398 readonly driver: ProviderDriverKind;
397399 readonly provider: ServerProvider | undefined;
400 readonly providers: ReadonlyArray<ServerProvider>;
398401 readonly title: string;
399402 readonly result: string | null;
400403 readonly progress: string | undefined;
......@@ -538,6 +541,7 @@ function SubagentTimelineTooltip(
538541 title={formatSubagentDisplayTitle(child?.title ?? props.title)}
539542 model={props.model}
540543 provider={props.provider}
544 providers={props.providers}
541545 driver={props.driver}
542546 elapsed={props.elapsed}
543547 status={props.status}