From 670af8a7bcf5e155e163a0e8c2a38b13710ef08f Mon Sep 17 00:00:00 2001 From: Vaibhav Gupta Date: Fri, 19 Jul 2024 01:35:46 -0700 Subject: [PATCH] Adding support for a sync client for Python + Typescript * Streaming in sync is support for Python as well * This resolves some issues with celery --- .../calling-baml/generate-baml-client.mdx | 29 +- docs/docs/get-started/quickstart/python.mdx | 25 +- engine/Cargo.lock | 1 + .../baml-lib/baml-core/src/configuration.rs | 43 + .../src/validate/generator_loader/v0.rs | 5 +- .../src/validate/generator_loader/v1.rs | 5 +- .../src/validate/generator_loader/v2.rs | 32 +- engine/baml-lib/diagnostics/src/error.rs | 4 +- engine/baml-runtime/Cargo.toml | 1 + engine/baml-runtime/src/cli/generate.rs | 20 +- engine/baml-runtime/src/cli/init.rs | 124 +- engine/baml-runtime/src/lib.rs | 21 + .../src/runtime/runtime_interface.rs | 2 + engine/baml-runtime/src/runtime_interface.rs | 1 + engine/baml-runtime/src/types/stream.rs | 16 + engine/language-client-codegen/src/lib.rs | 9 +- .../language-client-codegen/src/python/mod.rs | 61 +- .../src/python/templates/__init__.py.j2 | 6 +- .../{client.py.j2 => async_client.py.j2} | 12 +- .../src/python/templates/globals.py.j2 | 5 +- .../src/python/templates/sync_client.py.j2 | 125 + .../src/typescript/mod.rs | 69 +- .../{client.ts.j2 => async_client.ts.j2} | 7 +- .../src/typescript/templates/globals.ts.j2 | 2 - .../src/typescript/templates/index.ts.j2 | 8 +- .../typescript/templates/sync_client.ts.j2 | 56 + .../python_src/baml_py/__init__.py | 3 +- .../python_src/baml_py/baml_py.pyi | 23 + .../python_src/baml_py/ctx_manager.py | 4 +- .../python_src/baml_py/stream.py | 86 +- engine/language_client_python/src/lib.rs | 1 + engine/language_client_python/src/runtime.rs | 86 +- .../src/types/function_result_stream.rs | 70 + .../language_client_python/src/types/mod.rs | 2 +- engine/language_client_typescript/native.d.ts | 2 + .../language_client_typescript/src/runtime.rs | 84 + integ-tests/python/README.md | 2 +- integ-tests/python/baml_client/__init__.py | 4 +- .../{client.py => async_client.py} | 12 +- integ-tests/python/baml_client/globals.py | 5 +- integ-tests/python/baml_client/sync_client.py | 3725 +++++++++++++++++ integ-tests/python/tests/test_functions.py | 56 + .../{client.ts => async_client.ts} | 7 +- integ-tests/typescript/baml_client/globals.ts | 4 +- integ-tests/typescript/baml_client/index.ts | 4 +- .../typescript/baml_client/sync_client.ts | 1075 +++++ .../typescript/tests/integ-tests.test.ts | 11 +- 47 files changed, 5874 insertions(+), 81 deletions(-) rename engine/language-client-codegen/src/python/templates/{client.py.j2 => async_client.py.j2} (91%) create mode 100644 engine/language-client-codegen/src/python/templates/sync_client.py.j2 rename engine/language-client-codegen/src/typescript/templates/{client.ts.j2 => async_client.ts.j2} (88%) create mode 100644 engine/language-client-codegen/src/typescript/templates/sync_client.ts.j2 rename integ-tests/python/baml_client/{client.py => async_client.py} (99%) create mode 100644 integ-tests/python/baml_client/sync_client.py rename integ-tests/typescript/baml_client/{client.ts => async_client.ts} (99%) create mode 100644 integ-tests/typescript/baml_client/sync_client.ts diff --git a/docs/docs/calling-baml/generate-baml-client.mdx b/docs/docs/calling-baml/generate-baml-client.mdx index 07564ea26..4fa074be4 100644 --- a/docs/docs/calling-baml/generate-baml-client.mdx +++ b/docs/docs/calling-baml/generate-baml-client.mdx @@ -75,8 +75,15 @@ generate code for each of them. generator target { // Valid values: "python/pydantic", "typescript", "ruby/sorbet" output_type "python/pydantic" + // Where the generated code will be saved (relative to baml_src/) output_dir "../" + + // What interface you prefer to use for the generated code (sync/async) + // Both are generated regardless of the choice, just modifies what is exported + // at the top level + default_client_mode "sync" + // Version of runtime to generate code for (should match installed baml-py version) version "0.50.0" } @@ -86,8 +93,15 @@ generator target { generator target { // Valid values: "python/pydantic", "typescript", "ruby/sorbet" output_type "typescript" + // Where the generated code will be saved (relative to baml_src/) output_dir "../" + + // What interface you prefer to use for the generated code (sync/async) + // Both are generated regardless of the choice, just modifies what is exported + // at the top level + default_client_mode "async" + // Version of runtime to generate code for (should match the package @boundaryml/baml version) version "0.50.0" } @@ -97,8 +111,13 @@ generator target { generator target { // Valid values: "python/pydantic", "typescript", "ruby/sorbet" output_type "ruby/sorbet" + // Where the generated code will be saved (relative to baml_src/) output_dir "../" + + // This is a no-op for Ruby and can be ignored as futures are colorless in Ruby + // default_client_mode "sync" + // Version of runtime to generate code for (should match installed `baml` package version) version "0.50.0" } @@ -154,7 +173,7 @@ BAML: Code Generation disabled due to version mismatch... See the fix. **To fix any version mismatch issues, update all these things to the same version:** 1. VSCode extension 2. the installed baml dependency (e.g., `baml-py`) - - python: `pip install --upgrade package_name` + - python: `pip install --upgrade baml-py` - typescript: `npm install @boundaryml/baml@latest` 3. the `version` in your `generator` clause @@ -173,14 +192,12 @@ You can also tweak the generator settings below for a better experience. - + default="./baml_src"> Path to the BAML source directory. This is where the BAML files are located. + type="flag"> If set, it will disable checking the BAML source version with the installed BAML package version before generating code. - \ No newline at end of file + diff --git a/docs/docs/get-started/quickstart/python.mdx b/docs/docs/get-started/quickstart/python.mdx index 871660ac5..8ad0a7e72 100644 --- a/docs/docs/get-started/quickstart/python.mdx +++ b/docs/docs/get-started/quickstart/python.mdx @@ -53,8 +53,30 @@ To set up BAML in python do the following: ### Use a baml function in python! If `baml_client` doesn't exist, make sure to run the previous step! + ```python main.py - from baml_client import b + from baml_client.sync_client import b + from baml_client.types import Resume + + def example(raw_resume: str) -> Resume: + # BAML's internal parser guarantees ExtractResume + # to be always return a Resume type + response = b.ExtractResume(raw_resume) + return response + + def example_stream(raw_resume: str) -> Resume: + stream = b.stream.ExtractResume(raw_resume) + for msg in stream: + print(msg) # This will be a PartialResume type + + # This will be a Resume type + final = stream.get_final_response() + + return final + ``` + + ```python async_main.py + from baml_client.async_client import b from baml_client.types import Resume async def example(raw_resume: str) -> Resume: @@ -73,5 +95,6 @@ To set up BAML in python do the following: return final ``` + \ No newline at end of file diff --git a/engine/Cargo.lock b/engine/Cargo.lock index 982571933..de6ce7b8f 100644 --- a/engine/Cargo.lock +++ b/engine/Cargo.lock @@ -839,6 +839,7 @@ dependencies = [ "mime", "mime_guess", "pin-project-lite", + "pretty_assertions", "reqwest 0.12.5", "reqwest-eventsource", "ring", diff --git a/engine/baml-lib/baml-core/src/configuration.rs b/engine/baml-lib/baml-core/src/configuration.rs index 226804652..83aa3a0db 100644 --- a/engine/baml-lib/baml-core/src/configuration.rs +++ b/engine/baml-lib/baml-core/src/configuration.rs @@ -29,11 +29,41 @@ pub enum GeneratorOutputType { RubySorbet, } +impl GeneratorOutputType { + pub fn default_client_mode(&self) -> GeneratorDefaultClientMode { + match self { + // Due to legacy reasons, PythonPydantic and Typescript default to async + // DO NOT CHANGE THIS DEFAULT EVER OR YOU WILL BREAK EXISTING USERS + Self::PythonPydantic => GeneratorDefaultClientMode::Async, + Self::Typescript => GeneratorDefaultClientMode::Async, + Self::RubySorbet => GeneratorDefaultClientMode::Sync, + } + } + + /// Used to new generators when they are created (e.g. during baml-cli init) + pub fn recommended_default_client_mode(&self) -> GeneratorDefaultClientMode { + match self { + Self::PythonPydantic => GeneratorDefaultClientMode::Sync, + Self::Typescript => GeneratorDefaultClientMode::Async, + Self::RubySorbet => GeneratorDefaultClientMode::Sync, + } + } +} + +#[derive(Debug, Clone, strum::Display, strum::EnumString, strum::VariantNames, PartialEq, Eq)] +pub enum GeneratorDefaultClientMode { + #[strum(serialize = "sync")] + Sync, + #[strum(serialize = "async")] + Async, +} + #[derive(derive_builder::Builder, Debug, Clone)] pub struct Generator { pub name: String, pub baml_src: PathBuf, pub output_type: GeneratorOutputType, + default_client_mode: Option, output_dir: PathBuf, pub version: String, @@ -55,6 +85,19 @@ impl Generator { ) } + pub fn default_client_mode(&self) -> GeneratorDefaultClientMode { + self.default_client_mode + .clone() + .unwrap_or_else(|| self.output_type.default_client_mode()) + } + + /// Used to new generators when they are created + pub fn recommended_default_client_mode(&self) -> GeneratorDefaultClientMode { + self.default_client_mode + .clone() + .unwrap_or_else(|| self.output_type.recommended_default_client_mode()) + } + pub fn output_dir(&self) -> PathBuf { self.output_dir.join("baml_client") } diff --git a/engine/baml-lib/baml-core/src/validate/generator_loader/v0.rs b/engine/baml-lib/baml-core/src/validate/generator_loader/v0.rs index 5267e991b..6663a155b 100644 --- a/engine/baml-lib/baml-core/src/validate/generator_loader/v0.rs +++ b/engine/baml-lib/baml-core/src/validate/generator_loader/v0.rs @@ -208,8 +208,9 @@ pub(crate) fn parse_generator( }; builder.build().map_err(|e| { - vec![DatamodelError::new_internal_error( - anyhow::Error::from(e).context("Internal error while parsing generator (v1 syntax)"), + vec![DatamodelError::new_anyhow_error( + anyhow::Error::from(e) + .context("Internal error while parsing generator (legacy v0 syntax)"), ast_generator.span().clone(), )] }) diff --git a/engine/baml-lib/baml-core/src/validate/generator_loader/v1.rs b/engine/baml-lib/baml-core/src/validate/generator_loader/v1.rs index 5864c0564..922d43ad7 100644 --- a/engine/baml-lib/baml-core/src/validate/generator_loader/v1.rs +++ b/engine/baml-lib/baml-core/src/validate/generator_loader/v1.rs @@ -163,8 +163,9 @@ pub(crate) fn parse_generator( } builder.build().map_err(|e| { - vec![DatamodelError::new_internal_error( - anyhow::Error::from(e).context("Internal error while parsing generator (v1 syntax)"), + vec![DatamodelError::new_anyhow_error( + anyhow::Error::from(e) + .context("Internal error while parsing generator (legacy v1 syntax)"), ast_generator.span().clone(), )] }) diff --git a/engine/baml-lib/baml-core/src/validate/generator_loader/v2.rs b/engine/baml-lib/baml-core/src/validate/generator_loader/v2.rs index 6263a733d..98d0e0b0f 100644 --- a/engine/baml-lib/baml-core/src/validate/generator_loader/v2.rs +++ b/engine/baml-lib/baml-core/src/validate/generator_loader/v2.rs @@ -5,7 +5,9 @@ use internal_baml_schema_ast::ast::{self, WithName, WithSpan}; use semver::Version; use strum::VariantNames; -use crate::configuration::{Generator, GeneratorBuilder, GeneratorOutputType}; +use crate::configuration::{ + Generator, GeneratorBuilder, GeneratorDefaultClientMode, GeneratorOutputType, +}; const FIRST_CLASS_PROPERTIES: &[&str] = &["output_type", "output_dir", "version"]; @@ -158,13 +160,37 @@ pub(crate) fn parse_generator( } } + match parse_optional_key(&args, "default_client_mode") { + Ok(Some("sync")) => { + builder.default_client_mode(Some(GeneratorDefaultClientMode::Sync)); + } + Ok(Some("async")) => { + builder.default_client_mode(Some(GeneratorDefaultClientMode::Async)); + } + Ok(Some(name)) => { + errors.push(DatamodelError::new_validation_error( + &format!("'{}' is not supported. Use one of: 'async' or 'sync'", name), + args.get("default_client_mode") + .map(|arg| arg.span()) + .unwrap_or_else(|| ast_generator.span()) + .clone(), + )); + } + Ok(None) => { + builder.default_client_mode(None); + } + Err(err) => { + errors.push(err); + } + } + if !errors.is_empty() { return Err(errors); } builder.build().map_err(|e| { - vec![DatamodelError::new_internal_error( - anyhow::Error::from(e).context("Internal error while parsing generator (v1 syntax)"), + vec![DatamodelError::new_anyhow_error( + anyhow::Error::from(e).context("Error parsing generator"), ast_generator.span().clone(), )] }) diff --git a/engine/baml-lib/diagnostics/src/error.rs b/engine/baml-lib/diagnostics/src/error.rs index d932d1759..05bdc20a8 100644 --- a/engine/baml-lib/diagnostics/src/error.rs +++ b/engine/baml-lib/diagnostics/src/error.rs @@ -69,8 +69,8 @@ impl DatamodelError { DatamodelError { message, span } } - pub fn new_internal_error(error: anyhow::Error, span: Span) -> Self { - Self::new(format!("Internal error occurred: {error}"), span) + pub fn new_anyhow_error(error: anyhow::Error, span: Span) -> Self { + Self::new(format!("{error:#}"), span) } pub fn new_static(message: &'static str, span: Span) -> Self { diff --git a/engine/baml-runtime/Cargo.toml b/engine/baml-runtime/Cargo.toml index ca910d785..2ab100ba3 100644 --- a/engine/baml-runtime/Cargo.toml +++ b/engine/baml-runtime/Cargo.toml @@ -69,6 +69,7 @@ enum_dispatch = "0.3.13" ambassador = "0.4.0" aws-smithy-json = "0.60.7" jsonwebtoken = "9.3.0" +pretty_assertions = "1.4.0" [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/engine/baml-runtime/src/cli/generate.rs b/engine/baml-runtime/src/cli/generate.rs index d6f0f28f0..5d1042507 100644 --- a/engine/baml-runtime/src/cli/generate.rs +++ b/engine/baml-runtime/src/cli/generate.rs @@ -1,7 +1,8 @@ use crate::{runtime::runtime_interface::baml_src_files, BamlRuntime}; -use anyhow::{Context, Result}; +use anyhow::Result; use colored::*; -use std::{env, path::PathBuf}; +use internal_baml_core::configuration::GeneratorDefaultClientMode; +use std::path::PathBuf; #[derive(clap::Args, Debug)] pub struct GenerateArgs { @@ -40,6 +41,20 @@ impl GenerateArgs { // give the user a working config to copy-paste (so we need to run it through generator again) if generated.is_empty() { let client_type = caller_type.into(); + + let default_client_mode = match client_type { + internal_baml_core::configuration::GeneratorOutputType::PythonPydantic => { + // TODO: Consider changing this default to sync + GeneratorDefaultClientMode::Async + } + internal_baml_core::configuration::GeneratorOutputType::Typescript => { + GeneratorDefaultClientMode::Async + } + internal_baml_core::configuration::GeneratorOutputType::RubySorbet => { + GeneratorDefaultClientMode::Sync + } + }; + // Normally `baml_client` is added via the generator, but since we're not running the generator, we need to add it manually. let output_dir_relative_to_baml_src = PathBuf::from(".."); let version = env!("CARGO_PKG_VERSION"); let generate_output = runtime.generate_client( @@ -50,6 +65,7 @@ impl GenerateArgs { all_files.iter(), version.to_string(), false, + default_client_mode, )?, )?; diff --git a/engine/baml-runtime/src/cli/init.rs b/engine/baml-runtime/src/cli/init.rs index 3b740e02b..c3f8918c9 100644 --- a/engine/baml-runtime/src/cli/init.rs +++ b/engine/baml-runtime/src/cli/init.rs @@ -42,10 +42,19 @@ impl InitArgs { let main_baml = std::path::Path::new(&self.dest) .join("baml_src") .join("generators.baml"); - std::fs::write( - main_baml, - format!( - r#" + + let main_baml_content = generate_main_baml_content(&client_type); + std::fs::write(main_baml, main_baml_content)?; + + Ok(()) + } +} + +fn generate_main_baml_content(client_type: &GeneratorOutputType) -> String { + let default_mode = client_type.recommended_default_client_mode(); + + format!( + r#" // This helps use auto generate libraries you can use in the language of // your choice. You can have multiple generators if you use multiple languages. // Just ensure that the output_dir is different for each generator. @@ -57,13 +66,108 @@ generator target {{ // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml). // The BAML VSCode extension version should also match this version. version "{}" + // Valid values: "sync", "async" + // This controls what `b.FunctionName()` will be (sync or async). + // Regardless of this setting, you can always explicitly call either of the following: + // - b.sync.FunctionName() + // - b.async_.FunctionName() (note the underscore to avoid a keyword conflict) + default_client_mode {} }} - "#, - client_type.to_string(), - env!("CARGO_PKG_VERSION") - ), - )?; + "#, + client_type.to_string(), + env!("CARGO_PKG_VERSION"), + default_mode.to_string() + ) + .trim_end() + .into() +} - Ok(()) +#[cfg(test)] +mod tests { + use super::*; + use pretty_assertions::assert_eq; + + #[test] + fn test_generate_content_pydantic() { + assert_eq!( + generate_main_baml_content(&GeneratorOutputType::PythonPydantic), + format!(r#" +// This helps use auto generate libraries you can use in the language of +// your choice. You can have multiple generators if you use multiple languages. +// Just ensure that the output_dir is different for each generator. +generator target {{ + // Valid values: "python/pydantic", "typescript", "ruby/sorbet" + output_type "python/pydantic" + // Where the generated code will be saved (relative to baml_src/) + output_dir "../" + // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml). + // The BAML VSCode extension version should also match this version. + version "{}" + // Valid values: "sync", "async" + // This controls what `b.FunctionName()` will be (sync or async). + // Regardless of this setting, you can always explicitly call either of the following: + // - b.sync.FunctionName() + // - b.async_.FunctionName() (note the underscore to avoid a keyword conflict) + default_client_mode sync +}} + "#, env!("CARGO_PKG_VERSION")) + .trim_end() + ); + } + + #[test] + fn test_generate_content_typescript() { + assert_eq!( + generate_main_baml_content(&GeneratorOutputType::Typescript), + format!(r#" +// This helps use auto generate libraries you can use in the language of +// your choice. You can have multiple generators if you use multiple languages. +// Just ensure that the output_dir is different for each generator. +generator target {{ + // Valid values: "python/pydantic", "typescript", "ruby/sorbet" + output_type "typescript" + // Where the generated code will be saved (relative to baml_src/) + output_dir "../" + // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml). + // The BAML VSCode extension version should also match this version. + version "{}" + // Valid values: "sync", "async" + // This controls what `b.FunctionName()` will be (sync or async). + // Regardless of this setting, you can always explicitly call either of the following: + // - b.sync.FunctionName() + // - b.async_.FunctionName() (note the underscore to avoid a keyword conflict) + default_client_mode async +}} + "#, env!("CARGO_PKG_VERSION")) + .trim_end() + ); + } + + #[test] + fn test_generate_content_ruby() { + assert_eq!( + generate_main_baml_content(&GeneratorOutputType::RubySorbet), + format!(r#" +// This helps use auto generate libraries you can use in the language of +// your choice. You can have multiple generators if you use multiple languages. +// Just ensure that the output_dir is different for each generator. +generator target {{ + // Valid values: "python/pydantic", "typescript", "ruby/sorbet" + output_type "ruby/sorbet" + // Where the generated code will be saved (relative to baml_src/) + output_dir "../" + // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml). + // The BAML VSCode extension version should also match this version. + version "{}" + // Valid values: "sync", "async" + // This controls what `b.FunctionName()` will be (sync or async). + // Regardless of this setting, you can always explicitly call either of the following: + // - b.sync.FunctionName() + // - b.async_.FunctionName() (note the underscore to avoid a keyword conflict) + default_client_mode sync +}} + "#, env!("CARGO_PKG_VERSION")) + .trim_end() + ); } } diff --git a/engine/baml-runtime/src/lib.rs b/engine/baml-runtime/src/lib.rs index 206f4a95c..c8e12486e 100644 --- a/engine/baml-runtime/src/lib.rs +++ b/engine/baml-runtime/src/lib.rs @@ -67,6 +67,8 @@ pub struct BamlRuntime { inner: InternalBamlRuntime, tracer: Arc, env_vars: HashMap, + #[cfg(not(target_arch = "wasm32"))] + async_runtime: Arc, } impl BamlRuntime { @@ -88,6 +90,8 @@ impl BamlRuntime { inner: InternalBamlRuntime::from_directory(path)?, tracer: BamlTracer::new(None, env_vars.into_iter())?.into(), env_vars: copy, + #[cfg(not(target_arch = "wasm32"))] + async_runtime: tokio::runtime::Runtime::new()?.into(), }) } @@ -104,6 +108,8 @@ impl BamlRuntime { inner: InternalBamlRuntime::from_file_content(root_path, files)?, tracer: BamlTracer::new(None, env_vars.into_iter())?.into(), env_vars: copy, + #[cfg(not(target_arch = "wasm32"))] + async_runtime: tokio::runtime::Runtime::new()?.into(), }) } @@ -182,6 +188,19 @@ impl BamlRuntime { (response, target_id) } + #[cfg(not(target_arch = "wasm32"))] + pub fn call_function_sync( + &self, + function_name: String, + params: &BamlMap, + ctx: &RuntimeContextManager, + tb: Option<&TypeBuilder>, + cb: Option<&ClientRegistry>, + ) -> (Result, Option) { + let fut = self.call_function(function_name, params, ctx, tb, cb); + self.async_runtime.block_on(fut) + } + pub async fn call_function( &self, function_name: String, @@ -231,6 +250,7 @@ impl BamlRuntime { params, self.tracer.clone(), ctx.create_ctx(tb, cb)?, + self.async_runtime.clone(), ) } @@ -267,6 +287,7 @@ impl BamlRuntime { input_files.iter(), generator.version.clone(), no_version_check, + generator.default_client_mode(), )?, )) }) diff --git a/engine/baml-runtime/src/runtime/runtime_interface.rs b/engine/baml-runtime/src/runtime/runtime_interface.rs index b422e6832..794ed615b 100644 --- a/engine/baml-runtime/src/runtime/runtime_interface.rs +++ b/engine/baml-runtime/src/runtime/runtime_interface.rs @@ -353,6 +353,7 @@ impl RuntimeInterface for InternalBamlRuntime { params: &BamlMap, tracer: Arc, ctx: RuntimeContext, + tokio_runtime: Arc, ) -> Result { let func = self.get_function(&function_name, &ctx)?; let renderer = PromptRenderer::from_function(&func, self.ir(), &ctx)?; @@ -372,6 +373,7 @@ impl RuntimeInterface for InternalBamlRuntime { orchestrator, tracer, renderer, + tokio_runtime, }) } } diff --git a/engine/baml-runtime/src/runtime_interface.rs b/engine/baml-runtime/src/runtime_interface.rs index 544c8df53..f4a38bf71 100644 --- a/engine/baml-runtime/src/runtime_interface.rs +++ b/engine/baml-runtime/src/runtime_interface.rs @@ -43,6 +43,7 @@ pub trait RuntimeInterface { params: &BamlMap, tracer: Arc, ctx: RuntimeContext, + tokio_runtime: Arc, ) -> Result; } diff --git a/engine/baml-runtime/src/types/stream.rs b/engine/baml-runtime/src/types/stream.rs index c7879fef8..a92365cc9 100644 --- a/engine/baml-runtime/src/types/stream.rs +++ b/engine/baml-runtime/src/types/stream.rs @@ -27,6 +27,7 @@ pub struct FunctionResultStream { pub(crate) ir: Arc, pub(crate) orchestrator: OrchestratorNodeIterator, pub(crate) tracer: Arc, + pub(crate) tokio_runtime: Arc, } #[cfg(target_arch = "wasm32")] @@ -53,6 +54,21 @@ first.scope.clone(); */ impl FunctionResultStream { + pub fn run_sync( + &mut self, + on_event: Option, + ctx: &RuntimeContextManager, + tb: Option<&TypeBuilder>, + cb: Option<&ClientRegistry>, + ) -> (Result, Option) + where + F: Fn(FunctionResult) -> (), + { + let rt = self.tokio_runtime.clone(); + let fut = self.run(on_event, ctx, tb, cb); + rt.block_on(fut) + } + pub async fn run( &mut self, on_event: Option, diff --git a/engine/language-client-codegen/src/lib.rs b/engine/language-client-codegen/src/lib.rs index d6e696d49..0ee1e19ce 100644 --- a/engine/language-client-codegen/src/lib.rs +++ b/engine/language-client-codegen/src/lib.rs @@ -1,7 +1,10 @@ use anyhow::Result; use colored::*; use indexmap::IndexMap; -use internal_baml_core::{configuration::GeneratorOutputType, ir::repr::IntermediateRepr}; +use internal_baml_core::{ + configuration::{GeneratorDefaultClientMode, GeneratorOutputType}, + ir::repr::IntermediateRepr, +}; use semver::Version; use std::{collections::BTreeMap, path::PathBuf}; use version_check::{check_version, GeneratorType, VersionCheckMode}; @@ -23,6 +26,8 @@ pub struct GeneratorArgs { version: String, no_version_check: bool, + // Default call mode for functions + default_client_mode: GeneratorDefaultClientMode, } fn relative_path_to_baml_src(path: &PathBuf, baml_src: &PathBuf) -> Result { @@ -42,6 +47,7 @@ impl GeneratorArgs { input_files: impl IntoIterator, version: String, no_version_check: bool, + default_client_mode: GeneratorDefaultClientMode, ) -> Result { let baml_src = baml_src_dir.into(); let input_file_map: BTreeMap = input_files @@ -56,6 +62,7 @@ impl GeneratorArgs { input_file_map, version, no_version_check, + default_client_mode, }) } diff --git a/engine/language-client-codegen/src/python/mod.rs b/engine/language-client-codegen/src/python/mod.rs index f6954fa9c..c94cdd547 100644 --- a/engine/language-client-codegen/src/python/mod.rs +++ b/engine/language-client-codegen/src/python/mod.rs @@ -6,16 +6,42 @@ use std::path::PathBuf; use anyhow::Result; use either::Either; use indexmap::IndexMap; -use internal_baml_core::ir::{repr::IntermediateRepr, FieldType, IRHelper}; +use internal_baml_core::{ + configuration::GeneratorDefaultClientMode, + ir::{repr::IntermediateRepr, FieldType, IRHelper}, +}; use self::python_language_features::{PythonLanguageFeatures, ToPython}; use crate::dir_writer::FileCollector; #[derive(askama::Template)] -#[template(path = "client.py.j2", escape = "none")] +#[template(path = "async_client.py.j2", escape = "none")] +struct AsyncPythonClient { + funcs: Vec, +} + +#[derive(askama::Template)] +#[template(path = "sync_client.py.j2", escape = "none")] +struct SyncPythonClient { + funcs: Vec, +} + struct PythonClient { funcs: Vec, } + +impl From for AsyncPythonClient { + fn from(value: PythonClient) -> Self { + Self { funcs: value.funcs } + } +} + +impl From for SyncPythonClient { + fn from(value: PythonClient) -> Self { + Self { funcs: value.funcs } + } +} + struct PythonFunction { name: String, partial_return_type: String, @@ -25,7 +51,9 @@ struct PythonFunction { #[derive(askama::Template)] #[template(path = "__init__.py.j2", escape = "none")] -struct PythonInit {} +struct PythonInit { + default_client_mode: GeneratorDefaultClientMode, +} #[derive(askama::Template)] #[template(path = "globals.py.j2", escape = "none")] @@ -51,7 +79,8 @@ pub(crate) fn generate( .add_template::("partial_types.py", (ir, generator))?; collector.add_template::("types.py", (ir, generator))?; collector.add_template::("type_builder.py", (ir, generator))?; - collector.add_template::("client.py", (ir, generator))?; + collector.add_template::("async_client.py", (ir, generator))?; + collector.add_template::("sync_client.py", (ir, generator))?; collector.add_template::("globals.py", (ir, generator))?; collector.add_template::("tracing.py", (ir, generator))?; collector.add_template::("inlinedbaml.py", (ir, generator))?; @@ -71,8 +100,10 @@ impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for PythonTracing impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for PythonInit { type Error = anyhow::Error; - fn try_from(_: (&'_ IntermediateRepr, &'_ crate::GeneratorArgs)) -> Result { - Ok(PythonInit {}) + fn try_from((_, gen): (&'_ IntermediateRepr, &'_ crate::GeneratorArgs)) -> Result { + Ok(PythonInit { + default_client_mode: gen.default_client_mode.clone(), + }) } } @@ -94,6 +125,24 @@ impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for InlinedBaml { } } +impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for AsyncPythonClient { + type Error = anyhow::Error; + + fn try_from(params: (&'_ IntermediateRepr, &'_ crate::GeneratorArgs)) -> Result { + let python_client = PythonClient::try_from(params)?; + Ok(python_client.into()) + } +} + +impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for SyncPythonClient { + type Error = anyhow::Error; + + fn try_from(params: (&'_ IntermediateRepr, &'_ crate::GeneratorArgs)) -> Result { + let python_client = PythonClient::try_from(params)?; + Ok(python_client.into()) + } +} + impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for PythonClient { type Error = anyhow::Error; diff --git a/engine/language-client-codegen/src/python/templates/__init__.py.j2 b/engine/language-client-codegen/src/python/templates/__init__.py.j2 index 7a2e1bead..d287716c4 100644 --- a/engine/language-client-codegen/src/python/templates/__init__.py.j2 +++ b/engine/language-client-codegen/src/python/templates/__init__.py.j2 @@ -1,7 +1,11 @@ -from .globals import b from . import types from . import tracing from . import partial_types +{% if default_client_mode == GeneratorDefaultClientMode::Async %} +from .async_client import b +{% else %} +from .sync_client import b +{% endif %} __all__ = [ diff --git a/engine/language-client-codegen/src/python/templates/client.py.j2 b/engine/language-client-codegen/src/python/templates/async_client.py.j2 similarity index 91% rename from engine/language-client-codegen/src/python/templates/client.py.j2 rename to engine/language-client-codegen/src/python/templates/async_client.py.j2 index e3a8a516e..c03a0be26 100644 --- a/engine/language-client-codegen/src/python/templates/client.py.j2 +++ b/engine/language-client-codegen/src/python/templates/async_client.py.j2 @@ -7,6 +7,8 @@ from pydantic import BaseModel, ValidationError, create_model from . import partial_types, types from .type_builder import TypeBuilder +from .globals import DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME + OutputType = TypeVar('OutputType') @@ -26,7 +28,7 @@ class BamlCallOptions(TypedDict, total=False): tb: NotRequired[TypeBuilder] client_registry: NotRequired[baml_py.baml_py.ClientRegistry] -class BamlClient: +class BamlAsyncClient: __runtime: baml_py.BamlRuntime __ctx_manager: baml_py.BamlCtxManager __stream_client: "BamlStreamClient" @@ -40,6 +42,7 @@ class BamlClient: def stream(self): return self.__stream_client + {% for fn in funcs %} async def {{ fn.name }}( self, @@ -70,6 +73,7 @@ class BamlClient: return coerce(mdl, raw.parsed()) {% endfor %} + class BamlStreamClient: __runtime: baml_py.BamlRuntime __ctx_manager: baml_py.BamlCtxManager @@ -115,4 +119,8 @@ class BamlStreamClient: lambda x: coerce(mdl, x), self.__ctx_manager.get(), ) - {% endfor %} \ No newline at end of file + {% endfor %} + +b = BamlAsyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) + +__all__ = ["b"] diff --git a/engine/language-client-codegen/src/python/templates/globals.py.j2 b/engine/language-client-codegen/src/python/templates/globals.py.j2 index ea1c16118..e745cb1a1 100644 --- a/engine/language-client-codegen/src/python/templates/globals.py.j2 +++ b/engine/language-client-codegen/src/python/templates/globals.py.j2 @@ -1,7 +1,6 @@ import os from baml_py import BamlCtxManager, BamlRuntime -from .client import BamlClient from .inlinedbaml import get_baml_files DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = BamlRuntime.from_files( @@ -11,6 +10,4 @@ DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = BamlRuntime.from_ ) DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME) -b = BamlClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) - -__all__ = ['b'] +__all__ = [] \ No newline at end of file diff --git a/engine/language-client-codegen/src/python/templates/sync_client.py.j2 b/engine/language-client-codegen/src/python/templates/sync_client.py.j2 new file mode 100644 index 000000000..b1e4a80ac --- /dev/null +++ b/engine/language-client-codegen/src/python/templates/sync_client.py.j2 @@ -0,0 +1,125 @@ +from typing import Any, List, Optional, TypeVar, Union, TypedDict, Type +from typing_extensions import NotRequired +import pprint + +import baml_py +from pydantic import BaseModel, ValidationError, create_model + +from . import partial_types, types +from .type_builder import TypeBuilder +from .globals import DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME + +OutputType = TypeVar('OutputType') + +def coerce(cls: Type[BaseModel], parsed: Any) -> Any: + try: + return cls.model_validate({"inner": parsed}).inner # type: ignore + except ValidationError as e: + raise TypeError( + "Internal BAML error while casting output to {}\n{}".format( + cls.__name__, + pprint.pformat(parsed) + ) + ) from e + +# Define the TypedDict with optional parameters having default values +class BamlCallOptions(TypedDict, total=False): + tb: NotRequired[TypeBuilder] + client_registry: NotRequired[baml_py.baml_py.ClientRegistry] + +class BamlSyncClient: + __runtime: baml_py.BamlRuntime + __ctx_manager: baml_py.BamlCtxManager + __stream_client: "BamlStreamClient" + + def __init__(self, runtime: baml_py.BamlRuntime, ctx_manager: baml_py.BamlCtxManager): + self.__runtime = runtime + self.__ctx_manager = ctx_manager + self.__stream_client = BamlStreamClient(self.__runtime, self.__ctx_manager) + + @property + def stream(self): + return self.__stream_client + + {% for fn in funcs %} + def {{ fn.name }}( + self, + {% for (name, type) in fn.args -%} + {{name}}: {{type}}, + {%- endfor %} + baml_options: BamlCallOptions = {}, + ) -> {{fn.return_type}}: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "{{fn.name}}", + { + {% for (name, _) in fn.args -%} + "{{name}}": {{name}}, + {%- endfor %} + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("{{ fn.name }}ReturnType", inner=({{ fn.return_type }}, ...)) + return coerce(mdl, raw.parsed()) + {% endfor %} + + + +class BamlStreamClient: + __runtime: baml_py.BamlRuntime + __ctx_manager: baml_py.BamlCtxManager + + def __init__(self, runtime: baml_py.BamlRuntime, ctx_manager: baml_py.BamlCtxManager): + self.__runtime = runtime + self.__ctx_manager = ctx_manager + + {% for fn in funcs %} + def {{ fn.name }}( + self, + {% for (name, type) in fn.args -%} + {{name}}: {{type}}, + {%- endfor %} + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[{{ fn.partial_return_type }}, {{ fn.return_type }}]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "{{fn.name}}", + { + {%- for (name, _) in fn.args %} + "{{name}}": {{name}}, + {%- endfor %} + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("{{ fn.name }}ReturnType", inner=({{ fn.return_type }}, ...)) + partial_mdl = create_model("{{ fn.name }}PartialReturnType", inner=({{ fn.partial_return_type }}, ...)) + + return baml_py.BamlSyncStream[{{ fn.partial_return_type }}, {{ fn.return_type }}]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + {% endfor %} + +b = BamlSyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) + +__all__ = ["b"] diff --git a/engine/language-client-codegen/src/typescript/mod.rs b/engine/language-client-codegen/src/typescript/mod.rs index 00b5226f4..a4946173d 100644 --- a/engine/language-client-codegen/src/typescript/mod.rs +++ b/engine/language-client-codegen/src/typescript/mod.rs @@ -6,17 +6,51 @@ use std::path::PathBuf; use anyhow::Result; use either::Either; use indexmap::IndexMap; -use internal_baml_core::ir::{repr::IntermediateRepr, FieldType, IRHelper}; +use internal_baml_core::{ + configuration::GeneratorDefaultClientMode, + ir::{repr::IntermediateRepr, FieldType, IRHelper}, +}; use self::typescript_language_features::{ToTypescript, TypescriptLanguageFeatures}; use crate::dir_writer::FileCollector; #[derive(askama::Template)] -#[template(path = "client.ts.j2", escape = "none")] +#[template(path = "async_client.ts.j2", escape = "none")] +struct AsyncTypescriptClient { + funcs: Vec, + types: Vec, +} + +#[derive(askama::Template)] +#[template(path = "sync_client.ts.j2", escape = "none")] +struct SyncTypescriptClient { + funcs: Vec, + types: Vec, +} + struct TypescriptClient { funcs: Vec, types: Vec, } + +impl From for AsyncTypescriptClient { + fn from(value: TypescriptClient) -> Self { + Self { + funcs: value.funcs, + types: value.types, + } + } +} + +impl From for SyncTypescriptClient { + fn from(value: TypescriptClient) -> Self { + Self { + funcs: value.funcs, + types: value.types, + } + } +} + struct TypescriptFunction { name: String, // partial_return_type: String, @@ -26,7 +60,9 @@ struct TypescriptFunction { #[derive(askama::Template)] #[template(path = "index.ts.j2", escape = "none")] -struct TypescriptInit {} +struct TypescriptInit { + default_client_mode: GeneratorDefaultClientMode, +} #[derive(askama::Template)] #[template(path = "globals.ts.j2", escape = "none")] @@ -51,7 +87,8 @@ pub(crate) fn generate( let mut collector = FileCollector::::new(); collector.add_template::("types.ts", (ir, generator))?; collector.add_template::("type_builder.ts", (ir, generator))?; - collector.add_template::("client.ts", (ir, generator))?; + collector.add_template::("async_client.ts", (ir, generator))?; + collector.add_template::("sync_client.ts", (ir, generator))?; collector.add_template::("globals.ts", (ir, generator))?; collector.add_template::("tracing.ts", (ir, generator))?; collector.add_template::("index.ts", (ir, generator))?; @@ -60,6 +97,24 @@ pub(crate) fn generate( collector.commit(&generator.output_dir()) } +impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for AsyncTypescriptClient { + type Error = anyhow::Error; + + fn try_from(params: (&'_ IntermediateRepr, &'_ crate::GeneratorArgs)) -> Result { + let typscript_client = TypescriptClient::try_from(params)?; + Ok(typscript_client.into()) + } +} + +impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for SyncTypescriptClient { + type Error = anyhow::Error; + + fn try_from(params: (&'_ IntermediateRepr, &'_ crate::GeneratorArgs)) -> Result { + let typscript_client = TypescriptClient::try_from(params)?; + Ok(typscript_client.into()) + } +} + impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for TypescriptClient { type Error = anyhow::Error; @@ -136,8 +191,10 @@ impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for TypescriptTra impl TryFrom<(&'_ IntermediateRepr, &'_ crate::GeneratorArgs)> for TypescriptInit { type Error = anyhow::Error; - fn try_from(_: (&IntermediateRepr, &crate::GeneratorArgs)) -> Result { - Ok(TypescriptInit {}) + fn try_from((_, gen): (&IntermediateRepr, &crate::GeneratorArgs)) -> Result { + Ok(TypescriptInit { + default_client_mode: gen.default_client_mode.clone(), + }) } } diff --git a/engine/language-client-codegen/src/typescript/templates/client.ts.j2 b/engine/language-client-codegen/src/typescript/templates/async_client.ts.j2 similarity index 88% rename from engine/language-client-codegen/src/typescript/templates/client.ts.j2 rename to engine/language-client-codegen/src/typescript/templates/async_client.ts.j2 index b6078c56f..a3192659f 100644 --- a/engine/language-client-codegen/src/typescript/templates/client.ts.j2 +++ b/engine/language-client-codegen/src/typescript/templates/async_client.ts.j2 @@ -3,6 +3,7 @@ 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" export type RecursivePartialNull = T extends object ? { @@ -10,7 +11,7 @@ export type RecursivePartialNull = T extends object } : T | null; -export class BamlClient { +export class BamlAsyncClient { private runtime: BamlRuntime private ctx_manager: BamlCtxManager private stream_client: BamlStreamClient @@ -79,4 +80,6 @@ class BamlStreamClient { ) } {% endfor %} -} \ No newline at end of file +} + +export const b = new BamlAsyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) diff --git a/engine/language-client-codegen/src/typescript/templates/globals.ts.j2 b/engine/language-client-codegen/src/typescript/templates/globals.ts.j2 index 80bf0ed2d..0c04c73d2 100644 --- a/engine/language-client-codegen/src/typescript/templates/globals.ts.j2 +++ b/engine/language-client-codegen/src/typescript/templates/globals.ts.j2 @@ -1,5 +1,4 @@ import { BamlCtxManager, BamlRuntime } from '@boundaryml/baml' -import { BamlClient } from './client' import { getBamlFiles } from './inlinedbaml' @@ -9,4 +8,3 @@ export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = Baml process.env ) export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = new BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME) -export const b = new BamlClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) diff --git a/engine/language-client-codegen/src/typescript/templates/index.ts.j2 b/engine/language-client-codegen/src/typescript/templates/index.ts.j2 index c1a1a825f..d90145577 100644 --- a/engine/language-client-codegen/src/typescript/templates/index.ts.j2 +++ b/engine/language-client-codegen/src/typescript/templates/index.ts.j2 @@ -1,3 +1,7 @@ -export { b } from "./globals" +{% if default_client_mode == GeneratorDefaultClientMode::Async %} +export { b } from "./async_client" +{% else %} +export { b } from "./sync_client" +{% endif %} export * from "./types" -export * from "./tracing" \ No newline at end of file +export * from "./tracing" diff --git a/engine/language-client-codegen/src/typescript/templates/sync_client.ts.j2 b/engine/language-client-codegen/src/typescript/templates/sync_client.ts.j2 new file mode 100644 index 000000000..57b14144e --- /dev/null +++ b/engine/language-client-codegen/src/typescript/templates/sync_client.ts.j2 @@ -0,0 +1,56 @@ +import { BamlRuntime, FunctionResult, BamlCtxManager, BamlSyncStream, Image, ClientBuilder } from "@boundaryml/baml" +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" + +export type RecursivePartialNull = T extends object + ? { + [P in keyof T]?: RecursivePartialNull; + } + : T | null; + +export class BamlSyncClient { + private runtime: BamlRuntime + private ctx_manager: BamlCtxManager + + constructor(runtime: BamlRuntime, ctx_manager: BamlCtxManager) { + this.runtime = runtime + this.ctx_manager = ctx_manager + this.stream_client = new BamlStreamClient(runtime, ctx_manager) + } + + /* + * @deprecated NOT IMPLEMENTED as streaming must by async. We + * are not providing an async version as we want to reserve the + * right to provide a sync version in the future. + */ + get stream() { + throw new Error("stream is not available in BamlSyncClient. Use `import { b } from 'baml_client/async_client") + } + + {% for fn in funcs %} + {{ fn.name }}( + {% for (name, optional, type) in fn.args -%} + {{name}}{% if optional %}?{% endif %}: {{type}}, + {%- endfor %} + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): {{fn.return_type}} { + const raw = this.runtime.callFunctionSync( + "{{fn.name}}", + { + {% for (name, optional, type) in fn.args -%} + "{{name}}": {{name}}{% if optional %}?? null{% endif %}{% if !loop.last %},{% endif %} + {%- endfor %} + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as {{fn.return_type}} + } + {% endfor %} +} + +export const b = new BamlSyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) diff --git a/engine/language_client_python/python_src/baml_py/__init__.py b/engine/language_client_python/python_src/baml_py/__init__.py index 6e7a3e17e..f37ed90b6 100644 --- a/engine/language_client_python/python_src/baml_py/__init__.py +++ b/engine/language_client_python/python_src/baml_py/__init__.py @@ -10,13 +10,14 @@ invoke_runtime_cli, ClientRegistry, ) -from .stream import BamlStream +from .stream import BamlStream, BamlSyncStream from .ctx_manager import CtxManager as BamlCtxManager __all__ = [ "BamlRuntime", "ClientRegistry", "BamlStream", + "BamlSyncStream", "BamlCtxManager", "FunctionResult", "FunctionResultStream", diff --git a/engine/language_client_python/python_src/baml_py/baml_py.pyi b/engine/language_client_python/python_src/baml_py/baml_py.pyi index 693c241cd..365a2b9b2 100644 --- a/engine/language_client_python/python_src/baml_py/baml_py.pyi +++ b/engine/language_client_python/python_src/baml_py/baml_py.pyi @@ -31,6 +31,20 @@ class FunctionResultStream: ) -> FunctionResultStream: ... async def done(self, ctx: RuntimeContextManager) -> FunctionResult: ... +class SyncFunctionResultStream: + """The result of a BAML function stream. + + Provides a callback interface to receive events from a BAML result stream. + + Use `on_event` to set the callback, and `done` to drive the stream to completion. + """ + + def __str__(self) -> str: ... + def on_event( + self, on_event: Callable[[FunctionResult], None] + ) -> SyncFunctionResultStream: ... + def done(self, ctx: RuntimeContextManager) -> FunctionResult: ... + class BamlImagePy: @staticmethod def from_url(url: str) -> BamlImagePy: ... @@ -79,6 +93,15 @@ class BamlRuntime: tb: Optional[TypeBuilder], cr: Optional[ClientRegistry], ) -> FunctionResultStream: ... + def stream_function_sync( + self, + function_name: str, + args: Dict[str, Any], + on_event: Optional[Callable[[FunctionResult], None]], + ctx: RuntimeContextManager, + tb: Optional[TypeBuilder], + cr: Optional[ClientRegistry], + ) -> SyncFunctionResultStream: ... def create_context_manager(self) -> RuntimeContextManager: ... def flush(self) -> None: ... def drain_stats(self) -> TraceStats: ... diff --git a/engine/language_client_python/python_src/baml_py/ctx_manager.py b/engine/language_client_python/python_src/baml_py/ctx_manager.py index cb8049f9a..c63c7c1dd 100644 --- a/engine/language_client_python/python_src/baml_py/ctx_manager.py +++ b/engine/language_client_python/python_src/baml_py/ctx_manager.py @@ -20,7 +20,9 @@ def current_thread_id() -> int: current_thread = threading.current_thread() - return current_thread.native_id or 0 + if hasattr(current_thread, "native_id"): + return current_thread.native_id or 0 + return current_thread.ident or 0 class CtxManager: diff --git a/engine/language_client_python/python_src/baml_py/stream.py b/engine/language_client_python/python_src/baml_py/stream.py index 91da360cd..695deb517 100644 --- a/engine/language_client_python/python_src/baml_py/stream.py +++ b/engine/language_client_python/python_src/baml_py/stream.py @@ -2,9 +2,10 @@ from .baml_py import ( FunctionResult, FunctionResultStream, + SyncFunctionResultStream, RuntimeContextManager, ) -from typing import Callable, Generic, Optional, TypeVar +from typing import Callable, Generic, Optional, TypeVar, Union import threading import asyncio import concurrent.futures @@ -43,7 +44,6 @@ def __enqueue(self, data: FunctionResult) -> None: self.__event_queue.put_nowait(data) async def __drive_to_completion(self) -> FunctionResult: - try: retval = await self.__ffi_stream.done(self.__ctx_manager) @@ -78,3 +78,85 @@ async def __aiter__(self): async def get_final_response(self): final = self.__drive_to_completion_in_bg() return self.__final_coerce((await asyncio.wrap_future(final)).parsed()) + + +class BamlSyncStream(Generic[PartialOutputType, FinalOutputType]): + __ffi_stream: SyncFunctionResultStream + __partial_coerce: Callable[[FunctionResult], PartialOutputType] + __final_coerce: Callable[[FunctionResult], FinalOutputType] + __ctx_manager: RuntimeContextManager + __task: Optional[threading.Thread] + __event_queue: queue.Queue[Optional[FunctionResult]] + __result: Optional[FunctionResult] + __exception: Optional[Exception] + + def __init__( + self, + ffi_stream: SyncFunctionResultStream, + partial_coerce: Callable[[FunctionResult], PartialOutputType], + final_coerce: Callable[[FunctionResult], FinalOutputType], + ctx_manager: RuntimeContextManager, + ): + self.__ffi_stream = ffi_stream.on_event(self.__enqueue) + self.__partial_coerce = partial_coerce + self.__final_coerce = final_coerce + self.__ctx_manager = ctx_manager + self.__task = None + self.__event_queue = queue.Queue() + self.__result = None + self.__exception = None + + def __enqueue(self, data: FunctionResult) -> None: + print("Enqueuing data") + self.__event_queue.put_nowait(data) + + def __drive_to_completion(self) -> FunctionResult: + try: + print(f"Driving to completion: {type(self.__ffi_stream)}") + retval = self.__ffi_stream.done(self.__ctx_manager) + print(f"Setting result: {type(retval)}") + self.__result = retval + return retval + except Exception as e: + self.__exception = e + raise e + finally: + print("Putting None in queue") + self.__event_queue.put_nowait(None) + + def __drive_to_completion_in_bg(self): + if self.__task is None: + self.__task = threading.Thread(target=self.__threading_target, daemon=True) + self.__task.start() + + def __threading_target(self): + self.__drive_to_completion() + + def __iter__(self): + # TODO: This is deliberately __iter__ and not __aiter__ because we want to + # ensure that the caller is NOT using an async for loop. + self.__drive_to_completion_in_bg() + while True: + event = self.__event_queue.get() + if event is None: + print("Breaking out of loop") + break + yield self.__partial_coerce(event.parsed()) + + def get_final_response(self): + print("Getting final response") + self.__drive_to_completion_in_bg() + if self.__task is not None: + print("Waiting for task to complete") + self.__task.join() + else: + print("Task is None") + + if self.__exception is not None: + print("Raising exception") + raise self.__exception + + if self.__result is None: + raise Exception("BAML Internal error: Stream did not complete successfully. Please report this issue.") + + return self.__final_coerce(self.__result.parsed()) diff --git a/engine/language_client_python/src/lib.rs b/engine/language_client_python/src/lib.rs index ab569961d..ceecf9bae 100644 --- a/engine/language_client_python/src/lib.rs +++ b/engine/language_client_python/src/lib.rs @@ -38,6 +38,7 @@ fn baml_py(_: Python<'_>, m: Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; m.add_class::()?; + m.add_class::()?; m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/engine/language_client_python/src/runtime.rs b/engine/language_client_python/src/runtime.rs index d7e1bd345..94e506a51 100644 --- a/engine/language_client_python/src/runtime.rs +++ b/engine/language_client_python/src/runtime.rs @@ -3,7 +3,7 @@ use crate::types::function_results::FunctionResult; use crate::types::trace_stats::TraceStats; use crate::BamlError; -use crate::types::function_result_stream::FunctionResultStream; +use crate::types::function_result_stream::{FunctionResultStream, SyncFunctionResultStream}; use crate::types::runtime_ctx_manager::RuntimeContextManager; use crate::types::type_builder::TypeBuilder; use crate::types::ClientRegistry; @@ -139,6 +139,42 @@ impl BamlRuntime { .map(|f| f.into()) } + #[pyo3(signature = (function_name, args, ctx, tb, cb))] + fn call_function_sync( + &self, + function_name: String, + args: PyObject, + ctx: &RuntimeContextManager, + tb: Option<&TypeBuilder>, + cb: Option<&ClientRegistry>, + ) -> PyResult { + let Some(args) = parse_py_type(args, false)? else { + return Err(BamlError::new_err( + "Failed to parse args, perhaps you used a non-serializable type?", + )); + }; + let Some(args_map) = args.as_map_owned() else { + return Err(BamlError::new_err("Failed to parse args")); + }; + log::debug!("pyo3 call_function_sync parsed args into: {:#?}", args_map); + + let ctx_mng = ctx.inner.clone(); + let tb = tb.map(|tb| tb.inner.clone()); + let cb = cb.map(|cb| cb.inner.clone()); + + let (result, _event_id) = self.inner.call_function_sync( + function_name, + &args_map, + &ctx_mng, + tb.as_ref(), + cb.as_ref(), + ); + + result + .map(FunctionResult::from) + .map_err(BamlError::from_anyhow) + } + #[pyo3(signature = (function_name, args, on_event, ctx, tb, cb))] fn stream_function( &self, @@ -180,6 +216,47 @@ impl BamlRuntime { )) } + #[pyo3(signature = (function_name, args, on_event, ctx, tb, cb))] + fn stream_function_sync( + &self, + py: Python<'_>, + function_name: String, + args: PyObject, + on_event: Option, + ctx: &RuntimeContextManager, + tb: Option<&TypeBuilder>, + cb: Option<&ClientRegistry>, + ) -> PyResult { + let Some(args) = parse_py_type(args.into_bound(py).to_object(py), false)? else { + return Err(BamlError::new_err( + "Failed to parse args, perhaps you used a non-serializable type?", + )); + }; + let Some(args_map) = args.as_map() else { + return Err(BamlError::new_err("Failed to parse args")); + }; + log::debug!("pyo3 stream_function parsed args into: {:#?}", args_map); + + let ctx = ctx.inner.clone(); + let stream = self + .inner + .stream_function( + function_name, + args_map, + &ctx, + tb.map(|tb| tb.inner.clone()).as_ref(), + cb.map(|cb| cb.inner.clone()).as_ref(), + ) + .map_err(BamlError::from_anyhow)?; + + Ok(SyncFunctionResultStream::new( + stream, + on_event, + tb.map(|tb| tb.inner.clone()), + cb.map(|cb| cb.inner.clone()), + )) + } + #[pyo3()] fn flush(&self) -> PyResult<()> { self.inner.flush().map_err(BamlError::from_anyhow) @@ -195,7 +272,7 @@ impl BamlRuntime { let callback = callback.clone(); let baml_runtime = self.inner.clone(); - let res = baml_runtime + baml_runtime .as_ref() .set_log_event_callback(Box::new(move |log_event| { Python::with_gil(|py| { @@ -220,8 +297,7 @@ impl BamlRuntime { } } }) - })); - - Ok(()) + })) + .map_err(BamlError::from_anyhow) } } diff --git a/engine/language_client_python/src/types/function_result_stream.rs b/engine/language_client_python/src/types/function_result_stream.rs index e90048758..f0be61b20 100644 --- a/engine/language_client_python/src/types/function_result_stream.rs +++ b/engine/language_client_python/src/types/function_result_stream.rs @@ -14,6 +14,14 @@ crate::lang_wrapper!( cb: Option ); +crate::lang_wrapper!( + SyncFunctionResultStream, + baml_runtime::FunctionResultStream, sync_thread_safe, + on_event: Option, + tb: Option, + cb: Option +); + impl FunctionResultStream { pub(crate) fn new( inner: baml_runtime::FunctionResultStream, @@ -30,6 +38,22 @@ impl FunctionResultStream { } } +impl SyncFunctionResultStream { + pub(crate) fn new( + inner: baml_runtime::FunctionResultStream, + event: Option, + tb: Option, + cb: Option, + ) -> Self { + Self { + inner: std::sync::Arc::new(std::sync::Mutex::new(inner)), + on_event: event, + tb, + cb, + } + } +} + #[pymethods] impl FunctionResultStream { fn __str__(&self) -> String { @@ -78,3 +102,49 @@ impl FunctionResultStream { .map(|f| f.into()) } } + +#[pymethods] +impl SyncFunctionResultStream { + fn __str__(&self) -> String { + format!("SyncFunctionResultStream") + } + + /// Set the callback to be called when an event is received + /// + /// Callback will take an instance of FunctionResult + fn on_event<'p>( + mut slf: PyRefMut<'p, Self>, + py: Python<'p>, + on_event_cb: PyObject, + ) -> PyRefMut<'p, Self> { + slf.on_event = Some(on_event_cb.clone_ref(py)); + + slf + } + + fn done(&self, ctx: &RuntimeContextManager) -> PyResult { + let inner = self.inner.clone(); + + let on_event = self.on_event.as_ref().map(|cb| { + let cb = Python::with_gil(|py| cb.clone_ref(py)); + move |event| { + let partial = FunctionResult::from(event); + let res = Python::with_gil(|py| cb.call1(py, (partial,))).map(|_| ()); + if let Err(e) = res { + log::error!("Error calling on_event callback: {:?}", e); + } + } + }); + + let ctx_mng = ctx.inner.clone(); + let tb = self.tb.as_ref().map(|tb| tb.clone()); + let cb = self.cb.as_ref().map(|cb| cb.clone()); + + let ctx_mng = ctx_mng; + let mut locked = inner.lock().unwrap(); + let (res, _) = locked.run_sync(on_event, &ctx_mng, tb.as_ref(), cb.as_ref()); + res.map(FunctionResult::from) + .map_err(BamlError::from_anyhow) + .map(|f| f.into()) + } +} diff --git a/engine/language_client_python/src/types/mod.rs b/engine/language_client_python/src/types/mod.rs index 024c83f96..223a5f9a7 100644 --- a/engine/language_client_python/src/types/mod.rs +++ b/engine/language_client_python/src/types/mod.rs @@ -12,7 +12,7 @@ pub(crate) mod trace_stats; pub(crate) mod type_builder; pub use audio::BamlAudioPy; -pub use function_result_stream::FunctionResultStream; +pub use function_result_stream::{FunctionResultStream, SyncFunctionResultStream}; pub use function_results::FunctionResult; pub use image::BamlImagePy; diff --git a/engine/language_client_typescript/native.d.ts b/engine/language_client_typescript/native.d.ts index 1cf9e94dd..01b214faa 100644 --- a/engine/language_client_typescript/native.d.ts +++ b/engine/language_client_typescript/native.d.ts @@ -23,7 +23,9 @@ export class BamlRuntime { static fromFiles(rootPath: string, files: Record, envVars: Record): BamlRuntime createContextManager(): RuntimeContextManager callFunction(functionName: string, args: { [string]: any }, ctx: RuntimeContextManager, tb?: TypeBuilder | undefined | null, cb?: ClientRegistry | undefined | null): Promise + callFunctionSync(functionName: string, args: { [string]: any }, ctx: RuntimeContextManager, tb?: TypeBuilder | undefined | null, cb?: ClientRegistry | undefined | null): FunctionResult streamFunction(functionName: string, args: { [string]: any }, cb: (err: any, param: FunctionResult) => void, ctx: RuntimeContextManager, tb?: TypeBuilder | undefined | null, clientRegistry?: ClientRegistry | undefined | null): FunctionResultStream + streamFunctionSync(functionName: string, args: { [string]: any }, cb: (err: any, param: FunctionResult) => void, ctx: RuntimeContextManager, tb?: TypeBuilder | undefined | null, clientRegistry?: ClientRegistry | undefined | null): FunctionResultStream setLogEventCallback(func: (err: any, param: BamlLogEvent) => void): void flush(): void drainStats(): TraceStats diff --git a/engine/language_client_typescript/src/runtime.rs b/engine/language_client_typescript/src/runtime.rs index 96334c1a0..91fa9448e 100644 --- a/engine/language_client_typescript/src/runtime.rs +++ b/engine/language_client_typescript/src/runtime.rs @@ -118,6 +118,45 @@ impl BamlRuntime { env.execute_tokio_future(fut, |&mut _, data| Ok(data)) } + #[napi] + pub fn call_function_sync( + &self, + env: Env, + function_name: String, + #[napi(ts_arg_type = "{ [string]: any }")] args: JsObject, + ctx: &RuntimeContextManager, + tb: Option<&TypeBuilder>, + cb: Option<&ClientRegistry>, + ) -> napi::Result { + let args = parse_ts_types::js_object_to_baml_value(env, args)?; + + if !args.is_map() { + return Err(napi::Error::new( + napi::Status::GenericFailure, + format!( + "Invalid args: Expected a map of arguments, got: {}", + args.r#type() + ), + )); + } + let args_map = args.as_map_owned().unwrap(); + + let ctx_mng = ctx.inner.clone(); + let tb = tb.map(|tb| tb.inner.clone()); + let cb = cb.map(|cb| cb.inner.clone()); + let (result, _event_id) = self.inner.call_function_sync( + function_name, + &args_map, + &ctx_mng, + tb.as_ref(), + cb.as_ref(), + ); + + result + .map(FunctionResult::from) + .map_err(|e| napi::Error::new(napi::Status::GenericFailure, e.to_string())) + } + #[napi] pub fn stream_function( &self, @@ -163,6 +202,51 @@ impl BamlRuntime { Ok(FunctionResultStream::new(stream, cb, tb, client_registry)) } + #[napi] + pub fn stream_function_sync( + &self, + env: Env, + function_name: String, + #[napi(ts_arg_type = "{ [string]: any }")] args: JsObject, + #[napi(ts_arg_type = "(err: any, param: FunctionResult) => void")] cb: Option, + ctx: &RuntimeContextManager, + tb: Option<&TypeBuilder>, + client_registry: Option<&ClientRegistry>, + ) -> napi::Result { + let args: BamlValue = parse_ts_types::js_object_to_baml_value(env, args)?; + if !args.is_map() { + return Err(napi::Error::new( + napi::Status::GenericFailure, + format!( + "Invalid args: Expected a map of arguments, got: {}", + args.r#type() + ), + )); + } + let args_map = args.as_map_owned().unwrap(); + + let ctx = ctx.inner.clone(); + let tb = tb.map(|tb| tb.inner.clone()); + let client_registry = client_registry.map(|cb| cb.inner.clone()); + let stream = self + .inner + .stream_function( + function_name, + &args_map, + &ctx, + tb.as_ref(), + client_registry.as_ref(), + ) + .map_err(|e| napi::Error::new(napi::Status::GenericFailure, e.to_string()))?; + + let cb = match cb { + Some(cb) => Some(env.create_reference(cb)?), + None => None, + }; + + Ok(FunctionResultStream::new(stream, cb, tb, client_registry)) + } + #[napi] pub fn set_log_event_callback( &mut self, diff --git a/integ-tests/python/README.md b/integ-tests/python/README.md index de458c20b..d390cc2c3 100644 --- a/integ-tests/python/README.md +++ b/integ-tests/python/README.md @@ -5,5 +5,5 @@ infisical run --env=dev -- poetry run pytest app/test_functions.py env -u CONDA_PREFIX poetry run maturin develop --manifest-path ../../engine/language_client_python/Cargo.toml && poetry run baml-cli generate --from ../baml_src -BAML_LOG=baml_events infisical run --env=dev -- poetry run pytest app/test_functions.py -s +BAML_LOG=baml_events infisical run --env=test -- poetry run pytest app/test_functions.py -s ``` diff --git a/integ-tests/python/baml_client/__init__.py b/integ-tests/python/baml_client/__init__.py index 3a976b803..130de23d5 100644 --- a/integ-tests/python/baml_client/__init__.py +++ b/integ-tests/python/baml_client/__init__.py @@ -13,11 +13,13 @@ # flake8: noqa: E501,F401 # pylint: disable=unused-import,line-too-long # fmt: off -from .globals import b from . import types from . import tracing from . import partial_types +from .async_client import b + + __all__ = [ "b", diff --git a/integ-tests/python/baml_client/client.py b/integ-tests/python/baml_client/async_client.py similarity index 99% rename from integ-tests/python/baml_client/client.py rename to integ-tests/python/baml_client/async_client.py index e67acb441..a053d1b3e 100644 --- a/integ-tests/python/baml_client/client.py +++ b/integ-tests/python/baml_client/async_client.py @@ -22,6 +22,8 @@ from . import partial_types, types from .type_builder import TypeBuilder +from .globals import DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME + OutputType = TypeVar('OutputType') @@ -41,7 +43,7 @@ class BamlCallOptions(TypedDict, total=False): tb: NotRequired[TypeBuilder] client_registry: NotRequired[baml_py.baml_py.ClientRegistry] -class BamlClient: +class BamlAsyncClient: __runtime: baml_py.BamlRuntime __ctx_manager: baml_py.BamlCtxManager __stream_client: "BamlStreamClient" @@ -55,6 +57,7 @@ def __init__(self, runtime: baml_py.BamlRuntime, ctx_manager: baml_py.BamlCtxMan def stream(self): return self.__stream_client + async def AudioInput( self, @@ -1593,6 +1596,7 @@ async def UnionTest_Function( return coerce(mdl, raw.parsed()) + class BamlStreamClient: __runtime: baml_py.BamlRuntime __ctx_manager: baml_py.BamlCtxManager @@ -3715,4 +3719,8 @@ def UnionTest_Function( lambda x: coerce(mdl, x), self.__ctx_manager.get(), ) - \ No newline at end of file + + +b = BamlAsyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) + +__all__ = ["b"] \ No newline at end of file diff --git a/integ-tests/python/baml_client/globals.py b/integ-tests/python/baml_client/globals.py index 4db980cea..d23389f49 100644 --- a/integ-tests/python/baml_client/globals.py +++ b/integ-tests/python/baml_client/globals.py @@ -16,7 +16,6 @@ import os from baml_py import BamlCtxManager, BamlRuntime -from .client import BamlClient from .inlinedbaml import get_baml_files DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = BamlRuntime.from_files( @@ -26,6 +25,4 @@ ) DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME) -b = BamlClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) - -__all__ = ['b'] \ No newline at end of file +__all__ = [] \ No newline at end of file diff --git a/integ-tests/python/baml_client/sync_client.py b/integ-tests/python/baml_client/sync_client.py new file mode 100644 index 000000000..5c8c27dce --- /dev/null +++ b/integ-tests/python/baml_client/sync_client.py @@ -0,0 +1,3725 @@ +############################################################################### +# +# Welcome to Baml! To use this generated code, please run the following: +# +# $ pip install baml +# +############################################################################### + +# This file was generated by BAML: please do not edit it. Instead, edit the +# BAML files and re-generate this code. +# +# ruff: noqa: E501,F401 +# flake8: noqa: E501,F401 +# pylint: disable=unused-import,line-too-long +# fmt: off +from typing import Any, List, Optional, TypeVar, Union, TypedDict, Type +from typing_extensions import NotRequired +import pprint + +import baml_py +from pydantic import BaseModel, ValidationError, create_model + +from . import partial_types, types +from .type_builder import TypeBuilder +from .globals import DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME + +OutputType = TypeVar('OutputType') + +def coerce(cls: Type[BaseModel], parsed: Any) -> Any: + try: + return cls.model_validate({"inner": parsed}).inner # type: ignore + except ValidationError as e: + raise TypeError( + "Internal BAML error while casting output to {}\n{}".format( + cls.__name__, + pprint.pformat(parsed) + ) + ) from e + +# Define the TypedDict with optional parameters having default values +class BamlCallOptions(TypedDict, total=False): + tb: NotRequired[TypeBuilder] + client_registry: NotRequired[baml_py.baml_py.ClientRegistry] + +class BamlSyncClient: + __runtime: baml_py.BamlRuntime + __ctx_manager: baml_py.BamlCtxManager + __stream_client: "BamlStreamClient" + + def __init__(self, runtime: baml_py.BamlRuntime, ctx_manager: baml_py.BamlCtxManager): + self.__runtime = runtime + self.__ctx_manager = ctx_manager + self.__stream_client = BamlStreamClient(self.__runtime, self.__ctx_manager) + + @property + def stream(self): + return self.__stream_client + + + def AudioInput( + self, + aud: baml_py.Audio, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "AudioInput", + { + "aud": aud, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("AudioInputReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def ClassifyMessage( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.Category: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "ClassifyMessage", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("ClassifyMessageReturnType", inner=(types.Category, ...)) + return coerce(mdl, raw.parsed()) + + def ClassifyMessage2( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.Category: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "ClassifyMessage2", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("ClassifyMessage2ReturnType", inner=(types.Category, ...)) + return coerce(mdl, raw.parsed()) + + def ClassifyMessage3( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.Category: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "ClassifyMessage3", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("ClassifyMessage3ReturnType", inner=(types.Category, ...)) + return coerce(mdl, raw.parsed()) + + def DescribeImage( + self, + img: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "DescribeImage", + { + "img": img, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("DescribeImageReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def DescribeImage2( + self, + classWithImage: types.ClassWithImage,img2: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "DescribeImage2", + { + "classWithImage": classWithImage,"img2": img2, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("DescribeImage2ReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def DescribeImage3( + self, + classWithImage: types.ClassWithImage,img2: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "DescribeImage3", + { + "classWithImage": classWithImage,"img2": img2, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("DescribeImage3ReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def DescribeImage4( + self, + classWithImage: types.ClassWithImage,img2: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "DescribeImage4", + { + "classWithImage": classWithImage,"img2": img2, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("DescribeImage4ReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def DummyOutputFunction( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.DummyOutput: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "DummyOutputFunction", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("DummyOutputFunctionReturnType", inner=(types.DummyOutput, ...)) + return coerce(mdl, raw.parsed()) + + def DynamicFunc( + self, + input: types.DynamicClassOne, + baml_options: BamlCallOptions = {}, + ) -> types.DynamicClassTwo: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "DynamicFunc", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("DynamicFuncReturnType", inner=(types.DynamicClassTwo, ...)) + return coerce(mdl, raw.parsed()) + + def DynamicInputOutput( + self, + input: types.DynInputOutput, + baml_options: BamlCallOptions = {}, + ) -> types.DynInputOutput: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "DynamicInputOutput", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("DynamicInputOutputReturnType", inner=(types.DynInputOutput, ...)) + return coerce(mdl, raw.parsed()) + + def DynamicListInputOutput( + self, + input: List[types.DynInputOutput], + baml_options: BamlCallOptions = {}, + ) -> List[types.DynInputOutput]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "DynamicListInputOutput", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("DynamicListInputOutputReturnType", inner=(List[types.DynInputOutput], ...)) + return coerce(mdl, raw.parsed()) + + def ExtractNames( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> List[str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "ExtractNames", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("ExtractNamesReturnType", inner=(List[str], ...)) + return coerce(mdl, raw.parsed()) + + def ExtractPeople( + self, + text: str, + baml_options: BamlCallOptions = {}, + ) -> List[types.Person]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "ExtractPeople", + { + "text": text, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("ExtractPeopleReturnType", inner=(List[types.Person], ...)) + return coerce(mdl, raw.parsed()) + + def ExtractReceiptInfo( + self, + email: str, + baml_options: BamlCallOptions = {}, + ) -> types.ReceiptInfo: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "ExtractReceiptInfo", + { + "email": email, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("ExtractReceiptInfoReturnType", inner=(types.ReceiptInfo, ...)) + return coerce(mdl, raw.parsed()) + + def ExtractResume( + self, + resume: str,img: Optional[baml_py.Image], + baml_options: BamlCallOptions = {}, + ) -> types.Resume: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "ExtractResume", + { + "resume": resume,"img": img, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("ExtractResumeReturnType", inner=(types.Resume, ...)) + return coerce(mdl, raw.parsed()) + + def ExtractResume2( + self, + resume: str, + baml_options: BamlCallOptions = {}, + ) -> types.Resume: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "ExtractResume2", + { + "resume": resume, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("ExtractResume2ReturnType", inner=(types.Resume, ...)) + return coerce(mdl, raw.parsed()) + + def FnClassOptionalOutput( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> Optional[types.ClassOptionalOutput]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnClassOptionalOutput", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnClassOptionalOutputReturnType", inner=(Optional[types.ClassOptionalOutput], ...)) + return coerce(mdl, raw.parsed()) + + def FnClassOptionalOutput2( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> Optional[types.ClassOptionalOutput2]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnClassOptionalOutput2", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnClassOptionalOutput2ReturnType", inner=(Optional[types.ClassOptionalOutput2], ...)) + return coerce(mdl, raw.parsed()) + + def FnEnumListOutput( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> List[types.EnumOutput]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnEnumListOutput", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnEnumListOutputReturnType", inner=(List[types.EnumOutput], ...)) + return coerce(mdl, raw.parsed()) + + def FnEnumOutput( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.EnumOutput: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnEnumOutput", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnEnumOutputReturnType", inner=(types.EnumOutput, ...)) + return coerce(mdl, raw.parsed()) + + def FnNamedArgsSingleStringOptional( + self, + myString: Optional[str], + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnNamedArgsSingleStringOptional", + { + "myString": myString, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnNamedArgsSingleStringOptionalReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def FnOutputBool( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> bool: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnOutputBool", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnOutputBoolReturnType", inner=(bool, ...)) + return coerce(mdl, raw.parsed()) + + def FnOutputClass( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.TestOutputClass: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnOutputClass", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnOutputClassReturnType", inner=(types.TestOutputClass, ...)) + return coerce(mdl, raw.parsed()) + + def FnOutputClassList( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> List[types.TestOutputClass]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnOutputClassList", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnOutputClassListReturnType", inner=(List[types.TestOutputClass], ...)) + return coerce(mdl, raw.parsed()) + + def FnOutputClassNested( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.TestClassNested: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnOutputClassNested", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnOutputClassNestedReturnType", inner=(types.TestClassNested, ...)) + return coerce(mdl, raw.parsed()) + + def FnOutputClassWithEnum( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.TestClassWithEnum: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnOutputClassWithEnum", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnOutputClassWithEnumReturnType", inner=(types.TestClassWithEnum, ...)) + return coerce(mdl, raw.parsed()) + + def FnOutputStringList( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> List[str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnOutputStringList", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnOutputStringListReturnType", inner=(List[str], ...)) + return coerce(mdl, raw.parsed()) + + def FnTestAliasedEnumOutput( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.TestEnum: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnTestAliasedEnumOutput", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnTestAliasedEnumOutputReturnType", inner=(types.TestEnum, ...)) + return coerce(mdl, raw.parsed()) + + def FnTestClassAlias( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.TestClassAlias: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnTestClassAlias", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnTestClassAliasReturnType", inner=(types.TestClassAlias, ...)) + return coerce(mdl, raw.parsed()) + + def FnTestNamedArgsSingleEnum( + self, + myArg: types.NamedArgsSingleEnum, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "FnTestNamedArgsSingleEnum", + { + "myArg": myArg, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("FnTestNamedArgsSingleEnumReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def GetDataType( + self, + text: str, + baml_options: BamlCallOptions = {}, + ) -> types.RaysData: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "GetDataType", + { + "text": text, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("GetDataTypeReturnType", inner=(types.RaysData, ...)) + return coerce(mdl, raw.parsed()) + + def GetOrderInfo( + self, + email: types.Email, + baml_options: BamlCallOptions = {}, + ) -> types.OrderInfo: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "GetOrderInfo", + { + "email": email, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("GetOrderInfoReturnType", inner=(types.OrderInfo, ...)) + return coerce(mdl, raw.parsed()) + + def GetQuery( + self, + query: str, + baml_options: BamlCallOptions = {}, + ) -> types.SearchParams: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "GetQuery", + { + "query": query, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("GetQueryReturnType", inner=(types.SearchParams, ...)) + return coerce(mdl, raw.parsed()) + + def MyFunc( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> types.DynamicOutput: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "MyFunc", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("MyFuncReturnType", inner=(types.DynamicOutput, ...)) + return coerce(mdl, raw.parsed()) + + def OptionalTest_Function( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> List[Optional[types.OptionalTest_ReturnType]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "OptionalTest_Function", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("OptionalTest_FunctionReturnType", inner=(List[Optional[types.OptionalTest_ReturnType]], ...)) + return coerce(mdl, raw.parsed()) + + def PromptTestClaude( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "PromptTestClaude", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("PromptTestClaudeReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def PromptTestClaudeChat( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "PromptTestClaudeChat", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("PromptTestClaudeChatReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def PromptTestClaudeChatNoSystem( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "PromptTestClaudeChatNoSystem", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("PromptTestClaudeChatNoSystemReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def PromptTestOpenAI( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "PromptTestOpenAI", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("PromptTestOpenAIReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def PromptTestOpenAIChat( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "PromptTestOpenAIChat", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("PromptTestOpenAIChatReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def PromptTestOpenAIChatNoSystem( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "PromptTestOpenAIChatNoSystem", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("PromptTestOpenAIChatNoSystemReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def PromptTestStreaming( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "PromptTestStreaming", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("PromptTestStreamingReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestAnthropic( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestAnthropic", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestAnthropicReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestAws( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestAws", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestAwsReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestAzure( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestAzure", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestAzureReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFallbackClient( + self, + + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFallbackClient", + { + + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFallbackClientReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFnNamedArgsSingleBool( + self, + myBool: bool, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFnNamedArgsSingleBool", + { + "myBool": myBool, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFnNamedArgsSingleBoolReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFnNamedArgsSingleClass( + self, + myArg: types.NamedArgsSingleClass, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFnNamedArgsSingleClass", + { + "myArg": myArg, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFnNamedArgsSingleClassReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFnNamedArgsSingleEnumList( + self, + myArg: List[types.NamedArgsSingleEnumList], + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFnNamedArgsSingleEnumList", + { + "myArg": myArg, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFnNamedArgsSingleEnumListReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFnNamedArgsSingleFloat( + self, + myFloat: float, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFnNamedArgsSingleFloat", + { + "myFloat": myFloat, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFnNamedArgsSingleFloatReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFnNamedArgsSingleInt( + self, + myInt: int, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFnNamedArgsSingleInt", + { + "myInt": myInt, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFnNamedArgsSingleIntReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFnNamedArgsSingleString( + self, + myString: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFnNamedArgsSingleString", + { + "myString": myString, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFnNamedArgsSingleStringReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFnNamedArgsSingleStringArray( + self, + myStringArray: List[str], + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFnNamedArgsSingleStringArray", + { + "myStringArray": myStringArray, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFnNamedArgsSingleStringArrayReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestFnNamedArgsSingleStringList( + self, + myArg: List[str], + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestFnNamedArgsSingleStringList", + { + "myArg": myArg, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestFnNamedArgsSingleStringListReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestGemini( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestGemini", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestGeminiReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestImageInput( + self, + img: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestImageInput", + { + "img": img, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestImageInputReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestMulticlassNamedArgs( + self, + myArg: types.NamedArgsSingleClass,myArg2: types.NamedArgsSingleClass, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestMulticlassNamedArgs", + { + "myArg": myArg,"myArg2": myArg2, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestMulticlassNamedArgsReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestOllama( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestOllama", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestOllamaReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestOpenAILegacyProvider( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestOpenAILegacyProvider", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestOpenAILegacyProviderReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestRetryConstant( + self, + + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestRetryConstant", + { + + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestRetryConstantReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestRetryExponential( + self, + + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestRetryExponential", + { + + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestRetryExponentialReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def TestVertex( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> str: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "TestVertex", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("TestVertexReturnType", inner=(str, ...)) + return coerce(mdl, raw.parsed()) + + def UnionTest_Function( + self, + input: Union[str, bool], + baml_options: BamlCallOptions = {}, + ) -> types.UnionTest_ReturnType: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.call_function_sync( + "UnionTest_Function", + { + "input": input, + }, + self.__ctx_manager.get(), + tb, + __cr__, + ) + mdl = create_model("UnionTest_FunctionReturnType", inner=(types.UnionTest_ReturnType, ...)) + return coerce(mdl, raw.parsed()) + + + + +class BamlStreamClient: + __runtime: baml_py.BamlRuntime + __ctx_manager: baml_py.BamlCtxManager + + def __init__(self, runtime: baml_py.BamlRuntime, ctx_manager: baml_py.BamlCtxManager): + self.__runtime = runtime + self.__ctx_manager = ctx_manager + + + def AudioInput( + self, + aud: baml_py.Audio, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "AudioInput", + { + "aud": aud, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("AudioInputReturnType", inner=(str, ...)) + partial_mdl = create_model("AudioInputPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def ClassifyMessage( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[types.Category], types.Category]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "ClassifyMessage", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("ClassifyMessageReturnType", inner=(types.Category, ...)) + partial_mdl = create_model("ClassifyMessagePartialReturnType", inner=(Optional[types.Category], ...)) + + return baml_py.BamlSyncStream[Optional[types.Category], types.Category]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def ClassifyMessage2( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[types.Category], types.Category]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "ClassifyMessage2", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("ClassifyMessage2ReturnType", inner=(types.Category, ...)) + partial_mdl = create_model("ClassifyMessage2PartialReturnType", inner=(Optional[types.Category], ...)) + + return baml_py.BamlSyncStream[Optional[types.Category], types.Category]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def ClassifyMessage3( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[types.Category], types.Category]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "ClassifyMessage3", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("ClassifyMessage3ReturnType", inner=(types.Category, ...)) + partial_mdl = create_model("ClassifyMessage3PartialReturnType", inner=(Optional[types.Category], ...)) + + return baml_py.BamlSyncStream[Optional[types.Category], types.Category]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def DescribeImage( + self, + img: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "DescribeImage", + { + "img": img, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("DescribeImageReturnType", inner=(str, ...)) + partial_mdl = create_model("DescribeImagePartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def DescribeImage2( + self, + classWithImage: types.ClassWithImage,img2: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "DescribeImage2", + { + "classWithImage": classWithImage, + "img2": img2, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("DescribeImage2ReturnType", inner=(str, ...)) + partial_mdl = create_model("DescribeImage2PartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def DescribeImage3( + self, + classWithImage: types.ClassWithImage,img2: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "DescribeImage3", + { + "classWithImage": classWithImage, + "img2": img2, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("DescribeImage3ReturnType", inner=(str, ...)) + partial_mdl = create_model("DescribeImage3PartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def DescribeImage4( + self, + classWithImage: types.ClassWithImage,img2: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "DescribeImage4", + { + "classWithImage": classWithImage, + "img2": img2, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("DescribeImage4ReturnType", inner=(str, ...)) + partial_mdl = create_model("DescribeImage4PartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def DummyOutputFunction( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.DummyOutput, types.DummyOutput]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "DummyOutputFunction", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("DummyOutputFunctionReturnType", inner=(types.DummyOutput, ...)) + partial_mdl = create_model("DummyOutputFunctionPartialReturnType", inner=(partial_types.DummyOutput, ...)) + + return baml_py.BamlSyncStream[partial_types.DummyOutput, types.DummyOutput]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def DynamicFunc( + self, + input: types.DynamicClassOne, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.DynamicClassTwo, types.DynamicClassTwo]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "DynamicFunc", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("DynamicFuncReturnType", inner=(types.DynamicClassTwo, ...)) + partial_mdl = create_model("DynamicFuncPartialReturnType", inner=(partial_types.DynamicClassTwo, ...)) + + return baml_py.BamlSyncStream[partial_types.DynamicClassTwo, types.DynamicClassTwo]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def DynamicInputOutput( + self, + input: types.DynInputOutput, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.DynInputOutput, types.DynInputOutput]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "DynamicInputOutput", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("DynamicInputOutputReturnType", inner=(types.DynInputOutput, ...)) + partial_mdl = create_model("DynamicInputOutputPartialReturnType", inner=(partial_types.DynInputOutput, ...)) + + return baml_py.BamlSyncStream[partial_types.DynInputOutput, types.DynInputOutput]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def DynamicListInputOutput( + self, + input: List[types.DynInputOutput], + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[List[partial_types.DynInputOutput], List[types.DynInputOutput]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "DynamicListInputOutput", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("DynamicListInputOutputReturnType", inner=(List[types.DynInputOutput], ...)) + partial_mdl = create_model("DynamicListInputOutputPartialReturnType", inner=(List[partial_types.DynInputOutput], ...)) + + return baml_py.BamlSyncStream[List[partial_types.DynInputOutput], List[types.DynInputOutput]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def ExtractNames( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[List[Optional[str]], List[str]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "ExtractNames", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("ExtractNamesReturnType", inner=(List[str], ...)) + partial_mdl = create_model("ExtractNamesPartialReturnType", inner=(List[Optional[str]], ...)) + + return baml_py.BamlSyncStream[List[Optional[str]], List[str]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def ExtractPeople( + self, + text: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[List[partial_types.Person], List[types.Person]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "ExtractPeople", + { + "text": text, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("ExtractPeopleReturnType", inner=(List[types.Person], ...)) + partial_mdl = create_model("ExtractPeoplePartialReturnType", inner=(List[partial_types.Person], ...)) + + return baml_py.BamlSyncStream[List[partial_types.Person], List[types.Person]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def ExtractReceiptInfo( + self, + email: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.ReceiptInfo, types.ReceiptInfo]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "ExtractReceiptInfo", + { + "email": email, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("ExtractReceiptInfoReturnType", inner=(types.ReceiptInfo, ...)) + partial_mdl = create_model("ExtractReceiptInfoPartialReturnType", inner=(partial_types.ReceiptInfo, ...)) + + return baml_py.BamlSyncStream[partial_types.ReceiptInfo, types.ReceiptInfo]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def ExtractResume( + self, + resume: str,img: Optional[baml_py.Image], + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.Resume, types.Resume]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "ExtractResume", + { + "resume": resume, + "img": img, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("ExtractResumeReturnType", inner=(types.Resume, ...)) + partial_mdl = create_model("ExtractResumePartialReturnType", inner=(partial_types.Resume, ...)) + + return baml_py.BamlSyncStream[partial_types.Resume, types.Resume]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def ExtractResume2( + self, + resume: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.Resume, types.Resume]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "ExtractResume2", + { + "resume": resume, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("ExtractResume2ReturnType", inner=(types.Resume, ...)) + partial_mdl = create_model("ExtractResume2PartialReturnType", inner=(partial_types.Resume, ...)) + + return baml_py.BamlSyncStream[partial_types.Resume, types.Resume]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnClassOptionalOutput( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.ClassOptionalOutput, Optional[types.ClassOptionalOutput]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnClassOptionalOutput", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnClassOptionalOutputReturnType", inner=(Optional[types.ClassOptionalOutput], ...)) + partial_mdl = create_model("FnClassOptionalOutputPartialReturnType", inner=(partial_types.ClassOptionalOutput, ...)) + + return baml_py.BamlSyncStream[partial_types.ClassOptionalOutput, Optional[types.ClassOptionalOutput]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnClassOptionalOutput2( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.ClassOptionalOutput2, Optional[types.ClassOptionalOutput2]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnClassOptionalOutput2", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnClassOptionalOutput2ReturnType", inner=(Optional[types.ClassOptionalOutput2], ...)) + partial_mdl = create_model("FnClassOptionalOutput2PartialReturnType", inner=(partial_types.ClassOptionalOutput2, ...)) + + return baml_py.BamlSyncStream[partial_types.ClassOptionalOutput2, Optional[types.ClassOptionalOutput2]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnEnumListOutput( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[List[Optional[types.EnumOutput]], List[types.EnumOutput]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnEnumListOutput", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnEnumListOutputReturnType", inner=(List[types.EnumOutput], ...)) + partial_mdl = create_model("FnEnumListOutputPartialReturnType", inner=(List[Optional[types.EnumOutput]], ...)) + + return baml_py.BamlSyncStream[List[Optional[types.EnumOutput]], List[types.EnumOutput]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnEnumOutput( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[types.EnumOutput], types.EnumOutput]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnEnumOutput", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnEnumOutputReturnType", inner=(types.EnumOutput, ...)) + partial_mdl = create_model("FnEnumOutputPartialReturnType", inner=(Optional[types.EnumOutput], ...)) + + return baml_py.BamlSyncStream[Optional[types.EnumOutput], types.EnumOutput]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnNamedArgsSingleStringOptional( + self, + myString: Optional[str], + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnNamedArgsSingleStringOptional", + { + "myString": myString, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnNamedArgsSingleStringOptionalReturnType", inner=(str, ...)) + partial_mdl = create_model("FnNamedArgsSingleStringOptionalPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnOutputBool( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[bool], bool]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnOutputBool", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnOutputBoolReturnType", inner=(bool, ...)) + partial_mdl = create_model("FnOutputBoolPartialReturnType", inner=(Optional[bool], ...)) + + return baml_py.BamlSyncStream[Optional[bool], bool]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnOutputClass( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.TestOutputClass, types.TestOutputClass]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnOutputClass", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnOutputClassReturnType", inner=(types.TestOutputClass, ...)) + partial_mdl = create_model("FnOutputClassPartialReturnType", inner=(partial_types.TestOutputClass, ...)) + + return baml_py.BamlSyncStream[partial_types.TestOutputClass, types.TestOutputClass]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnOutputClassList( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[List[partial_types.TestOutputClass], List[types.TestOutputClass]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnOutputClassList", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnOutputClassListReturnType", inner=(List[types.TestOutputClass], ...)) + partial_mdl = create_model("FnOutputClassListPartialReturnType", inner=(List[partial_types.TestOutputClass], ...)) + + return baml_py.BamlSyncStream[List[partial_types.TestOutputClass], List[types.TestOutputClass]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnOutputClassNested( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.TestClassNested, types.TestClassNested]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnOutputClassNested", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnOutputClassNestedReturnType", inner=(types.TestClassNested, ...)) + partial_mdl = create_model("FnOutputClassNestedPartialReturnType", inner=(partial_types.TestClassNested, ...)) + + return baml_py.BamlSyncStream[partial_types.TestClassNested, types.TestClassNested]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnOutputClassWithEnum( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.TestClassWithEnum, types.TestClassWithEnum]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnOutputClassWithEnum", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnOutputClassWithEnumReturnType", inner=(types.TestClassWithEnum, ...)) + partial_mdl = create_model("FnOutputClassWithEnumPartialReturnType", inner=(partial_types.TestClassWithEnum, ...)) + + return baml_py.BamlSyncStream[partial_types.TestClassWithEnum, types.TestClassWithEnum]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnOutputStringList( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[List[Optional[str]], List[str]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnOutputStringList", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnOutputStringListReturnType", inner=(List[str], ...)) + partial_mdl = create_model("FnOutputStringListPartialReturnType", inner=(List[Optional[str]], ...)) + + return baml_py.BamlSyncStream[List[Optional[str]], List[str]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnTestAliasedEnumOutput( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[types.TestEnum], types.TestEnum]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnTestAliasedEnumOutput", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnTestAliasedEnumOutputReturnType", inner=(types.TestEnum, ...)) + partial_mdl = create_model("FnTestAliasedEnumOutputPartialReturnType", inner=(Optional[types.TestEnum], ...)) + + return baml_py.BamlSyncStream[Optional[types.TestEnum], types.TestEnum]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnTestClassAlias( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.TestClassAlias, types.TestClassAlias]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnTestClassAlias", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnTestClassAliasReturnType", inner=(types.TestClassAlias, ...)) + partial_mdl = create_model("FnTestClassAliasPartialReturnType", inner=(partial_types.TestClassAlias, ...)) + + return baml_py.BamlSyncStream[partial_types.TestClassAlias, types.TestClassAlias]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def FnTestNamedArgsSingleEnum( + self, + myArg: types.NamedArgsSingleEnum, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "FnTestNamedArgsSingleEnum", + { + "myArg": myArg, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("FnTestNamedArgsSingleEnumReturnType", inner=(str, ...)) + partial_mdl = create_model("FnTestNamedArgsSingleEnumPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def GetDataType( + self, + text: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.RaysData, types.RaysData]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "GetDataType", + { + "text": text, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("GetDataTypeReturnType", inner=(types.RaysData, ...)) + partial_mdl = create_model("GetDataTypePartialReturnType", inner=(partial_types.RaysData, ...)) + + return baml_py.BamlSyncStream[partial_types.RaysData, types.RaysData]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def GetOrderInfo( + self, + email: types.Email, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.OrderInfo, types.OrderInfo]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "GetOrderInfo", + { + "email": email, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("GetOrderInfoReturnType", inner=(types.OrderInfo, ...)) + partial_mdl = create_model("GetOrderInfoPartialReturnType", inner=(partial_types.OrderInfo, ...)) + + return baml_py.BamlSyncStream[partial_types.OrderInfo, types.OrderInfo]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def GetQuery( + self, + query: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.SearchParams, types.SearchParams]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "GetQuery", + { + "query": query, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("GetQueryReturnType", inner=(types.SearchParams, ...)) + partial_mdl = create_model("GetQueryPartialReturnType", inner=(partial_types.SearchParams, ...)) + + return baml_py.BamlSyncStream[partial_types.SearchParams, types.SearchParams]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def MyFunc( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.DynamicOutput, types.DynamicOutput]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "MyFunc", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("MyFuncReturnType", inner=(types.DynamicOutput, ...)) + partial_mdl = create_model("MyFuncPartialReturnType", inner=(partial_types.DynamicOutput, ...)) + + return baml_py.BamlSyncStream[partial_types.DynamicOutput, types.DynamicOutput]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def OptionalTest_Function( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[List[partial_types.OptionalTest_ReturnType], List[Optional[types.OptionalTest_ReturnType]]]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "OptionalTest_Function", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("OptionalTest_FunctionReturnType", inner=(List[Optional[types.OptionalTest_ReturnType]], ...)) + partial_mdl = create_model("OptionalTest_FunctionPartialReturnType", inner=(List[partial_types.OptionalTest_ReturnType], ...)) + + return baml_py.BamlSyncStream[List[partial_types.OptionalTest_ReturnType], List[Optional[types.OptionalTest_ReturnType]]]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def PromptTestClaude( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "PromptTestClaude", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("PromptTestClaudeReturnType", inner=(str, ...)) + partial_mdl = create_model("PromptTestClaudePartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def PromptTestClaudeChat( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "PromptTestClaudeChat", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("PromptTestClaudeChatReturnType", inner=(str, ...)) + partial_mdl = create_model("PromptTestClaudeChatPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def PromptTestClaudeChatNoSystem( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "PromptTestClaudeChatNoSystem", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("PromptTestClaudeChatNoSystemReturnType", inner=(str, ...)) + partial_mdl = create_model("PromptTestClaudeChatNoSystemPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def PromptTestOpenAI( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "PromptTestOpenAI", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("PromptTestOpenAIReturnType", inner=(str, ...)) + partial_mdl = create_model("PromptTestOpenAIPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def PromptTestOpenAIChat( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "PromptTestOpenAIChat", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("PromptTestOpenAIChatReturnType", inner=(str, ...)) + partial_mdl = create_model("PromptTestOpenAIChatPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def PromptTestOpenAIChatNoSystem( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "PromptTestOpenAIChatNoSystem", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("PromptTestOpenAIChatNoSystemReturnType", inner=(str, ...)) + partial_mdl = create_model("PromptTestOpenAIChatNoSystemPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def PromptTestStreaming( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "PromptTestStreaming", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("PromptTestStreamingReturnType", inner=(str, ...)) + partial_mdl = create_model("PromptTestStreamingPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestAnthropic( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestAnthropic", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestAnthropicReturnType", inner=(str, ...)) + partial_mdl = create_model("TestAnthropicPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestAws( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestAws", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestAwsReturnType", inner=(str, ...)) + partial_mdl = create_model("TestAwsPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestAzure( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestAzure", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestAzureReturnType", inner=(str, ...)) + partial_mdl = create_model("TestAzurePartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFallbackClient( + self, + + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFallbackClient", + { + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFallbackClientReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFallbackClientPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFnNamedArgsSingleBool( + self, + myBool: bool, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFnNamedArgsSingleBool", + { + "myBool": myBool, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFnNamedArgsSingleBoolReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFnNamedArgsSingleBoolPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFnNamedArgsSingleClass( + self, + myArg: types.NamedArgsSingleClass, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFnNamedArgsSingleClass", + { + "myArg": myArg, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFnNamedArgsSingleClassReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFnNamedArgsSingleClassPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFnNamedArgsSingleEnumList( + self, + myArg: List[types.NamedArgsSingleEnumList], + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFnNamedArgsSingleEnumList", + { + "myArg": myArg, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFnNamedArgsSingleEnumListReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFnNamedArgsSingleEnumListPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFnNamedArgsSingleFloat( + self, + myFloat: float, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFnNamedArgsSingleFloat", + { + "myFloat": myFloat, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFnNamedArgsSingleFloatReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFnNamedArgsSingleFloatPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFnNamedArgsSingleInt( + self, + myInt: int, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFnNamedArgsSingleInt", + { + "myInt": myInt, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFnNamedArgsSingleIntReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFnNamedArgsSingleIntPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFnNamedArgsSingleString( + self, + myString: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFnNamedArgsSingleString", + { + "myString": myString, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFnNamedArgsSingleStringReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFnNamedArgsSingleStringPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFnNamedArgsSingleStringArray( + self, + myStringArray: List[str], + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFnNamedArgsSingleStringArray", + { + "myStringArray": myStringArray, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFnNamedArgsSingleStringArrayReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFnNamedArgsSingleStringArrayPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestFnNamedArgsSingleStringList( + self, + myArg: List[str], + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestFnNamedArgsSingleStringList", + { + "myArg": myArg, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestFnNamedArgsSingleStringListReturnType", inner=(str, ...)) + partial_mdl = create_model("TestFnNamedArgsSingleStringListPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestGemini( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestGemini", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestGeminiReturnType", inner=(str, ...)) + partial_mdl = create_model("TestGeminiPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestImageInput( + self, + img: baml_py.Image, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestImageInput", + { + "img": img, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestImageInputReturnType", inner=(str, ...)) + partial_mdl = create_model("TestImageInputPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestMulticlassNamedArgs( + self, + myArg: types.NamedArgsSingleClass,myArg2: types.NamedArgsSingleClass, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestMulticlassNamedArgs", + { + "myArg": myArg, + "myArg2": myArg2, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestMulticlassNamedArgsReturnType", inner=(str, ...)) + partial_mdl = create_model("TestMulticlassNamedArgsPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestOllama( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestOllama", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestOllamaReturnType", inner=(str, ...)) + partial_mdl = create_model("TestOllamaPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestOpenAILegacyProvider( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestOpenAILegacyProvider", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestOpenAILegacyProviderReturnType", inner=(str, ...)) + partial_mdl = create_model("TestOpenAILegacyProviderPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestRetryConstant( + self, + + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestRetryConstant", + { + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestRetryConstantReturnType", inner=(str, ...)) + partial_mdl = create_model("TestRetryConstantPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestRetryExponential( + self, + + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestRetryExponential", + { + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestRetryExponentialReturnType", inner=(str, ...)) + partial_mdl = create_model("TestRetryExponentialPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def TestVertex( + self, + input: str, + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[Optional[str], str]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "TestVertex", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("TestVertexReturnType", inner=(str, ...)) + partial_mdl = create_model("TestVertexPartialReturnType", inner=(Optional[str], ...)) + + return baml_py.BamlSyncStream[Optional[str], str]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + def UnionTest_Function( + self, + input: Union[str, bool], + baml_options: BamlCallOptions = {}, + ) -> baml_py.BamlSyncStream[partial_types.UnionTest_ReturnType, types.UnionTest_ReturnType]: + __tb__ = baml_options.get("tb", None) + if __tb__ is not None: + tb = __tb__._tb + else: + tb = None + __cr__ = baml_options.get("client_registry", None) + + raw = self.__runtime.stream_function_sync( + "UnionTest_Function", + { + "input": input, + }, + None, + self.__ctx_manager.get(), + tb, + __cr__, + ) + + mdl = create_model("UnionTest_FunctionReturnType", inner=(types.UnionTest_ReturnType, ...)) + partial_mdl = create_model("UnionTest_FunctionPartialReturnType", inner=(partial_types.UnionTest_ReturnType, ...)) + + return baml_py.BamlSyncStream[partial_types.UnionTest_ReturnType, types.UnionTest_ReturnType]( + raw, + lambda x: coerce(partial_mdl, x), + lambda x: coerce(mdl, x), + self.__ctx_manager.get(), + ) + + +b = BamlSyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) + +__all__ = ["b"] \ No newline at end of file diff --git a/integ-tests/python/tests/test_functions.py b/integ-tests/python/tests/test_functions.py index 4a0dfd567..1b37ad45a 100644 --- a/integ-tests/python/tests/test_functions.py +++ b/integ-tests/python/tests/test_functions.py @@ -7,6 +7,7 @@ load_dotenv() import baml_py from ..baml_client import b +from ..baml_client.sync_client import b as sync_b from ..baml_client.globals import ( DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, ) @@ -16,6 +17,18 @@ import datetime +def test_sync(): + res = sync_b.TestFnNamedArgsSingleClass( + myArg=NamedArgsSingleClass( + key="key", + key_two=True, + key_three=52, + ) + ) + print("got response", res) + assert "52" in res + + @pytest.mark.asyncio async def test_should_work_for_all_inputs(): res = await b.TestFnNamedArgsSingleBool(True) @@ -229,6 +242,49 @@ async def test_streaming_uniterated(): assert len(final) > 0, "Expected non-empty final but got empty." +def test_streaming_sync(): + stream = sync_b.stream.PromptTestStreaming( + input="Programming languages are fun to create" + ) + msgs: list[str] = [] + + start_time = asyncio.get_event_loop().time() + last_msg_time = start_time + first_msg_time = start_time + 10 + for msg in stream: + msgs.append(str(msg)) + if len(msgs) == 1: + first_msg_time = asyncio.get_event_loop().time() + + last_msg_time = asyncio.get_event_loop().time() + + final = stream.get_final_response() + + assert ( + first_msg_time - start_time <= 1.5 + ), "Expected first message within 1 second but it took longer." + assert ( + last_msg_time - start_time >= 1 + ), "Expected last message after 1.5 seconds but it was earlier." + assert len(final) > 0, "Expected non-empty final but got empty." + assert len(msgs) > 0, "Expected at least one streamed response but got none." + for prev_msg, msg in zip(msgs, msgs[1:]): + assert msg.startswith( + prev_msg + ), "Expected messages to be continuous, but prev was %r and next was %r" % ( + prev_msg, + msg, + ) + assert msgs[-1] == final, "Expected last stream message to match final response." + + +def test_streaming_uniterated_sync(): + final = sync_b.stream.PromptTestStreaming( + input="The color blue makes me sad" + ).get_final_response() + assert len(final) > 0, "Expected non-empty final but got empty." + + @pytest.mark.asyncio async def test_streaming_claude(): stream = b.stream.PromptTestClaude(input="Mt Rainier is tall") diff --git a/integ-tests/typescript/baml_client/client.ts b/integ-tests/typescript/baml_client/async_client.ts similarity index 99% rename from integ-tests/typescript/baml_client/client.ts rename to integ-tests/typescript/baml_client/async_client.ts index 73b4d3bab..0e63572fa 100644 --- a/integ-tests/typescript/baml_client/client.ts +++ b/integ-tests/typescript/baml_client/async_client.ts @@ -18,6 +18,7 @@ $ pnpm add @boundaryml/baml import { BamlRuntime, FunctionResult, BamlCtxManager, BamlStream, Image, ClientBuilder } from "@boundaryml/baml" import {Blah, ClassOptionalOutput, ClassOptionalOutput2, ClassWithImage, DummyOutput, DynInputOutput, DynamicClassOne, DynamicClassTwo, DynamicOutput, Education, Email, Event, FakeImage, InnerClass, InnerClass2, NamedArgsSingleClass, OptionalTest_Prop1, OptionalTest_ReturnType, OrderInfo, Person, RaysData, ReceiptInfo, ReceiptItem, Resume, SearchParams, SomeClassNestedDynamic, TestClassAlias, TestClassNested, TestClassWithEnum, TestOutputClass, UnionTest_ReturnType, WithReasoning, Category, Category2, Category3, Color, DataType, DynEnumOne, DynEnumTwo, EnumInClass, EnumOutput, Hobby, NamedArgsSingleEnum, NamedArgsSingleEnumList, OptionalTest_CategoryType, OrderStatus, Tag, TestEnum} 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" export type RecursivePartialNull = T extends object ? { @@ -25,7 +26,7 @@ export type RecursivePartialNull = T extends object } : T | null; -export class BamlClient { +export class BamlAsyncClient { private runtime: BamlRuntime private ctx_manager: BamlCtxManager private stream_client: BamlStreamClient @@ -2543,4 +2544,6 @@ class BamlStreamClient { ) } -} \ No newline at end of file +} + +export const b = new BamlAsyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) \ No newline at end of file diff --git a/integ-tests/typescript/baml_client/globals.ts b/integ-tests/typescript/baml_client/globals.ts index b447f4cc7..d68658c35 100644 --- a/integ-tests/typescript/baml_client/globals.ts +++ b/integ-tests/typescript/baml_client/globals.ts @@ -16,7 +16,6 @@ $ pnpm add @boundaryml/baml // biome-ignore format: autogenerated code /* eslint-disable */ import { BamlCtxManager, BamlRuntime } from '@boundaryml/baml' -import { BamlClient } from './client' import { getBamlFiles } from './inlinedbaml' @@ -25,5 +24,4 @@ export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = Baml getBamlFiles(), process.env ) -export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = new BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME) -export const b = new BamlClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) \ No newline at end of file +export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = new BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME) \ No newline at end of file diff --git a/integ-tests/typescript/baml_client/index.ts b/integ-tests/typescript/baml_client/index.ts index 12e14f649..8f19f37b0 100644 --- a/integ-tests/typescript/baml_client/index.ts +++ b/integ-tests/typescript/baml_client/index.ts @@ -15,6 +15,8 @@ $ pnpm add @boundaryml/baml // @ts-nocheck // biome-ignore format: autogenerated code /* eslint-disable */ -export { b } from "./globals" + +export { b } from "./async_client" + export * from "./types" export * from "./tracing" \ No newline at end of file diff --git a/integ-tests/typescript/baml_client/sync_client.ts b/integ-tests/typescript/baml_client/sync_client.ts new file mode 100644 index 000000000..912009365 --- /dev/null +++ b/integ-tests/typescript/baml_client/sync_client.ts @@ -0,0 +1,1075 @@ +/************************************************************************************************* + +Welcome to Baml! To use this generated code, please run one of the following: + +$ npm install @boundaryml/baml +$ yarn add @boundaryml/baml +$ pnpm add @boundaryml/baml + +*************************************************************************************************/ + +// This file was generated by BAML: do not edit it. Instead, edit the BAML +// files and re-generate this code. +// +// tslint:disable +// @ts-nocheck +// biome-ignore format: autogenerated code +/* eslint-disable */ +import { BamlRuntime, FunctionResult, BamlCtxManager, BamlSyncStream, Image, ClientBuilder } from "@boundaryml/baml" +import {Blah, ClassOptionalOutput, ClassOptionalOutput2, ClassWithImage, DummyOutput, DynInputOutput, DynamicClassOne, DynamicClassTwo, DynamicOutput, Education, Email, Event, FakeImage, InnerClass, InnerClass2, NamedArgsSingleClass, OptionalTest_Prop1, OptionalTest_ReturnType, OrderInfo, Person, RaysData, ReceiptInfo, ReceiptItem, Resume, SearchParams, SomeClassNestedDynamic, TestClassAlias, TestClassNested, TestClassWithEnum, TestOutputClass, UnionTest_ReturnType, WithReasoning, Category, Category2, Category3, Color, DataType, DynEnumOne, DynEnumTwo, EnumInClass, EnumOutput, Hobby, NamedArgsSingleEnum, NamedArgsSingleEnumList, OptionalTest_CategoryType, OrderStatus, Tag, TestEnum} 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" + +export type RecursivePartialNull = T extends object + ? { + [P in keyof T]?: RecursivePartialNull; + } + : T | null; + +export class BamlSyncClient { + private runtime: BamlRuntime + private ctx_manager: BamlCtxManager + + constructor(runtime: BamlRuntime, ctx_manager: BamlCtxManager) { + this.runtime = runtime + this.ctx_manager = ctx_manager + this.stream_client = new BamlStreamClient(runtime, ctx_manager) + } + + /* + * @deprecated NOT IMPLEMENTED as streaming must by async. We + * are not providing an async version as we want to reserve the + * right to provide a sync version in the future. + */ + get stream() { + throw new Error("stream is not available in BamlSyncClient. Use `import { b } from 'baml_client/async_client") + } + + + AudioInput( + aud: Audio, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "AudioInput", + { + "aud": aud + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + ClassifyMessage( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): Category { + const raw = this.runtime.callFunctionSync( + "ClassifyMessage", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as Category + } + + ClassifyMessage2( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): Category { + const raw = this.runtime.callFunctionSync( + "ClassifyMessage2", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as Category + } + + ClassifyMessage3( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): Category { + const raw = this.runtime.callFunctionSync( + "ClassifyMessage3", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as Category + } + + DescribeImage( + img: Image, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "DescribeImage", + { + "img": img + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + DescribeImage2( + classWithImage: ClassWithImage,img2: Image, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "DescribeImage2", + { + "classWithImage": classWithImage,"img2": img2 + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + DescribeImage3( + classWithImage: ClassWithImage,img2: Image, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "DescribeImage3", + { + "classWithImage": classWithImage,"img2": img2 + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + DescribeImage4( + classWithImage: ClassWithImage,img2: Image, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "DescribeImage4", + { + "classWithImage": classWithImage,"img2": img2 + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + DummyOutputFunction( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): DummyOutput { + const raw = this.runtime.callFunctionSync( + "DummyOutputFunction", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as DummyOutput + } + + DynamicFunc( + input: DynamicClassOne, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): DynamicClassTwo { + const raw = this.runtime.callFunctionSync( + "DynamicFunc", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as DynamicClassTwo + } + + DynamicInputOutput( + input: DynInputOutput, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): DynInputOutput { + const raw = this.runtime.callFunctionSync( + "DynamicInputOutput", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as DynInputOutput + } + + DynamicListInputOutput( + input: DynInputOutput[], + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): DynInputOutput[] { + const raw = this.runtime.callFunctionSync( + "DynamicListInputOutput", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as DynInputOutput[] + } + + ExtractNames( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string[] { + const raw = this.runtime.callFunctionSync( + "ExtractNames", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string[] + } + + ExtractPeople( + text: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): Person[] { + const raw = this.runtime.callFunctionSync( + "ExtractPeople", + { + "text": text + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as Person[] + } + + ExtractReceiptInfo( + email: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): ReceiptInfo { + const raw = this.runtime.callFunctionSync( + "ExtractReceiptInfo", + { + "email": email + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as ReceiptInfo + } + + ExtractResume( + resume: string,img?: Image | null, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): Resume { + const raw = this.runtime.callFunctionSync( + "ExtractResume", + { + "resume": resume,"img": img?? null + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as Resume + } + + ExtractResume2( + resume: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): Resume { + const raw = this.runtime.callFunctionSync( + "ExtractResume2", + { + "resume": resume + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as Resume + } + + FnClassOptionalOutput( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): ClassOptionalOutput | null { + const raw = this.runtime.callFunctionSync( + "FnClassOptionalOutput", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as ClassOptionalOutput | null + } + + FnClassOptionalOutput2( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): ClassOptionalOutput2 | null { + const raw = this.runtime.callFunctionSync( + "FnClassOptionalOutput2", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as ClassOptionalOutput2 | null + } + + FnEnumListOutput( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): EnumOutput[] { + const raw = this.runtime.callFunctionSync( + "FnEnumListOutput", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as EnumOutput[] + } + + FnEnumOutput( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): EnumOutput { + const raw = this.runtime.callFunctionSync( + "FnEnumOutput", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as EnumOutput + } + + FnNamedArgsSingleStringOptional( + myString?: string | null, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "FnNamedArgsSingleStringOptional", + { + "myString": myString?? null + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + FnOutputBool( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): boolean { + const raw = this.runtime.callFunctionSync( + "FnOutputBool", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as boolean + } + + FnOutputClass( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): TestOutputClass { + const raw = this.runtime.callFunctionSync( + "FnOutputClass", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as TestOutputClass + } + + FnOutputClassList( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): TestOutputClass[] { + const raw = this.runtime.callFunctionSync( + "FnOutputClassList", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as TestOutputClass[] + } + + FnOutputClassNested( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): TestClassNested { + const raw = this.runtime.callFunctionSync( + "FnOutputClassNested", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as TestClassNested + } + + FnOutputClassWithEnum( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): TestClassWithEnum { + const raw = this.runtime.callFunctionSync( + "FnOutputClassWithEnum", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as TestClassWithEnum + } + + FnOutputStringList( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string[] { + const raw = this.runtime.callFunctionSync( + "FnOutputStringList", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string[] + } + + FnTestAliasedEnumOutput( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): TestEnum { + const raw = this.runtime.callFunctionSync( + "FnTestAliasedEnumOutput", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as TestEnum + } + + FnTestClassAlias( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): TestClassAlias { + const raw = this.runtime.callFunctionSync( + "FnTestClassAlias", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as TestClassAlias + } + + FnTestNamedArgsSingleEnum( + myArg: NamedArgsSingleEnum, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "FnTestNamedArgsSingleEnum", + { + "myArg": myArg + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + GetDataType( + text: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): RaysData { + const raw = this.runtime.callFunctionSync( + "GetDataType", + { + "text": text + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as RaysData + } + + GetOrderInfo( + email: Email, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): OrderInfo { + const raw = this.runtime.callFunctionSync( + "GetOrderInfo", + { + "email": email + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as OrderInfo + } + + GetQuery( + query: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): SearchParams { + const raw = this.runtime.callFunctionSync( + "GetQuery", + { + "query": query + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as SearchParams + } + + MyFunc( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): DynamicOutput { + const raw = this.runtime.callFunctionSync( + "MyFunc", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as DynamicOutput + } + + OptionalTest_Function( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): (OptionalTest_ReturnType | null)[] { + const raw = this.runtime.callFunctionSync( + "OptionalTest_Function", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as (OptionalTest_ReturnType | null)[] + } + + PromptTestClaude( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "PromptTestClaude", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + PromptTestClaudeChat( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "PromptTestClaudeChat", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + PromptTestClaudeChatNoSystem( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "PromptTestClaudeChatNoSystem", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + PromptTestOpenAI( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "PromptTestOpenAI", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + PromptTestOpenAIChat( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "PromptTestOpenAIChat", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + PromptTestOpenAIChatNoSystem( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "PromptTestOpenAIChatNoSystem", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + PromptTestStreaming( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "PromptTestStreaming", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestAnthropic( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestAnthropic", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestAws( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestAws", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestAzure( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestAzure", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFallbackClient( + + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFallbackClient", + { + + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFnNamedArgsSingleBool( + myBool: boolean, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFnNamedArgsSingleBool", + { + "myBool": myBool + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFnNamedArgsSingleClass( + myArg: NamedArgsSingleClass, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFnNamedArgsSingleClass", + { + "myArg": myArg + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFnNamedArgsSingleEnumList( + myArg: NamedArgsSingleEnumList[], + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFnNamedArgsSingleEnumList", + { + "myArg": myArg + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFnNamedArgsSingleFloat( + myFloat: number, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFnNamedArgsSingleFloat", + { + "myFloat": myFloat + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFnNamedArgsSingleInt( + myInt: number, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFnNamedArgsSingleInt", + { + "myInt": myInt + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFnNamedArgsSingleString( + myString: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFnNamedArgsSingleString", + { + "myString": myString + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFnNamedArgsSingleStringArray( + myStringArray: string[], + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFnNamedArgsSingleStringArray", + { + "myStringArray": myStringArray + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestFnNamedArgsSingleStringList( + myArg: string[], + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestFnNamedArgsSingleStringList", + { + "myArg": myArg + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestGemini( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestGemini", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestImageInput( + img: Image, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestImageInput", + { + "img": img + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestMulticlassNamedArgs( + myArg: NamedArgsSingleClass,myArg2: NamedArgsSingleClass, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestMulticlassNamedArgs", + { + "myArg": myArg,"myArg2": myArg2 + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestOllama( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestOllama", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestOpenAILegacyProvider( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestOpenAILegacyProvider", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestRetryConstant( + + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestRetryConstant", + { + + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestRetryExponential( + + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestRetryExponential", + { + + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + TestVertex( + input: string, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): string { + const raw = this.runtime.callFunctionSync( + "TestVertex", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as string + } + + UnionTest_Function( + input: string | boolean, + __baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry } + ): UnionTest_ReturnType { + const raw = this.runtime.callFunctionSync( + "UnionTest_Function", + { + "input": input + }, + this.ctx_manager.cloneContext(), + __baml_options__?.tb?.__tb(), + __baml_options__?.cr, + ) + return raw.parsed() as UnionTest_ReturnType + } + +} + +export const b = new BamlSyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX) \ No newline at end of file diff --git a/integ-tests/typescript/tests/integ-tests.test.ts b/integ-tests/typescript/tests/integ-tests.test.ts index 6f2303206..4336efb8c 100644 --- a/integ-tests/typescript/tests/integ-tests.test.ts +++ b/integ-tests/typescript/tests/integ-tests.test.ts @@ -14,7 +14,8 @@ import { TestClassNested, onLogEvent, } from '../baml_client' -import { RecursivePartialNull } from '../baml_client/client' +import { RecursivePartialNull } from '../baml_client/async_client' +import { b as b_sync } from '../baml_client/sync_client' import { config } from 'dotenv' import { BamlLogEvent, BamlRuntime } from '@boundaryml/baml/native' import { AsyncLocalStorage } from 'async_hooks' @@ -226,10 +227,9 @@ describe('Integ tests', () => { expect(msgs.at(-1)).toEqual(final) }) - it('should support vertex', async() => { + it('should support vertex', async () => { const res = await b.TestVertex('Donkey Kong') expect(res.toLowerCase()).toContain('donkey') - }) it('supports tracing sync', async () => { @@ -426,6 +426,11 @@ describe('Integ tests', () => { const res2 = await b.TestFnNamedArgsSingleStringList(['d', 'e', 'f']) expect(res2).toContain('d') }) + + it('should work with a sync client', () => { + const res = b_sync.TestFnNamedArgsSingleStringList(['a', 'b', 'c']) + expect(res).toContain('a') + }) }) interface MyInterface {