diff --git a/baml_language/crates/bridge_cffi/src/ffi/handle.rs b/baml_language/crates/bridge_cffi/src/ffi/handle.rs index bfd45d7581..3fe93e54d2 100644 --- a/baml_language/crates/bridge_cffi/src/ffi/handle.rs +++ b/baml_language/crates/bridge_cffi/src/ffi/handle.rs @@ -14,3 +14,17 @@ pub extern "C" fn clone_handle(key: u64) -> u64 { pub extern "C" fn release_handle(key: u64) { HANDLE_TABLE.release(key); } + +/// Release multiple handles in one call. Ignores null pointers. +/// +/// # Safety +/// +/// `keys` must be valid for reads of `len` elements. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn release_handles(keys: *const u64, len: usize) { + if keys.is_null() || len == 0 { + return; + } + let slice = unsafe { std::slice::from_raw_parts(keys, len) }; + HANDLE_TABLE.release_many(slice.iter().copied()); +} diff --git a/baml_language/crates/bridge_cffi/src/lib.rs b/baml_language/crates/bridge_cffi/src/lib.rs index 71258c467b..9aba35352e 100644 --- a/baml_language/crates/bridge_cffi/src/lib.rs +++ b/baml_language/crates/bridge_cffi/src/lib.rs @@ -19,7 +19,7 @@ pub use ffi::{ call_function_from_c, call_function_parse_from_c, call_function_stream_from_c, cancel_function_call, }, - handle::{clone_handle, release_handle}, + handle::{clone_handle, release_handle, release_handles}, objects::free_buffer, runtime::{create_baml_runtime, destroy_baml_runtime, invoke_runtime_cli, version}, }; diff --git a/baml_language/crates/bridge_ctypes/src/error.rs b/baml_language/crates/bridge_ctypes/src/error.rs index a997a32026..55b6686a81 100644 --- a/baml_language/crates/bridge_ctypes/src/error.rs +++ b/baml_language/crates/bridge_ctypes/src/error.rs @@ -14,6 +14,13 @@ pub enum CtypesError { #[error("Invalid handle key: {0}")] InvalidHandleKey(u64), + #[error("Handle type mismatch for key {key}: expected {expected}, actual {actual}")] + InvalidHandleType { + key: u64, + expected: i32, + actual: i32, + }, + #[error("Map entry missing key")] MapEntryMissingKey, diff --git a/baml_language/crates/bridge_ctypes/src/handle_table.rs b/baml_language/crates/bridge_ctypes/src/handle_table.rs index f96a4ba992..4245467f0d 100644 --- a/baml_language/crates/bridge_ctypes/src/handle_table.rs +++ b/baml_language/crates/bridge_ctypes/src/handle_table.rs @@ -23,10 +23,13 @@ pub enum HandleTableValue { Adt(BexExternalAdt), } +const DEFAULT_MAX_INLINE_MEDIA_BYTES: usize = 1_000_000; + pub struct HandleTableOptions<'a> { pub(crate) table: &'a HandleTable, pub(crate) serialize_media: bool, pub(crate) serialize_prompt_ast: bool, + pub(crate) max_inline_media_bytes: Option, } impl HandleTableOptions<'_> { @@ -35,6 +38,7 @@ impl HandleTableOptions<'_> { table: &HANDLE_TABLE, serialize_media: true, serialize_prompt_ast: true, + max_inline_media_bytes: Some(DEFAULT_MAX_INLINE_MEDIA_BYTES), } } @@ -43,6 +47,7 @@ impl HandleTableOptions<'_> { table: &HANDLE_TABLE, serialize_media: false, serialize_prompt_ast: false, + max_inline_media_bytes: None, } } } @@ -101,6 +106,33 @@ impl TryFrom for HandleTableValue { } } +impl TryFrom<&BexExternalValue> for HandleTableValue { + type Error = &'static str; + + fn try_from(value: &BexExternalValue) -> Result { + match value { + BexExternalValue::Handle(h) => Ok(Self::Handle(h.clone())), + BexExternalValue::Resource(r) => Ok(Self::Resource(r.clone())), + BexExternalValue::FunctionRef { global_index } => Ok(Self::FunctionRef { + global_index: *global_index, + }), + BexExternalValue::Adt(a) => Ok(Self::Adt(a.clone())), + BexExternalValue::Null + | BexExternalValue::Int(_) + | BexExternalValue::Float(_) + | BexExternalValue::Bool(_) + | BexExternalValue::String(_) + | BexExternalValue::Array { .. } + | BexExternalValue::Map { .. } + | BexExternalValue::Instance { .. } + | BexExternalValue::Variant { .. } + | BexExternalValue::Union { .. } => { + Err("only opaque BexExternalValue variants can be held as handles") + } + } + } +} + impl From for BexExternalValue { fn from(value: HandleTableValue) -> Self { match value { @@ -173,6 +205,20 @@ impl HandleTable { .remove(&key) .is_some() } + + /// Release multiple handles. + pub fn release_many(&self, keys: I) + where + I: IntoIterator, + { + let mut entries = self + .entries + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); + for key in keys { + entries.remove(&key); + } + } } impl Default for HandleTable { diff --git a/baml_language/crates/bridge_ctypes/src/value_decode.rs b/baml_language/crates/bridge_ctypes/src/value_decode.rs index 062945c87f..68ce3f3dba 100644 --- a/baml_language/crates/bridge_ctypes/src/value_decode.rs +++ b/baml_language/crates/bridge_ctypes/src/value_decode.rs @@ -10,8 +10,8 @@ use indexmap::IndexMap; use crate::{ baml::cffi::{ - InboundClassValue, InboundEnumValue, InboundListValue, InboundMapEntry, InboundMapValue, - InboundValue, inbound_value::Value as InboundValueVariant, + BamlHandleType, InboundClassValue, InboundEnumValue, InboundListValue, InboundMapEntry, + InboundMapValue, InboundValue, inbound_value::Value as InboundValueVariant, }, error::CtypesError, handle_table::HandleTable, @@ -39,12 +39,27 @@ pub fn inbound_to_external( let value = handle_table .resolve(handle.key) .ok_or(CtypesError::InvalidHandleKey(handle.key))?; + let actual = value.handle_type() as i32; + validate_handle_type(handle.key, handle.handle_type, actual)?; Ok(BexExternalValue::from((*value).clone())) } }, } } +fn validate_handle_type(key: u64, expected: i32, actual: i32) -> Result<(), CtypesError> { + match BamlHandleType::try_from(expected) { + Ok(BamlHandleType::HandleUnspecified | BamlHandleType::HandleUnknown) => Ok(()), + Ok(_) if expected == actual => Ok(()), + Err(_) => Ok(()), + Ok(_) => Err(CtypesError::InvalidHandleType { + key, + expected, + actual, + }), + } +} + fn convert_list( list: InboundListValue, handle_table: &HandleTable, @@ -136,3 +151,59 @@ pub fn kwargs_to_bex_values( } Ok(result) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + baml::cffi::{BamlHandle, inbound_value::Value as InboundValueVariant}, + handle_table::HandleTableValue, + }; + + fn inbound_handle(key: u64, handle_type: BamlHandleType) -> InboundValue { + InboundValue { + value: Some(InboundValueVariant::Handle(BamlHandle { + key, + handle_type: handle_type as i32, + })), + } + } + + #[test] + fn handle_type_matches() { + let table = HandleTable::new(); + let key = table.insert(HandleTableValue::FunctionRef { global_index: 1 }); + let inbound = inbound_handle(key, BamlHandleType::FunctionRef); + let out = inbound_to_external(inbound, &table).unwrap(); + assert!(matches!( + out, + BexExternalValue::FunctionRef { global_index: 1 } + )); + } + + #[test] + fn handle_type_unknown_is_allowed() { + let table = HandleTable::new(); + let key = table.insert(HandleTableValue::FunctionRef { global_index: 2 }); + let inbound = inbound_handle(key, BamlHandleType::HandleUnknown); + let out = inbound_to_external(inbound, &table).unwrap(); + assert!(matches!( + out, + BexExternalValue::FunctionRef { global_index: 2 } + )); + } + + #[test] + fn handle_type_mismatch_errors() { + let table = HandleTable::new(); + let key = table.insert(HandleTableValue::FunctionRef { global_index: 3 }); + let inbound = inbound_handle(key, BamlHandleType::AdtMediaImage); + let err = inbound_to_external(inbound, &table).unwrap_err(); + match err { + CtypesError::InvalidHandleType { key: err_key, .. } => { + assert_eq!(err_key, key); + } + _ => panic!("expected InvalidHandleType"), + } + } +} diff --git a/baml_language/crates/bridge_ctypes/src/value_encode.rs b/baml_language/crates/bridge_ctypes/src/value_encode.rs index 06f63dbdef..29090211f6 100644 --- a/baml_language/crates/bridge_ctypes/src/value_encode.rs +++ b/baml_language/crates/bridge_ctypes/src/value_encode.rs @@ -1,7 +1,7 @@ //! `BexExternalValue` -> `BamlOutboundValue` conversion. use baml_type::Literal; -use bex_project::{BexExternalAdt, BexExternalValue, Ty}; +use bex_project::{BexExternalAdt, BexExternalValue, MediaContent, Ty}; use crate::{ baml::cffi::{ @@ -24,6 +24,55 @@ pub fn external_to_baml_value( value: &BexExternalValue, options: &HandleTableOptions, ) -> Result { + let mut handles_created = Vec::new(); + let value = external_to_baml_value_inner(value, options, &mut handles_created)?; + Ok(BamlOutboundValue { + handles_created, + value, + }) +} + +fn encode_value( + value: &BexExternalValue, + options: &HandleTableOptions, + handles_created: &mut Vec, +) -> Result { + let value = external_to_baml_value_inner(value, options, handles_created)?; + Ok(BamlOutboundValue { + value, + ..Default::default() + }) +} + +fn encode_entries<'a, I>( + entries: I, + options: &HandleTableOptions, + handles_created: &mut Vec, +) -> Result, CtypesError> +where + I: IntoIterator, +{ + entries + .into_iter() + .map(|(key, val)| { + let value = encode_value(val, options, handles_created)?; + Ok(BamlOutboundMapEntry { + key: key.clone(), + value: Some(value), + }) + }) + .collect() +} + +fn build_handle(key: u64, handle_type: i32) -> BamlHandle { + BamlHandle { key, handle_type } +} + +fn external_to_baml_value_inner( + value: &BexExternalValue, + options: &HandleTableOptions, + handles_created: &mut Vec, +) -> Result, CtypesError> { let variant = match value { BexExternalValue::Null => None, BexExternalValue::Int(i) => Some(BamlValueVariant::IntValue(*i)), @@ -36,7 +85,7 @@ pub fn external_to_baml_value( } => { let values: Result, CtypesError> = items .iter() - .map(|v| external_to_baml_value(v, options)) + .map(|v| encode_value(v, options, handles_created)) .collect(); Some(BamlValueVariant::ListValue(BamlValueList { item_type: Some(ty_to_field_type(element_type)), @@ -48,13 +97,7 @@ pub fn external_to_baml_value( key_type, value_type, } => { - let mut baml_entries = Vec::new(); - for (key, val) in entries { - baml_entries.push(BamlOutboundMapEntry { - key: key.clone(), - value: Some(external_to_baml_value(val, options)?), - }); - } + let baml_entries = encode_entries(entries.iter(), options, handles_created)?; Some(BamlValueVariant::MapValue(BamlValueMap { key_type: Some(ty_to_field_type(key_type)), value_type: Some(ty_to_field_type(value_type)), @@ -62,13 +105,7 @@ pub fn external_to_baml_value( })) } BexExternalValue::Instance { class_name, fields } => { - let mut baml_fields = Vec::new(); - for (key, val) in fields { - baml_fields.push(BamlOutboundMapEntry { - key: key.clone(), - value: Some(external_to_baml_value(val, options)?), - }); - } + let baml_fields = encode_entries(fields.iter(), options, handles_created)?; Some(BamlValueVariant::ClassValue(BamlValueClass { name: Some(BamlTypeName { namespace: BamlTypeNamespace::Types as i32, @@ -89,7 +126,7 @@ pub fn external_to_baml_value( is_dynamic: false, })), BexExternalValue::Union { value, metadata } => { - let inner = external_to_baml_value(value, options)?; + let inner = encode_value(value, options, handles_created)?; Some(BamlValueVariant::UnionVariantValue(Box::new( BamlValueUnionVariant { name: metadata.name.as_ref().map(|n| BamlTypeName { @@ -105,9 +142,13 @@ pub fn external_to_baml_value( ))) } - BexExternalValue::Adt(BexExternalAdt::Media(media)) if options.serialize_media => Some( - BamlValueVariant::MediaValue(bex_media_to_proto_media(media)), - ), + BexExternalValue::Adt(BexExternalAdt::Media(media)) + if options.serialize_media && should_inline_media(media, options) => + { + Some(BamlValueVariant::MediaValue(bex_media_to_proto_media( + media, + ))) + } BexExternalValue::Adt(BexExternalAdt::PromptAst(prompt_ast)) if options.serialize_prompt_ast => @@ -122,19 +163,30 @@ pub fn external_to_baml_value( | BexExternalValue::Resource(_) | BexExternalValue::FunctionRef { .. } | BexExternalValue::Adt(_) => { - let table_value = HandleTableValue::try_from(value.clone()).map_err(|e| { + let table_value = HandleTableValue::try_from(value).map_err(|e| { CtypesError::InternalError(format!("handle table insertion failed: {e}")) })?; - let ht = table_value.handle_type(); + let handle_type = table_value.handle_type() as i32; let key = options.table.insert(table_value); - Some(BamlValueVariant::HandleValue(BamlHandle { + handles_created.push(build_handle(key, handle_type)); + Some(BamlValueVariant::HandleValue(build_handle( key, - handle_type: ht as i32, - })) + handle_type, + ))) } }; - Ok(BamlOutboundValue { value: variant }) + Ok(variant) +} + +fn should_inline_media(media: &bex_project::MediaValue, options: &HandleTableOptions) -> bool { + let Some(limit) = options.max_inline_media_bytes else { + return true; + }; + media.read_content(|content| match content { + MediaContent::Base64 { base64_data } => base64_data.len() <= limit, + MediaContent::Url { .. } | MediaContent::File { .. } => true, + }) } fn literal_to_field_type_literal(lit: &Literal) -> BamlFieldTypeLiteral { @@ -299,3 +351,78 @@ fn ty_to_field_type(ty: &Ty) -> BamlFieldType { BamlFieldType { r#type: field_type } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::handle_table::HandleTable; + use baml_type::MediaKind; + use bex_project::{BexExternalAdt, BexExternalValue, MediaContent, MediaValue}; + + fn options_for_media( + table: &HandleTable, + max_inline_media_bytes: usize, + ) -> HandleTableOptions<'_> { + HandleTableOptions { + table, + serialize_media: true, + serialize_prompt_ast: false, + max_inline_media_bytes: Some(max_inline_media_bytes), + } + } + + #[test] + fn handles_created_collects_opaque_values() { + let table = HandleTable::new(); + let options = HandleTableOptions { + table: &table, + serialize_media: false, + serialize_prompt_ast: false, + max_inline_media_bytes: None, + }; + + let value = BexExternalValue::FunctionRef { global_index: 1 }; + let out = external_to_baml_value(&value, &options).unwrap(); + + assert_eq!(out.handles_created.len(), 1); + assert!(matches!(out.value, Some(BamlValueVariant::HandleValue(_)))); + } + + #[test] + fn media_inlines_when_under_limit() { + let table = HandleTable::new(); + let options = options_for_media(&table, 3); + + let media = MediaValue::new( + MediaKind::Image, + MediaContent::Base64 { + base64_data: "AAA".to_string(), + }, + None, + ); + let value = BexExternalValue::Adt(BexExternalAdt::Media(std::sync::Arc::new(media))); + let out = external_to_baml_value(&value, &options).unwrap(); + + assert!(out.handles_created.is_empty()); + assert!(matches!(out.value, Some(BamlValueVariant::MediaValue(_)))); + } + + #[test] + fn media_falls_back_to_handle_over_limit() { + let table = HandleTable::new(); + let options = options_for_media(&table, 3); + + let media = MediaValue::new( + MediaKind::Image, + MediaContent::Base64 { + base64_data: "AAAA".to_string(), + }, + None, + ); + let value = BexExternalValue::Adt(BexExternalAdt::Media(std::sync::Arc::new(media))); + let out = external_to_baml_value(&value, &options).unwrap(); + + assert_eq!(out.handles_created.len(), 1); + assert!(matches!(out.value, Some(BamlValueVariant::HandleValue(_)))); + } +} diff --git a/baml_language/crates/bridge_ctypes/types/baml/cffi/v1/baml_outbound.proto b/baml_language/crates/bridge_ctypes/types/baml/cffi/v1/baml_outbound.proto index 65c04b2dc7..415021c7c6 100644 --- a/baml_language/crates/bridge_ctypes/types/baml/cffi/v1/baml_outbound.proto +++ b/baml_language/crates/bridge_ctypes/types/baml/cffi/v1/baml_outbound.proto @@ -35,6 +35,7 @@ message BamlOutboundValue { BamlValueMedia media_value = 17; BamlValuePromptAst prompt_ast_value = 18; } + repeated BamlHandle handles_created = 19; } enum BamlTypeNamespace { diff --git a/baml_language/crates/bridge_python/python_src/baml/cffi/v1/baml_inbound_pb2.py b/baml_language/crates/bridge_python/python_src/baml/cffi/v1/baml_inbound_pb2.py index 5aa232711d..d1d79d64fc 100644 --- a/baml_language/crates/bridge_python/python_src/baml/cffi/v1/baml_inbound_pb2.py +++ b/baml_language/crates/bridge_python/python_src/baml/cffi/v1/baml_inbound_pb2.py @@ -24,7 +24,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x62\x61ml/cffi/v1/baml_inbound.proto\x12\x0c\x62\x61ml.cffi.v1\"L\n\nBamlHandle\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x31\n\x0bhandle_type\x18\x02 \x01(\x0e\x32\x1c.baml.cffi.v1.BamlHandleType\"\xf5\x02\n\x0cInboundValue\x12\x16\n\x0cstring_value\x18\x02 \x01(\tH\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x04 \x01(\x01H\x00\x12\x14\n\nbool_value\x18\x05 \x01(\x08H\x00\x12\x34\n\nlist_value\x18\x06 \x01(\x0b\x32\x1e.baml.cffi.v1.InboundListValueH\x00\x12\x32\n\tmap_value\x18\x07 \x01(\x0b\x32\x1d.baml.cffi.v1.InboundMapValueH\x00\x12\x36\n\x0b\x63lass_value\x18\x08 \x01(\x0b\x32\x1f.baml.cffi.v1.InboundClassValueH\x00\x12\x34\n\nenum_value\x18\t \x01(\x0b\x32\x1e.baml.cffi.v1.InboundEnumValueH\x00\x12*\n\x06handle\x18\n \x01(\x0b\x32\x18.baml.cffi.v1.BamlHandleH\x00\x42\x07\n\x05value\">\n\x10InboundListValue\x12*\n\x06values\x18\x01 \x03(\x0b\x32\x1a.baml.cffi.v1.InboundValue\"A\n\x0fInboundMapValue\x12.\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x1d.baml.cffi.v1.InboundMapEntry\"\xb4\x01\n\x0fInboundMapEntry\x12\x14\n\nstring_key\x18\x01 \x01(\tH\x00\x12\x11\n\x07int_key\x18\x02 \x01(\x03H\x00\x12\x12\n\x08\x62ool_key\x18\x03 \x01(\x08H\x00\x12\x32\n\x08\x65num_key\x18\x05 \x01(\x0b\x32\x1e.baml.cffi.v1.InboundEnumValueH\x00\x12)\n\x05value\x18\x06 \x01(\x0b\x32\x1a.baml.cffi.v1.InboundValueB\x05\n\x03key\"P\n\x11InboundClassValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x1d.baml.cffi.v1.InboundMapEntry\"/\n\x10InboundEnumValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"A\n\x10\x43\x61llFunctionArgs\x12-\n\x06kwargs\x18\x01 \x03(\x0b\x32\x1d.baml.cffi.v1.InboundMapEntry\"&\n\x07\x43\x61llAck\x12\x0f\n\x05\x65rror\x18\x01 \x01(\tH\x00\x42\n\n\x08response*\xb0\x02\n\x0e\x42\x61mlHandleType\x12\x16\n\x12HANDLE_UNSPECIFIED\x10\x00\x12\x12\n\x0eHANDLE_UNKNOWN\x10\x01\x12\x11\n\rRESOURCE_FILE\x10\x02\x12\x13\n\x0fRESOURCE_SOCKET\x10\x03\x12\x1a\n\x16RESOURCE_HTTP_RESPONSE\x10\x04\x12\x10\n\x0c\x46UNCTION_REF\x10\x05\x12\x13\n\x0f\x41\x44T_MEDIA_IMAGE\x10\x06\x12\x13\n\x0f\x41\x44T_MEDIA_AUDIO\x10\x07\x12\x13\n\x0f\x41\x44T_MEDIA_VIDEO\x10\x08\x12\x11\n\rADT_MEDIA_PDF\x10\t\x12\x15\n\x11\x41\x44T_MEDIA_GENERIC\x10\n\x12\x12\n\x0e\x41\x44T_PROMPT_AST\x10\x0b\x12\x11\n\rADT_COLLECTOR\x10\x0c\x12\x0c\n\x08\x41\x44T_TYPE\x10\rB\x08Z\x06./cffib\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x62\x61ml/cffi/v1/baml_inbound.proto\x12\x0c\x62\x61ml.cffi.v1\"L\n\nBamlHandle\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x31\n\x0bhandle_type\x18\x02 \x01(\x0e\x32\x1c.baml.cffi.v1.BamlHandleType\"\xfb\x02\n\x0cInboundValue\x12\x16\n\x0cstring_value\x18\x02 \x01(\tH\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x04 \x01(\x01H\x00\x12\x14\n\nbool_value\x18\x05 \x01(\x08H\x00\x12\x34\n\nlist_value\x18\x06 \x01(\x0b\x32\x1e.baml.cffi.v1.InboundListValueH\x00\x12\x32\n\tmap_value\x18\x07 \x01(\x0b\x32\x1d.baml.cffi.v1.InboundMapValueH\x00\x12\x36\n\x0b\x63lass_value\x18\x08 \x01(\x0b\x32\x1f.baml.cffi.v1.InboundClassValueH\x00\x12\x34\n\nenum_value\x18\t \x01(\x0b\x32\x1e.baml.cffi.v1.InboundEnumValueH\x00\x12*\n\x06handle\x18\n \x01(\x0b\x32\x18.baml.cffi.v1.BamlHandleH\x00\x42\x07\n\x05valueJ\x04\x08\x01\x10\x02\">\n\x10InboundListValue\x12*\n\x06values\x18\x01 \x03(\x0b\x32\x1a.baml.cffi.v1.InboundValue\"A\n\x0fInboundMapValue\x12.\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x1d.baml.cffi.v1.InboundMapEntry\"\xb4\x01\n\x0fInboundMapEntry\x12\x14\n\nstring_key\x18\x01 \x01(\tH\x00\x12\x11\n\x07int_key\x18\x02 \x01(\x03H\x00\x12\x12\n\x08\x62ool_key\x18\x03 \x01(\x08H\x00\x12\x32\n\x08\x65num_key\x18\x05 \x01(\x0b\x32\x1e.baml.cffi.v1.InboundEnumValueH\x00\x12)\n\x05value\x18\x06 \x01(\x0b\x32\x1a.baml.cffi.v1.InboundValueB\x05\n\x03key\"P\n\x11InboundClassValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x1d.baml.cffi.v1.InboundMapEntry\"/\n\x10InboundEnumValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"A\n\x10\x43\x61llFunctionArgs\x12-\n\x06kwargs\x18\x01 \x03(\x0b\x32\x1d.baml.cffi.v1.InboundMapEntry\"&\n\x07\x43\x61llAck\x12\x0f\n\x05\x65rror\x18\x01 \x01(\tH\x00\x42\n\n\x08response*\xb0\x02\n\x0e\x42\x61mlHandleType\x12\x16\n\x12HANDLE_UNSPECIFIED\x10\x00\x12\x12\n\x0eHANDLE_UNKNOWN\x10\x01\x12\x11\n\rRESOURCE_FILE\x10\x02\x12\x13\n\x0fRESOURCE_SOCKET\x10\x03\x12\x1a\n\x16RESOURCE_HTTP_RESPONSE\x10\x04\x12\x10\n\x0c\x46UNCTION_REF\x10\x05\x12\x13\n\x0f\x41\x44T_MEDIA_IMAGE\x10\x06\x12\x13\n\x0f\x41\x44T_MEDIA_AUDIO\x10\x07\x12\x13\n\x0f\x41\x44T_MEDIA_VIDEO\x10\x08\x12\x11\n\rADT_MEDIA_PDF\x10\t\x12\x15\n\x11\x41\x44T_MEDIA_GENERIC\x10\n\x12\x12\n\x0e\x41\x44T_PROMPT_AST\x10\x0b\x12\x11\n\rADT_COLLECTOR\x10\x0c\x12\x0c\n\x08\x41\x44T_TYPE\x10\rB\x08Z\x06./cffib\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -32,24 +32,24 @@ if not _descriptor._USE_C_DESCRIPTORS: _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'Z\006./cffi' - _globals['_BAMLHANDLETYPE']._serialized_start=1056 - _globals['_BAMLHANDLETYPE']._serialized_end=1360 + _globals['_BAMLHANDLETYPE']._serialized_start=1062 + _globals['_BAMLHANDLETYPE']._serialized_end=1366 _globals['_BAMLHANDLE']._serialized_start=49 _globals['_BAMLHANDLE']._serialized_end=125 _globals['_INBOUNDVALUE']._serialized_start=128 - _globals['_INBOUNDVALUE']._serialized_end=501 - _globals['_INBOUNDLISTVALUE']._serialized_start=503 - _globals['_INBOUNDLISTVALUE']._serialized_end=565 - _globals['_INBOUNDMAPVALUE']._serialized_start=567 - _globals['_INBOUNDMAPVALUE']._serialized_end=632 - _globals['_INBOUNDMAPENTRY']._serialized_start=635 - _globals['_INBOUNDMAPENTRY']._serialized_end=815 - _globals['_INBOUNDCLASSVALUE']._serialized_start=817 - _globals['_INBOUNDCLASSVALUE']._serialized_end=897 - _globals['_INBOUNDENUMVALUE']._serialized_start=899 - _globals['_INBOUNDENUMVALUE']._serialized_end=946 - _globals['_CALLFUNCTIONARGS']._serialized_start=948 - _globals['_CALLFUNCTIONARGS']._serialized_end=1013 - _globals['_CALLACK']._serialized_start=1015 - _globals['_CALLACK']._serialized_end=1053 + _globals['_INBOUNDVALUE']._serialized_end=507 + _globals['_INBOUNDLISTVALUE']._serialized_start=509 + _globals['_INBOUNDLISTVALUE']._serialized_end=571 + _globals['_INBOUNDMAPVALUE']._serialized_start=573 + _globals['_INBOUNDMAPVALUE']._serialized_end=638 + _globals['_INBOUNDMAPENTRY']._serialized_start=641 + _globals['_INBOUNDMAPENTRY']._serialized_end=821 + _globals['_INBOUNDCLASSVALUE']._serialized_start=823 + _globals['_INBOUNDCLASSVALUE']._serialized_end=903 + _globals['_INBOUNDENUMVALUE']._serialized_start=905 + _globals['_INBOUNDENUMVALUE']._serialized_end=952 + _globals['_CALLFUNCTIONARGS']._serialized_start=954 + _globals['_CALLFUNCTIONARGS']._serialized_end=1019 + _globals['_CALLACK']._serialized_start=1021 + _globals['_CALLACK']._serialized_end=1059 # @@protoc_insertion_point(module_scope) diff --git a/baml_language/crates/bridge_python/python_src/baml/cffi/v1/baml_outbound_pb2.py b/baml_language/crates/bridge_python/python_src/baml/cffi/v1/baml_outbound_pb2.py index 244084b59f..b8a7119f34 100644 --- a/baml_language/crates/bridge_python/python_src/baml/cffi/v1/baml_outbound_pb2.py +++ b/baml_language/crates/bridge_python/python_src/baml/cffi/v1/baml_outbound_pb2.py @@ -25,7 +25,7 @@ from baml.cffi.v1 import baml_inbound_pb2 as baml_dot_cffi_dot_v1_dot_baml__inbound__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n baml/cffi/v1/baml_outbound.proto\x12\x0c\x62\x61ml.cffi.v1\x1a\x1f\x62\x61ml/cffi/v1/baml_inbound.proto\"\xa9\x05\n\x11\x42\x61mlOutboundValue\x12\x31\n\nnull_value\x18\x02 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlValueNullH\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x05 \x01(\x01H\x00\x12\x14\n\nbool_value\x18\x06 \x01(\x08H\x00\x12\x33\n\x0b\x63lass_value\x18\x07 \x01(\x0b\x32\x1c.baml.cffi.v1.BamlValueClassH\x00\x12\x31\n\nenum_value\x18\x08 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlValueEnumH\x00\x12;\n\rliteral_value\x18\t \x01(\x0b\x32\".baml.cffi.v1.BamlFieldTypeLiteralH\x00\x12\x31\n\nlist_value\x18\x0b \x01(\x0b\x32\x1b.baml.cffi.v1.BamlValueListH\x00\x12/\n\tmap_value\x18\x0c \x01(\x0b\x32\x1a.baml.cffi.v1.BamlValueMapH\x00\x12\x42\n\x13union_variant_value\x18\r \x01(\x0b\x32#.baml.cffi.v1.BamlValueUnionVariantH\x00\x12\x37\n\rchecked_value\x18\x0e \x01(\x0b\x32\x1e.baml.cffi.v1.BamlValueCheckedH\x00\x12\x46\n\x15streaming_state_value\x18\x0f \x01(\x0b\x32%.baml.cffi.v1.BamlValueStreamingStateH\x00\x12\x30\n\x0chandle_value\x18\x10 \x01(\x0b\x32\x18.baml.cffi.v1.BamlHandleH\x00\x42\x07\n\x05value\"P\n\x0c\x42\x61mlTypeName\x12\x32\n\tnamespace\x18\x01 \x01(\x0e\x32\x1f.baml.cffi.v1.BamlTypeNamespace\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x0f\n\rBamlValueNull\"o\n\rBamlValueList\x12.\n\titem_type\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12.\n\x05items\x18\x02 \x03(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\"S\n\x14\x42\x61mlOutboundMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\"\xa3\x01\n\x0c\x42\x61mlValueMap\x12-\n\x08key_type\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12/\n\nvalue_type\x18\x02 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12\x33\n\x07\x65ntries\x18\x03 \x03(\x0b\x32\".baml.cffi.v1.BamlOutboundMapEntry\"n\n\x0e\x42\x61mlValueClass\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\x12\x32\n\x06\x66ields\x18\x02 \x03(\x0b\x32\".baml.cffi.v1.BamlOutboundMapEntry\"\\\n\rBamlValueEnum\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\x12\r\n\x05value\x18\x02 \x01(\t\x12\x12\n\nis_dynamic\x18\x03 \x01(\x08\"\xec\x01\n\x15\x42\x61mlValueUnionVariant\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\x12\x13\n\x0bis_optional\x18\x02 \x01(\x08\x12\x19\n\x11is_single_pattern\x18\x03 \x01(\x08\x12.\n\tself_type\x18\x04 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12\x19\n\x11value_option_name\x18\x05 \x01(\t\x12.\n\x05value\x18\x06 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\"\x9a\x01\n\x10\x42\x61mlValueChecked\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\x12,\n\x06\x63hecks\x18\x03 \x03(\x0b\x32\x1c.baml.cffi.v1.BamlCheckValue\"\xf0\x07\n\rBamlFieldType\x12\x38\n\x0bstring_type\x18\x01 \x01(\x0b\x32!.baml.cffi.v1.BamlFieldTypeStringH\x00\x12\x32\n\x08int_type\x18\x02 \x01(\x0b\x32\x1e.baml.cffi.v1.BamlFieldTypeIntH\x00\x12\x36\n\nfloat_type\x18\x03 \x01(\x0b\x32 .baml.cffi.v1.BamlFieldTypeFloatH\x00\x12\x34\n\tbool_type\x18\x04 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlFieldTypeBoolH\x00\x12\x34\n\tnull_type\x18\x05 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlFieldTypeNullH\x00\x12:\n\x0cliteral_type\x18\x06 \x01(\x0b\x32\".baml.cffi.v1.BamlFieldTypeLiteralH\x00\x12\x36\n\nmedia_type\x18\x07 \x01(\x0b\x32 .baml.cffi.v1.BamlFieldTypeMediaH\x00\x12\x34\n\tenum_type\x18\x08 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlFieldTypeEnumH\x00\x12\x36\n\nclass_type\x18\t \x01(\x0b\x32 .baml.cffi.v1.BamlFieldTypeClassH\x00\x12?\n\x0ftype_alias_type\x18\n \x01(\x0b\x32$.baml.cffi.v1.BamlFieldTypeTypeAliasH\x00\x12\x34\n\tlist_type\x18\x0b \x01(\x0b\x32\x1f.baml.cffi.v1.BamlFieldTypeListH\x00\x12\x32\n\x08map_type\x18\x0c \x01(\x0b\x32\x1e.baml.cffi.v1.BamlFieldTypeMapH\x00\x12\x45\n\x12union_variant_type\x18\x0e \x01(\x0b\x32\'.baml.cffi.v1.BamlFieldTypeUnionVariantH\x00\x12<\n\roptional_type\x18\x0f \x01(\x0b\x32#.baml.cffi.v1.BamlFieldTypeOptionalH\x00\x12:\n\x0c\x63hecked_type\x18\x10 \x01(\x0b\x32\".baml.cffi.v1.BamlFieldTypeCheckedH\x00\x12\x43\n\x11stream_state_type\x18\x11 \x01(\x0b\x32&.baml.cffi.v1.BamlFieldTypeStreamStateH\x00\x12\x32\n\x08\x61ny_type\x18\x12 \x01(\x0b\x32\x1e.baml.cffi.v1.BamlFieldTypeAnyH\x00\x42\x06\n\x04type\"\x15\n\x13\x42\x61mlFieldTypeString\"\x12\n\x10\x42\x61mlFieldTypeInt\"\x14\n\x12\x42\x61mlFieldTypeFloat\"\x13\n\x11\x42\x61mlFieldTypeBool\"\x13\n\x11\x42\x61mlFieldTypeNull\"\x12\n\x10\x42\x61mlFieldTypeAny\"\"\n\x11\x42\x61mlLiteralString\x12\r\n\x05value\x18\x01 \x01(\t\"\x1f\n\x0e\x42\x61mlLiteralInt\x12\r\n\x05value\x18\x01 \x01(\x03\" \n\x0f\x42\x61mlLiteralBool\x12\r\n\x05value\x18\x01 \x01(\x08\"\xc8\x01\n\x14\x42\x61mlFieldTypeLiteral\x12\x39\n\x0estring_literal\x18\x01 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlLiteralStringH\x00\x12\x33\n\x0bint_literal\x18\x02 \x01(\x0b\x32\x1c.baml.cffi.v1.BamlLiteralIntH\x00\x12\x35\n\x0c\x62ool_literal\x18\x03 \x01(\x0b\x32\x1d.baml.cffi.v1.BamlLiteralBoolH\x00\x42\t\n\x07literal\"@\n\x12\x42\x61mlFieldTypeMedia\x12*\n\x05media\x18\x01 \x01(\x0e\x32\x1b.baml.cffi.v1.MediaTypeEnum\"!\n\x11\x42\x61mlFieldTypeEnum\x12\x0c\n\x04name\x18\x01 \x01(\t\">\n\x12\x42\x61mlFieldTypeClass\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\"B\n\x16\x42\x61mlFieldTypeTypeAlias\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\"C\n\x11\x42\x61mlFieldTypeList\x12.\n\titem_type\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\"r\n\x10\x42\x61mlFieldTypeMap\x12-\n\x08key_type\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12/\n\nvalue_type\x18\x02 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\"E\n\x19\x42\x61mlFieldTypeUnionVariant\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\"C\n\x15\x42\x61mlFieldTypeOptional\x12*\n\x05value\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\"o\n\x14\x42\x61mlFieldTypeChecked\x12*\n\x05value\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12+\n\x06\x63hecks\x18\x02 \x03(\x0b\x32\x1b.baml.cffi.v1.BamlCheckType\"F\n\x18\x42\x61mlFieldTypeStreamState\x12*\n\x05value\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\"\x1d\n\rBamlCheckType\x12\x0c\n\x04name\x18\x01 \x01(\t\"r\n\x0e\x42\x61mlCheckValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nexpression\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12.\n\x05value\x18\x04 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\"\xa1\x01\n\x17\x42\x61mlValueStreamingState\x12.\n\x05value\x18\x01 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\x12,\n\x05state\x18\x02 \x01(\x0e\x32\x1d.baml.cffi.v1.BamlStreamState\x12(\n\x04name\x18\x03 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName*i\n\x11\x42\x61mlTypeNamespace\x12\x0c\n\x08INTERNAL\x10\x00\x12\t\n\x05TYPES\x10\x01\x12\x10\n\x0cSTREAM_TYPES\x10\x02\x12\x16\n\x12STREAM_STATE_TYPES\x10\x03\x12\x11\n\rCHECKED_TYPES\x10\x04*9\n\rMediaTypeEnum\x12\t\n\x05IMAGE\x10\x00\x12\t\n\x05\x41UDIO\x10\x01\x12\x07\n\x03PDF\x10\x02\x12\t\n\x05VIDEO\x10\x03*5\n\x0f\x42\x61mlStreamState\x12\x0b\n\x07PENDING\x10\x00\x12\x0b\n\x07STARTED\x10\x01\x12\x08\n\x04\x44ONE\x10\x02\x42\x08Z\x06./cffib\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n baml/cffi/v1/baml_outbound.proto\x12\x0c\x62\x61ml.cffi.v1\x1a\x1f\x62\x61ml/cffi/v1/baml_inbound.proto\"\xcf\x06\n\x11\x42\x61mlOutboundValue\x12\x31\n\nnull_value\x18\x02 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlValueNullH\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x05 \x01(\x01H\x00\x12\x14\n\nbool_value\x18\x06 \x01(\x08H\x00\x12\x33\n\x0b\x63lass_value\x18\x07 \x01(\x0b\x32\x1c.baml.cffi.v1.BamlValueClassH\x00\x12\x31\n\nenum_value\x18\x08 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlValueEnumH\x00\x12;\n\rliteral_value\x18\t \x01(\x0b\x32\".baml.cffi.v1.BamlFieldTypeLiteralH\x00\x12\x31\n\nlist_value\x18\x0b \x01(\x0b\x32\x1b.baml.cffi.v1.BamlValueListH\x00\x12/\n\tmap_value\x18\x0c \x01(\x0b\x32\x1a.baml.cffi.v1.BamlValueMapH\x00\x12\x42\n\x13union_variant_value\x18\r \x01(\x0b\x32#.baml.cffi.v1.BamlValueUnionVariantH\x00\x12\x37\n\rchecked_value\x18\x0e \x01(\x0b\x32\x1e.baml.cffi.v1.BamlValueCheckedH\x00\x12\x46\n\x15streaming_state_value\x18\x0f \x01(\x0b\x32%.baml.cffi.v1.BamlValueStreamingStateH\x00\x12\x30\n\x0chandle_value\x18\x10 \x01(\x0b\x32\x18.baml.cffi.v1.BamlHandleH\x00\x12\x33\n\x0bmedia_value\x18\x11 \x01(\x0b\x32\x1c.baml.cffi.v1.BamlValueMediaH\x00\x12<\n\x10prompt_ast_value\x18\x12 \x01(\x0b\x32 .baml.cffi.v1.BamlValuePromptAstH\x00\x12\x31\n\x0fhandles_created\x18\x13 \x03(\x0b\x32\x18.baml.cffi.v1.BamlHandleB\x07\n\x05value\"P\n\x0c\x42\x61mlTypeName\x12\x32\n\tnamespace\x18\x01 \x01(\x0e\x32\x1f.baml.cffi.v1.BamlTypeNamespace\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x0f\n\rBamlValueNull\"o\n\rBamlValueList\x12.\n\titem_type\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12.\n\x05items\x18\x02 \x03(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\"S\n\x14\x42\x61mlOutboundMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\"\xa3\x01\n\x0c\x42\x61mlValueMap\x12-\n\x08key_type\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12/\n\nvalue_type\x18\x02 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12\x33\n\x07\x65ntries\x18\x03 \x03(\x0b\x32\".baml.cffi.v1.BamlOutboundMapEntry\"n\n\x0e\x42\x61mlValueClass\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\x12\x32\n\x06\x66ields\x18\x02 \x03(\x0b\x32\".baml.cffi.v1.BamlOutboundMapEntry\"\\\n\rBamlValueEnum\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\x12\r\n\x05value\x18\x02 \x01(\t\x12\x12\n\nis_dynamic\x18\x03 \x01(\x08\"\xec\x01\n\x15\x42\x61mlValueUnionVariant\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\x12\x13\n\x0bis_optional\x18\x02 \x01(\x08\x12\x19\n\x11is_single_pattern\x18\x03 \x01(\x08\x12.\n\tself_type\x18\x04 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12\x19\n\x11value_option_name\x18\x05 \x01(\t\x12.\n\x05value\x18\x06 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\"\x9a\x01\n\x10\x42\x61mlValueChecked\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\x12,\n\x06\x63hecks\x18\x03 \x03(\x0b\x32\x1c.baml.cffi.v1.BamlCheckValue\"\x9c\x01\n\x0e\x42\x61mlValueMedia\x12*\n\x05media\x18\x01 \x01(\x0e\x32\x1b.baml.cffi.v1.MediaTypeEnum\x12\x16\n\tmime_type\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\r\n\x03url\x18\x03 \x01(\tH\x00\x12\x10\n\x06\x62\x61se64\x18\x04 \x01(\tH\x00\x12\x0e\n\x04\x66ile\x18\x05 \x01(\tH\x00\x42\x07\n\x05valueB\x0c\n\n_mime_type\"\xd1\x01\n\x12\x42\x61mlValuePromptAst\x12\x38\n\x06simple\x18\x01 \x01(\x0b\x32&.baml.cffi.v1.BamlValuePromptAstSimpleH\x00\x12:\n\x07message\x18\x02 \x01(\x0b\x32\'.baml.cffi.v1.BamlValuePromptAstMessageH\x00\x12<\n\x08multiple\x18\x03 \x01(\x0b\x32(.baml.cffi.v1.BamlValuePromptAstMultipleH\x00\x42\x07\n\x05value\"|\n\x19\x42\x61mlValuePromptAstMessage\x12\x0c\n\x04role\x18\x01 \x01(\t\x12\x37\n\x07\x63ontent\x18\x02 \x01(\x0b\x32&.baml.cffi.v1.BamlValuePromptAstSimple\x12\x18\n\x10metadata_as_json\x18\x03 \x01(\t\"M\n\x1a\x42\x61mlValuePromptAstMultiple\x12/\n\x05items\x18\x01 \x03(\x0b\x32 .baml.cffi.v1.BamlValuePromptAst\"\xa8\x01\n\x18\x42\x61mlValuePromptAstSimple\x12\x10\n\x06string\x18\x01 \x01(\tH\x00\x12-\n\x05media\x18\x02 \x01(\x0b\x32\x1c.baml.cffi.v1.BamlValueMediaH\x00\x12\x42\n\x08multiple\x18\x03 \x01(\x0b\x32..baml.cffi.v1.BamlValuePromptAstSimpleMultipleH\x00\x42\x07\n\x05value\"Y\n BamlValuePromptAstSimpleMultiple\x12\x35\n\x05items\x18\x01 \x03(\x0b\x32&.baml.cffi.v1.BamlValuePromptAstSimple\"\xf0\x07\n\rBamlFieldType\x12\x38\n\x0bstring_type\x18\x01 \x01(\x0b\x32!.baml.cffi.v1.BamlFieldTypeStringH\x00\x12\x32\n\x08int_type\x18\x02 \x01(\x0b\x32\x1e.baml.cffi.v1.BamlFieldTypeIntH\x00\x12\x36\n\nfloat_type\x18\x03 \x01(\x0b\x32 .baml.cffi.v1.BamlFieldTypeFloatH\x00\x12\x34\n\tbool_type\x18\x04 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlFieldTypeBoolH\x00\x12\x34\n\tnull_type\x18\x05 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlFieldTypeNullH\x00\x12:\n\x0cliteral_type\x18\x06 \x01(\x0b\x32\".baml.cffi.v1.BamlFieldTypeLiteralH\x00\x12\x36\n\nmedia_type\x18\x07 \x01(\x0b\x32 .baml.cffi.v1.BamlFieldTypeMediaH\x00\x12\x34\n\tenum_type\x18\x08 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlFieldTypeEnumH\x00\x12\x36\n\nclass_type\x18\t \x01(\x0b\x32 .baml.cffi.v1.BamlFieldTypeClassH\x00\x12?\n\x0ftype_alias_type\x18\n \x01(\x0b\x32$.baml.cffi.v1.BamlFieldTypeTypeAliasH\x00\x12\x34\n\tlist_type\x18\x0b \x01(\x0b\x32\x1f.baml.cffi.v1.BamlFieldTypeListH\x00\x12\x32\n\x08map_type\x18\x0c \x01(\x0b\x32\x1e.baml.cffi.v1.BamlFieldTypeMapH\x00\x12\x45\n\x12union_variant_type\x18\x0e \x01(\x0b\x32\'.baml.cffi.v1.BamlFieldTypeUnionVariantH\x00\x12<\n\roptional_type\x18\x0f \x01(\x0b\x32#.baml.cffi.v1.BamlFieldTypeOptionalH\x00\x12:\n\x0c\x63hecked_type\x18\x10 \x01(\x0b\x32\".baml.cffi.v1.BamlFieldTypeCheckedH\x00\x12\x43\n\x11stream_state_type\x18\x11 \x01(\x0b\x32&.baml.cffi.v1.BamlFieldTypeStreamStateH\x00\x12\x32\n\x08\x61ny_type\x18\x12 \x01(\x0b\x32\x1e.baml.cffi.v1.BamlFieldTypeAnyH\x00\x42\x06\n\x04type\"\x15\n\x13\x42\x61mlFieldTypeString\"\x12\n\x10\x42\x61mlFieldTypeInt\"\x14\n\x12\x42\x61mlFieldTypeFloat\"\x13\n\x11\x42\x61mlFieldTypeBool\"\x13\n\x11\x42\x61mlFieldTypeNull\"\x12\n\x10\x42\x61mlFieldTypeAny\"\"\n\x11\x42\x61mlLiteralString\x12\r\n\x05value\x18\x01 \x01(\t\"\x1f\n\x0e\x42\x61mlLiteralInt\x12\r\n\x05value\x18\x01 \x01(\x03\" \n\x0f\x42\x61mlLiteralBool\x12\r\n\x05value\x18\x01 \x01(\x08\"\xc8\x01\n\x14\x42\x61mlFieldTypeLiteral\x12\x39\n\x0estring_literal\x18\x01 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlLiteralStringH\x00\x12\x33\n\x0bint_literal\x18\x02 \x01(\x0b\x32\x1c.baml.cffi.v1.BamlLiteralIntH\x00\x12\x35\n\x0c\x62ool_literal\x18\x03 \x01(\x0b\x32\x1d.baml.cffi.v1.BamlLiteralBoolH\x00\x42\t\n\x07literal\"@\n\x12\x42\x61mlFieldTypeMedia\x12*\n\x05media\x18\x01 \x01(\x0e\x32\x1b.baml.cffi.v1.MediaTypeEnum\"!\n\x11\x42\x61mlFieldTypeEnum\x12\x0c\n\x04name\x18\x01 \x01(\t\">\n\x12\x42\x61mlFieldTypeClass\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\"B\n\x16\x42\x61mlFieldTypeTypeAlias\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\"C\n\x11\x42\x61mlFieldTypeList\x12.\n\titem_type\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\"r\n\x10\x42\x61mlFieldTypeMap\x12-\n\x08key_type\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12/\n\nvalue_type\x18\x02 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\"E\n\x19\x42\x61mlFieldTypeUnionVariant\x12(\n\x04name\x18\x01 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName\"C\n\x15\x42\x61mlFieldTypeOptional\x12*\n\x05value\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\"o\n\x14\x42\x61mlFieldTypeChecked\x12*\n\x05value\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\x12+\n\x06\x63hecks\x18\x02 \x03(\x0b\x32\x1b.baml.cffi.v1.BamlCheckType\"F\n\x18\x42\x61mlFieldTypeStreamState\x12*\n\x05value\x18\x01 \x01(\x0b\x32\x1b.baml.cffi.v1.BamlFieldType\"\x1d\n\rBamlCheckType\x12\x0c\n\x04name\x18\x01 \x01(\t\"r\n\x0e\x42\x61mlCheckValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nexpression\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12.\n\x05value\x18\x04 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\"\xa1\x01\n\x17\x42\x61mlValueStreamingState\x12.\n\x05value\x18\x01 \x01(\x0b\x32\x1f.baml.cffi.v1.BamlOutboundValue\x12,\n\x05state\x18\x02 \x01(\x0e\x32\x1d.baml.cffi.v1.BamlStreamState\x12(\n\x04name\x18\x03 \x01(\x0b\x32\x1a.baml.cffi.v1.BamlTypeName*i\n\x11\x42\x61mlTypeNamespace\x12\x0c\n\x08INTERNAL\x10\x00\x12\t\n\x05TYPES\x10\x01\x12\x10\n\x0cSTREAM_TYPES\x10\x02\x12\x16\n\x12STREAM_STATE_TYPES\x10\x03\x12\x11\n\rCHECKED_TYPES\x10\x04*`\n\rMediaTypeEnum\x12\x1a\n\x16MEDIA_TYPE_UNSPECIFIED\x10\x00\x12\t\n\x05IMAGE\x10\x01\x12\t\n\x05\x41UDIO\x10\x02\x12\x07\n\x03PDF\x10\x03\x12\t\n\x05VIDEO\x10\x04\x12\t\n\x05OTHER\x10\x05*5\n\x0f\x42\x61mlStreamState\x12\x0b\n\x07PENDING\x10\x00\x12\x0b\n\x07STARTED\x10\x01\x12\x08\n\x04\x44ONE\x10\x02\x42\x08Z\x06./cffib\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -33,78 +33,90 @@ if not _descriptor._USE_C_DESCRIPTORS: _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'Z\006./cffi' - _globals['_BAMLTYPENAMESPACE']._serialized_start=4330 - _globals['_BAMLTYPENAMESPACE']._serialized_end=4435 - _globals['_MEDIATYPEENUM']._serialized_start=4437 - _globals['_MEDIATYPEENUM']._serialized_end=4494 - _globals['_BAMLSTREAMSTATE']._serialized_start=4496 - _globals['_BAMLSTREAMSTATE']._serialized_end=4549 + _globals['_BAMLTYPENAMESPACE']._serialized_start=5334 + _globals['_BAMLTYPENAMESPACE']._serialized_end=5439 + _globals['_MEDIATYPEENUM']._serialized_start=5441 + _globals['_MEDIATYPEENUM']._serialized_end=5537 + _globals['_BAMLSTREAMSTATE']._serialized_start=5539 + _globals['_BAMLSTREAMSTATE']._serialized_end=5592 _globals['_BAMLOUTBOUNDVALUE']._serialized_start=84 - _globals['_BAMLOUTBOUNDVALUE']._serialized_end=765 - _globals['_BAMLTYPENAME']._serialized_start=767 - _globals['_BAMLTYPENAME']._serialized_end=847 - _globals['_BAMLVALUENULL']._serialized_start=849 - _globals['_BAMLVALUENULL']._serialized_end=864 - _globals['_BAMLVALUELIST']._serialized_start=866 - _globals['_BAMLVALUELIST']._serialized_end=977 - _globals['_BAMLOUTBOUNDMAPENTRY']._serialized_start=979 - _globals['_BAMLOUTBOUNDMAPENTRY']._serialized_end=1062 - _globals['_BAMLVALUEMAP']._serialized_start=1065 - _globals['_BAMLVALUEMAP']._serialized_end=1228 - _globals['_BAMLVALUECLASS']._serialized_start=1230 - _globals['_BAMLVALUECLASS']._serialized_end=1340 - _globals['_BAMLVALUEENUM']._serialized_start=1342 - _globals['_BAMLVALUEENUM']._serialized_end=1434 - _globals['_BAMLVALUEUNIONVARIANT']._serialized_start=1437 - _globals['_BAMLVALUEUNIONVARIANT']._serialized_end=1673 - _globals['_BAMLVALUECHECKED']._serialized_start=1676 - _globals['_BAMLVALUECHECKED']._serialized_end=1830 - _globals['_BAMLFIELDTYPE']._serialized_start=1833 - _globals['_BAMLFIELDTYPE']._serialized_end=2841 - _globals['_BAMLFIELDTYPESTRING']._serialized_start=2843 - _globals['_BAMLFIELDTYPESTRING']._serialized_end=2864 - _globals['_BAMLFIELDTYPEINT']._serialized_start=2866 - _globals['_BAMLFIELDTYPEINT']._serialized_end=2884 - _globals['_BAMLFIELDTYPEFLOAT']._serialized_start=2886 - _globals['_BAMLFIELDTYPEFLOAT']._serialized_end=2906 - _globals['_BAMLFIELDTYPEBOOL']._serialized_start=2908 - _globals['_BAMLFIELDTYPEBOOL']._serialized_end=2927 - _globals['_BAMLFIELDTYPENULL']._serialized_start=2929 - _globals['_BAMLFIELDTYPENULL']._serialized_end=2948 - _globals['_BAMLFIELDTYPEANY']._serialized_start=2950 - _globals['_BAMLFIELDTYPEANY']._serialized_end=2968 - _globals['_BAMLLITERALSTRING']._serialized_start=2970 - _globals['_BAMLLITERALSTRING']._serialized_end=3004 - _globals['_BAMLLITERALINT']._serialized_start=3006 - _globals['_BAMLLITERALINT']._serialized_end=3037 - _globals['_BAMLLITERALBOOL']._serialized_start=3039 - _globals['_BAMLLITERALBOOL']._serialized_end=3071 - _globals['_BAMLFIELDTYPELITERAL']._serialized_start=3074 - _globals['_BAMLFIELDTYPELITERAL']._serialized_end=3274 - _globals['_BAMLFIELDTYPEMEDIA']._serialized_start=3276 - _globals['_BAMLFIELDTYPEMEDIA']._serialized_end=3340 - _globals['_BAMLFIELDTYPEENUM']._serialized_start=3342 - _globals['_BAMLFIELDTYPEENUM']._serialized_end=3375 - _globals['_BAMLFIELDTYPECLASS']._serialized_start=3377 - _globals['_BAMLFIELDTYPECLASS']._serialized_end=3439 - _globals['_BAMLFIELDTYPETYPEALIAS']._serialized_start=3441 - _globals['_BAMLFIELDTYPETYPEALIAS']._serialized_end=3507 - _globals['_BAMLFIELDTYPELIST']._serialized_start=3509 - _globals['_BAMLFIELDTYPELIST']._serialized_end=3576 - _globals['_BAMLFIELDTYPEMAP']._serialized_start=3578 - _globals['_BAMLFIELDTYPEMAP']._serialized_end=3692 - _globals['_BAMLFIELDTYPEUNIONVARIANT']._serialized_start=3694 - _globals['_BAMLFIELDTYPEUNIONVARIANT']._serialized_end=3763 - _globals['_BAMLFIELDTYPEOPTIONAL']._serialized_start=3765 - _globals['_BAMLFIELDTYPEOPTIONAL']._serialized_end=3832 - _globals['_BAMLFIELDTYPECHECKED']._serialized_start=3834 - _globals['_BAMLFIELDTYPECHECKED']._serialized_end=3945 - _globals['_BAMLFIELDTYPESTREAMSTATE']._serialized_start=3947 - _globals['_BAMLFIELDTYPESTREAMSTATE']._serialized_end=4017 - _globals['_BAMLCHECKTYPE']._serialized_start=4019 - _globals['_BAMLCHECKTYPE']._serialized_end=4048 - _globals['_BAMLCHECKVALUE']._serialized_start=4050 - _globals['_BAMLCHECKVALUE']._serialized_end=4164 - _globals['_BAMLVALUESTREAMINGSTATE']._serialized_start=4167 - _globals['_BAMLVALUESTREAMINGSTATE']._serialized_end=4328 + _globals['_BAMLOUTBOUNDVALUE']._serialized_end=931 + _globals['_BAMLTYPENAME']._serialized_start=933 + _globals['_BAMLTYPENAME']._serialized_end=1013 + _globals['_BAMLVALUENULL']._serialized_start=1015 + _globals['_BAMLVALUENULL']._serialized_end=1030 + _globals['_BAMLVALUELIST']._serialized_start=1032 + _globals['_BAMLVALUELIST']._serialized_end=1143 + _globals['_BAMLOUTBOUNDMAPENTRY']._serialized_start=1145 + _globals['_BAMLOUTBOUNDMAPENTRY']._serialized_end=1228 + _globals['_BAMLVALUEMAP']._serialized_start=1231 + _globals['_BAMLVALUEMAP']._serialized_end=1394 + _globals['_BAMLVALUECLASS']._serialized_start=1396 + _globals['_BAMLVALUECLASS']._serialized_end=1506 + _globals['_BAMLVALUEENUM']._serialized_start=1508 + _globals['_BAMLVALUEENUM']._serialized_end=1600 + _globals['_BAMLVALUEUNIONVARIANT']._serialized_start=1603 + _globals['_BAMLVALUEUNIONVARIANT']._serialized_end=1839 + _globals['_BAMLVALUECHECKED']._serialized_start=1842 + _globals['_BAMLVALUECHECKED']._serialized_end=1996 + _globals['_BAMLVALUEMEDIA']._serialized_start=1999 + _globals['_BAMLVALUEMEDIA']._serialized_end=2155 + _globals['_BAMLVALUEPROMPTAST']._serialized_start=2158 + _globals['_BAMLVALUEPROMPTAST']._serialized_end=2367 + _globals['_BAMLVALUEPROMPTASTMESSAGE']._serialized_start=2369 + _globals['_BAMLVALUEPROMPTASTMESSAGE']._serialized_end=2493 + _globals['_BAMLVALUEPROMPTASTMULTIPLE']._serialized_start=2495 + _globals['_BAMLVALUEPROMPTASTMULTIPLE']._serialized_end=2572 + _globals['_BAMLVALUEPROMPTASTSIMPLE']._serialized_start=2575 + _globals['_BAMLVALUEPROMPTASTSIMPLE']._serialized_end=2743 + _globals['_BAMLVALUEPROMPTASTSIMPLEMULTIPLE']._serialized_start=2745 + _globals['_BAMLVALUEPROMPTASTSIMPLEMULTIPLE']._serialized_end=2834 + _globals['_BAMLFIELDTYPE']._serialized_start=2837 + _globals['_BAMLFIELDTYPE']._serialized_end=3845 + _globals['_BAMLFIELDTYPESTRING']._serialized_start=3847 + _globals['_BAMLFIELDTYPESTRING']._serialized_end=3868 + _globals['_BAMLFIELDTYPEINT']._serialized_start=3870 + _globals['_BAMLFIELDTYPEINT']._serialized_end=3888 + _globals['_BAMLFIELDTYPEFLOAT']._serialized_start=3890 + _globals['_BAMLFIELDTYPEFLOAT']._serialized_end=3910 + _globals['_BAMLFIELDTYPEBOOL']._serialized_start=3912 + _globals['_BAMLFIELDTYPEBOOL']._serialized_end=3931 + _globals['_BAMLFIELDTYPENULL']._serialized_start=3933 + _globals['_BAMLFIELDTYPENULL']._serialized_end=3952 + _globals['_BAMLFIELDTYPEANY']._serialized_start=3954 + _globals['_BAMLFIELDTYPEANY']._serialized_end=3972 + _globals['_BAMLLITERALSTRING']._serialized_start=3974 + _globals['_BAMLLITERALSTRING']._serialized_end=4008 + _globals['_BAMLLITERALINT']._serialized_start=4010 + _globals['_BAMLLITERALINT']._serialized_end=4041 + _globals['_BAMLLITERALBOOL']._serialized_start=4043 + _globals['_BAMLLITERALBOOL']._serialized_end=4075 + _globals['_BAMLFIELDTYPELITERAL']._serialized_start=4078 + _globals['_BAMLFIELDTYPELITERAL']._serialized_end=4278 + _globals['_BAMLFIELDTYPEMEDIA']._serialized_start=4280 + _globals['_BAMLFIELDTYPEMEDIA']._serialized_end=4344 + _globals['_BAMLFIELDTYPEENUM']._serialized_start=4346 + _globals['_BAMLFIELDTYPEENUM']._serialized_end=4379 + _globals['_BAMLFIELDTYPECLASS']._serialized_start=4381 + _globals['_BAMLFIELDTYPECLASS']._serialized_end=4443 + _globals['_BAMLFIELDTYPETYPEALIAS']._serialized_start=4445 + _globals['_BAMLFIELDTYPETYPEALIAS']._serialized_end=4511 + _globals['_BAMLFIELDTYPELIST']._serialized_start=4513 + _globals['_BAMLFIELDTYPELIST']._serialized_end=4580 + _globals['_BAMLFIELDTYPEMAP']._serialized_start=4582 + _globals['_BAMLFIELDTYPEMAP']._serialized_end=4696 + _globals['_BAMLFIELDTYPEUNIONVARIANT']._serialized_start=4698 + _globals['_BAMLFIELDTYPEUNIONVARIANT']._serialized_end=4767 + _globals['_BAMLFIELDTYPEOPTIONAL']._serialized_start=4769 + _globals['_BAMLFIELDTYPEOPTIONAL']._serialized_end=4836 + _globals['_BAMLFIELDTYPECHECKED']._serialized_start=4838 + _globals['_BAMLFIELDTYPECHECKED']._serialized_end=4949 + _globals['_BAMLFIELDTYPESTREAMSTATE']._serialized_start=4951 + _globals['_BAMLFIELDTYPESTREAMSTATE']._serialized_end=5021 + _globals['_BAMLCHECKTYPE']._serialized_start=5023 + _globals['_BAMLCHECKTYPE']._serialized_end=5052 + _globals['_BAMLCHECKVALUE']._serialized_start=5054 + _globals['_BAMLCHECKVALUE']._serialized_end=5168 + _globals['_BAMLVALUESTREAMINGSTATE']._serialized_start=5171 + _globals['_BAMLVALUESTREAMINGSTATE']._serialized_end=5332 # @@protoc_insertion_point(module_scope) diff --git a/baml_language/crates/bridge_python/python_src/baml_py/proto.py b/baml_language/crates/bridge_python/python_src/baml_py/proto.py index db6d8fb8b7..17688ec581 100644 --- a/baml_language/crates/bridge_python/python_src/baml_py/proto.py +++ b/baml_language/crates/bridge_python/python_src/baml_py/proto.py @@ -10,8 +10,8 @@ from typing import Any, Dict from baml.cffi.v1 import baml_inbound_pb2, baml_outbound_pb2 -from baml_py.baml_py import BamlHandle +from baml_py.baml_py import BamlHandle # --------------------------------------------------------------------------- # Encoding: Python kwargs → CallFunctionArgs @@ -45,7 +45,9 @@ def _set_inbound_value(inbound_value, value: Any) -> None: for k, v in value.items(): _set_inbound_map_entry(map_val.entries.add(), k, v) else: - raise TypeError(f"Cannot encode value of type {type(value).__name__} to protobuf") + raise TypeError( + f"Cannot encode value of type {type(value).__name__} to protobuf" + ) def _set_inbound_map_entry(entry, key: Any, value: Any) -> None: @@ -132,6 +134,19 @@ def _decode_value_holder(holder) -> Any: return None +def _collect_handles(value: Any, used: set[int]) -> None: + if isinstance(value, BamlHandle): + used.add(value.key) + return + if isinstance(value, dict): + for item in value.values(): + _collect_handles(item, used) + return + if isinstance(value, (list, tuple)): + for item in value: + _collect_handles(item, used) + + def decode_call_result(data: bytes) -> Any: """Decode a BamlOutboundValue protobuf to a Python value. @@ -143,4 +158,14 @@ def decode_call_result(data: bytes) -> Any: """ holder = baml_outbound_pb2.BamlOutboundValue() holder.ParseFromString(data) - return _decode_value_holder(holder) + value = _decode_value_holder(holder) + + created = {handle.key for handle in holder.handles_created} + if created: + used: set[int] = set() + _collect_handles(value, used) + unused = created - used + if unused: + BamlHandle.release_many(list(unused)) + + return value diff --git a/baml_language/crates/bridge_python/src/handle.rs b/baml_language/crates/bridge_python/src/handle.rs index 5037c7cb1d..7c42d3c7a8 100644 --- a/baml_language/crates/bridge_python/src/handle.rs +++ b/baml_language/crates/bridge_python/src/handle.rs @@ -30,6 +30,11 @@ impl BamlHandle { self.handle_type } + #[staticmethod] + pub fn release_many(keys: Vec) { + HANDLE_TABLE.release_many(keys); + } + pub fn __copy__(&self) -> PyResult { let new_key = HANDLE_TABLE.clone_handle(self.key).ok_or_else(|| { pyo3::exceptions::PyRuntimeError::new_err("Handle is no longer valid") diff --git a/baml_language/crates/bridge_wasm/src/handle.rs b/baml_language/crates/bridge_wasm/src/handle.rs index 76d24a4706..f44833f576 100644 --- a/baml_language/crates/bridge_wasm/src/handle.rs +++ b/baml_language/crates/bridge_wasm/src/handle.rs @@ -23,6 +23,11 @@ fn type_name(ht: BamlHandleType) -> &'static str { } } +#[wasm_bindgen(js_name = "releaseHandles")] +pub fn release_handles(keys: Vec) { + HANDLE_TABLE.release_many(keys.into_iter().filter_map(|key| key.parse::().ok())); +} + /// A reference to an opaque BAML value held in the engine's handle table. /// /// When this object is garbage-collected by JS (via `FinalizationRegistry`), diff --git a/baml_language/crates/bridge_wasm/src/lib.rs b/baml_language/crates/bridge_wasm/src/lib.rs index 242eb30cfa..35c910da1a 100644 --- a/baml_language/crates/bridge_wasm/src/lib.rs +++ b/baml_language/crates/bridge_wasm/src/lib.rs @@ -46,6 +46,8 @@ mod error; mod handle; mod registry; + +pub use handle::release_handles; mod send_wrapper; mod wasm_env; mod wasm_fs;