LangSchema.Converter behaviour (LangSchema v0.3.0)

View Source

Defines the behaviour and provides a macro for creating specific schema converters.

This module serves as a foundation for transforming an abstract schema definition into a JSON schema compatible with a specific AI provider (like OpenAI, Gemini, etc.).

It defines the convert/2 callback that all specific converter modules must implement and provides a __using__ macro to inject basic conversion logic and allow for customization.

Usage

To create a new converter for a specific provider, you use LangSchema.Converter within your module definition and implement the required callbacks.

See LangSchema.Converter.OpenAI and LangSchema.Converter.Gemini.

Summary

Callbacks

Returns the list of supported schema combination types.

Converts a schema into a JSON schema.

Returns a map of keyword-specific processors.

Returns a map of custom type converters.

Wraps the resulting JSON schema into a final structure required by the target provider.

Types

combination()

@type combination() :: :any_of | :one_of | :all_of

Callbacks

allowed_combinations()

@callback allowed_combinations() :: [combination()]

Returns the list of supported schema combination types.

This specifies which JSON Schema combinators are allowed during conversion. Common values include :any_of, :one_of, and :all_of, corresponding to anyOf, oneOf, and allOf in the JSON Schema specification.

You can override this in a specific converter module if a provider supports only a subset.

convert(schema, opts)

@callback convert(schema :: map(), opts :: keyword()) :: json_schema :: map()

Converts a schema into a JSON schema.

Options

The supported options are:

  • :ordered_properties - If set to true, the properties of objects will be ordered according to the order they are defined in the schema. Default is false.

    When this option is enabled, the properties in the object schema should ideally be provided as a keyword list to preserve the order, since maps in Elixir do not retain insertion order. For providers like Gemini that support a separate propertyOrdering field, using a map may still work. However, if you're targeting multiple AI providers, using a keyword list is recommended to ensure consistent ordering behavior.

    Ordered properties may be serialized using Jason.OrderedObject to retain order in the resulting JSON string. This assumes that Jason is used for final serialization; other encoders are not currently supported for ordered output.

  • :wrap? – If set to false, the resulting JSON schema will be returned as-is, without being passed through the wrap/2 function. By default, wrap/2 may add an outer structure around the schema (e.g., placing it under a "schema" field) depending on the needs of the target AI provider.

    Disabling wrapping can be useful when the final schema needs to be embedded manually or used in a context that does not require such additional structure. Default is true.

keywords()

@callback keywords() :: map()

Returns a map of keyword-specific processors.

Each key represents a JSON Schema keyword (e.g., :pattern, :nullable), and its value is a module responsible for processing that keyword during conversion.

If a keyword is not explicitly handled, the behavior defined in LangSchema.Keyword.Default is applied.

See LangSchema.Keyword for more details about keyword processing and extension.

By default, returns an empty map.

types()

@callback types() :: map()

Returns a map of custom type converters.

This allows overriding or extending the default type conversion logic for each type. Keys must be atoms (e.g., :string, :object), and values must implement the corresponding conversion logic.

See LangSchema.Type modules for how to define custom type converters.

By default, returns an empty map.

wrap(json_schema, opts)

@callback wrap(json_schema :: map(), opts :: keyword()) :: json_schema :: map()

Wraps the resulting JSON schema into a final structure required by the target provider.

This function is used when a provider requires the JSON schema to be embedded within an additional enclosing structure. For example, OpenAI's Chat Completion expects the schema to be placed under a "schema" field.

This function is also designed to be compatible with the json_schema input expected by the LangChain library.

By default, it returns the JSON schema as-is. You can override this function in a specific converter module to modify the wrapping behavior.

Functions

convert(schema, converter_mod, opts)