github.com/aldelo/common@v1.5.1/wrapper/bedrockruntime/bedrockruntime.go (about) 1 package bedrockruntime 2 3 import ( 4 "context" 5 "errors" 6 "net/http" 7 8 awshttp2 "github.com/aldelo/common/wrapper/aws" 9 "github.com/aldelo/common/wrapper/aws/awsregion" 10 "github.com/aldelo/common/wrapper/xray" 11 "github.com/aws/aws-sdk-go-v2/config" 12 "github.com/aws/aws-sdk-go-v2/service/bedrockruntime" 13 "github.com/aws/aws-sdk-go/aws" 14 ) 15 16 /* 17 * Copyright 2020-2024 Aldelo, LP 18 * 19 * Licensed under the Apache License, Version 2.0 (the "License"); 20 * you may not use this file except in compliance with the License. 21 * You may obtain a copy of the License at 22 * 23 * http://www.apache.org/licenses/LICENSE-2.0 24 * 25 * Unless required by applicable law or agreed to in writing, software 26 * distributed under the License is distributed on an "AS IS" BASIS, 27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 * See the License for the specific language governing permissions and 29 * limitations under the License. 30 */ 31 32 // ================================================================================================================= 33 // AWS CREDENTIAL: 34 // use $> aws configure (to set aws access key and secret to target machine) 35 // Store AWS Access ID and Secret Key into Default Profile Using '$ aws configure' cli 36 // 37 // To Install & Setup AWS CLI on Host: 38 // 1) https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html 39 // On Ubuntu, if host does not have zip and unzip: 40 // $> sudo apt install zip 41 // $> sudo apt install unzip 42 // On Ubuntu, to install AWS CLI v2: 43 // $> curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 44 // $> unzip awscliv2.zip 45 // $> sudo ./aws/install 46 // 2) $> aws configure set region awsRegionName --profile default 47 // 3) $> aws configure 48 // follow prompts to enter Access ID and Secret Key 49 // 50 // AWS Region Name Reference: 51 // us-west-2, us-east-1, ap-northeast-1, etc 52 // See: https://docs.aws.amazon.com/general/latest/gr/rande.html 53 // ================================================================================================================= 54 55 // ================================================================================================================ 56 // STRUCTS 57 // ================================================================================================================ 58 59 // BedrockRuntime struct encapsulates the AWS BedrockRuntime access functionality 60 type BedrockRuntime struct { 61 // define the AWS region that BedrockRuntime is located at 62 AwsRegion awsregion.AWSRegion 63 64 // custom http2 client options 65 HttpOptions *awshttp2.HttpClientSettings 66 67 // store BedrockRuntime client object 68 bedrockruntimeClient *bedrockruntime.Client 69 70 _parentSegment *xray.XRayParentSegment 71 } 72 73 // ================================================================================================================ 74 // STRUCTS FUNCTIONS 75 // ================================================================================================================ 76 77 // ---------------------------------------------------------------------------------------------------------------- 78 // utility functions 79 // ---------------------------------------------------------------------------------------------------------------- 80 81 // Connect will establish a connection to the BedrockRuntime service 82 func (s *BedrockRuntime) Connect(parentSegment ...*xray.XRayParentSegment) (err error) { 83 if xray.XRayServiceOn() { 84 if len(parentSegment) > 0 { 85 s._parentSegment = parentSegment[0] 86 } 87 88 seg := xray.NewSegment("BedrockRuntime-Connect", s._parentSegment) 89 defer seg.Close() 90 defer func() { 91 _ = seg.Seg.AddMetadata("BedrockRuntime-AWS-Region", s.AwsRegion) 92 93 if err != nil { 94 _ = seg.Seg.AddError(err) 95 } 96 }() 97 98 err = s.connectInternal(seg.Ctx) 99 100 return err 101 } else { 102 return s.connectInternal(context.Background()) 103 } 104 } 105 106 // Connect will establish a connection to the BedrockRuntime service 107 func (s *BedrockRuntime) connectInternal(ctx context.Context) error { 108 // clean up prior bedrockruntime client reference 109 s.bedrockruntimeClient = nil 110 111 if !s.AwsRegion.Valid() || s.AwsRegion == awsregion.UNKNOWN { 112 return errors.New("Connect to BedrockRuntime Failed: (AWS Session Error) " + "Region is Required") 113 } 114 115 // create custom http2 client if needed 116 var httpCli *http.Client 117 var httpErr error 118 119 if s.HttpOptions == nil { 120 s.HttpOptions = new(awshttp2.HttpClientSettings) 121 } 122 123 // use custom http2 client 124 h2 := &awshttp2.AwsHttp2Client{ 125 Options: s.HttpOptions, 126 } 127 128 if httpCli, httpErr = h2.NewHttp2Client(); httpErr != nil { 129 return errors.New("Connect to BedrockRuntime Failed: (AWS Session Error) " + "Create Custom http2 Client Errored = " + httpErr.Error()) 130 } 131 132 // establish aws session connection 133 if cfg, err := config.LoadDefaultConfig(ctx, config.WithHTTPClient(httpCli)); err != nil { 134 // aws session error 135 return errors.New("Connect to BedrockRuntime Failed: (AWS Session Error) " + err.Error()) 136 } else { 137 // create cached objects for shared use 138 s.bedrockruntimeClient = bedrockruntime.NewFromConfig(cfg) 139 140 if s.bedrockruntimeClient == nil { 141 return errors.New("Connect to BedrockRuntime Client Failed: (New BedrockRuntime Client Connection) " + "Connection Object Nil") 142 } 143 144 // connect successful 145 return nil 146 } 147 } 148 149 // Disconnect will clear bedrockruntime client 150 func (s *BedrockRuntime) Disconnect() { 151 s.bedrockruntimeClient = nil 152 } 153 154 // UpdateParentSegment updates this struct's xray parent segment, if no parent segment, set nil 155 func (s *BedrockRuntime) UpdateParentSegment(parentSegment *xray.XRayParentSegment) { 156 s._parentSegment = parentSegment 157 } 158 159 // ---------------------------------------------------------------------------------------------------------------- 160 // Invoke functions 161 // ---------------------------------------------------------------------------------------------------------------- 162 163 // Invokes the specified Amazon Bedrock model to run inference using the prompt 164 // and inference parameters provided in the request body. You use model inference 165 // to generate text, images, and embeddings. For example code, see Invoke model 166 // code examples in the Amazon Bedrock User Guide. This operation requires 167 // permission for the bedrock:InvokeModel action. 168 func (s *BedrockRuntime) InvokeModel(modelId string, requestBody []byte) (responseBody []byte, err error) { 169 segCtx := context.Background() 170 segCtxSet := false 171 172 seg := xray.NewSegmentNullable("BedrockRuntime-InvokeModel", s._parentSegment) 173 174 if seg != nil { 175 segCtx = seg.Ctx 176 segCtxSet = true 177 178 defer seg.Close() 179 defer func() { 180 _ = seg.Seg.AddMetadata("BedrockRuntime-InvokeModel-ResponseBody", responseBody) 181 182 if err != nil { 183 _ = seg.Seg.AddError(err) 184 } 185 }() 186 } 187 188 // validation 189 if s.bedrockruntimeClient == nil { 190 err = errors.New("InvokeModel Failed: " + "BedrockRuntime Client is Required") 191 return nil, err 192 } 193 194 if len(modelId) <= 0 { 195 err = errors.New("InvokeModel Failed: " + "Model ID is Required") 196 return nil, err 197 } 198 199 if len(requestBody) <= 0 { 200 err = errors.New("InvokeModel Failed: " + "Request Body is Required") 201 return nil, err 202 } 203 204 // create input object 205 input := &bedrockruntime.InvokeModelInput{ 206 ModelId: aws.String(modelId), 207 Body: requestBody, 208 Accept: aws.String("application/json"), 209 ContentType: aws.String("application/json"), 210 } 211 212 // perform action 213 var output *bedrockruntime.InvokeModelOutput 214 215 if segCtxSet { 216 output, err = s.bedrockruntimeClient.InvokeModel(segCtx, input) 217 } else { 218 output, err = s.bedrockruntimeClient.InvokeModel(context.Background(), input) 219 } 220 221 // evaluate result 222 if err != nil { 223 return nil, err 224 } 225 if len(output.Body) == 0 { 226 return nil, errors.New("InvokeModel Failed: " + "No Response Body Returned") 227 } 228 229 return output.Body, nil 230 }