fix(app): support text attachments (#17335)

This commit is contained in:
Adam
2026-03-13 06:58:24 -05:00
committed by GitHub
parent 05cb3c87ca
commit 843f188aaa
28 changed files with 422 additions and 136 deletions

View File

@@ -54,6 +54,7 @@ import { AnimatedCountList } from "./tool-count-summary"
import { ToolStatusTitle } from "./tool-status-title"
import { animate } from "motion"
import { useLocation } from "@solidjs/router"
import { attached, inline, kind } from "./message-file"
function ShellSubmessage(props: { text: string; animate?: boolean }) {
let widthRef: HTMLSpanElement | undefined
@@ -901,19 +902,9 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp
const files = createMemo(() => (props.parts?.filter((p) => p.type === "file") as FilePart[]) ?? [])
const attachments = createMemo(() =>
files()?.filter((f) => {
const mime = f.mime
return mime.startsWith("image/") || mime === "application/pdf"
}),
)
const attachments = createMemo(() => files().filter(attached))
const inlineFiles = createMemo(() =>
files().filter((f) => {
const mime = f.mime
return !mime.startsWith("image/") && mime !== "application/pdf" && f.source?.text?.start !== undefined
}),
)
const inlineFiles = createMemo(() => files().filter(inline))
const agents = createMemo(() => (props.parts?.filter((p) => p.type === "agent") as AgentPart[]) ?? [])
@@ -973,32 +964,34 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp
<Show when={attachments().length > 0}>
<div data-slot="user-message-attachments">
<For each={attachments()}>
{(file) => (
<div
data-slot="user-message-attachment"
data-type={file.mime.startsWith("image/") ? "image" : "file"}
onClick={() => {
if (file.mime.startsWith("image/") && file.url) {
openImagePreview(file.url, file.filename)
}
}}
>
<Show
when={file.mime.startsWith("image/") && file.url}
fallback={
<div data-slot="user-message-attachment-icon">
<Icon name="folder" />
</div>
}
{(file) => {
const type = kind(file)
const name = file.filename ?? i18n.t("ui.message.attachment.alt")
return (
<div
data-slot="user-message-attachment"
data-type={type}
data-clickable={type === "image" ? "true" : undefined}
title={type === "file" ? name : undefined}
onClick={() => {
if (type === "image") openImagePreview(file.url, name)
}}
>
<img
data-slot="user-message-attachment-image"
src={file.url}
alt={file.filename ?? i18n.t("ui.message.attachment.alt")}
/>
</Show>
</div>
)}
<Show
when={type === "image"}
fallback={
<div data-slot="user-message-attachment-file">
<FileIcon node={{ path: name, type: "file" }} />
<span data-slot="user-message-attachment-name">{name}</span>
</div>
}
>
<img data-slot="user-message-attachment-image" src={file.url} alt={name} />
</Show>
</div>
)
}}
</For>
</div>
</Show>