diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index 2afba471..7dd0b325 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -362,35 +362,57 @@ export namespace Session { const app = App.info() input.parts = await Promise.all( - input.parts.map(async (part) => { + input.parts.map(async (part): Promise => { if (part.type === "file") { const url = new URL(part.url) switch (url.protocol) { case "file:": - let content = await Bun.file( - path.join(app.path.cwd, url.pathname), - ).text() - const range = { - start: url.searchParams.get("start"), - end: url.searchParams.get("end"), - } - if (range.start != null && part.mediaType === "text/plain") { - const lines = content.split("\n") - const start = parseInt(range.start) - const end = range.end ? parseInt(range.end) : lines.length - content = lines.slice(start, end).join("\n") - } - return { - type: "file", - url: `data:${part.mediaType};base64,` + btoa(content), - mediaType: part.mediaType, - filename: part.filename, + let content = Bun.file(path.join(app.path.cwd, url.pathname)) + + if (part.mediaType === "text/plain") { + let text = await content.text() + const range = { + start: url.searchParams.get("start"), + end: url.searchParams.get("end"), + } + if (range.start != null && part.mediaType === "text/plain") { + const lines = text.split("\n") + const start = parseInt(range.start) + const end = range.end ? parseInt(range.end) : lines.length + text = lines.slice(start, end).join("\n") + } + return [ + { + type: "text", + text: [ + "Called the Read tool on " + url.pathname, + "", + text, + "", + ].join("\n"), + }, + ] } + + return [ + { + type: "text", + text: ["Called the Read tool on " + url.pathname].join("\n"), + }, + { + type: "file", + url: + `data:${part.mediaType};base64,` + + Buffer.from(await content.bytes()).toString("base64url"), + mediaType: part.mediaType, + filename: path.basename(part.filename!), + }, + ] } } - return part + return [part] }), - ) + ).then((x) => x.flat()) if (msgs.length === 0 && !session.parentID) { generateText({ maxTokens: input.providerID === "google" ? 1024 : 20, diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go index 49fdf723..3d001130 100644 --- a/packages/tui/internal/components/chat/messages.go +++ b/packages/tui/internal/components/chat/messages.go @@ -134,6 +134,7 @@ func (m *messagesComponent) renderView(width int) { switch message.Role { case opencode.MessageRoleUser: + userLoop: for partIndex, part := range message.Parts { switch part := part.AsUnion().(type) { case opencode.TextPart: @@ -195,6 +196,8 @@ func (m *messagesComponent) renderView(width int) { m = m.updateSelected(content, part.Text) blocks = append(blocks, content) } + // Only render the first text part + break userLoop } }