fix(opencode): decouple title generation from step counter, add bounded retries (#138) - #153
Merged
Merged
Conversation
…ed retries (#138) Title generation fired at most once (gated on `step === 1`), but multiple code paths (silent-turn guard, prose-question guard) pre-increment `step` with `step++; continue` before the title trigger is reached. By the time the loop hits the trigger, step is already past 1 — permanently dead. Additionally, `title()` itself bailed if `userMessages.length !== 1`, so even a late retry after a second user message would never succeed. Fix: 1. Replace `step === 1` with a dedicated `titleAttempts` counter (max 3). Checked every loop pass via `Session.isDefaultTitle(session.title)` — stops retrying after success (no wasted API calls). 2. Relax the single-message guard from `!== 1` to `< 1` — allows retries to succeed even after a second user message arrives. Invariants preserved: - Effect.ignore stays (non-critical, silent on failure) - Model selection unchanged (getSmallModel → fallback) - Title generation remains forked (never blocks the main response) - The <think> tag stripping and 100-char truncation are untouched Fixes #138
jeonghun-jj-lee
force-pushed
the
fix/138-session-title-generation
branch
from
August 9, 2026 01:11
41f114e to
e03108e
Compare
Effect.orDie in the title function promoted provider errors (rate limit, auth, network) into defects. The fork site used Effect.ignore, which only catches expected errors — defects bypass it, killing the background fiber with no log and no title set. Fix: 1. Remove Effect.orDie from the title LLM stream — errors stay in the E channel where Effect.ignore handles them gracefully. On failure the function exits early (no title), retries on the next loop pass (up to 3). 2. Fix setArchived typecheck: get(sessionID) returns Effect<Info, NotFound> but the interface declares Effect<void> — add .pipe(Effect.orDie) since archiving a non-existent session is a programmer error. 3. Add integration test confirming title generation fires on a new session. Fixes #138
jeonghun-jj-lee
force-pushed
the
fix/138-session-title-generation
branch
from
August 9, 2026 02:26
7f6c199 to
0d4e25e
Compare
…#138) The titlebar SessionChatsDropdown queried sessions from serverSync().data.path.directory (the server's cwd), which is the opencode-project workspace dir — not where sessions live. The store for that directory was never populated, so the dropdown was always empty. Fix: source sessions from all registered project directories via globalCtx.ensureServerCtx (the same data path the dashboard uses). Archive/unarchive handlers now reload the specific session's directory instead of the stale cwd reference.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Every new session received the static title "New session - [timestamp]" and never updated — the chat history became a wall of identical titles.
Root Cause
Title generation in
prompt.tsfires exactly once, gated onstep === 1. Multiple code paths silently prevent this from ever succeeding:step++; continuebefore the title trigger is reachedstep++; continuepatterntitle()(line 208) bails ifuserMessages.length !== 1Effect.ignoreswallows all errorsFix
Two changes in
packages/opencode/src/session/prompt.ts:1. Replace
step === 1with a dedicatedtitleAttemptscounterThe counter is checked every loop pass, so retries fire immediately without waiting for a new user message. The
isDefaultTitlecheck prevents wasted calls after success.2. Relax the single-message guard in
title()Allows retries to succeed even after the second user message arrives. Double-titling prevented by the
isDefaultTitlecheck at the caller.Invariants preserved
Effect.ignorestays — title generation remains non-critical and silentgetSmallModel→ fallback)<think>tag stripping and 100-char truncation are untouchedFixes #138