11import {
2- BedrockRuntimeClient ,
3- ConverseStreamCommand ,
4- ConverseCommand ,
5- BedrockRuntimeClientConfig ,
6- ContentBlock ,
7- Message ,
8- SystemContentBlock ,
2+ BedrockRuntimeClient ,
3+ ConverseStreamCommand ,
4+ ConverseCommand ,
5+ BedrockRuntimeClientConfig ,
6+ ContentBlock ,
7+ Message ,
8+ SystemContentBlock ,
99} from "@aws-sdk/client-bedrock-runtime"
10+ import { NodeHttpHandler } from "@aws-sdk/node-http-handler"
1011import { fromIni } from "@aws-sdk/credential-providers"
1112import { Anthropic } from "@anthropic-ai/sdk"
13+ import * as vscode from "vscode"
14+ import * as fs from "fs"
15+ import { ProxyAgent } from "proxy-agent"
16+ import * as https from "https"
1217
1318import {
1419 type ModelInfo ,
@@ -225,15 +230,17 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
225230 this . options . awsBedrockEndpointEnabled && { endpoint : this . options . awsBedrockEndpoint } ) ,
226231 }
227232
233+ // Build a Node HTTP handler that respects VS Code proxy and strict SSL settings
234+ const httpHandler = this . createNodeHttpHandler ( )
235+ if ( httpHandler ) {
236+ clientConfig . requestHandler = httpHandler
237+ }
238+
228239 if ( this . options . awsUseApiKey && this . options . awsApiKey ) {
229240 // Use API key/token-based authentication if enabled and API key is set
230241 clientConfig . token = { token : this . options . awsApiKey }
231242 clientConfig . authSchemePreference = [ "httpBearerAuth" ] // Otherwise there's no end of credential problems.
232- clientConfig . requestHandler = {
233- // This should be the default anyway, but without setting something
234- // this provider fails to work with LiteLLM passthrough.
235- requestTimeout : 0 ,
236- }
243+ // If we created a NodeHttpHandler above, ensure request timeout behavior is set there.
237244 } else if ( this . options . awsUseProfile && this . options . awsProfile ) {
238245 // Use profile-based credentials if enabled and profile is set
239246 clientConfig . credentials = fromIni ( {
@@ -252,6 +259,65 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
252259 this . client = new BedrockRuntimeClient ( clientConfig )
253260 }
254261
262+ /**
263+ * Create a NodeHttpHandler configured to work behind corporate proxies and with custom CAs.
264+ * - Honors VS Code settings: `http.proxy` and `http.proxyStrictSSL`
265+ * - Honors env vars: HTTPS_PROXY/HTTP_PROXY/ALL_PROXY, NODE_EXTRA_CA_CERTS, AWS_CA_BUNDLE
266+ */
267+ private createNodeHttpHandler ( ) : NodeHttpHandler | undefined {
268+ try {
269+ const httpConfig = vscode . workspace . getConfiguration ( "http" )
270+ const proxyUrl = ( httpConfig . get < string > ( "proxy" ) || process . env . HTTPS_PROXY || process . env . HTTP_PROXY || process . env . ALL_PROXY || "" ) . trim ( )
271+ const strictSSL = httpConfig . get < boolean > ( "proxyStrictSSL" , true )
272+
273+ let ca : Buffer | undefined
274+ const caPath = ( process . env . NODE_EXTRA_CA_CERTS || process . env . AWS_CA_BUNDLE || "" ) . trim ( )
275+ if ( caPath ) {
276+ try {
277+ ca = fs . readFileSync ( caPath )
278+ } catch ( e ) {
279+ logger . warn ( "Failed to read custom CA bundle; continuing without it" , {
280+ ctx : "bedrock" ,
281+ error : e instanceof Error ? e . message : String ( e ) ,
282+ caPath,
283+ } )
284+ }
285+ }
286+
287+ const agentOptions : https . AgentOptions = {
288+ rejectUnauthorized : strictSSL ,
289+ ...( ca ? { ca } : { } ) ,
290+ }
291+
292+ let httpAgent : any | undefined
293+ let httpsAgent : any | undefined
294+
295+ if ( proxyUrl ) {
296+ // Use proxy-agent to support http/https/socks/PAC proxies seamlessly
297+ const proxyAgent = new ProxyAgent ( proxyUrl ) as unknown as https . Agent
298+ // proxy-agent returns a single agent for both protocols
299+ httpAgent = proxyAgent
300+ httpsAgent = proxyAgent
301+ } else {
302+ // Direct connection agents with proper TLS options
303+ httpsAgent = new https . Agent ( agentOptions )
304+ }
305+
306+ return new NodeHttpHandler ( {
307+ httpAgent,
308+ httpsAgent,
309+ // 0 = no timeout (let Bedrock stream indefinitely until our own AbortController cancels)
310+ requestTimeout : 0 ,
311+ } )
312+ } catch ( err ) {
313+ logger . warn ( "Failed to initialize custom NodeHttpHandler; falling back to default" , {
314+ ctx : "bedrock" ,
315+ error : err instanceof Error ? err . message : String ( err ) ,
316+ } )
317+ return undefined
318+ }
319+ }
320+
255321 // Helper to guess model info from custom modelId string if not in bedrockModels
256322 private guessModelInfoFromId ( modelId : string ) : Partial < ModelInfo > {
257323 // Define a mapping for model ID patterns and their configurations
0 commit comments