Skip to content

refactor: consolidate Provider's four generate paths (plan 017)#88

Open
DavertMik wants to merge 1 commit into
mainfrom
refactor/provider-generate-consolidation
Open

refactor: consolidate Provider's four generate paths (plan 017)#88
DavertMik wants to merge 1 commit into
mainfrom
refactor/provider-generate-consolidation

Conversation

@DavertMik

Copy link
Copy Markdown
Contributor

Plan 017 — Consolidate the four duplicated generate paths in Provider

src/ai/provider.ts had four near-identical generate paths (chat, generateWithTools, generateObject, processImage) each re-implementing config assembly, usage recording, the idle-timeout race, and context-length recovery. This extracts four private helpers:

  • recordUsage(agentName, modelName, usage) — single Stats.recordTokens call site (was 4). Also adds the cached token field to processImage (was the only path missing it).
  • recoverFromContextLength(error, messages, options, retry) — single context-length reduce+retry, retry callback stays method-specific.
  • buildGenerateConfig(defaults, overrides, options) — shared mergeProviderOptions + finalizeConfig assembly.
  • raceWithIdleTimeout(fn, timeoutMs) — single Promise.race against the idle abort.

Drift reconciliation

This plan was written at 9e22b0d; since then plan 005 (abort in-flight request on idle timeout, PR #73) and plan 007 (PR #75) reshaped these methods. Per the plan's Step 4 guidance, plan 005's per-attempt AbortController + combinedAbortSignal is folded inside raceWithIdleTimeout — one controller per retry attempt (the helper is called inside the withRetry callback), signature (signal) => generateX({ ...config, abortSignal: signal }).

Behavior-preserving

  • Config spread order is preserved per site: defaults land before ...(this.config.config) (so user config can still override the maxOutputTokens: 16384 default), overrides (model/abortSignal/stopWhen) land after ...options.
  • generateWithTools no longer strips stopWhen from options — stopWhen: stopConditions in overrides already wins over ...options, and stopConditions still folds in options.stopWhen via extraStop. Identical result.

Deliberately NOT changed (behavior changes wanting their own review)

  • chat() still has no idle-timeout race.
  • processImage() still skips context-length recovery and keeps its minimal config path (routing it through buildGenerateConfig would change agent-level provider-option behavior).

Verification

  • bun test tests/unit765 pass / 0 fail (+1 new context-length-recovery-through-helper test).
  • bun test tests/integration/63 pass / 0 fail.
  • bun run lint → clean.
  • tsc errors: 639 → 636 total (provider.ts 10 → 6) — refactor removed 4 promptTokens/completionTokens TS2339s; no new errors.
  • Greps: Stats.recordTokens ×1, tryReduceMessages ×2, abortAfterIdle ×2, Promise.race ×1.

🤖 Generated with Claude Code

Extract four shared helpers from chat/generateWithTools/generateObject/
processImage: recordUsage, recoverFromContextLength, buildGenerateConfig,
raceWithIdleTimeout. Plan 005's per-attempt AbortController + combined
idle-abort signal is folded into raceWithIdleTimeout, preserving one
controller per retry attempt.

Behavior-preserving: config spread order kept per site (defaults before
config.config so user config can override maxOutputTokens; overrides after
options). chat() still has no idle race; processImage() still skips
context-length recovery and its minimal config path. processImage now
records the cached token field like the other three paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Explorbot Self-Regression

Commit a0f91fa · run

Scenario Result Attempts Duration
basic (native) PASS 1/3 7m
experience: control OK — failed as expected 1/1 1m
experience: seeded PASS 1/3 1m

Attempt details

  • basic (native) attempt 1 — PASS: login evidence: PASS (post-login plan=true, post-login research=true); research: PASS (files=6, wellFormed=true, keywords=7/3); scenarios: PASS (tests=6/5, features=4/3); tests passed: PASS (5 passed, 0 failed (reporter: 5 passed, 0 failed))
  • experience: control attempt 1 — PASS: control: OK — failed as expected (0 passed, 1 failed)
  • experience: seeded attempt 1 — PASS: seeded: PASS (1 passed, 0 failed)

Session analysis — basic (native):

Session Analysis

The Issues list feature was explored. Core flows for creating, viewing, searching, and filtering issues all function correctly. ET-2 had a verification retry that succeeded, and ET-5 required alternative selectors but achieved the goal.

Coverage

  • Pages: /issues, /issues/:id, /issues?new=1, /issues?q=..., /issues?status=..., /issues?label=...
  • Features: Create issue, View issue detail, Search by keyword, Filter by status, Filter by label

What works

  • Create issueET-1 Create new issue via toolbar button
  • View issue detailET-2 Open issue detail from list
  • Search by keywordET-3 Search for existing issue by keyword
  • Filter by statusET-4 Filter issues by status using combobox
  • Filter by labelET-5 Filter issues by Bug label

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants