Repository navigation
Conversation
|
Two things I measured on the current base (
So on the chat-completions path the new The 403 in your "known limitation" is the request body rather than credential hydration. Measured across three models and both the Chat Completions and Responses surfaces, the upstream needs all four of: #14013 adds that body half on top of the same header work from #13937, credited there. Between #13937, this PR and #14013 there are now three changes to |
4839353 to
720e50a
Compare
|
Thanks for measuring both halves — verified on my side and updated the PR accordingly:
|
…identity (cheaper-inference#13935) - Register oc -> OpencodeExecutor("opencode"): the no-auth Free tier now gets Bearer public + canonical ses_/msg_ synthesis instead of DefaultExecutor pass-through (the Playground fix). - Canonical ses_/msg_ generation per sst/opencode identifier.ts, deterministic foreign session translation, live CLI version from npm registry JSON API (no npm binary; pinned fallback offline). - Correct stale .env.example opencode docs; regenerate executor-map golden snapshot. - AI-assisted with OMP (Oh My Pi).
720e50a to
f5795b1
Compare
- Default UA is now the exact working extension string (opencode/<live> ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.14), not the bare version. - Measured overnight: bare vs full UA both 403 from Node/Bun keyless, so this aligns us byte-for-byte with the only proven-working client pending the upstream/host fix; no behavior claim beyond parity.
|
Thanks for this — the live CLI-version auto-refresh (npm registry fetch, 5s timeout, 6h TTL, fire-and-forget, offline-safe pin) is a genuinely nice idea. The #13935 fix itself has now merged via #14013 (headers + the measured body contract), so the header half of this PR is covered. Two notes on the rest: the |
Part of #13935 — the header half. Body half (
stream+ tools contract) lives in #14013; land order between the two does not matter.Summary
Keyless OpenCode requests failed with
403 FreeTierErrorbecause the synthesized CLI identity had rotted: an unversioned User-Agent pin plus random-UUID session/request ids. This PR brings the CLI identity (User-Agent+ses_/msg_headers) up to the current upstream contract, with the CLI version resolved live so it cannot rot again. Scope is headers only — no request-body changes.Problem
Requests through the OpenCode Free tier (
oc/*models, e.g. the dashboard Playground) failed with:The fallback UA was a hardcoded pin plus random-UUID session/request ids — upstream validates the CLI identity contract (
opencode/<semver>+ses_[0-9a-f]{12}[base62]{14}/msg_…), so non-CLI clients kept getting rejected.Changes
open-sse/utils/opencodeHeaders.ts(from fix(opencode): send canonical free-tier identity headers #13937, kept) — canonicalses_/msg_generation persst/opencodeidentifier.ts(descending for sessions, ascending for requests), deterministic SHA-256 translation of foreign session ids (conversation-stable, so upstream prompt-cache affinity holds), removal of the muse-spark UUID session overwrite. Client-supplied valid values always win.open-sse/utils/opencodeCliVersion.ts(new) — resolves the live CLI version from the npm registry JSON API (opencode-ai/latest) via plainglobalThis.fetch. No npm binary required, so npm-less and offline machines still work: cold/offline falls back to the pinned1.18.31, andOPENCODE_USER_AGENTstill overrides everything. Sync header synthesis never blocks —buildHeaders()reads cache/pin only, whileexecute()warms the cache fire-and-forget (coalesced, 6h TTL, never throws).open-sse/executors/opencode.ts—execute()kicks the version refresh;buildHeaders()uses the live UA;sessionBodynow also covers Responses-APIinputitems so session fingerprints stay stable there. Also registers theocalias onOpencodeExecutorso the no-auth Free tier gets the same synthesis..env.example— the opencode block documented stale defaults (opencode-cli/1.0.0/cli/default, "OFF by default"); corrected to the shipped behavior (ON by default, live UA,desktop/global, canonical ids).opencode-cli-version.test.ts(5 tests: cold → pin without fetching, live registry read, offline keeps stale/pin, concurrent coalescing, malformed payloads); updated5997/10571/12633/ executor suites to the canonical contract.Verification
opencode-executor58/58 pass,tsc -p tsconfig.typecheck-core.jsonexit 0 (run 2026-09-18).opencode/1.18.31 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.14+ canonicalses_/msg_).Known limitation (the other half)
Headers alone do not satisfy the gate: measured live, a request also needs
stream: trueplus a non-emptytoolsarray (and, for title/compaction-style calls that carry none, a borrowed/placeholder tool list) — that body half is #14013. This PR intentionally stops at headers so each half stays reviewable on its own.AI-assisted with OMP (Oh My Pi).