Skip to content

feat(core): keep web search providers sticky per session - #47334

Merged
nexxeln merged 5 commits into
v2from
sticky-websearch
Sep 6, 2026
Merged

nexxeln merged 5 commits into
v2from
sticky-websearch

Conversation

@nexxeln

@nexxeln nexxeln commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Issue for this PR

User-requested improvement; no linked issue.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Makes the existing websearch.provider: "random" mode sticky per session: pick a random provider on the first search, keep using it, and retain a replacement after HTTP 429. Concurrent failures reuse the session's healthy replacement. Cooldowns honor Retry-After or default to 60 seconds. Each provider is attempted at most once per query; searches fail promptly when all providers are cooling down.

Keeps the existing configuration name, permissions, consent, and provider labels. Fixed/explicit providers do not fail over. Preferred providers are session-local; cooldowns remain shared per Location. API/plugin callers without session context retain Location affinity. Ordinary default inspection does not select or change affinity.

In the TUI, a live retry transitions just the provider name with a short fade-through instead of abruptly replacing it. First paint, new calls, completion-only changes, and loading history do not start animations. The label and metadata still identify the actual provider. Animations stop when a row leaves view and respect the existing animation setting.

The trusted tool context supplies the session ID through an internal option. Affinity stays in memory and is cleaned up on session deletion/movement or Location disposal; moving a session resets its preference. No new public API or durable schema changes, and no new generated-file changes for the scope update.

Includes concurrent-failover and consent regression fixes, scoped HTTP cleanup, shared HTTP test helpers, docs, and regenerated clients/OpenAPI. Regeneration also picks up existing compaction fields missing from the checked-in OpenAPI snapshots.

How did you verify your code works?

  • Core: 54 tests across websearch.test.ts, tool-websearch.test.ts, config/websearch.test.ts, and plugin/websearch.test.ts, including independent peers, shared cooldowns, concurrent initial/fallback routing, late successes, and in-flight cleanup on deletion/movement.
  • Schema: 5 config tests; TUI: provider-label transport regression test.
  • TUI: 25 focused animation/wrapping tests, including rapid fallbacks, Unicode wrapping, animations-off, offscreen rows, and unmount cleanup.
  • All 33 repository typecheck tasks passed in the pre-push hook.
  • Client/OpenAPI generation, generated-document checks, and the www build/link validation.
  • Drive 2.1.0 on Bun 1.4.1, using the real Core websearch tool with controlled provider implementations: 9 concurrent searches stayed on Firecrawl, 3 overlapping 429s converged on Parallel and retained it, and a second session retained Tavily. Also exercised empty results, exhausted providers, and 15 long queries at a narrow viewport with scrolling.

Screenshots / recordings

Private Drive recordings cover session affinity and the retry-only provider-name transition at normal and narrow widths. Initial rendering, ordinary calls, completion, and reopened history remain unanimated. Core routing and metadata are unchanged by the animation.

Separate follow-up

Cooldowns are still keyed only by provider ID. Credential changes do not explicitly invalidate them in this module (code review only, not runtime-verified). A focused follow-up should invalidate the affected provider's cooldown on an active-credential change and add a regression test; this PR does not expand into credential handling.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@nexxeln nexxeln changed the title feat(core): add sticky auto web search failover feat(core): make random web search selection sticky Sep 4, 2026
@nexxeln nexxeln changed the title feat(core): make random web search selection sticky feat(core): keep web search providers sticky per session Sep 4, 2026
@nexxeln
nexxeln merged commit e3c8965 into v2 Sep 6, 2026
10 checks passed
@nexxeln
nexxeln deleted the sticky-websearch branch September 6, 2026 21:39
ilya-bogin-keenable added a commit to keenableai/opencode that referenced this pull request Sep 8, 2026
Follow anomalyco#47334: release the rate-limited HTTP request before its error is cached, and join the abort-signal test that enumerates the bundled providers.
ilya-bogin-keenable added a commit to keenableai/opencode that referenced this pull request Sep 18, 2026
Follow anomalyco#47334: release the rate-limited HTTP request before its error is cached, and join the abort-signal test that enumerates the bundled providers.
jinhuang712 pushed a commit to jinhuang712/opencode that referenced this pull request Sep 26, 2026
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.

1 participant