History

fix(web): simplify expanded tool details (#9549)

maria committed 2 months ago

Commit 710f6dc1 parent f96a2201 file · +65 −27Browse files

Unified · Split

apps/web/src/components/chat/MessagesTimeline.tsx+65−27
@@ -2886,27 +2886,47 @@ function workEntryRawCommand( · 2885 unmodified lines
2886function buildToolCallExpandedBody(2886function buildToolCallExpandedBody(
2887 workEntry: TimelineWorkEntry,2887 workEntry: TimelineWorkEntry,
2888 workspaceRoot: string | undefined,2888 workspaceRoot: string | undefined,
2889 visibleLabel: string,
2890 viewedImagePath: string | null,
2889): string | null {2891): string | null {
2890 const blocks: string[] = [];2892 const blocks: string[] = [];
2893 const seen = new Set<string>();
2894 const addBlock = (value: string | null | undefined) => {
2895 const text = value?.trim();
2896 if (!text || seen.has(text)) return;
2897 seen.add(text);
2898 blocks.push(text);
2899 };
2891 if (workEntry.itemType === "mcp_tool_call" && workEntry.toolData !== undefined) {2900 if (workEntry.itemType === "mcp_tool_call" && workEntry.toolData !== undefined) {
2892 blocks.push(`MCP call\n${JSON.stringify(workEntry.toolData, null, 2)}`);2901 addBlock(`MCP call\n${JSON.stringify(workEntry.toolData, null, 2)}`);
2893 }2902 }
2903 const command = workEntry.command?.trim();
2894 const raw = workEntryRawCommand(workEntry);2904 const raw = workEntryRawCommand(workEntry);
2895 if (raw?.trim()) {2905 if (command === visibleLabel.trim()) {
2896 blocks.push(raw.trim());2906 seen.add(command);
2897 } else if (workEntry.command?.trim()) {2907 } else {
2898 blocks.push(workEntry.command.trim());2908 addBlock(raw ?? command);
2899 }2909 }
2900 if (workEntry.detail?.trim()) {2910 const detail = workEntry.detail?.trim();
2901 blocks.push(workEntry.detail.trim());2911 if (detail !== viewedImagePath?.trim()) {
2912 addBlock(detail);
2902 }2913 }
2903 const changedFiles = workEntry.changedFiles ?? [];2914 const viewedImagePaths = new Set(
2915 viewedImagePath
2916 ? [viewedImagePath.trim(), formatWorkspaceRelativePath(viewedImagePath, workspaceRoot)]
2917 : [],
2918 );
2919 const changedFiles = (workEntry.changedFiles ?? []).flatMap((filePath) => {
2920 const formattedPath = formatWorkspaceRelativePath(filePath, workspaceRoot);
2921 return viewedImagePaths.has(filePath) ||
2922 viewedImagePaths.has(formattedPath) ||
2923 filePath.trim() === detail ||
2924 formattedPath === detail
2925 ? []
2926 : [formattedPath];
2927 });
2904 if (changedFiles.length > 0) {2928 if (changedFiles.length > 0) {
2905 blocks.push(2929 addBlock([...new Set(changedFiles)].join("\n"));
2906 changedFiles
2907 .map((filePath) => formatWorkspaceRelativePath(filePath, workspaceRoot))
2908 .join("\n"),
2909 );
2910 }2930 }
2911 return blocks.length > 0 ? blocks.join("\n\n") : null;2931 return blocks.length > 0 ? blocks.join("\n\n") : null;
2912}2932}
@@ -3092,19 +3112,7 @@ const PlainWorkEntryRow = memo(function PlainWorkEntryRow(props: { · 179 unmodified lines
3092 ? "circle-alert"3112 ? "circle-alert"
3093 : workEntryIconName(workEntry);3113 : workEntryIconName(workEntry);
3094 const previewText = displayLabel ?? workEntryDisplayLabel(workEntry, workspaceRoot);3114 const previewText = displayLabel ?? workEntryDisplayLabel(workEntry, workspaceRoot);
3095 const displayText =
3096 !toolPresentation && expanded && workEntry.command?.trim() ? "Command" : previewText;
3097 const viewedImagePath = workEntryViewedImagePath(workEntry);3115 const viewedImagePath = workEntryViewedImagePath(workEntry);
3098 const canExpand =
3099 (workEntry.itemType === "mcp_tool_call" && workEntry.toolData !== undefined) ||
3100 Boolean(
3101 workEntryRawCommand(workEntry) ||
3102 workEntry.command?.trim() ||
3103 workEntry.detail?.trim() ||
3104 workEntry.changedFiles?.length ||
3105 viewedImagePath,
3106 );
3107 const expandedBody = expanded ? buildToolCallExpandedBody(workEntry, workspaceRoot) : null;
3108 const viewedImage =3116 const viewedImage =
3109 viewedImagePath && threadRef3117 viewedImagePath && threadRef
3110 ? resolveViewedImageAsset(viewedImagePath, {3118 ? resolveViewedImageAsset(viewedImagePath, {
@@ -3112,6 +3120,24 @@ const PlainWorkEntryRow = memo(function PlainWorkEntryRow(props: { · 1 unmodified line
3112 workspaceRoot,3120 workspaceRoot,
3113 })3121 })
3114 : null;3122 : null;
3123 const commandMatchesVisibleLabel = workEntry.command?.trim() === previewText.trim();
3124 const canExpand =
3125 (workEntry.itemType === "mcp_tool_call" && workEntry.toolData !== undefined) ||
3126 Boolean(
3127 (!commandMatchesVisibleLabel &&
3128 (workEntryRawCommand(workEntry) || workEntry.command?.trim())) ||
3129 workEntry.detail?.trim() ||
3130 workEntry.changedFiles?.length ||
3131 viewedImage,
3132 );
3133 const expandedBody = expanded
3134 ? buildToolCallExpandedBody(
3135 workEntry,
3136 workspaceRoot,
3137 previewText,
3138 viewedImage ? viewedImagePath : null,
3139 )
3140 : null;
3115 const showDestructiveRowStyle =3141 const showDestructiveRowStyle =
3116 showFailedIndicator &&3142 showFailedIndicator &&
3117 (workEntrySignalsSevereFailure(workEntry) || !workLogEntryIsToolLike(workEntry));3143 (workEntrySignalsSevereFailure(workEntry) || !workLogEntryIsToolLike(workEntry));
@@ -3183,7 +3209,19 @@ const PlainWorkEntryRow = memo(function PlainWorkEntryRow(props: { · 65 unmodified lines
3183 <div className="flex min-w-0 flex-1 items-center gap-1.5">3209 <div className="flex min-w-0 flex-1 items-center gap-1.5">
3184 <div className="min-w-0 flex-1 overflow-hidden">3210 <div className="min-w-0 flex-1 overflow-hidden">
3185 <p className="flex min-w-0 w-full items-baseline gap-1.5 text-sm leading-relaxed">3211 <p className="flex min-w-0 w-full items-baseline gap-1.5 text-sm leading-relaxed">
3186 <span className={cn("min-w-0 flex-1 truncate", headingClass)}>{displayText}</span>3212 <span
3213 className={cn(
3214 "min-w-0 flex-1",
3215 expanded || (commandMatchesVisibleLabel && !canExpand)
3216 ? "whitespace-pre-wrap break-words select-text"
3217 : "truncate",
3218 headingClass,
3219 )}
3220 onClick={expanded ? stopRowToggle : undefined}
3221 onPointerDown={expanded ? stopRowToggle : undefined}
3222 >
3223 {previewText}
3224 </span>
3187 </p>3225 </p>
3188 </div>3226 </div>
3189 {showFailedIndicator && hasSpecialToolIcon ? (3227 {showFailedIndicator && hasSpecialToolIcon ? (
@@ -3224,7 +3262,7 @@ const PlainWorkEntryRow = memo(function PlainWorkEntryRow(props: { · 34 unmodified lines
3224 ) : null}3262 ) : null}
3225 {expanded && canExpand && expandedBody ? (3263 {expanded && canExpand && expandedBody ? (
3226 <div3264 <div
3227 className="mt-1 ms-7 cursor-default border-s border-border/45 ps-3 pt-0.5"3265 className="mt-1 ms-7 cursor-default rounded-md bg-muted/40 px-3 py-2"
3228 onClick={stopRowToggle}3266 onClick={stopRowToggle}
3229 onPointerDown={stopRowToggle}3267 onPointerDown={stopRowToggle}
3230 >3268 >