Types
Here’s a list of all the types that can be represented in BAML:
Primitive Types
boolintfloatstringnull
Literal Types
This feature was added in: v0.61.0.
The primitive types string, int and bool can be constrained to a specific value.
For example, you can use literal values as return types:
See Union(|) for more details.
Multimodal Types
See calling a function with multimodal types and testing image inputs
Implementation details: runtime and security considerations
BAML’s multimodal types are designed for ease of use: we have deliberately made it
easy for you to construct an image, audio, pdf, or video instance from a URL. Under the
hood, depending on the model you’re using, BAML may need to download the file
and transcode it (usually as base64) for the model to consume.
This ease-of-use does come with some tradeoffs; namely, if you construct a multimodal instance using untrusted user input, you may be exposing yourself to server-side request forgery (SSRF) attacks. Attackers may be able to fetch files on your internal network, on external networks using your application’s identity, or simply excessively drive up your cloud network bandwidth bill.
To prevent this, we recommend only using URLs from trusted sources/users or validating them using allowlists or denylists.
image
You can use an image like this for models that support them:
You cannot name a variable image at the moment as it is a reserved keyword.
Calling a function with an image type:
Pydantic compatibility
If using Pydantic, the following are valid ways to construct the Image type.
audio
Example
Calling functions that have audio types.
pdf
Example
Note Pdf inputs must be provided as Base64 data using
Pdf.from_base64. URL-based inputs are not currently supported.
video
Example
Calling functions that have video types.
Note When you provide a
Videovia URL the URL is passed directly to the model. Some models cannot download external media; in that case convert the video to Base64 first.
Composite/Structured Types
enum
See also: Enum
A user-defined type consisting of a set of named constants. Use it when you need a model to choose from a known set of values, like in classification problems
If you need to add new variants, because they need to be loaded from a file or fetched dynamically from a database, you can do this with Dynamic Types.
class
See also: Class
Classes are for user-defined complex data structures.
Use when you need an LLM to call another function (e.g. OpenAI’s function calling), you can model the function’s parameters as a class. You can also get models to return complex structured data by using a class.
Example:
Note that properties have no :
If you need to add fields to a class because some properties of your class are only known at runtime, you can do this with Dynamic Types.
Optional (?)
A type that represents a value that might or might not be present.
Useful when a variable might not have a value and you want to explicitly handle its absence.
Syntax: Type?
Example: int? or (MyClass | int)?
Union (|)
A type that can hold one of several specified types.
This can be helpful with function calling, where you want to return different types of data depending on which function should be called.
Syntax: Type1 | Type2
Example: int | string or (int | string) | MyClass or string | MyClass | int[]
Order is important. int | string is not the same as string | int.
For example, if you have a "1" string, it will be parsed as an int if
you use int | string, but as a string if you use string | int.
List/Array ([])
A collection of elements of the same type.
Syntax: Type[]
Example: string[] or (int | string)[] or int[][]
- Array types can be nested to create multi-dimensional arrays
- An array type cannot be optional
Map
A mapping of strings or enums to elements of another type.
Syntax: map<string, ValueType>
Example: map<string, string>
Enums and literal strings can also be used as keys.
❌ Set
- Not yet supported. Use a
Listinstead.
❌ Tuple
- Not yet supported. Use a
classinstead.
Type Aliases
This feature was added in: v0.71.0.
A type alias is an alternative name for an existing type. It can be used to
simplify complex types or to give a more descriptive name to a type. Type
aliases are defined using the type keyword:
Type aliases can point to other aliases:
Recursive type aliases are supported only through map or list containers, just like in TypeScript:
Aliases can also refer to themselves:
However, this is invalid since no value can satisfy this type:
Examples and Equivalents
Here are some examples and what their equivalents are in different languages.
Example 1
Example 2
Example 3
Example 4
Example 5
⚠️ Unsupported
any/json- Not supported. We don’t want to encourage its use as it defeats the purpose of having a type system. if you really need it, for now usestringand calljson.parseyourself or use dynamic typesdatetime- Not yet supported. Use astringinstead.duration- Not yet supported. We recommend usingstringand specifying that it must be an “ISO8601 duration” in the description, which you can parse yourself into a duration.units (currency, temperature)- Not yet supported. Use a number (intorfloat) and have the unit be part of the variable name. For example,temperature_fahrenheitandcost_usd(see @alias)