mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
Merge pull request #12010 from Kilo-Org/research-inline-image-rendering
feat(vscode): render read-tool images inline in chat view
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"kilo-code": minor
|
||||
---
|
||||
|
||||
Render images inline in the chat view when the agent reads an image file. Images appear below the read tool card and can be clicked to open a full-size preview.
|
||||
@@ -412,6 +412,35 @@ html[data-theme="kilo-vscode"] [data-component="bash-output"] {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
[data-slot="tool-read-images"] {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
padding-top: 8px;
|
||||
max-width: min(100%, 64ch);
|
||||
}
|
||||
|
||||
[data-slot="tool-read-image"] {
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
border-radius: var(--radius-sm, 6px);
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border-weak-base);
|
||||
cursor: pointer;
|
||||
transition: border-color 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--border-strong-base);
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="tool-read-image-img"] {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 200px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
[data-component="todos"] {
|
||||
[data-slot="message-part-todo-hidden"] {
|
||||
padding: 2px 0 2px 28px;
|
||||
|
||||
@@ -995,6 +995,7 @@ export interface ToolProps {
|
||||
callID?: string
|
||||
output?: string
|
||||
status?: string
|
||||
attachments?: FilePart[]
|
||||
hideDetails?: boolean
|
||||
defaultOpen?: boolean
|
||||
forceOpen?: boolean
|
||||
@@ -1243,6 +1244,8 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) {
|
||||
// @ts-expect-error
|
||||
output={part.state.output}
|
||||
status={part.state.status}
|
||||
// @ts-expect-error
|
||||
attachments={part.state.attachments}
|
||||
hideDetails={props.hideDetails}
|
||||
defaultOpen={props.defaultOpen}
|
||||
animate
|
||||
@@ -1746,6 +1749,7 @@ ToolRegistry.register({
|
||||
render(props) {
|
||||
const data = useData()
|
||||
const i18n = useI18n()
|
||||
const dialog = useDialog()
|
||||
const args: string[] = []
|
||||
if (props.input.offset) args.push("offset=" + props.input.offset)
|
||||
if (props.input.limit) args.push("limit=" + props.input.limit)
|
||||
@@ -1755,6 +1759,10 @@ ToolRegistry.register({
|
||||
return value.filter((p): p is string => typeof p === "string")
|
||||
})
|
||||
const pending = createMemo(() => busy(props.status))
|
||||
const images = createMemo(() =>
|
||||
(props.attachments ?? []).filter((f) => f.mime.startsWith("image/") && f.url),
|
||||
)
|
||||
const preview = (url: string, alt?: string) => dialog.show(() => <ImagePreview src={url} alt={alt} />)
|
||||
return (
|
||||
<>
|
||||
<BasicTool
|
||||
@@ -1783,6 +1791,23 @@ ToolRegistry.register({
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
<Show when={images().length > 0}>
|
||||
<div data-slot="tool-read-images">
|
||||
<For each={images()}>
|
||||
{(file) => (
|
||||
<div data-slot="tool-read-image" onClick={() => preview(file.url, file.filename)}>
|
||||
<img
|
||||
data-slot="tool-read-image-img"
|
||||
src={file.url}
|
||||
alt={file.filename ?? i18n.t("ui.message.attachment.alt")}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</Show>
|
||||
</>
|
||||
)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user