Skip to content

fix(opencode-go): always send x-opencode-session via per-instance session id - #1710

Merged
edelauna merged 2 commits into
Zoo-Code-Org:mainfrom
myk1yt:fix/1511-opencode-go-session-header
Oct 16, 2026
Merged

edelauna merged 2 commits into
Zoo-Code-Org:mainfrom
myk1yt:fix/1511-opencode-go-session-header

Conversation

@myk1yt

@myk1yt myk1yt commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Related GitHub Issue

Closes: #1511

Description

The OpenCode Go provider only sent the x-opencode-session header when metadata.taskId was set, so any request without a task context (including every completePrompt call from the prompt-enhancement flow) omitted the header entirely. Operators use this header for session affinity, so those requests could land on a different backend session.

The handler now always sends the header: metadata.taskId when available, otherwise a stable per-instance uuidv7() session id — the exact pattern openai-native.ts already uses (sessionId field, same import; ?? instead of ||, semantically identical since taskId is string | undefined).

Coverage: chat-completions streaming, Responses streaming, Anthropic /v1/messages streaming, and all three completePrompt paths (Anthropic, Responses, chat-completions — CompletePromptOptions has no taskId, so the instance session id is used there). Per-request headers merge over the SDK clients' existing defaultHeaders, so the DEFAULT_HEADERS/User-Agent wiring is untouched.

Test Procedure

  • src/api/providers/__tests__/opencode-go.spec.ts:
    • new fallback tests for all three streaming formats — no-taskId request still sends x-opencode-session, and the value is stable across two calls on the same handler
    • new header-presence tests for all three completePrompt paths
    • existing taskId-wins tests unchanged and still passing; ~10 single-arg SDK-call assertions converted to equivalent mock.calls[0][0] property assertions (same or stricter)
  • cd src && ./node_modules/.bin/vitest run api/providers → 78 files / 1924 tests passed, 1 skipped.
  • cd src && pnpm run check-types → 0 errors.
  • ESLint on both changed files → clean (suppression counts unchanged).

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Visual Snapshot (UI changes only): N/A — no UI changes.
  • Documentation Impact: No documentation updates are required.
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Visual Snapshots

N/A.

Videos (interaction / animation only)

N/A.

Documentation Updates

  • No documentation updates are required.

Additional Notes

No manifest changes needed — uuid v7 was already a dependency. Follow-up idea (out of scope): other providers using conditional session headers could adopt the same per-instance fallback, but each deserves its own small PR.

Get in Touch

GitHub: @myk1yt — please tag me here; I monitor notifications.

…sion id

The Go gateway requires the x-opencode-session header on every request
for operator-side session affinity (requests missing it may error). It
was only sent when metadata.taskId existed, and completePrompt never
sent it at all.

Add a uuidv7 per-instance session id on the handler (mirroring the
OpenAiNativeHandler fallback pattern) and send
x-opencode-session: metadata.taskId ?? sessionId at every request site:
chat-completions streaming, Anthropic /v1/messages streaming, Responses
streaming, and all three completePrompt paths.

Fixes Zoo-Code-Org#1511
@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: Zoo-Code-Org/Zoo-Code/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: edffcb7f-6872-4b1f-9735-e893d72a9edc

📥 Commits

Reviewing files that changed from the base of the PR and between f76b38a and 1d04f1d.

📒 Files selected for processing (2)
  • src/api/providers/__tests__/opencode-go.spec.ts
  • src/api/providers/opencode-go.ts

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.

📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (5)
Treat model, provider, MCP, path, command, and tool data as untrusted.

⚙️ CodeRabbit configuration file

Files:

  • src/api/providers/__tests__/opencode-go.spec.ts
  • src/api/providers/opencode-go.ts
Require regression coverage at the lowest valid harness with behavior-focused assertions, including relevant negative, error, false/unset, and boundary cases.

⚙️ CodeRabbit configuration file

Files:

  • src/api/providers/__tests__/opencode-go.spec.ts
Check strict typing and exhaustive behavior across normal, boundary, error, cancellation, retry, and compatibility paths.

⚙️ CodeRabbit configuration file

Files:

  • src/api/providers/__tests__/opencode-go.spec.ts
  • src/api/providers/opencode-go.ts
Verify extension/webview contracts, cancellation and error propagation, VS Code lifecycle correctness, and behavior under retries and partial failure.

⚙️ CodeRabbit configuration file

Files:

  • src/api/providers/__tests__/opencode-go.spec.ts
  • src/api/providers/opencode-go.ts
Act as an adversarial second-opinion reviewer.

⚙️ CodeRabbit configuration file

Files:

  • src/api/providers/__tests__/opencode-go.spec.ts
  • src/api/providers/opencode-go.ts
🔇 Additional comments (2)
src/api/providers/opencode-go.ts (1)

129-132: LGTM!

Also applies to: 264-266, 399-400, 527-529, 715-728

src/api/providers/__tests__/opencode-go.spec.ts (1)

640-650: LGTM!

Also applies to: 652-668


📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • OpenCode Go requests now consistently include session information across chat, Anthropic, and Responses formats.
    • Provided task sessions are used when available; otherwise, requests reuse a stable automatically generated session.
    • Session headers are included for non-streaming requests and abort-signal workflows.
    • Anthropic requests now fall back to the model’s maximum token limit when configured limits are unavailable.
  • Tests
    • Added coverage for session reuse, header handling, and token-limit fallback across supported request formats.

Walkthrough

Changes

OpenCode Go session headers

Layer / File(s) Summary
Session identity initialization
src/api/providers/opencode-go.ts
OpencodeGoHandler now creates and stores a UUIDv7 session ID during construction.
Streaming request headers
src/api/providers/opencode-go.ts, src/api/providers/__tests__/opencode-go.spec.ts
Streaming chat-completions, Responses, and Anthropic requests now send x-opencode-session using taskId or the stable handler session ID. Tests cover fallback reuse and existing request fields.
completePrompt session headers
src/api/providers/opencode-go.ts, src/api/providers/__tests__/opencode-go.spec.ts
All non-streaming completePrompt request formats now send the handler session ID. Tests cover headers, abort-signal forwarding, and the Anthropic max_tokens fallback.

Priority: ⬆️ High

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant OpencodeGoHandler
  participant OpenCodeGoAPI
  Caller->>OpencodeGoHandler: createMessage or completePrompt
  OpencodeGoHandler->>OpencodeGoHandler: Select taskId or sessionId
  OpencodeGoHandler->>OpenCodeGoAPI: Send request with x-opencode-session
  OpenCodeGoAPI-->>OpencodeGoHandler: Return response
Loading
🚥 Pre-merge checks | ✅ 8
✅ Passed checks (8 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #1511 requires x-opencode-session on OpenCode Go requests and one stable ID per conversation. The changed handler creates one per-instance uuidv7() fallback ID, uses metadata.taskId when a…
Out of Scope Changes check ✅ Passed The production changes add session ID selection and header forwarding for the OpenCode Go request paths. The test changes verify those behaviors and update affected request assertions. The summary sho…
Regression Evidence ✅ Passed The changed session-header behavior has focused unit coverage in opencode-go.spec.ts. The tests cover no-taskId fallback and reuse for chat-completions, Responses, and Anthropic streaming; taskId …
Security Boundaries ✅ Passed PASS. The only changed implementation is src/api/providers/opencode-go.ts. It generates a fresh per-handler UUID (uuidv7()) and sends it as x-opencode-session; this value is not a secret or PII.…
Persistence Integrity ✅ Passed No changed persistence path exists. The pull request adds an in-memory per-handler sessionId and propagates it through request headers. The changed network calls are awaited, and no file, database, …
Lifecycle Resource Cleanup ✅ Passed No changed lifecycle path introduces a resource leak or duplicate work. The provider changes add one per-handler UUID string and request headers only. Streaming request paths retain their existing ite…
Title check ✅ Passed The title clearly and concisely describes the main change: always sending x-opencode-session with a per-instance session ID.
Description check ✅ Passed The description includes the linked issue, implementation details, test procedure, completed checklist, documentation impact, and additional reviewer context. It matches the required template and expl…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Review status

Thanks for contributing. This comment tracks the review sequence and the next action.

Current step: Awaiting fresh human maintainer or CODEOWNER approval.

Automated review is complete for the latest commit but does not replace human approval.

Review-state labels are managed by this workflow; do not edit them manually. community-approved is managed the same way — do not add or remove it manually. It signals a fresh community code approval for the current head as an advisory priority only; maintainer review is still required.

@codecov

codecov Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions github-actions Bot added coderabbit-review-active Required CI passed; CodeRabbit review is active awaiting-coderabbit Waiting for CodeRabbit to approve the latest commit labels Sep 20, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Sep 20, 2026
@github-actions github-actions Bot added awaiting-maintainer CodeRabbit approved; waiting for a human maintainer and removed coderabbit-review-active Required CI passed; CodeRabbit review is active awaiting-coderabbit Waiting for CodeRabbit to approve the latest commit labels Sep 20, 2026
…diff churn

The codecov patch partials were not the streaming header fallbacks
(those arms are all exercised by the metadata-absent createMessage
tests): they were lines 720-722, pre-existing conditionals that became
patch lines because the completePrompt Anthropic restructure
re-indented the untouched params object.

- Send the session header on the Anthropic client's defaultHeaders
  instead of a per-request option in completePrompt (per-request
  headers still override it with taskId when streaming), so the
  completePrompt params block stays byte-identical to main and out of
  the diff. The supportsTemperature false arm there is unreachable for
  Anthropic-format Go models by design.
- Add a completePrompt test for the includeMaxTokens-on /
  modelMaxTokens-unset max_tokens fallback, mirroring the streaming
  test of the same name, and assert the defaultHeaders session header.

Patch coverage of opencode-go.ts vs base is now 100% with no untaken
branch arms on added lines.
@github-actions github-actions Bot added coderabbit-review-active Required CI passed; CodeRabbit review is active awaiting-coderabbit Waiting for CodeRabbit to approve the latest commit and removed awaiting-maintainer CodeRabbit approved; waiting for a human maintainer labels Sep 20, 2026
@github-actions github-actions Bot added awaiting-maintainer CodeRabbit approved; waiting for a human maintainer and removed coderabbit-review-active Required CI passed; CodeRabbit review is active awaiting-coderabbit Waiting for CodeRabbit to approve the latest commit labels Sep 20, 2026
@edelauna
edelauna added this pull request to the merge queue Oct 16, 2026
Merged via the queue into Zoo-Code-Org:main with commit e2fc548 Oct 16, 2026
16 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-maintainer CodeRabbit approved; waiting for a human maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT]

2 participants