feat: align outbound HTTP headers with canonical OpenCode desktop#940
Conversation
Central httpIdentity() function returns canonical OpenCode desktop headers (User-Agent, x-opencode-client) for all outbound requests to OpenCode backends. Version is pinned from UPSTREAM_VERSION file at build time via a new OPENCODE_HTTP_VERSION define, keeping the global OPENCODE_CHANNEL and OPENCODE_VERSION unchanged for storage, diagnostics, and update channels.
- Zen LLM opencode branch: add explicit User-Agent from HTTP_USER_AGENT - Zen LLM non-opencode branch: use HTTP_VERSION instead of VERSION - Models API fetch: switch to HTTP_USER_AGENT - gitlab, cloudflare-workers-ai, cloudflare-ai-gateway: use HTTP_VERSION
- Account API: wrap Effect HTTP client with canonical User-Agent via HttpClient.mapRequest, covering device auth, token refresh, orgs, user, and config endpoints. - Electron: replace PawWork/ with opencode/ in userAgentFallback to prevent identity leakage from renderer/webview requests.
📝 WalkthroughWalkthroughThis PR introduces a complete HTTP versioning system that reads an upstream version file, exposes it through build-time injection, and propagates it as User-Agent headers across runtime components. The version flows from UPSTREAM_VERSION → Script.httpVersion → OPENCODE_HTTP_VERSION injection → Installation exports → User-Agent headers in HTTP requests. ChangesHTTP Versioning Pipeline
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces OPENCODE_HTTP_VERSION and InstallationHTTPVersion to manage and propagate the upstream HTTP version for outbound requests. It updates user agent strings across several modules (including providers, account services, and LLM sessions) to use this new version. Feedback on the changes includes updating the user agent replacement regex in the Electron main process to correctly handle development mode, and leveraging the newly introduced Installation.httpIdentity() helper in the account service to ensure all canonical headers are consistently applied.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/core/src/installation/version.ts`:
- Around line 19-22: The exported InstallationHTTPVersion currently returns
OPENCODE_HTTP_VERSION without trimming even though the condition checks trim();
update the ternary to return OPENCODE_HTTP_VERSION.trim() when it's used so
surrounding whitespace doesn't leak into the User-Agent; modify the expression
that defines InstallationHTTPVersion (referencing OPENCODE_HTTP_VERSION and
InstallationVersion) to call trim() on OPENCODE_HTTP_VERSION before returning
it.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: b14f2725-9c81-471a-9f42-5a2d21c8db1f
📒 Files selected for processing (11)
UPSTREAM_VERSIONpackages/core/src/installation/version.tspackages/desktop-electron/src/main/index.tspackages/opencode/script/build-node.tspackages/opencode/script/build.tspackages/opencode/src/account/index.tspackages/opencode/src/installation/index.tspackages/opencode/src/provider/models.tspackages/opencode/src/provider/provider.tspackages/opencode/src/session/llm.tspackages/script/src/index.ts
- P2: Account API now uses httpIdentity() (User-Agent + x-opencode-client) instead of setting only User-Agent - P3: InstallationHTTPVersion returns trimmed value to prevent whitespace pollution in User-Agent - Electron UA fallback regex now matches dev/beta variants (PawWork Dev/, PawWork Beta/) in addition to PawWork/
Bump PawWork desktop release version to 2026.5.28. Changes since v2026.5.27: - feat(ui): fold reasoning into trow block (#948) - feat: align outbound HTTP headers with canonical OpenCode desktop (#940) - feat(app): collapse notification settings to single tri-state control (#938) - fix(ui): track List header surface via --list-surface (#954) - fix(ui): render tooltip shortcut hints as plain sans glyphs (#955) - fix(watcher): isolate macOS workspace roots - fix(session): terminalize stale question blockers - fix(session): unify transport error classification for stream disconnect recovery (#941) - test: add route inventory guardrails - ci: repair electron desktop build + install
Summary
Aligns all outbound HTTP headers with canonical OpenCode desktop client format, solving the Zen free-tier rate-limiting issue. Introduces a central
httpIdentity()helper andUPSTREAM_VERSIONfile as single source of truth for HTTP identity.Why
Upstream commit
0b8050d453addedcheckHeaders+dailyRequestsFallbackin the Zen rate limiter. Clients whose headers don't match canonical patterns get routed to a tiny fallback pool. PawWork's Electron default User-Agent (PawWork/2026.5.27) andInstallation.USER_AGENT(opencode/prod/0.0.0-prod-*/desktop) both failed this check, causing free-tier users to hit rate limits after ~3 messages.PawWork is a fork of OpenCode Desktop — the runtime layer IS OpenCode. Aligning outbound headers is correcting an identity mismatch, not spoofing. The Pi Agent + Kimi Code ban incident (May 2026) further validated that third-party clients using distinct identifiers are vulnerable to arbitrary blocking.
Upstream issues anomalyco/opencode#28807 and #28808 had zero response for 5+ days despite maintainer activity. This PR eliminates the dependency on upstream action.
Related Issue
No open issue. #737 (closed) covered the same problem but concluded "wait for upstream"; this PR supersedes that approach with a proactive fix.
Human Review Status
Pending
Review Focus
httpIdentity()helper covers all outbound paths (Zen LLM, Models API, 3 provider UAs, Account API, Electron fallback)OPENCODE_HTTP_VERSION/OPENCODE_HTTP_CHANNELare isolated from globalOPENCODE_VERSION/OPENCODE_CHANNELto avoid side effects on storage paths, diagnostics, and update channelsPawWork Dev/,PawWork Beta/)Risk Notes
checkHeaderscriteria; build-time pinned version mitigates frequent version churn but may need periodic bumpsHTTP_VERSION— intentional full alignment to avoid partial identity fingerprintingUPSTREAM_VERSIONfile (1.15.10) must be manually updated when syncing upstreamHow To Verify
Screenshots or Recordings
N/A — no visible UI changes.
Checklist
enhancementplatform,harnessP2Pending,Approved by @<reviewer>, orNot required: <reason>.app.userAgentFallbackis cross-platform; regex tested against dev/beta/prod app names.UPSTREAM_VERSIONfile noted in Risk Notes.dev, and my PR title and commit messages use Conventional Commits in English.