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..facceb25364 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 caa13032292..41d25ed6379 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -503,6 +503,10 @@ export function Prompt(props: PromptProps) { promptModelWarning() return } + const currentAgent = local.agent.current() + if (!currentAgent) { + return + } const sessionID = props.sessionID ? props.sessionID : await (async () => { @@ -538,7 +542,7 @@ export function Prompt(props: PromptProps) { if (store.mode === "shell") { sdk.client.session.shell({ sessionID, - agent: local.agent.current().name, + agent: currentAgent.name, model: { providerID: selectedModel.providerID, modelID: selectedModel.modelID, @@ -565,7 +569,7 @@ export function Prompt(props: PromptProps) { sessionID, command: command.slice(1), arguments: args, - agent: local.agent.current().name, + agent: currentAgent.name, model: `${selectedModel.providerID}/${selectedModel.modelID}`, messageID, variant, @@ -582,7 +586,7 @@ export function Prompt(props: PromptProps) { sessionID, ...selectedModel, messageID, - agent: local.agent.current().name, + agent: currentAgent.name, model: selectedModel, variant, parts: [ @@ -703,7 +707,9 @@ 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) + const currentAgent = local.agent.current() + if (!currentAgent) return theme.border + return local.agent.color(currentAgent.name) }) const showVariant = createMemo(() => { @@ -714,7 +720,8 @@ export function Prompt(props: PromptProps) { }) const spinnerDef = createMemo(() => { - const color = local.agent.color(local.agent.current().name) + const currentAgent = local.agent.current() + const color = currentAgent ? local.agent.color(currentAgent.name) : theme.border return { frames: createFrames({ color, @@ -952,7 +959,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 ?? "")}{" "} diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index d058ce54fb3..9436d58468a 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -36,9 +36,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const agent = iife(() => { const agents = createMemo(() => sync.data.agent.filter((x) => x.mode !== "subagent" && !x.hidden)) const [agentStore, setAgentStore] = createStore<{ - current: string + current: string | undefined }>({ - current: agents()[0].name, + current: agents()[0]?.name, }) const { theme } = useTheme() const colors = createMemo(() => [ @@ -54,7 +54,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ return agents() }, current() { - return agents().find((x) => x.name === agentStore.current)! + const list = agents() + const found = list.find((x) => x.name === agentStore.current) + return found ?? list[0] }, set(name: string) { if (!agents().some((x) => x.name === name)) @@ -67,10 +69,12 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ }, move(direction: 1 | -1) { batch(() => { - let next = agents().findIndex((x) => x.name === agentStore.current) + direction - if (next < 0) next = agents().length - 1 - if (next >= agents().length) next = 0 - const value = agents()[next] + const list = agents() + if (list.length === 0) return + let next = list.findIndex((x) => x.name === agentStore.current) + direction + if (next < 0) next = list.length - 1 + if (next >= list.length) next = 0 + const value = list[next] setAgentStore("current", value.name) }) }, @@ -188,6 +192,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const currentModel = createMemo(() => { const a = agent.current() + if (!a) return undefined return ( getFirstValidModel( () => modelStore.model[a.name], @@ -228,6 +233,8 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ cycle(direction: 1 | -1) { const current = currentModel() if (!current) return + const currentAgent = agent.current() + if (!currentAgent) return const recent = modelStore.recent const index = recent.findIndex((x) => x.providerID === current.providerID && x.modelID === current.modelID) if (index === -1) return @@ -236,7 +243,7 @@ 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 }) + setModelStore("model", currentAgent.name, { ...val }) }, cycleFavorite(direction: 1 | -1) { const favorites = modelStore.favorite.filter((item) => isModelValid(item)) @@ -262,7 +269,9 @@ 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) return + setModelStore("model", currentAgent.name, { ...next }) const uniq = uniqueBy([next, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`) if (uniq.length > 10) uniq.pop() setModelStore( @@ -281,7 +290,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ }) return } - setModelStore("model", agent.current().name, model) + const currentAgent = agent.current() + if (!currentAgent) return + 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() @@ -377,19 +388,18 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ // Automatically update model when agent changes createEffect(() => { const value = agent.current() - if (value.model) { - if (isModelValid(value.model)) - model.set({ - providerID: value.model.providerID, - modelID: value.model.modelID, - }) - else - toast.show({ - variant: "warning", - message: `Agent ${value.name}'s configured model ${value.model.providerID}/${value.model.modelID} is not valid`, - duration: 3000, - }) - } + if (!value || !value.model) return + if (isModelValid(value.model)) + model.set({ + providerID: value.model.providerID, + modelID: value.model.modelID, + }) + else + toast.show({ + variant: "warning", + message: `Agent ${value.name}'s configured model ${value.model.providerID}/${value.model.modelID} is not valid`, + duration: 3000, + }) }) const result = {