Skip to content

Commit 53d3343

Browse files
authored
feat: aws support (vscode aws sso login, options.profile) (#1493)
Fixes three issues: - AWS_PROFILE is only supported through `aws_config::default_provider` right now, aka when the user provides no cues about aws creds in the baml client options - options.profile is not respected by baml-runtime in python/ts - options.profile is not respected by the vscode extension (aka wasm) Some chores: - fix unused code/imports warnings and crank those warnings up to build errors - rename WebPanelView to WebviewPanelHost Implementation notes: - vscode extensions are somewhat limited in what files they're allowed to access through the vscode API - technically, they're only allowed to open files available in the repository/workspace - although apparently the roo-code extension [doesn't have this issue](https://github.com/RooVetGit/Roo-Code/blob/bfd50240270fe01a34d37fa9c933dc26e4330b07/src/core/Cline.ts#L964)? seems some experimentation is required here to determine what is/isn't allowed (but i definitely remember testing this when i implemented file ref support for images) - upon further investigation, this is only if you request through the vscode API. extension sandboxing is nonexistent therefore node processes in the extension can do whatever the heck they want. - the baml playground (since it's a webview) currently has to request files from vscode by RPCing through the extension - the language server _does_ have filesystem access, so we could go through that (i don't love the idea of pushing the aws config files and cached credentials through the LSP stdin/stdio channel) - better approach is to probably re-purpose the request proxy for this (vbv's work around enabling/disabling the proxy will conflict with this, unfortunately), and use that to bypass vscode filesystem limitations - we need this filesystem access for the playground (this is complicated b/c the rust->wasm code doesn't have filesystem access (since WASI is not yet a standard): `AWS_PROFILE` can be backed by either IAM role profiles or SSO exchanges - IAM role profile creds are cached in `~/.aws/credentials` - SSO profiles are stored in `~/.aws/sso/` (I'm unclear on how exactly the Rust SDK hooks into this yet, nor if an override point exists here) - so there's a number of files that we need to support; at a minimum we should support aws sso, and we should also look into what other files are needed to implement a reasonable level of support for - alternatively: if instead of providing a shim for `std::fs::read` in wasm, we instead just implement `ProvideCredentials` in wasm and force it to delegate to `npm:@aws-sdk/credential-providers` in the proxy, that feels a lot more doable. however, protocol will also need to support forwarding env vars over (and shimming them on the node side). we may also need some shenanigans to make sure bedrock works on promptfiddle if we do this. fixes #1488 <!-- ELLIPSIS_HIDDEN --> ---- > [!IMPORTANT] > This pull request adds support for AWS profile configuration in the BAML runtime and VSCode extension, including new commands for loading AWS credentials and environment variables, and updates test cases to validate these changes. > > - **AWS Profile Support**: > - Added support for `options.profile` in `baml-runtime` and `vscode` extension. > - Implemented `LOAD_AWS_CREDS` command in `vscode-rpc.ts` to load AWS credentials based on profile. > - Updated `WebviewPanelHost` to handle AWS credentials loading. > - **Environment Variables**: > - Added `LOAD_ENV` command in `vscode-rpc.ts` to load environment variables from `.env` file or command. > - Implemented environment variable loading logic in `WebviewPanelHost`. > - **Testing**: > - Updated `aws.test.ts` to include tests for AWS profile configuration and invalid profile handling. > - **Miscellaneous**: > - Updated `package.json` and `uv.lock` to reflect new dependencies and configurations. > - Minor refactoring and logging improvements in `vscode` extension files. > > <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=BoundaryML%2Fbaml&utm_source=github&utm_medium=referral)<sup> for 803e9f8. It will automatically update as commits are pushed.</sup> <!-- ELLIPSIS_HIDDEN -->
1 parent 412d7f8 commit 53d3343

41 files changed

Lines changed: 1774 additions & 299 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

engine/Cargo.lock

Lines changed: 24 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

engine/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ serde_yaml = "0.9.34"
9494
static_assertions = "1.1.0"
9595
strum = { version = "0.26.2", features = ["derive"] }
9696
strum_macros = "0.26.2"
97+
thiserror = "2.0.12"
9798
time = { version = "0.3.36", features = ["formatting"] }
9899
tracing-core = { version = "0.1.31" }
99100
pin-project-lite = "0.2.14"

engine/baml-lib/baml-log/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ authors.workspace = true
66
license-file.workspace = true
77
description = "Logging library for BAML for end user logging"
88

9+
[lints.rust]
10+
dead_code = "deny"
11+
elided_named_lifetimes = "deny"
12+
unused_imports = "deny"
13+
unused_variables = "deny"
14+
915
[dependencies]
1016
serde = { version = "1.0", features = ["derive"] }
1117
serde_json.workspace = true

engine/baml-lib/baml-log/src/event.rs

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,3 @@
1-
use crate::logger::Loggable;
2-
use crate::Level;
3-
use serde_json::Value;
4-
5-
/// Creates a JSON-serializable event for structured logging
6-
pub struct Event<'a, T>
7-
where
8-
T: Loggable,
9-
{
10-
/// Log level
11-
pub level: Level,
12-
/// Event name
13-
pub name: &'a str,
14-
/// Event payload
15-
pub payload: T,
16-
/// Module path
17-
pub module_path: Option<&'a str>,
18-
/// File
19-
pub file: Option<&'a str>,
20-
/// Line
21-
pub line: Option<u32>,
22-
}
23-
24-
impl<'a, T> Event<'a, T>
25-
where
26-
T: Loggable,
27-
{
28-
pub fn new(
29-
level: Level,
30-
name: &'a str,
31-
payload: T,
32-
module_path: Option<&'a str>,
33-
file: Option<&'a str>,
34-
line: Option<u32>,
35-
) -> Self {
36-
Self {
37-
level,
38-
name,
39-
payload,
40-
module_path,
41-
file,
42-
line,
43-
}
44-
}
45-
}
46-
471
/// Logs a structured event at the specified level
482
///
493
/// This can be used for structured logging that works with both regular and JSON formats.

engine/baml-lib/baml-log/src/logger.rs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use colored::*;
22
use lazy_static::lazy_static;
3-
use serde::Serialize;
43
use std::collections::HashMap;
54
use std::env;
65
use std::fmt::{self, Display};
@@ -191,7 +190,7 @@ impl ConfigValue for LogLevelConfig {
191190
"BAML_LOG"
192191
}
193192

194-
fn parse_value(value: &str) -> Option<Self> {
193+
fn parse_value(_: &str) -> Option<Self> {
195194
Some(LogLevelConfig)
196195
}
197196

@@ -215,7 +214,7 @@ impl ConfigValue for JsonModeConfig {
215214
"BAML_LOG_JSON"
216215
}
217216

218-
fn parse_value(value: &str) -> Option<Self> {
217+
fn parse_value(_: &str) -> Option<Self> {
219218
Some(JsonModeConfig)
220219
}
221220

@@ -238,7 +237,7 @@ impl ConfigValue for ColorModeConfig {
238237
"BAML_LOG_COLOR_MODE"
239238
}
240239

241-
fn parse_value(value: &str) -> Option<Self> {
240+
fn parse_value(_: &str) -> Option<Self> {
242241
Some(ColorModeConfig)
243242
}
244243

@@ -262,7 +261,7 @@ impl ConfigValue for MaxMessageLengthConfig {
262261
"BAML_LOG_MAX_MESSAGE_LENGTH"
263262
}
264263

265-
fn parse_value(value: &str) -> Option<Self> {
264+
fn parse_value(_: &str) -> Option<Self> {
266265
Some(MaxMessageLengthConfig)
267266
}
268267

@@ -376,24 +375,24 @@ pub enum LogError {
376375
}
377376

378377
/// JSON-serializable log entry
379-
#[derive(Serialize)]
380-
struct LogEntry<'a> {
381-
/// Timestamp in ISO 8601 format
382-
timestamp: String,
383-
/// Log level as a string
384-
level: &'a str,
385-
/// Log message
386-
message: String,
387-
/// Optional module path
388-
#[serde(skip_serializing_if = "Option::is_none")]
389-
module_path: Option<&'a str>,
390-
/// Optional file name
391-
#[serde(skip_serializing_if = "Option::is_none")]
392-
file: Option<&'a str>,
393-
/// Optional line number
394-
#[serde(skip_serializing_if = "Option::is_none")]
395-
line: Option<u32>,
396-
}
378+
// #[derive(Serialize)]
379+
// struct LogEntry<'a> {
380+
// /// Timestamp in ISO 8601 format
381+
// timestamp: String,
382+
// /// Log level as a string
383+
// level: &'a str,
384+
// /// Log message
385+
// message: String,
386+
// /// Optional module path
387+
// #[serde(skip_serializing_if = "Option::is_none")]
388+
// module_path: Option<&'a str>,
389+
// /// Optional file name
390+
// #[serde(skip_serializing_if = "Option::is_none")]
391+
// file: Option<&'a str>,
392+
// /// Optional line number
393+
// #[serde(skip_serializing_if = "Option::is_none")]
394+
// line: Option<u32>,
395+
// }
397396

398397
/// Logger instance that can be customized
399398
pub struct Logger {
@@ -603,9 +602,9 @@ impl Logger {
603602
now: String,
604603
level: Level,
605604
message: &str,
606-
module_path: Option<&str>,
607-
file: Option<&str>,
608-
line: Option<u32>,
605+
_module_path: Option<&str>,
606+
_file: Option<&str>,
607+
_line: Option<u32>,
609608
) {
610609
// Configure color control based on mode
611610
match self.color_mode {
@@ -628,9 +627,9 @@ impl Logger {
628627
pub fn log_event_internal<T: Loggable>(
629628
level: Level,
630629
payload: &T,
631-
module_path: Option<&str>,
632-
file: Option<&str>,
633-
line: Option<u32>,
630+
_module_path: Option<&str>,
631+
_file: Option<&str>,
632+
_line: Option<u32>,
634633
) {
635634
// Ensure the logger is initialized
636635
let _ = INIT.call_once(|| {

engine/baml-lib/baml-types/src/value_expr.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,13 +477,23 @@ impl crate::BamlMedia {
477477
}
478478
}
479479

480+
#[derive(Clone)]
480481
pub struct ApiKeyWithProvenance {
481482
/// The key itself.
482483
pub api_key: SecretString,
483484
/// The name of the environment variable from which the key was read.
484485
pub provenance: Option<String>,
485486
}
486487

488+
impl std::fmt::Debug for ApiKeyWithProvenance {
489+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
490+
f.debug_struct("ApiKeyWithProvenance")
491+
.field("api_key", &"<no-repr-available>")
492+
.field("provenance", &self.provenance)
493+
.finish()
494+
}
495+
}
496+
487497
impl ApiKeyWithProvenance {
488498
/// Print the api_key if exposing the secret is allowed.
489499
/// Otherwise, render the provenance as an environment variable

0 commit comments

Comments
 (0)