ToolCall. Typespec
(ToolCall v0.1.0)
Copy Markdown
Converts a quoted typespec AST (aliases already expanded) into ToolCall.IR.Type.
This module is deliberately total: unknown shapes degrade to :any rather
than raising, so that adding a new typespec construct to a codebase never
breaks compilation of unrelated tools.
Summary
Functions
True when the tree contains an object whose keys the spec does not fix.
Maps a quoted type to a ToolCall.IR.Type.
True when the tree contains a tuple, which strict mode cannot express.
True when the tree contains a domain JSON cannot represent at all.
True when the tree has no JSON type the model can constrain against.
Validates a runtime ToolCall.IR.Tool and returns a copy with prepared
parameters.
Validates a runtime ToolCall.IR.Type and returns a copy with compiled
pattern_regex.
Functions
@spec open_object?(ToolCall.IR.Type.t() | nil) :: boolean()
True when the tree contains an object whose keys the spec does not fix.
Strict mode closes every object with additionalProperties: false, so an open
one reaches the model as an object that accepts no key at all.
@spec to_type(term(), [module()]) :: ToolCall.IR.Type.t()
Maps a quoted type to a ToolCall.IR.Type.
Aliases must already be expanded (Macro.expand/2), otherwise remote types
such as String.t() arrive as {:__aliases__, ...} and degrade to :any.
Built-in providers resolve String, Keyword, Path and the calendar types
and are used by default. Passing providers explicitly replaces that default;
use ToolCall, types: [...] prepends the built-ins before the user list. A
provider must return a well-formed IR node: an unknown kind, a non-string or
uncompilable pattern, a malformed transform, enum values, bounds, bound
ordering, array minimums, formats, nullability, field metadata, or malformed
fields/items/variants/additional raises at compile time.
@spec tuple?(ToolCall.IR.Type.t() | nil) :: boolean()
True when the tree contains a tuple, which strict mode cannot express.
OpenAI rejects prefixItems, so the emitter can only keep the arity.
@spec unrepresentable?(ToolCall.IR.Type.t()) :: boolean()
True when the tree contains a domain JSON cannot represent at all.
:any is not unrepresentable: it means "unknown", and JSON can carry any
value for it. Only :unsupported (functions, pids, refs) is.
@spec untyped?(ToolCall.IR.Type.t() | nil) :: boolean()
True when the tree has no JSON type the model can constrain against.
This is broader than unrepresentable?/1: :any and open objects do have a
JSON encoding, but they cannot be typed in the strict schema subset.
@spec validate_tool!(ToolCall.IR.Tool.t()) :: ToolCall.IR.Tool.t()
Validates a runtime ToolCall.IR.Tool and returns a copy with prepared
parameters.
Parameter types are validated through validate_type!/1, so hand-built
patterns receive a compiled pattern_regex; tool and parameter metadata are
checked as well.
@spec validate_type!(ToolCall.IR.Type.t()) :: ToolCall.IR.Type.t()
Validates a runtime ToolCall.IR.Type and returns a copy with compiled
pattern_regex.
Use this for hand-built types before passing them to ToolCall.Coerce or
rendering them with ToolCall.Emit.