Skip to content

Commit

Permalink
fix: make sure to handl wasm differently for env vars
Browse files Browse the repository at this point in the history
  • Loading branch information
seawatts committed Dec 31, 2024
1 parent 036dba7 commit 9a3efc3
Show file tree
Hide file tree
Showing 17 changed files with 1,022 additions and 113 deletions.
5 changes: 4 additions & 1 deletion engine/baml-lib/llm-client/src/clients/aws_bedrock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ impl UnresolvedAwsBedrock {
}
None => match ctx.get_env_var("AWS_REGION") {
Ok(region) if !region.is_empty() => Some(region),
_ => None,
_ => match ctx.get_env_var("AWS_DEFAULT_REGION") {
Ok(region) if !region.is_empty() => Some(region),
_ => None,
},
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,17 @@ fn resolve_properties(
properties: &UnresolvedClientProperty<()>,
ctx: &RuntimeContext,
) -> Result<ResolvedAwsBedrock> {
let properties = properties.resolve(provider, &ctx.eval_ctx(false))?;
let strict = {
#[cfg(target_arch = "wasm32")]
{
false
}

#[cfg(not(target_arch = "wasm32"))]
true
};
let properties = properties.resolve(provider, &ctx.eval_ctx(strict))?;

let ResolvedClientProperty::AWSBedrock(props) = properties else {
anyhow::bail!(
"Invalid client property. Should have been a aws-bedrock property but got: {}",
Expand Down Expand Up @@ -135,7 +145,6 @@ impl AwsClient {

// Set region if specified
if let Some(aws_region) = self.properties.region.as_ref() {
#[cfg(target_arch = "wasm32")]
if aws_region.starts_with("$") {
return Err(anyhow::anyhow!(
"AWS region expected, please set: env.{}",
Expand All @@ -153,21 +162,18 @@ impl AwsClient {
) {
let aws_session_token = self.properties.session_token.clone();

#[cfg(target_arch = "wasm32")]
if aws_access_key_id.starts_with("$") {
return Err(anyhow::anyhow!(
"AWS access key id expected, please set: env.{}",
&aws_access_key_id[1..]
));
}
#[cfg(target_arch = "wasm32")]
if aws_secret_access_key.starts_with("$") {
return Err(anyhow::anyhow!(
"AWS secret access key expected, please set: env.{}",
&aws_secret_access_key[1..]
));
}
#[cfg(target_arch = "wasm32")]
if let Some(aws_session_token) = aws_session_token.as_ref() {
if aws_session_token.starts_with("$") {
return Err(anyhow::anyhow!(
Expand Down Expand Up @@ -704,8 +710,32 @@ impl WithChat for AwsClient {
request_options,
latency: instant_start.elapsed(),
message: format!("{:#?}", e),
// TODO: derive this from the aws-returned error
code: ErrorCode::Other(2),
code: match e {
SdkError::ConstructionFailure(_) => ErrorCode::Other(2),
SdkError::TimeoutError(_) => ErrorCode::Other(2),
SdkError::DispatchFailure(_) => ErrorCode::Other(2),
SdkError::ResponseError(e) => {
ErrorCode::UnsupportedResponse(e.raw().status().as_u16())
}
SdkError::ServiceError(e) => {
let status = e.raw().status();
match status.as_u16() {
400 => ErrorCode::InvalidAuthentication,
403 => ErrorCode::NotSupported,
429 => ErrorCode::RateLimited,
500 => ErrorCode::ServerError,
503 => ErrorCode::ServiceUnavailable,
_ => {
if status.is_server_error() {
ErrorCode::ServerError
} else {
ErrorCode::Other(status.as_u16())
}
}
}
}
_ => ErrorCode::Other(2),
},
});
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BamlRuntime, FunctionResult, BamlCtxManager, BamlStream, Image, ClientRegistry, BamlValidationError, createBamlValidationError } from "@boundaryml/baml"
import { Checked, Check } from "./types"
import {
{%- for t in types %}{{ t }}{% if !loop.last %}, {% endif %}{% endfor -%}
import {
{%- for t in types %}{{ t }}{% if !loop.last %}, {% endif %}{% endfor -%}
} from "./types"
import TypeBuilder from "./type_builder"
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
Expand All @@ -25,7 +25,7 @@ export class BamlAsyncClient {

get stream() {
return this.stream_client
}
}

{% for fn in funcs %}
async {{ fn.name }}(
Expand Down
62 changes: 57 additions & 5 deletions fern/03-reference/baml/clients/providers/aws-bedrock.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,39 @@ client<llm> MyClient {

We use the AWS SDK under the hood, which will respect [all authentication
mechanisms supported by the
SDK](https://docs.rs/aws-config/latest/aws_config/index.html), including but not
limited to:
SDK](https://docs.rs/aws-config/latest/aws_config/index.html), including:

- loading the specified `AWS_PROFILE` from `~/.aws/config`
- built-in authn for services running in EC2, ECS, Lambda, etc.
- You can also specify the access key ID, secret access key, and region directly (see below)
- Environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`)
- AWS SSO (Single Sign-On) credentials from `~/.aws/config`
- IAM Role credentials for services running in AWS (EC2, ECS, Lambda)
- AWS credentials file (`~/.aws/credentials`)
- AWS config file profiles (`~/.aws/config`)

For SSO users, ensure you've run `aws sso login` with your profile first. Then you can use the profile in your BAML configuration:

```baml
client<llm> MyClient {
provider aws-bedrock
options {
profile "my-sso-profile" // Profile name from ~/.aws/config
model "anthropic.claude-3-sonnet-20240229-v1:0"
}
}
```

You can also specify credentials directly in your BAML configuration (not recommended for production):

```baml
client<llm> MyClient {
provider aws-bedrock
options {
access_key_id env.AWS_ACCESS_KEY_ID
secret_access_key env.AWS_SECRET_ACCESS_KEY
region "us-east-1"
model "anthropic.claude-3-sonnet-20240229-v1:0"
}
}
```

## Playground setup
Add these three environment variables to your extension variables to use the AWS Bedrock provider in the playground.
Expand Down Expand Up @@ -83,6 +109,32 @@ Add these three environment variables to your extension variables to use the AWS
The AWS secret access key to use. **Default: `AWS_SECRET_ACCESS_KEY` environment variable**
</ParamField>

<ParamField
path="session_token"
type="string"
>
A temporary session token for AWS authentication, typically used with temporary security credentials. **Default: `AWS_SESSION_TOKEN` environment variable**

This is commonly used when assuming IAM roles or using temporary credentials from AWS STS (Security Token Service).
</ParamField>

<ParamField
path="profile"
type="string"
>
The AWS profile to use from your AWS credentials file (typically `~/.aws/credentials`). This allows you to specify different sets of credentials for different AWS accounts or roles. **Default: `AWS_PROFILE` environment variable**

Example:
```baml
client<llm> MyClient {
provider aws-bedrock
options {
profile "my-aws-profile"
model "anthropic.claude-3-sonnet-20240229-v1:0"
}
}
```
</ParamField>

## Forwarded options

Expand Down
54 changes: 52 additions & 2 deletions integ-tests/baml_src/clients.baml
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ client<llm> AwsBedrock {
inference_configuration {
max_tokens 100
}
// session_token env.FOO
// region env.AWS_REGION2
// model "anthropic.claude-3-5-sonnet-20240620-v1:0"
// model_id "anthropic.claude-3-haiku-20240307-v1:0"
model_id "meta.llama3-8b-instruct-v1:0"
Expand All @@ -126,6 +124,58 @@ client<llm> AwsBedrockInvalidRegion {
}
}

client<llm> AwsBedrockInvalidAccessKey {
provider aws-bedrock
options {
model_id "meta.llama3-8b-instruct-v1:0"
access_key_id "AKIAINVALID12345678"
secret_access_key "abcdef1234567890abcdef1234567890abcdef12"
inference_configuration {
max_tokens 100
}
}
}

client<llm> AwsBedrockInvalidProfile {
provider aws-bedrock
options {
model_id "meta.llama3-8b-instruct-v1:0"
profile "invalid-profile"
inference_configuration {
max_tokens 100
}
}
}

client<llm> AwsBedrockSessionToken {
provider aws-bedrock
options {
model_id "meta.llama3-8b-instruct-v1:0"
region "us-east-1"
access_key_id "AKIAINVALID12345678"
secret_access_key "abcdef1234567890abcdef1234567890abcdef12"
session_token "invalid-session-token"
inference_configuration {
max_tokens 100
}
}
}


client<llm> Invalid{
provider aws-bedrock
options {
model_id "meta.llama3-8b-instruct-v1:0"
region "us-east-1"
access_key_id "AKIAINVALID12345678"
secret_access_key "abcdef1234567890abcdef1234567890abcdef12"
session_token "invalid-session-token"
inference_configuration {
max_tokens 100
}
}
}

client<llm> Sonnet {
provider anthropic
options {
Expand Down
22 changes: 22 additions & 0 deletions integ-tests/baml_src/test-files/providers/providers.baml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,28 @@ function TestAwsInvalidRegion(input: string) -> string {
"#
}

function TestAwsInvalidAccessKey(input: string) -> string {
client AwsBedrockInvalidAccessKey
prompt #"
Write a nice short story about {{ input }}
"#
}

function TestAwsInvalidProfile(input: string) -> string {
client AwsBedrockInvalidProfile
prompt #"
Write a nice short story about {{ input }}
"#
}

function TestAwsSessionToken(input: string) -> string {
client AwsBedrockSessionToken
prompt #"
Write a nice short story about {{ input }}
"#
}


function TestOpenAIShorthand(input: string) -> string {
client GPT35
prompt #"
Expand Down
Loading

0 comments on commit 9a3efc3

Please sign in to comment.