From 2d9a593767955ce9c73d2e101b8c7a9cfc7c233c Mon Sep 17 00:00:00 2001 From: Janni Turunen Date: Thu, 5 Feb 2026 11:42:53 +0200 Subject: [PATCH] fix(oclite): add text streaming and session error handling (#142) - Add text streaming handler for message.part.updated events with delta - Add try/catch for session initialization with user-visible errors - Add race condition guard in handleSubmit to prevent premature submissions - Fixes non-functional TUI by enabling text response streaming --- packages/opencode/src/cli/ink/App.tsx | 39 +++++++++++++------ .../src/cli/ink/hooks/useSDKEvents.ts | 11 ++++++ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/packages/opencode/src/cli/ink/App.tsx b/packages/opencode/src/cli/ink/App.tsx index 40e317df84d..4b82f6a09ba 100644 --- a/packages/opencode/src/cli/ink/App.tsx +++ b/packages/opencode/src/cli/ink/App.tsx @@ -23,18 +23,26 @@ export const App = (): ReactElement => { // Initialize session on mount useEffect(() => { const initSession = async () => { - const session = await Session.createNext({ directory: Instance.directory }) - const agent = await Agent.defaultAgent() - dispatch({ - type: "SET_SESSION", - payload: { - id: session.id, - agent, - model: null, - }, - }) + try { + const session = await Session.createNext({ directory: Instance.directory }) + const agent = await Agent.defaultAgent() + dispatch({ + type: "SET_SESSION", + payload: { + id: session.id, + agent, + model: null, + }, + }) + } catch (error) { + console.error("Session init failed:", error) + dispatch({ + type: "STREAM_TEXT", + payload: `Error: Failed to initialize session - ${error}\n`, + }) + } } - initSession().catch(console.error) + initSession() }, []) // Use SDK events hook for streaming @@ -50,7 +58,14 @@ export const App = (): ReactElement => { }).catch(() => { // Silently handle command errors }) - } else if (value.trim() && state.session.id) { + } else if (value.trim()) { + if (!state.session.id) { + dispatch({ + type: "STREAM_TEXT", + payload: "Waiting for session to initialize...\n", + }) + return + } // Send message via SDK hook await sendMessage(value.trim()) } diff --git a/packages/opencode/src/cli/ink/hooks/useSDKEvents.ts b/packages/opencode/src/cli/ink/hooks/useSDKEvents.ts index c01b6374e03..f053fb29fcc 100644 --- a/packages/opencode/src/cli/ink/hooks/useSDKEvents.ts +++ b/packages/opencode/src/cli/ink/hooks/useSDKEvents.ts @@ -103,6 +103,17 @@ function handleEvent( const part = event.properties.part if (part.sessionID !== sessionId) return + // Handle text streaming + if (part.type === "text") { + const delta = event.properties.delta + if (delta) { + dispatch({ + type: "STREAM_TEXT", + payload: delta, + }) + } + } + if (part.type === "tool") { const toolState = part.state