summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-08-13 16:29:07 -0400
committerDax Raad <[email protected]>2025-08-14 12:20:22 -0400
commit796bc390dba5ef7f78c98a6a007dfc5efebcba49 (patch)
tree2500ee5d3dafe297b7206b4791b3a47e6a46a0bf
parent703ae4967556e0644a0860e9a7aa439ad2d4c2d1 (diff)
downloadopencode-796bc390dba5ef7f78c98a6a007dfc5efebcba49.tar.gz
opencode-796bc390dba5ef7f78c98a6a007dfc5efebcba49.zip
fix for session stuck in "Working..."
-rw-r--r--packages/opencode/src/session/index.ts6
-rw-r--r--packages/opencode/src/util/defer.ts12
-rw-r--r--packages/tui/internal/app/app.go2
-rw-r--r--packages/tui/internal/components/chat/messages.go5
4 files changed, 24 insertions, 1 deletions
diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts
index 68c5fad8f..2e5e15dd7 100644
--- a/packages/opencode/src/session/index.ts
+++ b/packages/opencode/src/session/index.ts
@@ -45,6 +45,7 @@ import { Agent } from "../agent/agent"
import { Permission } from "../permission"
import { Wildcard } from "../util/wildcard"
import { ulid } from "ulid"
+import { defer } from "../util/defer"
export namespace Session {
const log = Log.create({ service: "session" })
@@ -763,6 +764,11 @@ export namespace Session {
sessionID: input.sessionID,
}
await updateMessage(assistantMsg)
+ await using _ = defer(async () => {
+ if (assistantMsg.time.completed) return
+ await Storage.remove(`session/message/${input.sessionID}/${assistantMsg.id}`)
+ await Bus.publish(MessageV2.Event.Removed, { sessionID: input.sessionID, messageID: assistantMsg.id })
+ })
const tools: Record<string, AITool> = {}
const processor = createProcessor(assistantMsg, model.info)
diff --git a/packages/opencode/src/util/defer.ts b/packages/opencode/src/util/defer.ts
new file mode 100644
index 000000000..8de21528c
--- /dev/null
+++ b/packages/opencode/src/util/defer.ts
@@ -0,0 +1,12 @@
+export function defer<T extends () => void | Promise<void>>(
+ fn: T,
+): T extends () => Promise<void> ? { [Symbol.asyncDispose]: () => Promise<void> } : { [Symbol.dispose]: () => void } {
+ return {
+ [Symbol.dispose]() {
+ fn()
+ },
+ [Symbol.asyncDispose]() {
+ return Promise.resolve(fn())
+ },
+ } as any
+}
diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go
index ce3a54229..023b799d5 100644
--- a/packages/tui/internal/app/app.go
+++ b/packages/tui/internal/app/app.go
@@ -631,7 +631,7 @@ func (a *App) IsBusy() bool {
if casted, ok := lastMessage.Info.(opencode.AssistantMessage); ok {
return casted.Time.Completed == 0
}
- return true
+ return false
}
func (a *App) SaveState() tea.Cmd {
diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go
index 92259e93a..ec7735d58 100644
--- a/packages/tui/internal/components/chat/messages.go
+++ b/packages/tui/internal/components/chat/messages.go
@@ -203,6 +203,11 @@ func (m *messagesComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if msg.Properties.Part.SessionID == m.app.Session.ID {
cmds = append(cmds, m.renderView())
}
+ case opencode.EventListResponseEventMessageRemoved:
+ if msg.Properties.SessionID == m.app.Session.ID {
+ m.cache.Clear()
+ cmds = append(cmds, m.renderView())
+ }
case opencode.EventListResponseEventMessagePartRemoved:
if msg.Properties.SessionID == m.app.Session.ID {
// Clear the cache when a part is removed to ensure proper re-rendering