refactor(tui): extract shared frontend helpers (#37868)
This commit is contained in:
parent
deee40c572
commit
0eb71d0fc7
52 changed files with 1655 additions and 1614 deletions
|
|
@ -1,8 +1,9 @@
|
|||
import type { MiniFrontendInput } from "@opencode-ai/tui/mini"
|
||||
import { createModelPreferenceRepository } from "@opencode-ai/tui/model-preference"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import fs from "node:fs"
|
||||
import { mkdir, readFile, writeFile } from "node:fs/promises"
|
||||
import { readFile } from "node:fs/promises"
|
||||
import path from "node:path"
|
||||
import { ReadStream } from "node:tty"
|
||||
|
||||
|
|
@ -14,51 +15,17 @@ export type InteractiveStdin = {
|
|||
}
|
||||
|
||||
type MiniHost = MiniFrontendInput["host"]
|
||||
type ModelState = Record<string, unknown> & {
|
||||
variant?: Record<string, string | undefined>
|
||||
}
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return !!value && typeof value === "object" && !Array.isArray(value)
|
||||
}
|
||||
|
||||
function state(value: unknown): ModelState {
|
||||
if (!isRecord(value)) return {}
|
||||
const variant = isRecord(value.variant)
|
||||
? Object.fromEntries(
|
||||
Object.entries(value.variant).flatMap(([key, item]) =>
|
||||
typeof item === "string" ? ([[key, item]] as const) : [],
|
||||
),
|
||||
)
|
||||
: undefined
|
||||
return { ...value, variant }
|
||||
}
|
||||
|
||||
function variantKey(model: NonNullable<MiniFrontendInput["model"]>) {
|
||||
return `${model.providerID}/${model.modelID}`
|
||||
}
|
||||
|
||||
function preferences(statePath: string): MiniHost["preferences"] {
|
||||
const file = path.join(statePath, "model.json")
|
||||
const read = () =>
|
||||
readFile(file, "utf8")
|
||||
.then((value) => state(JSON.parse(value)))
|
||||
.catch(() => state(undefined))
|
||||
const repository = createModelPreferenceRepository(path.join(statePath, "model.json"))
|
||||
return {
|
||||
async resolveVariant(model) {
|
||||
if (!model) return
|
||||
const variant = (await read()).variant?.[variantKey(model)]
|
||||
return variant === "default" ? undefined : variant
|
||||
return repository.resolveVariant(model)
|
||||
},
|
||||
async saveVariant(model, variant) {
|
||||
if (!model) return
|
||||
const current = await read()
|
||||
const next = { ...current.variant }
|
||||
if (variant) next[variantKey(model)] = variant
|
||||
if (!variant) delete next[variantKey(model)]
|
||||
await mkdir(path.dirname(file), { recursive: true })
|
||||
.then(() => writeFile(file, JSON.stringify({ ...current, variant: next }, null, 2)))
|
||||
.catch(() => {})
|
||||
await repository.saveVariant(model, variant).catch(() => undefined)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export default defineScript({
|
|||
|
||||
const registration = await serviceRegistration(artifacts)
|
||||
const root = path.resolve(import.meta.dir, "../../../..")
|
||||
const preload = Bun.resolveSync("@opentui/solid/preload", path.join(root, "packages/cli"))
|
||||
const session = `mini-stage2-${process.pid}`
|
||||
const snapshots = path.join(artifacts, "mini-stage2")
|
||||
await mkdir(snapshots, { recursive: true })
|
||||
|
|
@ -56,7 +57,7 @@ export default defineScript({
|
|||
"OPENCODE_DIRECT_TRACE=1",
|
||||
process.execPath,
|
||||
"--conditions=browser",
|
||||
"--preload=@opentui/solid/preload",
|
||||
`--preload=${preload}`,
|
||||
path.join(root, "packages/cli/src/index.ts"),
|
||||
"mini",
|
||||
"--server",
|
||||
|
|
|
|||
|
|
@ -159,37 +159,19 @@ describe("Mini CLI host", () => {
|
|||
expect(typeof input.startup.now()).toBe("number")
|
||||
})
|
||||
|
||||
test("merges, clears, and repairs persisted model variants", async () => {
|
||||
test("delegates model variant preferences", async () => {
|
||||
const directory = await root()
|
||||
const input = host({ stdin: stream(true), cleanup() {} }, directory)
|
||||
const file = path.join(directory, "model.json")
|
||||
await Bun.write(
|
||||
file,
|
||||
JSON.stringify({
|
||||
recent: [{ providerID: "anthropic", modelID: "sonnet" }],
|
||||
variant: { "openai/gpt-4.1": "low", invalid: 42 },
|
||||
}),
|
||||
)
|
||||
|
||||
await input.preferences.saveVariant(model, "high")
|
||||
expect(await input.preferences.resolveVariant(model)).toBe("high")
|
||||
expect(await Bun.file(file).json()).toEqual({
|
||||
recent: [{ providerID: "anthropic", modelID: "sonnet" }],
|
||||
variant: { "openai/gpt-4.1": "low", "openai/gpt-5": "high" },
|
||||
})
|
||||
|
||||
await input.preferences.saveVariant(model, undefined)
|
||||
expect(await input.preferences.resolveVariant(model)).toBeUndefined()
|
||||
expect(await Bun.file(file).json()).toEqual({
|
||||
recent: [{ providerID: "anthropic", modelID: "sonnet" }],
|
||||
variant: { "openai/gpt-4.1": "low" },
|
||||
})
|
||||
|
||||
await Bun.write(file, JSON.stringify({ variant: { "openai/gpt-5": "default" } }))
|
||||
await input.preferences.saveVariant(model, "default")
|
||||
expect(await input.preferences.resolveVariant(model)).toBeUndefined()
|
||||
|
||||
await Bun.write(file, "{")
|
||||
await input.preferences.saveVariant(model, "high")
|
||||
expect(await Bun.file(file).json()).toEqual({ variant: { "openai/gpt-5": "high" } })
|
||||
expect(await input.preferences.resolveVariant(model)).toBe("high")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue