1
+ import { env } from 'hono/adapter' ;
2
+ import { GatewayError } from '../../errors/GatewayError' ;
1
3
import { ProviderAPIConfig } from '../types' ;
2
- import { generateAWSHeaders } from './utils' ;
4
+ import { bedrockInvokeModels } from './constants' ;
5
+ import { generateAWSHeaders , getAssumedRoleCredentials } from './utils' ;
3
6
4
7
const BedrockAPIConfig : ProviderAPIConfig = {
5
8
getBaseURL : ( { providerOptions } ) =>
6
9
`https://bedrock-runtime.${ providerOptions . awsRegion || 'us-east-1' } .amazonaws.com` ,
7
10
headers : async ( {
11
+ c,
8
12
providerOptions,
9
13
transformedRequestBody,
10
14
transformedRequestUrl,
@@ -13,6 +17,41 @@ const BedrockAPIConfig: ProviderAPIConfig = {
13
17
'content-type' : 'application/json' ,
14
18
} ;
15
19
20
+ if ( providerOptions . awsAuthType === 'assumedRole' ) {
21
+ try {
22
+ // Assume the role in the source account
23
+ const sourceRoleCredentials = await getAssumedRoleCredentials (
24
+ c ,
25
+ env ( c ) . AWS_ASSUME_ROLE_SOURCE_ARN , // Role ARN in the source account
26
+ env ( c ) . AWS_ASSUME_ROLE_SOURCE_EXTERNAL_ID || '' , // External ID for source role (if needed)
27
+ providerOptions . awsRegion || ''
28
+ ) ;
29
+
30
+ if ( ! sourceRoleCredentials ) {
31
+ throw new Error ( 'Server Error while assuming internal role' ) ;
32
+ }
33
+
34
+ // Assume role in destination account using temporary creds obtained in first step
35
+ const { accessKeyId, secretAccessKey, sessionToken } =
36
+ ( await getAssumedRoleCredentials (
37
+ c ,
38
+ providerOptions . awsRoleArn || '' ,
39
+ providerOptions . awsExternalId || '' ,
40
+ providerOptions . awsRegion || '' ,
41
+ {
42
+ accessKeyId : sourceRoleCredentials . accessKeyId ,
43
+ secretAccessKey : sourceRoleCredentials . secretAccessKey ,
44
+ sessionToken : sourceRoleCredentials . sessionToken ,
45
+ }
46
+ ) ) || { } ;
47
+ providerOptions . awsAccessKeyId = accessKeyId ;
48
+ providerOptions . awsSecretAccessKey = secretAccessKey ;
49
+ providerOptions . awsSessionToken = sessionToken ;
50
+ } catch ( e ) {
51
+ throw new GatewayError ( 'Error while assuming bedrock role' ) ;
52
+ }
53
+ }
54
+
16
55
return generateAWSHeaders (
17
56
transformedRequestBody ,
18
57
headers ,
@@ -27,12 +66,20 @@ const BedrockAPIConfig: ProviderAPIConfig = {
27
66
} ,
28
67
getEndpoint : ( { fn, gatewayRequestBody } ) => {
29
68
const { model, stream } = gatewayRequestBody ;
69
+ if ( ! model ) throw new GatewayError ( 'Model is required' ) ;
30
70
let mappedFn = fn ;
31
71
if ( stream ) {
32
72
mappedFn = `stream-${ fn } ` ;
33
73
}
34
- const endpoint = `/model/${ model } /invoke` ;
35
- const streamEndpoint = `/model/${ model } /invoke-with-response-stream` ;
74
+ let endpoint = `/model/${ model } /invoke` ;
75
+ let streamEndpoint = `/model/${ model } /invoke-with-response-stream` ;
76
+ if (
77
+ ( mappedFn === 'chatComplete' || mappedFn === 'stream-chatComplete' ) &&
78
+ ! bedrockInvokeModels . includes ( model )
79
+ ) {
80
+ endpoint = `/model/${ model } /converse` ;
81
+ streamEndpoint = `/model/${ model } /converse-stream` ;
82
+ }
36
83
switch ( mappedFn ) {
37
84
case 'chatComplete' : {
38
85
return endpoint ;
0 commit comments