diff --git a/engine/Cargo.lock b/engine/Cargo.lock index f14f4fa4e8..b5ebc998e1 100644 --- a/engine/Cargo.lock +++ b/engine/Cargo.lock @@ -1058,6 +1058,19 @@ dependencies = [ "uuid", ] +[[package]] +name = "baml-router" +version = "0.88.0" +dependencies = [ + "axum", + "console_error_panic_hook", + "serde", + "serde_json", + "tower-service", + "worker", + "worker-macros", +] + [[package]] name = "baml-rpc" version = "0.0.1" @@ -3583,9 +3596,9 @@ checksum = "8b23360e99b8717f20aaa4598f5a6541efbe30630039fbc7706cf954a87947ae" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -5481,6 +5494,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde-wasm-bindgen" version = "0.6.5" @@ -6644,19 +6668,20 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", @@ -6681,9 +6706,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6691,9 +6716,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", @@ -6704,9 +6729,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-bindgen-test" @@ -6773,9 +6798,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -7062,6 +7087,81 @@ dependencies = [ "bitflags 2.9.0", ] +[[package]] +name = "worker" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727789ca7eff9733efbea9d0e97779edc1cf1926e98aee7d7d8afe32805458aa" +dependencies = [ + "async-trait", + "axum", + "bytes", + "chrono", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "js-sys", + "matchit", + "pin-project", + "serde", + "serde-wasm-bindgen 0.6.5", + "serde_json", + "serde_urlencoded", + "tokio", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "worker-kv", + "worker-macros", + "worker-sys", +] + +[[package]] +name = "worker-kv" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f06d4d1416a9f8346ee9123b0d9a11b3cfa38e6cfb5a139698017d1597c4d41" +dependencies = [ + "js-sys", + "serde", + "serde-wasm-bindgen 0.5.0", + "serde_json", + "thiserror 1.0.62", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "worker-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d625c24570ba9207a2617476013335f28a95cbe513e59bb814ffba092a18058" +dependencies = [ + "async-trait", + "proc-macro2", + "quote", + "syn 2.0.87", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-macro-support", + "worker-sys", +] + +[[package]] +name = "worker-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34563340d41016b4381257c5a16b0d2bc590dbe00500ecfbebcaa16f5f85ce90" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "write16" version = "1.0.0" diff --git a/engine/Cargo.toml b/engine/Cargo.toml index b802113093..018f27b091 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -1,131 +1,202 @@ [workspace] -resolver = "2" members = [ - "baml-lib/*", - "baml-lsp-types", - "baml-rpc", - "baml-runtime", - "baml-schema-wasm", - "bstd", - "cli", - "language_client_codegen", - "language_client_python", - "language_client_ruby/ext/ruby_ffi", - "language_client_typescript", - "language_server", - "language_client_cffi", - "sandbox", + "baml-lib/*", + "baml-lsp-types", + "baml-router", + "baml-rpc", + "baml-runtime", + "baml-schema-wasm", + "bstd", + "cli", + "language_client_cffi", + "language_client_codegen", + "language_client_python", + "language_client_ruby/ext/ruby_ffi", + "language_client_typescript", + "language_server", + "sandbox", ] default-members = [ - "baml-lsp-types", - "baml-lib/*", - "baml-rpc", - "baml-runtime", - # Disabled by default: --features no_wasm and --features wasm are mutually exclusive - # Building baml-schema-wasm in combination with everything else triggers feature unification, - # and it's OK to not build this by default because we have to build ts separately (this may - # also have something to do with resolver=2 and how duplicate dep builds are handled) - # "baml-schema-wasm", - "bstd", - "cli", - "language_client_cffi", - "language_client_codegen", - "language_client_python", - "language_client_ruby/ext/ruby_ffi", - "language_client_typescript", - "language_server", + "baml-lsp-types", + "baml-lib/*", + "baml-rpc", + "baml-runtime", + "bstd", + "cli", + "language_client_cffi", + "language_client_codegen", + "language_client_python", + "language_client_ruby/ext/ruby_ffi", + "language_client_typescript", + "language_server", ] +resolver = "2" + +[workspace.metadata.workspaces] +allow_branch = "canary" + +[workspace.package] +version = "0.88.0" +authors = ["Boundary "] +description = "BAML Toolchain" +license-file = "LICENSE" [workspace.dependencies] -lsp-server = { version = "0.7.6" } -lsp-types = { version = "0.95.0" } anyhow = "1.0" askama = "0.12.1" -baml-cli = { path = "cli" } -baml-types = { path = "baml-lib/baml-types" } -baml-log = { path = "baml-lib/baml-log" } base64 = "0.22.1" -bstd = { path = "bstd" } bytes = "1.6.0" cfg-if = "1.0.0" -clap = { version = "4.4.6", features = ["cargo", "derive"] } dashmap = "5.5.3" derive-new = "0.7" derive_builder = "0.20.0" -derive_more = { version = "0.99.18", features = ["constructor"] } either = "1.8.1" env_logger = "0.11.3" -futures = { version = "0.3.30", features = ["executor"] } http = "1.1.0" http-body = "1.0.0" -indexmap = { version = "2.1.0", features = ["serde"] } indoc = "2.0.5" -internal-baml-codegen = { path = "language_client_codegen" } -internal-baml-core = { path = "baml-lib/baml-core" } -internal-baml-jinja = { path = "baml-lib/jinja-runtime" } -internal-llm-client = { path = "baml-lib/llm-client" } -baml-lsp-types = { path = "baml-lsp-types" } -jsonish = { path = "baml-lib/jsonish" } log = "0.4.20" -# TODO: disable imports, etc -minijinja = { version = "1.0.16", default-features = false, features = [ - "macros", - "builtins", - "debug", - "preserve_order", - "adjacent_loop_items", - "unicode", - "json", - "unstable_machinery", - "unstable_machinery_serde", - "custom_syntax", - "internal_debug", - "deserialization", - # We don't want to use these features: - # multi_template - # loader - # -] } once_cell = "1" +pin-project-lite = "0.2.14" pretty_assertions = "1.4.1" rand = "0.8.5" regex = "1.10.4" -reqwest = { version = "0.12.12", features = [ - "json", - "native-tls-alpn", - "native-tls-vendored", - "stream", -] } scopeguard = "1.2.0" -secrecy = { version = "0.10.3", features = ["serde"] } -serde_json = { version = "1", features = ["float_roundtrip", "preserve_order"] } -serde = { version = "1", features = ["alloc", "derive", "rc"] } serde_yaml = "0.9.34" static_assertions = "1.1.0" -strum = { version = "0.26.2", features = ["derive"] } strum_macros = "0.26.2" thiserror = "2.0.12" -time = { version = "0.3.36", features = ["formatting"] } -tracing-core = { version = "0.1.31" } -pin-project-lite = "0.2.14" url = "2.5.2" -uuid = { version = "1.8.0", features = ["v4", "v7", "serde"] } walkdir = "2.5.0" web-time = "1.1.0" -tokio = { version = "1", default-features = false, features = [ - "macros", - "time", -] } -[workspace.package] -version = "0.88.0" -authors = ["Boundary "] +[workspace.dependencies.baml-cli] +path = "cli" -description = "BAML Toolchain" -license-file = "LICENSE" +[workspace.dependencies.baml-log] +path = "baml-lib/baml-log" -[workspace.metadata.workspaces] -allow_branch = "canary" +[workspace.dependencies.baml-lsp-types] +path = "baml-lsp-types" + +[workspace.dependencies.baml-types] +path = "baml-lib/baml-types" + +[workspace.dependencies.bstd] +path = "bstd" + +[workspace.dependencies.clap] +version = "4.4.6" +features = [ + "cargo", + "derive", +] + +[workspace.dependencies.derive_more] +version = "0.99.18" +features = ["constructor"] + +[workspace.dependencies.futures] +version = "0.3.30" +features = ["executor"] + +[workspace.dependencies.indexmap] +version = "2.1.0" +features = ["serde"] + +[workspace.dependencies.internal-baml-codegen] +path = "language_client_codegen" + +[workspace.dependencies.internal-baml-core] +path = "baml-lib/baml-core" + +[workspace.dependencies.internal-baml-jinja] +path = "baml-lib/jinja-runtime" + +[workspace.dependencies.internal-llm-client] +path = "baml-lib/llm-client" + +[workspace.dependencies.jsonish] +path = "baml-lib/jsonish" + +[workspace.dependencies.lsp-server] +version = "0.7.6" + +[workspace.dependencies.lsp-types] +version = "0.95.0" + +[workspace.dependencies.minijinja] +version = "1.0.16" +features = [ + "macros", + "builtins", + "debug", + "preserve_order", + "adjacent_loop_items", + "unicode", + "json", + "unstable_machinery", + "unstable_machinery_serde", + "custom_syntax", + "internal_debug", + "deserialization", +] +default-features = false + +[workspace.dependencies.reqwest] +version = "0.12.12" +features = [ + "json", + "native-tls-alpn", + "native-tls-vendored", + "stream", +] + +[workspace.dependencies.secrecy] +version = "0.10.3" +features = ["serde"] + +[workspace.dependencies.serde] +version = "1" +features = [ + "alloc", + "derive", + "rc", +] + +[workspace.dependencies.serde_json] +version = "1" +features = [ + "float_roundtrip", + "preserve_order", +] + +[workspace.dependencies.strum] +version = "0.26.2" +features = ["derive"] + +[workspace.dependencies.time] +version = "0.3.36" +features = ["formatting"] + +[workspace.dependencies.tokio] +version = "1" +features = [ + "macros", + "time", +] +default-features = false + +[workspace.dependencies.tracing-core] +version = "0.1.31" + +[workspace.dependencies.uuid] +version = "1.8.0" +features = [ + "v4", + "v7", + "serde", +] [profile.dev] lto = false diff --git a/engine/baml-lsp-types/Cargo.toml b/engine/baml-lsp-types/Cargo.toml index dc820b13a4..ee2d1da0b1 100644 --- a/engine/baml-lsp-types/Cargo.toml +++ b/engine/baml-lsp-types/Cargo.toml @@ -21,7 +21,7 @@ internal-baml-codegen.workspace = true internal-baml-core.workspace = true jsonish = { path = "../baml-lib/jsonish" } internal-llm-client = { path = "../baml-lib/llm-client" } -js-sys = "=0.3.69" +js-sys = "=0.3.70" log.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/engine/baml-router/.gitignore b/engine/baml-router/.gitignore new file mode 100644 index 0000000000..d27315f031 --- /dev/null +++ b/engine/baml-router/.gitignore @@ -0,0 +1,3 @@ +target +node_modules +.wrangler diff --git a/engine/baml-router/Cargo.toml b/engine/baml-router/Cargo.toml new file mode 100644 index 0000000000..5ced908a03 --- /dev/null +++ b/engine/baml-router/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "baml-router" +version.workspace = true +edition = "2021" +authors.workspace = true + +[package.metadata.release] +release = false + +# https://github.com/rustwasm/wasm-pack/issues/1247 +[package.metadata.wasm-pack.profile.release] +wasm-opt = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +worker = { version="0.5.0", features=['http', 'axum'] } +worker-macros = { version="0.5.0", features=['http'] } +axum = { version = "0.7", default-features = false, features = ["json"] } +tower-service = "0.3.2" +console_error_panic_hook = { version = "0.1.1" } +serde.workspace = true +serde_json.workspace = true diff --git a/engine/baml-router/src/lib.rs b/engine/baml-router/src/lib.rs new file mode 100644 index 0000000000..0bac9636b9 --- /dev/null +++ b/engine/baml-router/src/lib.rs @@ -0,0 +1,124 @@ +use axum::{routing::{get, post}, Router, Json, http::StatusCode}; +use serde::Deserialize; +use tower_service::Service; +use worker::*; + +fn router() -> Router { + Router::new() + .route("/", get(root)) + .route("/v1/chat/completions/prompt", post(chat_completion_prompt)) +} + +#[event(fetch)] +async fn fetch( + req: HttpRequest, + _env: Env, + _ctx: Context, +) -> Result> { + console_error_panic_hook::set_once(); + Ok(router().call(req).await?) +} + +pub async fn root() -> &'static str { + "Hello Axum!" +} + + + +pub async fn chat_completion_prompt( + Json(mut body): Json, +) -> (StatusCode, Json) { + if let Some(inner_body) = body.as_object_mut() { + let tools = inner_body.remove("tools").map(|v| serde_json::from_value::>(v.clone()).unwrap_or_default()); + let tools = match tools { + Some(tools) => { + tools.into_iter().map(|tool| { + match tool { + // TODO(aaronvg): convert to type builder class + OpenAITool::Function(function) => function, + } + }).collect::>() + }, + None => return (StatusCode::BAD_REQUEST, Json(body)), + }; + + if let Some(messages) = inner_body.get_mut("messages") { + if let Some(messages) = messages.as_array_mut() { + messages.push(serde_json::json!({ + "role": "user", + // TODO(aaronvg): call the actual method here. + "content": "ctx.output_format" + })); + } + } + } + + (StatusCode::OK, Json(body)) +} + +#[derive(Deserialize)] +#[serde(tag = "type", content = "function", rename_all = "snake_case")] +enum OpenAITool { + Function(OpenAIToolFunction), +} + +#[derive(Deserialize)] +struct OpenAIToolFunction { + name: String, + description: Option, + parameters: Option, + strict: Option, +} + +#[cfg(test)] +mod tests { + use serde_json::json; + + use super::*; + + #[test] + fn test_openai_tool() { + let tool_str = r#" + [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. San Francisco, CA" + }, + "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]} + }, + "required": ["location"] + } + } + } + ] + "#; + let tool: Vec = serde_json::from_str(tool_str).unwrap(); + assert_eq!(tool.len(), 1); + let tool = &tool[0]; + let function = match tool { + OpenAITool::Function(function) => function, + }; + assert_eq!(function.name, "get_current_weather"); + assert_eq!(function.description, Some("Get the current weather in a given location".to_string())); + assert_eq!(function.parameters.as_ref().unwrap(), &json!({ + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. San Francisco, CA" + }, + "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]} + }, + "required": ["location"] + })); + } + +} diff --git a/engine/baml-router/wrangler.toml b/engine/baml-router/wrangler.toml new file mode 100644 index 0000000000..f95a37579d --- /dev/null +++ b/engine/baml-router/wrangler.toml @@ -0,0 +1,6 @@ +name = "baml-router" +main = "build/worker/shim.mjs" +compatibility_date = "2025-05-21" + +[build] +command = "cargo install -q worker-build && worker-build --release" \ No newline at end of file diff --git a/engine/baml-runtime/Cargo.toml b/engine/baml-runtime/Cargo.toml index 32142e718e..1157fbae12 100644 --- a/engine/baml-runtime/Cargo.toml +++ b/engine/baml-runtime/Cargo.toml @@ -123,7 +123,7 @@ colored = { version = "2.1.0", default-features = false, features = [ "no-color", ] } futures-timer = { version = "3.0.3", features = ["wasm-bindgen"] } -js-sys = "=0.3.69" +js-sys = "=0.3.70" reqwest = { version = "0.12.12", features = [ "stream", "json", diff --git a/engine/baml-schema-wasm/Cargo.toml b/engine/baml-schema-wasm/Cargo.toml index 0ebc5adcc4..3891d9a21b 100644 --- a/engine/baml-schema-wasm/Cargo.toml +++ b/engine/baml-schema-wasm/Cargo.toml @@ -33,7 +33,7 @@ internal-baml-codegen.workspace = true internal-baml-core.workspace = true jsonish = { path = "../baml-lib/jsonish" } internal-llm-client = { path = "../baml-lib/llm-client" } -js-sys = "=0.3.69" +js-sys = "=0.3.70" log.workspace = true serde.workspace = true serde_json.workspace = true @@ -42,7 +42,7 @@ time.workspace = true tokio = { workspace = true, features = ["sync"] } url.workspace = true uuid = { version = "1.8", features = ["v4", "js"] } -wasm-bindgen = "=0.2.92" +wasm-bindgen = "=0.2.93" wasm-bindgen-futures = "0.4.42" wasm-logger = { version = "0.2.0" } web-time.workspace = true