authorgravatar for 97427849+flamboh@users.noreply.github.comoliver <97427849+flamboh@users.noreply.github.com> 2026-10-14 10:49:18-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-14 17:49:18+00:00
loge093789dd2340d8a41ee7ac12341fb011f9ff86c
tree220c3cd93841f2e49f594a1645c6189261c1ceda
parent7897a695e351b7e8ebaa0d8c693660291af18286
signature Signed by PGP key B5690EEEBB952194

fix(web): subagent lists in the composer banner no longer start lines with a comma (#19170)


3 files changed, 41 insertions(+), 26 deletions(-)

apps/mobile/src/features/threads/thread-handoff-row.tsx+8-5
......@@ -9,7 +9,7 @@ import type {
99 ServerProvider,
1010} from "@t3tools/contracts";
1111import { Atom } from "effect/reactivity";
12import { Fragment, useMemo } from "react";
12import { useMemo } from "react";
1313import { Alert, Pressable, View, type ColorValue } from "react-native";
1414import { AppText as Text } from "../../components/AppText";
1515import { SymbolView } from "../../components/AppSymbol";
......@@ -76,14 +76,17 @@ export function ThreadHandoffDivider(props: {
7676 >
7777 <View className="flex-row flex-wrap items-center justify-center gap-1.5">
7878 {endpoints.from.map((endpoint, index) => (
79 <Fragment key={`${endpoint.instanceId}:${endpoint.model ?? ""}`}>
80 {index > 0 ? (
79 <View
80 key={`${endpoint.instanceId}:${endpoint.model ?? ""}`}
81 className="max-w-full flex-row items-center"
82 >
83 <HandoffEndpoint {...endpoint} providers={config?.providers ?? []} />
84 {index < endpoints.from.length - 1 ? (
8185 <Text accessible={false} className="text-xs text-foreground-muted">
8286 ,
8387 </Text>
8488 ) : null}
85 <HandoffEndpoint {...endpoint} providers={config?.providers ?? []} />
86 </Fragment>
89 </View>
8790 ))}
8891 {endpoints.from.length > 0 ? (
8992 <SymbolView name="arrow.right" size={12} tintColor={props.iconColor} />
apps/web/src/components/ChatView.tsx+23-13
......@@ -7472,10 +7472,13 @@ export default function ChatView(props: ChatViewProps) {
74727472 : `${childThreadInputs.length} subagents need input`,
74737473 description: childThreadInputs.map((child, index) => (
74747474 <Fragment key={child.id}>
7475 {index > 0 ? ", " : null}
7476 <InlineButton tone="muted" onClick={() => onOpenRelatedThread(child.id)}>
7477 {child.title}
7478 </InlineButton>
7475 {index > 0 ? " " : null}
7476 <span className="whitespace-nowrap">
7477 <InlineButton tone="muted" onClick={() => onOpenRelatedThread(child.id)}>
7478 {child.title}
7479 </InlineButton>
7480 {index < childThreadInputs.length - 1 ? "," : null}
7481 </span>
74797482 </Fragment>
74807483 )),
74817484 actions: (
......@@ -7643,19 +7646,26 @@ export default function ChatView(props: ChatViewProps) {
76437646 ? undefined
76447647 : presentation.items.map((item, index) => {
76457648 const childThreadId = item.childThreadId;
7649 const separator = index < presentation.items.length - 1 ? "," : null;
76467650 return (
76477651 <Fragment key={item.taskId}>
7648 {index > 0 ? ", " : null}
7652 {index > 0 ? " " : null}
76497653 {childThreadId === undefined ? (
7650 item.label
7651 ) : (
7652 <InlineButton
7653 tone="muted"
7654 aria-label={`Open subagent ${item.label}`}
7655 onClick={() => onOpenRelatedThread(childThreadId)}
7656 >
7654 <>
76577655 {item.label}
7658 </InlineButton>
7656 {separator}
7657 </>
7658 ) : (
7659 <span className="whitespace-nowrap">
7660 <InlineButton
7661 tone="muted"
7662 aria-label={`Open subagent ${item.label}`}
7663 onClick={() => onOpenRelatedThread(childThreadId)}
7664 >
7665 {item.label}
7666 </InlineButton>
7667 {separator}
7668 </span>
76597669 )}
76607670 </Fragment>
76617671 );
apps/web/src/components/chat/V2LifecycleRow.tsx+10-8
......@@ -15,7 +15,6 @@ import {
1515 type HandoffEndpoints,
1616 type HandoffTimelineRun,
1717} from "@t3tools/client-runtime/handoff";
18import { Fragment } from "react";
1918import { formatSubagentDisplayTitle } from "@t3tools/client-runtime/state/subagent-display";
2019import {
2120 ProviderDriverKind,
......@@ -562,18 +561,21 @@ export function HandoffRow(props: {
562561 detail={
563562 <span className="inline-flex min-w-0 flex-wrap items-center justify-center gap-1.5">
564563 {fromEndpoints.map((endpoint, index) => (
565 <Fragment key={`${endpoint.instanceId}:${endpoint.model ?? ""}`}>
566 {index > 0 ? (
567 <span aria-hidden="true" className="-ml-1">
568 ,
569 </span>
570 ) : null}
564 <span
565 key={`${endpoint.instanceId}:${endpoint.model ?? ""}`}
566 className="inline-flex min-w-0 items-center"
567 >
571568 <HandoffEndpoint
572569 providers={props.providers}
573570 instanceId={endpoint.instanceId}
574571 model={endpoint.model}
575572 />
576 </Fragment>
573 {index < fromEndpoints.length - 1 ? (
574 <span aria-hidden="true" className="ml-0.5">
575 ,
576 </span>
577 ) : null}
578 </span>
577579 ))}
578580 {fromEndpoints.length > 0 ? (
579581 <ArrowRightIcon aria-hidden="true" className="size-3 shrink-0" />