Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/services/api/openaiShim/requestExecutor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,40 @@ test('raw-env LLMTR ignores unsupported custom auth and custom headers', async (
expect(captured.headers['X-Tenant-Secret']).toBeUndefined()
})

test('OpenCode Go sends the required stable session and user-agent headers', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://opencode.ai/zen/go/v1'
process.env.OPENAI_MODEL = 'glm-5.1'
process.env.OPENCODE_API_KEY = 'opencode-key'
delete process.env.OPENAI_API_KEY
delete process.env.OPENAI_API_KEYS

const captured = await captureChatCompletionRequest('glm-5.1', {
Comment thread
birajrai marked this conversation as resolved.
'x-opencode-session': 'caller-session',
'User-Agent': 'caller-agent',
})

expect(captured.headers['x-opencode-session']).toMatch(
/^[0-9a-f-]{36}$/,
)
expect(captured.headers['User-Agent']).toMatch(/^openclaude\//)
expect(captured.headers['x-opencode-session']).not.toBe('caller-session')
expect(captured.headers['User-Agent']).not.toBe('caller-agent')
})
Comment thread
birajrai marked this conversation as resolved.
Comment thread
birajrai marked this conversation as resolved.

test('OpenCode Zen does not receive the OpenCode Go session header', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://opencode.ai/zen/v1'
process.env.OPENAI_MODEL = 'gpt-5.4'
process.env.OPENCODE_API_KEY = 'opencode-key'
delete process.env.OPENAI_API_KEY
delete process.env.OPENAI_API_KEYS

const captured = await captureChatCompletionRequest('gpt-5.4')

expect(captured.headers['x-opencode-session']).toBeUndefined()
})
Comment thread
birajrai marked this conversation as resolved.

test('custom endpoints preserve configured auth and custom headers', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://proxy.example/v1'
Expand Down
6 changes: 5 additions & 1 deletion src/services/api/openaiShim/requestExecutor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { CredentialLease, CredentialPool } from '../credentialPool.js'
import type { OpenAICompatibilityFailure } from '../openaiErrorClassification.js'
import type { OpenAIShimRuntimeContext } from '../../../integrations/runtimeMetadata.js'
import { resolveRouteIdFromBaseUrl } from '../../../integrations/routeMetadata.js'
import { getCommandcodeChatCompletionsModelError } from '../../../integrations/gateways/commandcode.js'
import {
redactEncodedSecretSubstringsForDisplay,
Expand Down Expand Up @@ -295,7 +296,10 @@ export async function executeOpenAIRequest(
const isXaiRoute =
runtimeShimContext.routeId === 'xai' || isXaiBaseUrl(request.baseUrl)
const openCodeGoSessionId =
runtimeShimContext.routeId === 'opencode-go' ? getSessionId() : null
(runtimeShimContext.routeId === 'opencode-go' ||
resolveRouteIdFromBaseUrl(request.baseUrl) === 'opencode-go')
? getSessionId()
: null
const openAIApiKeysPoolRaw =
routeAcceptsGenericOpenAICredentials &&
parseCredentialList(requestProcessEnv.OPENAI_API_KEYS).length > 0
Expand Down