Fix null agent access in TUI

Co-authored-by: adamdotdevin <adamdotdevin@users.noreply.github.com>
This commit is contained in:
opencode-agent[bot]
2026-01-17 15:55:51 +00:00
parent a58d1be822
commit 5f7355fb73
3 changed files with 30 additions and 19 deletions

View File

@@ -20,7 +20,7 @@ export function DialogAgent() {
return ( return (
<DialogSelect <DialogSelect
title="Select agent" title="Select agent"
current={local.agent.current().name} current={local.agent.current()?.name ?? "coder"}
options={options()} options={options()}
onSelect={(option) => { onSelect={(option) => {
local.agent.set(option.value) local.agent.set(option.value)

View File

@@ -531,7 +531,7 @@ export function Prompt(props: PromptProps) {
if (store.mode === "shell") { if (store.mode === "shell") {
sdk.client.session.shell({ sdk.client.session.shell({
sessionID, sessionID,
agent: local.agent.current().name, agent: local.agent.current()?.name ?? "coder",
model: { model: {
providerID: selectedModel.providerID, providerID: selectedModel.providerID,
modelID: selectedModel.modelID, modelID: selectedModel.modelID,
@@ -552,7 +552,7 @@ export function Prompt(props: PromptProps) {
sessionID, sessionID,
command: command.slice(1), command: command.slice(1),
arguments: args.join(" "), arguments: args.join(" "),
agent: local.agent.current().name, agent: local.agent.current()?.name ?? "coder",
model: `${selectedModel.providerID}/${selectedModel.modelID}`, model: `${selectedModel.providerID}/${selectedModel.modelID}`,
messageID, messageID,
variant, variant,
@@ -569,7 +569,7 @@ export function Prompt(props: PromptProps) {
sessionID, sessionID,
...selectedModel, ...selectedModel,
messageID, messageID,
agent: local.agent.current().name, agent: local.agent.current()?.name ?? "coder",
model: selectedModel, model: selectedModel,
variant, variant,
parts: [ parts: [
@@ -690,7 +690,7 @@ export function Prompt(props: PromptProps) {
const highlight = createMemo(() => { const highlight = createMemo(() => {
if (keybind.leader) return theme.border if (keybind.leader) return theme.border
if (store.mode === "shell") return theme.primary if (store.mode === "shell") return theme.primary
return local.agent.color(local.agent.current().name) return local.agent.color(local.agent.current()?.name ?? "coder")
}) })
const showVariant = createMemo(() => { const showVariant = createMemo(() => {
@@ -701,7 +701,7 @@ export function Prompt(props: PromptProps) {
}) })
const spinnerDef = createMemo(() => { const spinnerDef = createMemo(() => {
const color = local.agent.color(local.agent.current().name) const color = local.agent.color(local.agent.current()?.name ?? "coder")
return { return {
frames: createFrames({ frames: createFrames({
color, color,
@@ -935,7 +935,7 @@ export function Prompt(props: PromptProps) {
/> />
<box flexDirection="row" flexShrink={0} paddingTop={1} gap={1}> <box flexDirection="row" flexShrink={0} paddingTop={1} gap={1}>
<text fg={highlight()}> <text fg={highlight()}>
{store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current().name)}{" "} {store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current()?.name ?? "coder")}{" "}
</text> </text>
<Show when={store.mode === "normal"}> <Show when={store.mode === "normal"}>
<box flexDirection="row" gap={1}> <box flexDirection="row" gap={1}>

View File

@@ -38,7 +38,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
const [agentStore, setAgentStore] = createStore<{ const [agentStore, setAgentStore] = createStore<{
current: string current: string
}>({ }>({
current: agents()[0].name, current: agents()[0]?.name ?? "",
}) })
const { theme } = useTheme() const { theme } = useTheme()
const colors = createMemo(() => [ const colors = createMemo(() => [
@@ -54,7 +54,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
return agents() return agents()
}, },
current() { current() {
return agents().find((x) => x.name === agentStore.current)! return agents().find((x) => x.name === agentStore.current) ?? agents()[0]
}, },
set(name: string) { set(name: string) {
if (!agents().some((x) => x.name === name)) if (!agents().some((x) => x.name === name))
@@ -67,10 +67,13 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
}, },
move(direction: 1 | -1) { move(direction: 1 | -1) {
batch(() => { batch(() => {
let next = agents().findIndex((x) => x.name === agentStore.current) + direction const list = agents()
if (next < 0) next = agents().length - 1 if (list.length === 0) return
if (next >= agents().length) next = 0 let next = list.findIndex((x) => x.name === agentStore.current) + direction
const value = agents()[next] if (next < 0) next = list.length - 1
if (next >= list.length) next = 0
const value = list[next]
if (!value) return
setAgentStore("current", value.name) setAgentStore("current", value.name)
}) })
}, },
@@ -179,6 +182,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
const currentModel = createMemo(() => { const currentModel = createMemo(() => {
const a = agent.current() const a = agent.current()
if (!a) return undefined
return ( return (
getFirstValidModel( getFirstValidModel(
() => modelStore.model[a.name], () => modelStore.model[a.name],
@@ -217,17 +221,19 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
} }
}), }),
cycle(direction: 1 | -1) { cycle(direction: 1 | -1) {
const current = currentModel() const a = agent.current()
if (!current) return if (!a) return
const model = currentModel()
if (!model) return
const recent = modelStore.recent const recent = modelStore.recent
const index = recent.findIndex((x) => x.providerID === current.providerID && x.modelID === current.modelID) const index = recent.findIndex((x) => x.providerID === model.providerID && x.modelID === model.modelID)
if (index === -1) return if (index === -1) return
let next = index + direction let next = index + direction
if (next < 0) next = recent.length - 1 if (next < 0) next = recent.length - 1
if (next >= recent.length) next = 0 if (next >= recent.length) next = 0
const val = recent[next] const val = recent[next]
if (!val) return if (!val) return
setModelStore("model", agent.current().name, { ...val }) setModelStore("model", a.name, { ...val })
}, },
cycleFavorite(direction: 1 | -1) { cycleFavorite(direction: 1 | -1) {
const favorites = modelStore.favorite.filter((item) => isModelValid(item)) const favorites = modelStore.favorite.filter((item) => isModelValid(item))
@@ -253,7 +259,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
} }
const next = favorites[index] const next = favorites[index]
if (!next) return if (!next) return
setModelStore("model", agent.current().name, { ...next }) const a = agent.current()
if (!a) return
setModelStore("model", a.name, { ...next })
const uniq = uniqueBy([next, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`) const uniq = uniqueBy([next, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`)
if (uniq.length > 10) uniq.pop() if (uniq.length > 10) uniq.pop()
setModelStore( setModelStore(
@@ -264,6 +272,8 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
}, },
set(model: { providerID: string; modelID: string }, options?: { recent?: boolean }) { set(model: { providerID: string; modelID: string }, options?: { recent?: boolean }) {
batch(() => { batch(() => {
const a = agent.current()
if (!a) return
if (!isModelValid(model)) { if (!isModelValid(model)) {
toast.show({ toast.show({
message: `Model ${model.providerID}/${model.modelID} is not valid`, message: `Model ${model.providerID}/${model.modelID} is not valid`,
@@ -272,7 +282,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
}) })
return return
} }
setModelStore("model", agent.current().name, model) setModelStore("model", a.name, model)
if (options?.recent) { if (options?.recent) {
const uniq = uniqueBy([model, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`) const uniq = uniqueBy([model, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`)
if (uniq.length > 10) uniq.pop() if (uniq.length > 10) uniq.pop()
@@ -368,6 +378,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
// Automatically update model when agent changes // Automatically update model when agent changes
createEffect(() => { createEffect(() => {
const value = agent.current() const value = agent.current()
if (!value) return
if (value.model) { if (value.model) {
if (isModelValid(value.model)) if (isModelValid(value.model))
model.set({ model.set({