fix(tui): pin queued prompts below output (#34791)

This commit is contained in:
Shoubhit Dash 2026-07-02 01:53:51 +05:30 committed by GitHub
commit 932a40cfd9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -73,8 +73,10 @@ export function createSessionRows(sessionID: Accessor<string>) {
setRows( setRows(
produce((draft) => { produce((draft) => {
if (draft.some((row) => row.type === "message" && row.messageID === messageID)) return if (draft.some((row) => row.type === "message" && row.messageID === messageID)) return
completePrevious(draft) const queued = isQueued(messageID)
draft.push({ type: "message", messageID }) const index = queued ? draft.length : queuedStart(draft)
if (!queued) completePrevious(draft, index)
draft.splice(index, 0, { type: "message", messageID })
}), }),
) )
@ -82,14 +84,15 @@ export function createSessionRows(sessionID: Accessor<string>) {
setRows( setRows(
produce((draft) => { produce((draft) => {
if (hasPart(draft, ref)) return if (hasPart(draft, ref)) return
const index = queuedStart(draft)
if (name && exploration(name)) { if (name && exploration(name)) {
const previous = draft.at(-1) const previous = draft[index - 1]
if (previous?.type === "group" && previous.kind === "exploration") { if (previous?.type === "group" && previous.kind === "exploration") {
previous.refs.push(ref) previous.refs.push(ref)
return return
} }
completePrevious(draft) completePrevious(draft, index)
draft.push({ draft.splice(index, 0, {
type: "group", type: "group",
kind: "exploration", kind: "exploration",
refs: [ref], refs: [ref],
@ -98,8 +101,8 @@ export function createSessionRows(sessionID: Accessor<string>) {
}) })
return return
} }
completePrevious(draft) completePrevious(draft, index)
draft.push({ type: "part", ref }) draft.splice(index, 0, { type: "part", ref })
}), }),
) )
@ -107,11 +110,22 @@ export function createSessionRows(sessionID: Accessor<string>) {
setRows( setRows(
produce((draft) => { produce((draft) => {
if (draft.some((row) => row.type === "assistant-footer" && row.messageID === messageID)) return if (draft.some((row) => row.type === "assistant-footer" && row.messageID === messageID)) return
completePrevious(draft) const index = queuedStart(draft)
draft.push({ type: "assistant-footer", messageID }) completePrevious(draft, index)
draft.splice(index, 0, { type: "assistant-footer", messageID })
}), }),
) )
const isQueued = (messageID: string) => {
const message = data.session.message.get(sessionID(), messageID)
return message?.type === "user" && message.metadata?.queued === true
}
const queuedStart = (rows: SessionRow[]) => {
const index = rows.findIndex((row) => row.type === "message" && isQueued(row.messageID))
return index === -1 ? rows.length : index
}
const message = (event: { data: { sessionID: string; messageID: string } }) => { const message = (event: { data: { sessionID: string; messageID: string } }) => {
if (event.data.sessionID === sessionID()) appendMessage(event.data.messageID) if (event.data.sessionID === sessionID()) appendMessage(event.data.messageID)
} }
@ -160,10 +174,12 @@ export function createSessionRows(sessionID: Accessor<string>) {
} }
export function reduceSessionRows(messages: SessionMessage[]) { export function reduceSessionRows(messages: SessionMessage[]) {
return messages.reduce<SessionRow[]>((rows, message) => { return [...messages.filter((message) => !isQueuedMessage(message)), ...messages.filter(isQueuedMessage)].reduce<
SessionRow[]
>((rows, message) => {
if (message.type !== "assistant") { if (message.type !== "assistant") {
if (message.type === "synthetic" && !message.description?.trim()) return rows if (message.type === "synthetic" && !message.description?.trim()) return rows
completePrevious(rows) if (!isQueuedMessage(message)) completePrevious(rows)
rows.push({ type: "message", messageID: message.id }) rows.push({ type: "message", messageID: message.id })
return rows return rows
} }
@ -179,6 +195,10 @@ export function reduceSessionRows(messages: SessionMessage[]) {
}, []) }, [])
} }
function isQueuedMessage(message: SessionMessage) {
return message.type === "user" && message.metadata?.queued === true
}
function append(rows: SessionRow[], ref: PartRef, part: SessionMessageAssistant["content"][number]) { function append(rows: SessionRow[], ref: PartRef, part: SessionMessageAssistant["content"][number]) {
if (part.type === "tool") { if (part.type === "tool") {
if (exploration(part.name)) { if (exploration(part.name)) {
@ -196,8 +216,8 @@ function append(rows: SessionRow[], ref: PartRef, part: SessionMessageAssistant[
rows.push({ type: "part", ref }) rows.push({ type: "part", ref })
} }
function completePrevious(rows: SessionRow[]) { function completePrevious(rows: SessionRow[], index = rows.length) {
const previous = rows.at(-1) const previous = rows[index - 1]
if (previous?.type === "group") previous.completed = true if (previous?.type === "group") previous.completed = true
} }