Skip to content

fix(opencode): send CLI identity + x-opencode-session on background calls - #13005

Open
alvinveroy wants to merge 7 commits into
diegosouzapw:release/v3.8.52from
alvinveroy:pr/opencode-background-identity
Open

alvinveroy wants to merge 7 commits into
diegosouzapw:release/v3.8.52from
alvinveroy:pr/opencode-background-identity

Conversation

@alvinveroy

Copy link
Copy Markdown
Contributor

What

OpenCode background calls — model discovery (PROVIDER_MODELS_CONFIG) and the quota fetcher — went out as bare Bun fetch with no x-opencode-session, which is exactly the shape OpenCode's operator warning names (enforcement announced from 2026-09-06).

Change

Add buildOpencodeBackgroundHeaders() (User-Agent + x-opencode-session/request/client/project, stable per-workspace seed) and use it from the opencode-family discovery entries and the quota fetcher so background calls carry the same conversation-scoped identity the operator sends.

  • open-sse/utils/opencodeHeaders.ts — add buildOpencodeBackgroundHeaders.
  • src/app/api/providers/[id]/models/discovery/providerModelsConfig.ts — build opencode/zen/go discovery entries with the identity headers.
  • open-sse/services/opencodeQuotaFetcher.ts — attach the headers to quota calls.
  • tests/unit/opencode-background-identity-headers.test.ts — regression.

CI failures on this repo are pre-existing (not from this change)

The default branch release/v3.8.51 has failing CI independent of this PR:

  • Release-Green (continuous) (scheduled, run 34152080135): fails in "Validate active release branch" because the self-hosted runner "lost communication with the server" — infrastructure, not code.
  • API Route Typecheck (e.g. run 34175616875 on an unrelated PR): fails with open-sse/handlers/chatCore.ts TS2339 (baseline 0, live 13) — a typecheck regression on the default branch, in a file this PR does not touch.
  • Quality Gates → Unit Tests fast-path (1–4/4) (e.g. run 34175126633): all four shards fail at test:unit:ci:shard (includes an expired Perplexity session cookie 401), on unrelated PRs.

This PR does not modify open-sse/handlers/chatCore.ts and introduces no new typecheck diagnostics.

@diegosouzapw

Copy link
Copy Markdown
Owner

Clean, well-scoped fix — I traced the two background call sites
(opencodeQuotaFetcher.ts, the models-discovery config) and confirmed neither sent
x-opencode-session or a CLI-identity User-Agent before this PR, which matches OpenCode's
operator warning exactly. Ran your 6 new tests against a probe worktree — all green, and they
exercise the real production code paths (not a reimplementation). Two small asks before merge:
a changelog.d/fixes/ fragment (repo convention), and a quick confirmation that adding the new
opencode discovery-config key (it didn't exist before — only opencode-zen/opencode-go
had it) is intentional scope for this PR. No conflicts with #12719 or #13179 — different files
entirely, all three can land independently.

alvinveroy and others added 3 commits September 16, 2026 10:41
…alls

Discovery (PROVIDER_MODELS_CONFIG) and quota-fetch background calls went out
as bare 'Bun fetch' with no x-opencode-session, so opencode.ai hard-errors
them (announced for 2026-09-06). Add buildOpencodeBackgroundHeaders() and use
it from the discovery entries and the quota fetcher so background calls carry
the stable conversation-scoped identity the operator sends.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…with connection-id fallback

Discovery's readOpencodeBackgroundSeed only read 'opencodeGoWorkspaceId',
but the providerSpecificData validator accepts three spellings
(openCodeGoWorkspaceId / opencodeGoWorkspaceId / workspaceId). A connection
using either of the other two silently fell through to the helper's
randomUUID fallback — a fresh anonymous x-opencode-session per discovery
call, exactly the shape the operator warning targets.

Read all three spellings, then fall back to the connection id so a
workspace-less connection still gets a deterministic per-connection
session instead of a random one. Add id to ProviderModelsHeaderContext
(the route spreads the full connection row, so it is already present).

Tests fail on branch HEAD (2 of 8) and pass after the fix.
@alvinveroy
alvinveroy force-pushed the pr/opencode-background-identity branch from a768868 to 98bde55 Compare September 16, 2026 03:20
@alvinveroy

Copy link
Copy Markdown
Contributor Author

Both asks answered on 98bde5519 (rebased onto cde49c937; mergeable=true).

1. The new opencode discovery-config key is intentional scope, and it's a fix rather than an addition. Your reading of the base is right — only opencode-zen/opencode-go had an entry. The reason opencode needed one is the fallback path it was silently taking. route.ts:2090 looks the provider up in PROVIDER_MODELS_CONFIG, and only when that misses does it fall through to deriveConfigFromRegistryModelsUrl() (discoveryConfig.ts:24). That derive path builds its own headers:

authHeader: "Authorization",
authPrefix: "Bearer ",
headers: { "Content-Type": "application/json" },

— a plain Bearer fetch with no buildHeaders hook, so it can never attach the CLI identity. And the opencode registry entry (open-sse/config/providers/registry/opencode/index.ts:4) declares modelsUrl: "https://opencode.ai/zen/v1/models", i.e. exactly the URL this PR now maps explicitly. So opencode is a registered provider whose background discovery was reaching the same upstream endpoint through the derived path with a bare "Bun fetch" UA and no x-opencode-session — the precise shape OpenCode's operator warning names, and the one gap the other two keys didn't have. Mapping it explicitly is what closes it.

2. Changelog fragment — changelog.d/fixes/13005-opencode-background-identity-headers.md.

One correction for your records: the branch carries 8 tests, not 6 (tests/unit/opencode-background-identity-headers.test.ts, new file) — 8/8 pass. Two cover the seed resolution specifically, since that's where the bug was: discovery seed honours every workspace spelling the validator accepts matches the validator's own triple at providerSpecificData.ts:380 (openCodeGoWorkspaceId/opencodeGoWorkspaceId/workspaceId — the third spelling being the one the original code missed), and discovery falls back to the connection id, not a random session, when no workspace is set. I verified that fallback is live rather than dead code: route.ts:2298 builds headerContext = { ...connection, accessToken, apiKey }, so both id and providerSpecificData actually reach buildHeaders.

Thanks for confirming the non-overlap with #12719/#13179.

alvinveroy and others added 2 commits September 18, 2026 07:51
Resolves the two conflicts in providerModelsConfig.ts — independent additions at the same spots (this PR's OpenCode identity-header discovery entry; the base's xai-oauth live-discovery flag from the release); kept both. typecheck:core clean.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
The release added a lockstep set mirroring PROVIDER_MODELS_CONFIG's keys after
this branch was cut; the new 'opencode' entry needs its twin there
(discovery-class + xai-oauth-discovery lockstep tests).

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw diegosouzapw changed the title fix(opencode): send CLI identity + x-opencode-session on background calls [defer] fix(opencode): send CLI identity + x-opencode-session on background calls Sep 29, 2026
@diegosouzapw diegosouzapw added the deferred-v3.8.52 Grande demais / suspeito para o lote atual; precisa de sessão dedicada no ciclo v3.8.52 label Sep 29, 2026
@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.51 to release/v3.8.52 September 29, 2026 11:27
@diegosouzapw

Copy link
Copy Markdown
Owner

Re-homed to release/v3.8.52: v3.8.51 entered its release freeze, so the branch now belongs to the release captain and development continues on the next cycle. Nothing is wrong with this PR — it just needed a live base. No action needed from you; CI will re-run against the new base.

yano added 2 commits October 1, 2026 07:20
Conflict in open-sse/utils/opencodeHeaders.ts: upstream canonicalized the
x-opencode-request/x-opencode-session ids emitted by applyCliDefaults
(msg_/ses_ shapes); this branch adds buildOpencodeBackgroundHeaders after
it. Kept upstream's canonicalization and the background-headers helper
below it; the helper's seed-based session override still wins.
…elper

The base's applyCliDefaults now canonicalizes x-opencode-request/-session
(msg_/ses_ shapes). Seed the session BEFORE calling it so the canonicalizer
derives the deterministic ses_ id from the raw workspace/connection seed,
instead of overwriting with a bare 16-hex fingerprint afterwards. The suite
now asserts the canonical shapes on the request id, the seeded and seedless
sessions, and the discovery headers.
@alvinveroy

Copy link
Copy Markdown
Contributor Author

Refreshed onto the latest release/v3.8.52 (merge 2fe7852): upstream's canonical msg_/ses_ id shapes are kept, and the background identity helper now seeds the session before the canonicalizer so it emits a deterministic ses_… (2c476d4). The PR's own suite and the other opencode suites pass (93 tests).

@diegosouzapw diegosouzapw removed the deferred-v3.8.52 Grande demais / suspeito para o lote atual; precisa de sessão dedicada no ciclo v3.8.52 label Oct 1, 2026
@diegosouzapw diegosouzapw changed the title [defer] fix(opencode): send CLI identity + x-opencode-session on background calls fix(opencode): send CLI identity + x-opencode-session on background calls Oct 1, 2026

This branch has not been deployed

No deployments
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