From 0deb44e6b56ef68f68cc6f68789dcb0b8e5357ca Mon Sep 17 00:00:00 2001 From: tdawe1 Date: Mon, 12 Jan 2026 06:25:19 +0000 Subject: [PATCH] fix(opencode): add null checks for agent.current() in prompt and local context --- .../cli/cmd/tui/component/dialog-agent.tsx | 2 +- .../cli/cmd/tui/component/prompt/index.tsx | 36 +++++++++---------- .../src/cli/cmd/tui/context/local.tsx | 20 ++++++----- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx index 365a22445b4..202967f09f6 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx @@ -20,7 +20,7 @@ export function DialogAgent() { return ( { local.agent.set(option.value) diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 644ac262241..b061f4843b2 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -498,9 +498,9 @@ export function Prompt(props: PromptProps) { const sessionID = props.sessionID ? props.sessionID : await (async () => { - const sessionID = await sdk.client.session.create({}).then((x) => x.data!.id) - return sessionID - })() + const sessionID = await sdk.client.session.create({}).then((x) => x.data!.id) + return sessionID + })() const messageID = Identifier.ascending("message") let inputText = store.prompt.input @@ -530,7 +530,7 @@ export function Prompt(props: PromptProps) { if (store.mode === "shell") { sdk.client.session.shell({ sessionID, - agent: local.agent.current().name, + agent: local.agent.current()?.name ?? "default", model: { providerID: selectedModel.providerID, modelID: selectedModel.modelID, @@ -551,7 +551,7 @@ export function Prompt(props: PromptProps) { sessionID, command: command.slice(1), arguments: args.join(" "), - agent: local.agent.current().name, + agent: local.agent.current()?.name ?? "default", model: `${selectedModel.providerID}/${selectedModel.modelID}`, messageID, variant, @@ -567,7 +567,7 @@ export function Prompt(props: PromptProps) { sessionID, ...selectedModel, messageID, - agent: local.agent.current().name, + agent: local.agent.current()?.name ?? "default", model: selectedModel, variant, parts: [ @@ -687,7 +687,7 @@ export function Prompt(props: PromptProps) { const highlight = createMemo(() => { if (keybind.leader) return theme.border if (store.mode === "shell") return theme.primary - return local.agent.color(local.agent.current().name) + return local.agent.color(local.agent.current()?.name ?? "default") }) const showVariant = createMemo(() => { @@ -698,7 +698,7 @@ export function Prompt(props: PromptProps) { }) const spinnerDef = createMemo(() => { - const color = local.agent.color(local.agent.current().name) + const color = local.agent.color(local.agent.current()?.name ?? "default") return { frames: createFrames({ color, @@ -875,7 +875,7 @@ export function Prompt(props: PromptProps) { // Handle SVG as raw text content, not as base64 image if (file.type === "image/svg+xml") { event.preventDefault() - const content = await file.text().catch(() => {}) + const content = await file.text().catch(() => { }) if (content) { pasteText(content, `[SVG: ${file.name ?? "image"}]`) return @@ -886,7 +886,7 @@ export function Prompt(props: PromptProps) { const content = await file .arrayBuffer() .then((buffer) => Buffer.from(buffer).toString("base64")) - .catch(() => {}) + .catch(() => { }) if (content) { await pasteImage({ filename: file.name, @@ -896,7 +896,7 @@ export function Prompt(props: PromptProps) { return } } - } catch {} + } catch { } } const lineCount = (pastedContent.match(/\n/g)?.length ?? 0) + 1 @@ -932,7 +932,7 @@ export function Prompt(props: PromptProps) { /> - {store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current().name)}{" "} + {store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current()?.name ?? "default")}{" "} @@ -967,13 +967,13 @@ export function Prompt(props: PromptProps) { customBorderChars={ theme.backgroundElement.a !== 0 ? { - ...EmptyBorder, - horizontal: "▀", - } + ...EmptyBorder, + horizontal: "▀", + } : { - ...EmptyBorder, - horizontal: " ", - } + ...EmptyBorder, + horizontal: " ", + } } /> diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index 63f1d9743bf..8a3dcf74313 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -38,7 +38,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const [agentStore, setAgentStore] = createStore<{ current: string }>({ - current: agents()[0].name, + current: agents()[0]?.name ?? "default", }) const { theme } = useTheme() const colors = createMemo(() => [ @@ -54,7 +54,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ return agents() }, current() { - return agents().find((x) => x.name === agentStore.current)! + return agents().find((x) => x.name === agentStore.current) }, set(name: string) { if (!agents().some((x) => x.name === name)) @@ -132,7 +132,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ if (Array.isArray(x.favorite)) setModelStore("favorite", x.favorite) if (typeof x.variant === "object" && x.variant !== null) setModelStore("variant", x.variant) }) - .catch(() => {}) + .catch(() => { }) .finally(() => { setModelStore("ready", true) }) @@ -181,8 +181,8 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const a = agent.current() return ( getFirstValidModel( - () => modelStore.model[a.name], - () => a.model, + () => a ? modelStore.model[a.name] : undefined, + () => a?.model, fallbackModel, ) ?? undefined ) @@ -227,7 +227,8 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ if (next >= recent.length) next = 0 const val = recent[next] if (!val) return - setModelStore("model", agent.current().name, { ...val }) + const currentAgent = agent.current() + if (currentAgent) setModelStore("model", currentAgent.name, { ...val }) }, cycleFavorite(direction: 1 | -1) { const favorites = modelStore.favorite.filter((item) => isModelValid(item)) @@ -253,7 +254,8 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ } const next = favorites[index] if (!next) return - setModelStore("model", agent.current().name, { ...next }) + const currentAgent = agent.current() + if (currentAgent) setModelStore("model", currentAgent.name, { ...next }) const uniq = uniqueBy([next, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`) if (uniq.length > 10) uniq.pop() setModelStore( @@ -272,7 +274,8 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ }) return } - setModelStore("model", agent.current().name, model) + const currentAgent = agent.current() + if (currentAgent) setModelStore("model", currentAgent.name, model) if (options?.recent) { const uniq = uniqueBy([model, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`) if (uniq.length > 10) uniq.pop() @@ -368,6 +371,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ // Automatically update model when agent changes createEffect(() => { const value = agent.current() + if (!value) return if (value.model) { if (isModelValid(value.model)) model.set({