Skip to content

Commit 4150652

Browse files
committed
fix: handle undefined agent.current() in opentui
Fixes anomalyco#16982 Remove unsafe non-null assertion and add proper null checks when accessing agent.current() properties. This prevents the fatal error when no agents are available.
1 parent 8024166 commit 4150652

3 files changed

Lines changed: 34 additions & 11 deletions

File tree

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ export function DialogAgent() {
1717
}),
1818
)
1919

20+
const currentAgent = local.agent.current()
21+
2022
return (
2123
<DialogSelect
2224
title="Select agent"
23-
current={local.agent.current().name}
25+
current={currentAgent?.name}
2426
options={options()}
2527
onSelect={(option) => {
2628
local.agent.set(option.value)

‎packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,15 @@ export function Prompt(props: PromptProps) {
541541
return
542542
}
543543

544+
const currentAgent = local.agent.current()
545+
if (!currentAgent) {
546+
toast.show({
547+
message: "No agent available",
548+
variant: "error",
549+
})
550+
return
551+
}
552+
544553
let sessionID = props.sessionID
545554
if (sessionID == null) {
546555
const res = await sdk.client.session.create({
@@ -590,7 +599,7 @@ export function Prompt(props: PromptProps) {
590599
if (store.mode === "shell") {
591600
sdk.client.session.shell({
592601
sessionID,
593-
agent: local.agent.current().name,
602+
agent: currentAgent.name,
594603
model: {
595604
providerID: selectedModel.providerID,
596605
modelID: selectedModel.modelID,
@@ -617,7 +626,7 @@ export function Prompt(props: PromptProps) {
617626
sessionID,
618627
command: command.slice(1),
619628
arguments: args,
620-
agent: local.agent.current().name,
629+
agent: currentAgent.name,
621630
model: `${selectedModel.providerID}/${selectedModel.modelID}`,
622631
messageID,
623632
variant,
@@ -634,7 +643,7 @@ export function Prompt(props: PromptProps) {
634643
sessionID,
635644
...selectedModel,
636645
messageID,
637-
agent: local.agent.current().name,
646+
agent: currentAgent.name,
638647
model: selectedModel,
639648
variant,
640649
parts: [
@@ -755,7 +764,9 @@ export function Prompt(props: PromptProps) {
755764
const highlight = createMemo(() => {
756765
if (keybind.leader) return theme.border
757766
if (store.mode === "shell") return theme.primary
758-
return local.agent.color(local.agent.current().name)
767+
const agent = local.agent.current()
768+
if (!agent) return theme.border
769+
return local.agent.color(agent.name)
759770
})
760771

761772
const showVariant = createMemo(() => {
@@ -775,7 +786,9 @@ export function Prompt(props: PromptProps) {
775786
})
776787

777788
const spinnerDef = createMemo(() => {
778-
const color = local.agent.color(local.agent.current().name)
789+
const agent = local.agent.current()
790+
if (!agent) return { frames: [], interval: 80 }
791+
const color = local.agent.color(agent.name)
779792
return {
780793
frames: createFrames({
781794
color,
@@ -1014,7 +1027,7 @@ export function Prompt(props: PromptProps) {
10141027
/>
10151028
<box flexDirection="row" flexShrink={0} paddingTop={1} gap={1}>
10161029
<text fg={highlight()}>
1017-
{store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current().name)}{" "}
1030+
{store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current()?.name ?? "No Agent")}{" "}
10181031
</text>
10191032
<Show when={store.mode === "normal"}>
10201033
<box flexDirection="row" gap={1}>

‎packages/opencode/src/cli/cmd/tui/context/local.tsx‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
5757
return agents()
5858
},
5959
current() {
60-
return agents().find((x) => x.name === agentStore.current)!
60+
return agents().find((x) => x.name === agentStore.current)
6161
},
6262
set(name: string) {
6363
if (!agents().some((x) => x.name === name))
@@ -192,6 +192,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
192192

193193
const currentModel = createMemo(() => {
194194
const a = agent.current()
195+
if (!a) return undefined
195196
return (
196197
getFirstValidModel(
197198
() => modelStore.model[a.name],
@@ -240,7 +241,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
240241
if (next >= recent.length) next = 0
241242
const val = recent[next]
242243
if (!val) return
243-
setModelStore("model", agent.current().name, { ...val })
244+
const a = agent.current()
245+
if (!a) return
246+
setModelStore("model", a.name, { ...val })
244247
},
245248
cycleFavorite(direction: 1 | -1) {
246249
const favorites = modelStore.favorite.filter((item) => isModelValid(item))
@@ -266,7 +269,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
266269
}
267270
const next = favorites[index]
268271
if (!next) return
269-
setModelStore("model", agent.current().name, { ...next })
272+
const a = agent.current()
273+
if (!a) return
274+
setModelStore("model", a.name, { ...next })
270275
const uniq = uniqueBy([next, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`)
271276
if (uniq.length > 10) uniq.pop()
272277
setModelStore(
@@ -285,7 +290,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
285290
})
286291
return
287292
}
288-
setModelStore("model", agent.current().name, model)
293+
const a = agent.current()
294+
if (!a) return
295+
setModelStore("model", a.name, model)
289296
if (options?.recent) {
290297
const uniq = uniqueBy([model, ...modelStore.recent], (x) => `${x.providerID}/${x.modelID}`)
291298
if (uniq.length > 10) uniq.pop()
@@ -381,6 +388,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
381388
// Automatically update model when agent changes
382389
createEffect(() => {
383390
const value = agent.current()
391+
if (!value) return
384392
if (value.model) {
385393
if (isModelValid(value.model))
386394
model.set({

0 commit comments

Comments
 (0)