({
apiKey,
maxRetries,
model,
fetchOverride,
source,
}: {
apiKey?: string
maxRetries: number
model?: string
fetchOverride?: ClientOptions['fetch']
source?: string
})
| 94 | } |
| 95 | |
| 96 | export async function getAnthropicClient({ |
| 97 | apiKey, |
| 98 | maxRetries, |
| 99 | model, |
| 100 | fetchOverride, |
| 101 | source, |
| 102 | }: { |
| 103 | apiKey?: string |
| 104 | maxRetries: number |
| 105 | model?: string |
| 106 | fetchOverride?: ClientOptions['fetch'] |
| 107 | source?: string |
| 108 | }): Promise<Anthropic> { |
| 109 | const containerId = process.env.CLAUDE_CODE_CONTAINER_ID |
| 110 | const remoteSessionId = process.env.CLAUDE_CODE_REMOTE_SESSION_ID |
| 111 | const clientApp = process.env.CLAUDE_AGENT_SDK_CLIENT_APP |
| 112 | const customHeaders = getCustomHeaders() |
| 113 | const defaultHeaders: { [key: string]: string } = { |
| 114 | 'x-app': 'cli', |
| 115 | 'User-Agent': getUserAgent(), |
| 116 | 'X-Claude-Code-Session-Id': getSessionId(), |
| 117 | ...customHeaders, |
| 118 | ...(containerId ? { 'x-claude-remote-container-id': containerId } : {}), |
| 119 | ...(remoteSessionId |
| 120 | ? { 'x-claude-remote-session-id': remoteSessionId } |
| 121 | : {}), |
| 122 | // SDK consumers can identify their app/library for backend analytics |
| 123 | ...(clientApp ? { 'x-client-app': clientApp } : {}), |
| 124 | } |
| 125 | |
| 126 | // Log API client configuration for HFI debugging |
| 127 | logForDebugging( |
| 128 | `[API:request] Creating client, ANTHROPIC_CUSTOM_HEADERS present: ${!!process.env.ANTHROPIC_CUSTOM_HEADERS}, has Authorization header: ${!!customHeaders['Authorization']}`, |
| 129 | ) |
| 130 | |
| 131 | // Add additional protection header if enabled via env var |
| 132 | const additionalProtectionEnabled = isEnvTruthy( |
| 133 | process.env.CLAUDE_CODE_ADDITIONAL_PROTECTION, |
| 134 | ) |
| 135 | if (additionalProtectionEnabled) { |
| 136 | defaultHeaders['x-anthropic-additional-protection'] = 'true' |
| 137 | } |
| 138 | |
| 139 | logForDebugging('[API:auth] OAuth token check starting') |
| 140 | await checkAndRefreshOAuthTokenIfNeeded() |
| 141 | logForDebugging('[API:auth] OAuth token check complete') |
| 142 | |
| 143 | if (!isClaudeAISubscriber()) { |
| 144 | await configureApiKeyHeaders(defaultHeaders, getIsNonInteractiveSession()) |
| 145 | } |
| 146 | |
| 147 | const resolvedFetch = buildFetch(fetchOverride, source) |
| 148 | |
| 149 | const ARGS = { |
| 150 | defaultHeaders, |
| 151 | maxRetries, |
| 152 | timeout: parseInt(process.env.API_TIMEOUT_MS || String(600 * 1000), 10), |
| 153 | dangerouslyAllowBrowser: true, |
no test coverage detected