All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
0.6.0 - 2026-10-21
Added
- The
descriptionof a resource attribute, or of a map or typed struct field, is carried into its field schema, soZoi.to_json_schema/1(and a tool schema built from it) describes each field.
Fixed
- Single-variant unions now validate their wrapper and value instead of raising.
- Handle Spark's MFA representation of regex
matchconstraints. - Exclude local Dialyzer PLT caches from Hex packages.
Changed
- Breaking: Parsing supported Ash types now returns native values:
%Ash.Union{},%Money{},%Ash.CiString{}, resource structs, and TypedStruct structs instead of their input maps/strings. Nested values and NewType subtypes are converted too. JSON Schema continues to describe input shapes; Elixir typespecs describe outputs. Resource parsing constructs structs without running Ash actions or authorization. - Money parsing now validates currency codes and rejects non-finite amounts via
Money.new/3, returning Zoi errors rather than invalid money maps. - Require Zoi
~> 0.18.11for improved discriminated unions and JSON Schema encoding. - Update locked dependencies: Ash to 3.36.1, Decimal to 3.2.0, Spark to 2.7.8, and Ymlr to 5.1.6.
0.5.0 - 2026-10-07
Added
- Ash resource descriptions are now preserved in generated Zoi schema metadata and JSON Schema output.
0.4.1 - 2026-08-12
Changed
- Loosened the Zoi dependency requirement to
~> 0.17, allowing newer Zoi releases that support Decimal 3.
0.4.0 - 2026-06-09
Added
:coerceoption forto_schema/2— whencoerce: trueis passed, enablesZoi.coerce/1on all nodes in the generated schema. This allowsZoi.parse/2to automatically coerce values to expected types: JSON floats toDecimal, strings to enum atoms, and string map keys to atom keys. Useful when parsing raw JSON (e.g. from LLM responses) that needs to be cast through Ash types.
0.3.0 - 2026-06-04
Added
AshMoney.Types.Moneysupport — money types are now converted toZoi.map(%{currency: Zoi.string(), amount: Zoi.decimal()})withmin/maxconstraints applied to the amount field. Requires the optionalash_moneydependency; without it, money types fall back toZoi.any().
0.2.1 - 2026-04-08
Fixed
Ash.Type.Enumschemas now accept string values and coerce them to atoms. Previously, enums generated withAshZoi.to_schema/2only accepted atom inputs, which broke LLM tool call flows where parameters arrive as JSON strings.
0.2.0 - 2026-04-07
Added
Ash.Type.Enumsupport — enums defined withuse Ash.Type.Enum, values: [...]are now converted toZoi.enum(values)for proper validation
0.1.0 - 2026-03-23
Added
AshZoi.to_schema/2for converting Ash types to Zoi validation schemas- Support for all built-in Ash types: String, CiString, Integer, Float, Boolean, Atom, Decimal, Date, Time, DateTime, NaiveDatetime, UtcDatetime, UtcDatetimeUsec, UUID, UUIDv7, Binary, Map, Struct, Module, and Union
- Automatic constraint mapping from Ash to Zoi (min/max → gte/lte, min_length/max_length, match → regex, one_of → enum)
- Ash Resource introspection — pass a resource module to generate a Zoi map schema from its public attributes
:onlyand:exceptoptions for filtering resource attributes- Embedded resource support — nested resources are converted recursively
Ash.Type.Structsupport withinstance_ofandfieldsconstraintsAsh.Type.Unionsupport viaZoi.discriminated_union/3using Ash's_union_type/_union_valueinput formatAsh.TypedStructsupport — typed structs are introspected and converted to Zoi map schemasAsh.Type.NewTypesupport — NewTypes are automatically unwrapped to their underlying type with merged constraints- Array type support (
{:array, type}) with element-level and array-level constraints - Depth-limited NewType unwrapping to prevent infinite recursion