refactor(sessiontitle): simplify Generator without changing behavior#2575
Merged
dgageot merged 2 commits intodocker:mainfrom Apr 28, 2026
Merged
Conversation
- Consolidate the three early-return guards (nil generator, no models, no\n user messages) at the top of Generate, before allocating the timeout\n context.\n- Use slices.DeleteFunc to filter nil providers in New, replacing the\n manual two-pass append loop.\n- Extract generateOnce so each attempt closes its stream via defer and\n returns plainly, removing the streamErr plumbing.\n- Extract buildPrompt to keep message construction out of the main loop.\n- Drop the dead 'if baseModel == nil' check in the loop; New already\n filters nils.\n- Tighten sanitizeTitle into a single loop body.\n- Unify per-attempt failure logging into a single message; the wrapped\n error already distinguishes create-stream vs receive-stream failures. Assisted-By: docker-agent
- Move the 'empty model output' check into generateOnce so it returns\n a regular error like any other attempt failure. The main loop now has\n a single failure path: log at Debug and continue to the next model.\n- Extract drainStream as a small helper that owns reading and closing\n the message stream, removing the streamErr plumbing from generateOnce.\n- Unify per-attempt logging at Debug level. Per-attempt failures are not\n fatal as long as we have fallbacks, and callers already log/wrap the\n final returned error.\n- Drop the post-loop 'if lastErr != nil' guard: every non-success path\n in the loop now sets lastErr, so the wrap can be unconditional. Assisted-By: docker-agent
gtardif
approved these changes
Apr 28, 2026
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.
Simplifies
pkg/sessiontitleto make it easier to read and maintain. No public API changes, no behavior changes — same fallback chain, same timeout, same prompts, same observable outputs to callers.Changes
Two refactor-only commits, kept separate so the diff stays easy to follow.
1.
refactor(sessiontitle): tidy Generator without changing behaviorg == nil, no models, no user messages) at the top ofGenerate, before allocating the timeout context.Newwith a singleslices.DeleteFunc.generateOnceso each attempt closes its stream viadefer(no morestreamErrplumbing).buildPromptto keep prompt construction out of the main loop.if baseModel == nil { continue }(Newalready filters nils).sanitizeTitleto a single-line loop body.2.
refactor(sessiontitle): unify the per-attempt failure pathgenerateOnce: it now returns a normal error like any other attempt failure, so the main loop has a single failure path.drainStreamas a small helper that owns reading and closing the message stream.if lastErr != nilguard — the loop's invariants now makelastErralways non-nil at that point.Final shape
The package is now a clear linear pipeline of small, single-purpose functions:
New— build the model list (filtering nils)Generate— iterate models, log per-attempt outcomes, return the first success or wrap the last failuregenerateOnce— clone provider, open stream, drain, sanitize, validate non-emptydrainStream— read + closebuildPrompt— format messagessanitizeTitle— first non-empty line, strip\rValidation
mise lint— clean (golangci-lint: 0 issues; custom analyzer: no offenses;go mod tidyclean)mise test— full suite passes, includingpkg/sessiontitle,pkg/app,pkg/server,pkg/runtime,cmd/rootTestGenerator_Generate_FallsBackOnStreamCreateError,TestGenerator_Generate_FallsBackOnRecvError,TestGenerator_Generate_FallsBackOnEmptyOutput) all still pass unchanged.