@@dynamic

The @@dynamic attribute in BAML allows for the dynamic modification of fields or values at runtime. This is particularly useful when you need to adapt the structure of your data models based on runtime conditions or external inputs.

Usage

Dynamic Classes

The @@dynamic attribute can be applied to classes, enabling the addition of fields dynamically during runtime.

BAML
class MyClass {
property1 string
property2 int?
@@dynamic // allows adding fields dynamically at runtime
}

Dynamic Enums

Similarly, the @@dynamic attribute can be applied to enums, allowing for the modification of enum values at runtime.

BAML
enum MyEnum {
Value1
Value2
@@dynamic // allows modifying enum values dynamically at runtime
}

Using @@dynamic with TypeBuilder

To modify dynamic types at runtime, you can use the TypeBuilder from the baml_client. Below are examples for Python, TypeScript, and Ruby.

Read more about the TypeBuilder in the TypeBuilder section.

Python Example

from baml_client.type_builder import TypeBuilder
from baml_client import b
async def run():
tb = TypeBuilder()
tb.MyClass.add_property('email', tb.string())
tb.MyClass.add_property('address', tb.string()).description("The user's address")
res = await b.DynamicUserCreator("some user info", { "tb": tb })
# Now res can have email and address fields
print(res)

TypeScript Example

import TypeBuilder from '../baml_client/type_builder'
import { b } from '../baml_client'
async function run() {
const tb = new TypeBuilder()
tb.MyClass.addProperty('email', tb.string())
tb.MyClass.addProperty('address', tb.string()).description("The user's address")
const res = await b.DynamicUserCreator("some user info", { tb: tb })
// Now res can have email and address fields
console.log(res)
}

Ruby Example

require_relative 'baml_client/client'
def run
tb = Baml::TypeBuilder.new
tb.MyClass.add_property('email', tb.string)
tb.MyClass.add_property('address', tb.string).description("The user's address")
res = Baml::Client.dynamic_user_creator(input: "some user info", baml_options: {tb: tb})
# Now res can have email and address fields
puts res
end

Testing Dynamic Types

Dynamic classes and enums can be modified in tests using the type_builder and dynamic blocks. All properties added in the dynamic block will be available during the test execution.

class DynamicClass {
static_prop string
@@dynamic
}
function ReturnDynamicClass(input: string) -> DynamicClass {
// ...
}
test DynamicClassTest {
functions [ReturnDynamicClass]
type_builder {
dynamic class DynamicClass {
new_prop_here string
}
}
args {
input "test data"
}
}