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
7 changes: 7 additions & 0 deletions src/integrations/gateways/gitlawb-opengateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ export default defineGateway({
requiresAuth: false,
authMode: 'none',
},
validation: {
kind: 'credential-env',
credentialEnvVars: [],
routing: {
matchBaseUrlHosts: ['opengateway.gitlawb.com', 'opengateway.fly.dev'],
},
},
transportConfig: {
kind: 'openai-compatible',
openaiShim: {
Expand Down
16 changes: 16 additions & 0 deletions src/utils/providerValidation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,22 @@ test('xiaomi mimo validation accepts MIMO_API_KEY without OPENAI_API_KEY', async
await expect(getProviderValidationError(process.env)).resolves.toBeNull()
})

test('opengateway validation allows no-auth access without OPENAI_API_KEY', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://opengateway.gitlawb.com/v1'
delete process.env.OPENAI_API_KEY

await expect(getProviderValidationError(process.env)).resolves.toBeNull()
})

test('opengateway validation allows no-auth access with model-specific path', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://opengateway.gitlawb.com/v1/xiaomi-mimo'
delete process.env.OPENAI_API_KEY

await expect(getProviderValidationError(process.env)).resolves.toBeNull()
})

test('github validation stays descriptor-selected and reports missing auth', async () => {
process.env.CLAUDE_CODE_USE_GITHUB = '1'
delete process.env.CLAUDE_CODE_USE_OPENAI
Expand Down
15 changes: 15 additions & 0 deletions src/utils/providerValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,21 @@ export async function getProviderValidationError(
}

if (!env.OPENAI_API_KEY && !isLocalProviderUrl(request.baseUrl)) {
// If we have a validation target that explicitly says it doesn't require auth,
// we should not require OPENAI_API_KEY.
if (validationTarget?.descriptor.setup?.requiresAuth === false) {
return null
}

// For other OpenAI-compatible providers, check if any of their specific
// credential env vars are set before falling back to the generic error.
if (validationTarget?.kind === 'vendor' || validationTarget?.kind === 'gateway') {
const envVars = validationTarget.descriptor.setup?.credentialEnvVars ?? []
if (envVars.some(v => env[v])) {
return null
}
}

return getOpenAIMissingKeyMessage()
}

Expand Down