fix(tui): restore compaction model marker

This commit is contained in:
Kit Langton 2026-07-14 11:35:12 -04:00
commit 76f205d260
13 changed files with 105 additions and 19 deletions

View file

@ -732,6 +732,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
Object.assign(current, {
status: "completed",
reason: event.data.reason,
model: event.data.model,
summary: event.data.text,
recent: event.data.recent,
})
@ -742,6 +743,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
type: "compaction",
status: "completed",
reason: event.data.reason,
model: event.data.model,
summary: event.data.text,
recent: event.data.recent,
time: { created: event.created },

View file

@ -73,7 +73,7 @@ import { OPENCODE_BASE_MODE, useBindings, useCommandShortcut } from "../../keyma
import { usePathFormatter } from "../../context/path-format"
import { LocationProvider } from "../../context/location"
import { createSessionRows, resolvePart, type PartRef, type SessionRow } from "./rows"
import { switchLabel } from "../../util/model"
import { compactionMarker, switchLabel } from "../../util/model"
addDefaultParsers(parsers.parsers)
@ -1306,10 +1306,14 @@ function SessionSkillMessage(props: { message: Extract<SessionMessageInfo, { typ
function CompactionMessage(props: { message: Extract<SessionMessageInfo, { type: "compaction" }> }) {
const ctx = use()
const local = useLocal()
const { theme, syntax } = useTheme()
const status = () => props.message.status
const text = () => (props.message.status === "failed" ? props.message.error.message : props.message.summary)
const content = createMemo(() => text().trim())
const marker = createMemo(() =>
compactionMarker(props.message.status === "completed" ? props.message.model : undefined, ctx.models()),
)
const color = () => (status() === "failed" ? theme.error : theme.textMuted)
return (
<box>
@ -1344,6 +1348,16 @@ function CompactionMessage(props: { message: Extract<SessionMessageInfo, { type:
/>
</box>
</Show>
<Show when={marker()}>
{(value) => (
<box paddingLeft={3} marginTop={1}>
<text>
<span style={{ fg: local.agent.color(value().agent) }}>{Locale.titlecase(value().agent)}</span>
<span style={{ fg: theme.textMuted }}> · {value().model}</span>
</text>
</box>
)}
</Show>
</box>
)
}

View file

@ -7,6 +7,18 @@ export function formatRef(model: { providerID: string; id: string; variant?: str
return [model.providerID, model.id, model.variant].filter((value) => value !== undefined).join("/")
}
export function compactionMarker(
model: { providerID: string; id: string; variant?: string } | undefined,
models?: readonly { providerID: string; id: string; name: string }[],
) {
if (!model) return
return {
agent: "compaction",
model:
models?.find((item) => item.providerID === model.providerID && item.id === model.id)?.name ?? formatRef(model),
}
}
export function switchLabel(
model: { providerID: string; id: string; variant?: string },
models?: readonly { providerID: string; id: string; name: string }[],

View file

@ -1126,7 +1126,13 @@ test("tracks session status from active sessions and execution events", async ()
created: 0,
type: "session.compaction.ended",
durable: durable("session-live", 5),
data: { sessionID: "session-live", reason: "auto", text: "Live summary", recent: "recent" },
data: {
sessionID: "session-live",
reason: "auto",
model: { providerID: "anthropic", id: "claude-sonnet" },
text: "Live summary",
recent: "recent",
},
})
await wait(() => {
const message = data.session.message.get("session-live", "msg_compaction_started")
@ -1135,6 +1141,7 @@ test("tracks session status from active sessions and execution events", async ()
expect(data.session.message.get("session-live", "msg_compaction_started")).toMatchObject({
type: "compaction",
status: "completed",
model: { providerID: "anthropic", id: "claude-sonnet" },
summary: "Live summary",
})
expect(rows.find((row) => row.type === "message" && row.messageID === "msg_compaction_started")).toBe(

View file

@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
import { formatRef, parse, switchLabel } from "../../src/util/model"
import { compactionMarker, formatRef, parse, switchLabel } from "../../src/util/model"
describe("util.model", () => {
test("splits provider from a nested model identifier", () => {
@ -12,6 +12,20 @@ describe("util.model", () => {
expect(formatRef({ providerID: "anthropic", id: "sonnet" })).toBe("anthropic/sonnet")
})
test("labels completed compactions with their actual model", () => {
const models = [{ providerID: "anthropic", id: "sonnet", name: "Claude Sonnet" }]
expect(compactionMarker({ providerID: "anthropic", id: "sonnet" }, models)).toEqual({
agent: "compaction",
model: "Claude Sonnet",
})
expect(compactionMarker({ providerID: "removed", id: "gone", variant: "high" }, models)).toEqual({
agent: "compaction",
model: "removed/gone/high",
})
expect(compactionMarker(undefined, models)).toBeUndefined()
})
test("includes the selected variant in model switch notices", () => {
expect(switchLabel({ providerID: "anthropic", id: "sonnet", variant: "thinking" })).toBe(
"Switched model to anthropic/sonnet/thinking",