({
apiKey,
maxRetries,
model,
fetchOverride,
source,
}: {
apiKey?: string
maxRetries: number
model?: string
fetchOverride?: ClientOptions['fetch']
source?: string
})
| 82 | } |
| 83 | |
| 84 | export async function getAnthropicClient({ |
| 85 | apiKey, |
| 86 | maxRetries, |
| 87 | model, |
| 88 | fetchOverride, |
| 89 | source, |
| 90 | }: { |
| 91 | apiKey?: string |
| 92 | maxRetries: number |
| 93 | model?: string |
| 94 | fetchOverride?: ClientOptions['fetch'] |
| 95 | source?: string |
| 96 | }): Promise<Anthropic> { |
| 97 | const containerId = process.env.CLAUDE_CODE_CONTAINER_ID |
| 98 | const remoteSessionId = process.env.CLAUDE_CODE_REMOTE_SESSION_ID |
| 99 | const clientApp = process.env.CLAUDE_AGENT_SDK_CLIENT_APP |
| 100 | const customHeaders = getCustomHeaders() |
| 101 | const defaultHeaders: { [key: string]: string } = { |
| 102 | 'x-app': 'cli', |
| 103 | 'User-Agent': getUserAgent(), |
| 104 | 'X-Claude-Code-Session-Id': getSessionId(), |
| 105 | ...customHeaders, |
| 106 | ...(containerId ? { 'x-claude-remote-container-id': containerId } : {}), |
| 107 | ...(remoteSessionId |
| 108 | ? { 'x-claude-remote-session-id': remoteSessionId } |
| 109 | : {}), |
| 110 | // SDK consumers can identify their app/library for backend analytics |
| 111 | ...(clientApp ? { 'x-client-app': clientApp } : {}), |
| 112 | // SSH auth proxy nonce — tunneled API requests must carry this header |
| 113 | ...(process.env.ANTHROPIC_AUTH_NONCE |
| 114 | ? { 'x-auth-nonce': process.env.ANTHROPIC_AUTH_NONCE } |
| 115 | : {}), |
| 116 | } |
| 117 | |
| 118 | // Log API client configuration for HFI debugging |
| 119 | logForDebugging( |
| 120 | `[API:request] Creating client, ANTHROPIC_CUSTOM_HEADERS present: ${!!process.env.ANTHROPIC_CUSTOM_HEADERS}, has Authorization header: ${!!customHeaders['Authorization']}`, |
| 121 | ) |
| 122 | |
| 123 | // Add additional protection header if enabled via env var |
| 124 | const additionalProtectionEnabled = isEnvTruthy( |
| 125 | process.env.CLAUDE_CODE_ADDITIONAL_PROTECTION, |
| 126 | ) |
| 127 | if (additionalProtectionEnabled) { |
| 128 | defaultHeaders['x-anthropic-additional-protection'] = 'true' |
| 129 | } |
| 130 | |
| 131 | logForDebugging('[API:auth] OAuth token check starting') |
| 132 | await checkAndRefreshOAuthTokenIfNeeded() |
| 133 | logForDebugging('[API:auth] OAuth token check complete') |
| 134 | |
| 135 | if (!isClaudeAISubscriber()) { |
| 136 | await configureApiKeyHeaders(defaultHeaders, getIsNonInteractiveSession()) |
| 137 | } |
| 138 | |
| 139 | const resolvedFetch = buildFetch(fetchOverride, source) |
| 140 | |
| 141 | const ARGS = { |
no test coverage detected