diff --git a/src/services/relay/claudeConsoleRelayService.js b/src/services/relay/claudeConsoleRelayService.js index 50c05275..a8590c52 100644 --- a/src/services/relay/claudeConsoleRelayService.js +++ b/src/services/relay/claudeConsoleRelayService.js @@ -1472,14 +1472,22 @@ class ClaudeConsoleRelayService { : `${cleanUrl}/v1/messages?beta=true` const payload = createClaudeTestPayload(model, { stream: true }) - await sendStreamTestRequest({ + const extraHeaders = account.userAgent ? { 'User-Agent': account.userAgent } : {} + const requestOptions = { apiUrl, - authorization: `Bearer ${account.apiKey}`, responseStream, payload, proxyAgent: claudeConsoleAccountService._createProxyAgent(account.proxy), - extraHeaders: account.userAgent ? { 'User-Agent': account.userAgent } : {} - }) + extraHeaders + } + + if (account.apiKey && account.apiKey.startsWith('sk-ant-')) { + requestOptions.extraHeaders['x-api-key'] = account.apiKey + } else { + requestOptions.authorization = `Bearer ${account.apiKey}` + } + + await sendStreamTestRequest(requestOptions) } catch (error) { logger.error(`❌ Test account connection failed:`, error) if (!responseStream.headersSent) { diff --git a/src/utils/testPayloadHelper.js b/src/utils/testPayloadHelper.js index 4a2187b5..66df8305 100644 --- a/src/utils/testPayloadHelper.js +++ b/src/utils/testPayloadHelper.js @@ -146,7 +146,7 @@ async function sendStreamTestRequest(options) { 'Content-Type': 'application/json', 'anthropic-version': '2023-06-01', 'User-Agent': 'claude-cli/2.0.52 (external, cli)', - authorization, + ...(authorization ? { authorization } : {}), ...extraHeaders }, timeout, diff --git a/tests/claudeConsoleRelayService.test.js b/tests/claudeConsoleRelayService.test.js index 67dbfde4..a678a026 100644 --- a/tests/claudeConsoleRelayService.test.js +++ b/tests/claudeConsoleRelayService.test.js @@ -32,7 +32,7 @@ describe('claudeConsoleRelayService.testAccountConnection', () => { jest.clearAllMocks() }) - it('passes selected model stream payload to sendStreamTestRequest', async () => { + it('passes selected model stream payload and bearer auth for non sk-ant key', async () => { claudeConsoleAccountService.getAccount.mockResolvedValue({ name: 'Console A1', apiUrl: 'https://console.example.com', @@ -55,8 +55,42 @@ describe('claudeConsoleRelayService.testAccountConnection', () => { expect(createClaudeTestPayload).toHaveBeenCalledWith('claude-sonnet-4-6', { stream: true }) expect(sendStreamTestRequest).toHaveBeenCalledWith( expect.objectContaining({ - payload + payload, + authorization: 'Bearer test-key' }) ) }) + + it('passes selected model stream payload and x-api-key for sk-ant key', async () => { + claudeConsoleAccountService.getAccount.mockResolvedValue({ + name: 'Console A1', + apiUrl: 'https://console.example.com', + apiKey: 'sk-ant-test-key', + proxy: null, + userAgent: null + }) + claudeConsoleAccountService._createProxyAgent.mockReturnValue(undefined) + + const payload = { + model: 'claude-sonnet-4-6', + stream: true + } + createClaudeTestPayload.mockReturnValue(payload) + sendStreamTestRequest.mockResolvedValue(undefined) + + const res = {} + await claudeConsoleRelayService.testAccountConnection('a1', res, 'claude-sonnet-4-6') + + expect(createClaudeTestPayload).toHaveBeenCalledWith('claude-sonnet-4-6', { stream: true }) + const requestOptions = sendStreamTestRequest.mock.calls[0][0] + expect(requestOptions).toEqual( + expect.objectContaining({ + payload, + extraHeaders: expect.objectContaining({ + 'x-api-key': 'sk-ant-test-key' + }) + }) + ) + expect(requestOptions).not.toHaveProperty('authorization') + }) })