Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// One JSON Schema object for a function's parameters, derived from the
// signature: every parameter typed via baml.json.schema.
function _schema_for_signature(handler: baml.AnyFunction) -> map<string, unknown> {
function _schema_for_signature(handler: reflect.AnyFunction) -> map<string, unknown> {
let sig = reflect.signature(handler);
let props: map<string, unknown> = {};
let required: string[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Tool {
name: string,
description: string,
input_schema: map<string, unknown>, // JSON Schema for the arguments object
handler: baml.AnyFunction?, // signature-derived dispatch; null for raw tools
handler: reflect.AnyFunction?, // signature-derived dispatch; null for raw tools
// Dynamic-source dispatch: the handler receives the validated-by-schema
// argument map as one value. Set by raw_tool() when the schema does not
// derive from a BAML signature (MCP servers, OpenAPI specs).
Expand All @@ -26,7 +26,7 @@ class Tool {
if let rh: (map<string, unknown>) -> string throws unknown = self.raw_handler {
return rh(args);
}
if let h: baml.AnyFunction = self.handler {
if let h: reflect.AnyFunction = self.handler {
let value = reflect.call_any(h, args) catch (e) {
let bad: reflect.InvalidArgumentError => {
throw baml.errors.InvalidArgument { message: `invalid arguments for ${self.name}: ${bad.to_string()}` }
Expand All @@ -41,7 +41,7 @@ class Tool {

// The explicit constructor. `tools: [f]` normalizes through this.
function tool(
handler: baml.AnyFunction,
handler: reflect.AnyFunction,
name: string? = null,
description: string? = null,
on_error: ErrorMode? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ interface ToString {
}
}

/// Renders a reflected type's name. Declared here, beside the interface it
/// implements, rather than in the `reflect` package: `reflect.Type` is the
/// compiler metatype (no package dependency arises from naming it), while
/// `reflect` deliberately references nothing from `baml`, keeping the stdlib
/// dependency graph acyclic by construction.
implement root.ToString for reflect.Type {
function to_string(self) -> string throws never {
self._to_string_impl()
}
}

/// Internal: default structural rendering used by `string.from` for values
/// whose runtime type does not implement `baml.ToString`. Primitives render
/// naturally (`5`, `true`, `null`); containers and class instances render
Expand Down
103 changes: 0 additions & 103 deletions baml_language/crates/baml_builtins2/baml_std/baml/core.baml
Original file line number Diff line number Diff line change
Expand Up @@ -14,109 +14,6 @@ implement<T> Concrete for T {

}

/// Implemented automatically by every function value, with its parameter
/// list erased. `Returns` pins the held function's return type and `Throws`
/// its error type; both default to `unknown`, so a bare `AnyFunction`
/// accepts any function. A compiler builtin: it cannot be implemented by
/// hand, cannot be used as a generic bound, and declares no methods. Call
/// the held function through `reflect.call_any`; read its signature with
/// `reflect.signature`.
interface AnyFunction {
type Returns = unknown
type Throws = unknown
}

/// A read-only reflected view implemented automatically by class values.
///
/// Narrow an opaque value with `let value: baml.AnyClass = opaque else { ... }`
/// before using this surface. Ordinary class instances implement it, including
/// runtime-minted classes. Of the sealed reflection-kind views, only
/// `reflect.class.Type` implements it.
interface AnyClass {
/// Read a field as `T`. A missing field returns `null`; use `has_field` to
/// distinguish that case from a present field whose value is null.
function get<T>(self, name: string) -> T? throws baml.errors.TypeMismatch {
if (!self.has_field(name)) {
return null
}
// NOTE: spelled with `let … else` rather than `self.get_field(name)?.value<T>()`
// because an optional-chained call does not thread `T` to the callee.
let field: reflect.class.Field = self.get_field(name) else {
return null
}
field.value<T>()
}

/// Return a value-bound field handle, or `null` when no such field exists.
function get_field(self, name: string) -> reflect.class.Field? throws never {
let class_type: reflect.class.Type = reflect.Type.of_value(self).as_class() else {
return null
}
for (let field in class_type.fields()) {
if (field.name == name) {
return reflect.class.Field {
name: field.name,
type: field.type,
meta: field.meta,
_owner: self,
}
}
}
null
}

function has_field(self, name: string) -> bool throws never {
let class_type: reflect.class.Type = reflect.Type.of_value(self).as_class() else {
return false
}
for (let field in class_type.fields()) {
if (field.name == name) {
return true
}
}
false
}

/// Reflected fields bound to this value for `Field.value<T>()`.
function list_fields(self) -> reflect.class.Field[] throws never {
let class_type: reflect.class.Type = reflect.Type.of_value(self).as_class() else {
return []
}
let fields: reflect.class.Field[] = []
for (let field in class_type.fields()) {
fields.push(reflect.class.Field {
name: field.name,
type: field.type,
meta: field.meta,
_owner: self,
})
}
fields
}

function name(self) -> string throws never {
reflect.Type.of_value(self).to_string()
}

function type(self) -> reflect.Type throws never {
reflect.Type.of_value(self)
}

function attributes(self) -> reflect.Meta throws never {
let class_type: reflect.class.Type = reflect.Type.of_value(self).as_class() else {
return reflect.Meta {
alias: null,
description: null,
docstring: null,
other: {},
}
}
class_type.meta()
}
}

implement<T> AnyClass for T {}

/// The structured value a tagged template literal produces.
///
/// BEP-049 §10. A `tag` ` `…` ` call site lowers to `tag(body = () -> TaggedString { … })`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ class CompilationError {
/// could not be inferred and must be specified, or repeat occurrences of a
/// `TypeVar` have no consistent binding. Synthesized host-side from
/// `EngineError::TypeMismatch`; each host SDK surfaces it as its native
/// type-error (Python `TypeError`).
/// type-error (Python `TypeError`). The stdlib itself never throws this class
/// from BAML source (reflection's typed reads throw
/// `reflect.errors.TypeMismatch` instead); user code remains free to.
class TypeMismatch {
message: string,
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
/// An array-kind view of a `type` value. Users never construct this class.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
//baml:mut_vm
//baml:fallible
function element_type(self) -> reflect.Type throws never { $rust_function }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class Field {
name string
type reflect.Type?
meta reflect.Meta
/// Present only for handles returned from `baml.AnyClass.list_fields` or
/// Present only for handles returned from `reflect.AnyClass.list_fields` or
/// `get_field`. Type-side descriptors returned by `Type.fields()` are
/// intentionally ownerless.
_owner unknown?
Expand All @@ -13,13 +13,13 @@ class Field {

/// Read this field from its bound owner. An ownerless type-side descriptor
/// returns `null`.
function value<T>(self) -> T? throws baml.errors.TypeMismatch {
let owner: baml.AnyClass = self._owner else {
function value<T>(self) -> T? throws reflect.errors.TypeMismatch {
let owner: reflect.AnyClass = self._owner else {
return null
}
reflect.class.get_field<T>(owner, self.name) catch (e) {
reflect.errors.CompilationError { message } => {
throw baml.errors.TypeMismatch { message: message }
throw reflect.errors.TypeMismatch { message: message }
}
}
}
Expand Down Expand Up @@ -154,12 +154,20 @@ function get_field<T>(value: unknown, name: string) -> T throws reflect.errors.C

/// A class-kind view of a `type` value. Users never construct this class.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
//baml:mut_vm
//baml:fallible
function fields(self) -> Field[] throws never { $rust_function }
//baml:mut_vm
//baml:fallible
function meta(self) -> reflect.Meta throws never { $rust_function }
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,20 @@ function get_value(value: unknown) -> string throws never { $rust_function }

/// An enum-kind view of a `type` value. Users never construct this class.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
//baml:mut_vm
//baml:fallible
function values(self) -> Value[] throws never { $rust_function }
//baml:mut_vm
//baml:fallible
function meta(self) -> reflect.Meta throws never { $rust_function }
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ class EvaluationError {
message string
}

/// A reflective typed read did not fit the requested type: `Field.value<T>()`
/// or `AnyClass.get<T>()` asked for a `T` the underlying value is not.
///
/// Distinct from `baml.errors.TypeMismatch`, the host call-boundary error
/// synthesized from `EngineError::TypeMismatch` — that one names the FFI
/// contract; this one names a reflection read.
class TypeMismatch {
message string
}

/// A session rejected concurrent use.
class SessionBusy {
message string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@ class Parameter {
/// A function-kind view of a `type` value. Throws are intentionally not part
/// of the function reflection surface.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
//baml:mut_vm
//baml:fallible
function params(self) -> Parameter[] throws never { $rust_function }
//baml:mut_vm
//baml:fallible
function return_type(self) -> reflect.Type throws never { $rust_function }
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
/// An interface-kind view of a `type` value. Users never construct this class.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
//baml:vm
//baml:fallible
function implemented_by(self, other: reflect.Type) -> bool throws never { $rust_function }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ function new(value: string | int | bool) -> Type throws never {

/// A literal-kind view of a `type` value. Users never construct this class.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@ function new(key: reflect.Type, value: reflect.Type) -> Type throws never {

/// A map-kind view of a `type` value. Users never construct this class.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
//baml:mut_vm
//baml:fallible
function key_type(self) -> reflect.Type throws never { $rust_function }
//baml:mut_vm
//baml:fallible
function value_type(self) -> reflect.Type throws never { $rust_function }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/// A primitive-kind view of a `type` value. Users never construct this class.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ function new(types: reflect.Type[]) -> Type throws reflect.errors.CompilationErr

/// A union-kind view of a `type` value. Users never construct this class.
class Type {
/// The wrapped `type` value. Private by invariant: reflection natives are
/// its only readers, and each kind method panics if the held type no longer
/// classifies as this view's kind.
_ty reflect.Type

implements reflect.TypeView {
//baml:vm
//baml:fallible
function as_type(self) -> reflect.Type throws never { $rust_function }
}
//baml:mut_vm
//baml:fallible
function member_types(self) -> reflect.Type[] throws never { $rust_function }
}
Loading
Loading