Skip to content

Commit c56b407

Browse files
committed
tui: display 'Free' badge for zero-cost models in model selection dialog
1 parent bdaa0e8 commit c56b407

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ import { useSync } from "@tui/context/sync"
44
import { map, pipe, flatMap, entries, filter, isDeepEqual, sortBy } from "remeda"
55
import { DialogSelect, type DialogSelectRef } from "@tui/ui/dialog-select"
66
import { useDialog } from "@tui/ui/dialog"
7+
import { useTheme } from "../context/theme"
8+
9+
function Free() {
10+
const { theme } = useTheme()
11+
return <span style={{ fg: theme.secondary }}>Free</span>
12+
}
713

814
export function DialogModel() {
915
const local = useLocal()
1016
const sync = useSync()
1117
const dialog = useDialog()
1218
const [ref, setRef] = createSignal<DialogSelectRef<unknown>>()
19+
const { theme } = useTheme()
1320

1421
const options = createMemo(() => {
1522
return [
@@ -29,6 +36,7 @@ export function DialogModel() {
2936
title: model.name ?? item.modelID,
3037
description: provider.name,
3138
category: "Recent",
39+
footer: model.cost.input === 0 && provider.id === "opencode" ? <Free /> : undefined,
3240
},
3341
]
3442
})
@@ -51,6 +59,7 @@ export function DialogModel() {
5159
title: info.name ?? model,
5260
description: provider.name,
5361
category: provider.name,
62+
footer: info.cost.input === 0 && provider.id === "opencode" ? <Free /> : undefined,
5463
})),
5564
filter((x) => Boolean(ref()?.filter) || !local.model.recent().find((y) => isDeepEqual(y, x.value))),
5665
),

packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export interface DialogSelectOption<T = any> {
3030
title: string
3131
value: T
3232
description?: string
33-
footer?: string
33+
footer?: JSX.Element | string
3434
category?: string
3535
disabled?: boolean
3636
bg?: RGBA
@@ -172,7 +172,6 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
172172
props.onFilter?.(e)
173173
})
174174
}}
175-
onKeyDown={(e) => {}}
176175
focusedBackgroundColor={theme.backgroundPanel}
177176
cursorColor={theme.primary}
178177
focusedTextColor={theme.textMuted}
@@ -256,7 +255,7 @@ function Option(props: {
256255
description?: string
257256
active?: boolean
258257
current?: boolean
259-
footer?: string
258+
footer?: JSX.Element | string
260259
onMouseOver?: () => void
261260
}) {
262261
const { theme } = useTheme()

0 commit comments

Comments
 (0)