Dsxir.LM behaviour (dsxir v0.5.0)

Copy Markdown

Behaviour for LM providers.

Predictors and adapters issue LM requests through this contract; they never reach into a specific provider SDK directly. The active impl plus its config live in Dsxir.Settings under :lm as a {impl_module, config :: keyword()} tuple. The dispatcher functions on this module read :lm from settings, merge per-call opts on top of the config, and invoke the impl.

The behaviour declares the callbacks predictors and adapters call. New callbacks (structured output for the Json adapter, streaming for the Chat adapter, embeddings for the in-memory retriever) extend the behaviour when their consumers land — old impls keep working while their new-callback path raises until implemented.

In tests, stub impl callbacks with mimic rather than building bespoke fakes.

Summary

Types

A streaming sink passed in opts under :stream. The 1-arity form is invoked once per Dsxir.LM.StreamChunk; the 2-arity accumulator form threads acc across chunks (callers carry parser state without a process). Implementations translate their provider's chunk type into Dsxir.LM.StreamChunk before invoking the sink, and still return the final assembled result.

Functions

Dispatch an embed call to the impl module currently active in Dsxir.Settings. Per-call opts are merged on top of the config. Raises Dsxir.Errors.Invalid.Configuration when :lm is unset, malformed, or the configured impl does not implement the optional embed/3 callback. Emits [:dsxir, :lm, :embed, :stop] on a successful result.

Zero-valued Dsxir.Cost used when the upstream LM reported no usage.

Dispatch a generate_object call to the impl module currently active in Dsxir.Settings, requesting a structured object validated against schema.

Dispatch a generate_text call to the impl module currently active in Dsxir.Settings. Per-call opts are merged on top of the config from settings. Raises Dsxir.Errors.Invalid.Configuration when :lm is unset or malformed.

Types

config()

@type config() :: keyword()

messages()

@type messages() :: [map()]

opts()

@type opts() :: keyword()

stream_sink()

@type stream_sink() ::
  (Dsxir.LM.StreamChunk.t() -> term())
  | {term(), (Dsxir.LM.StreamChunk.t(), term() -> term())}

A streaming sink passed in opts under :stream. The 1-arity form is invoked once per Dsxir.LM.StreamChunk; the 2-arity accumulator form threads acc across chunks (callers carry parser state without a process). Implementations translate their provider's chunk type into Dsxir.LM.StreamChunk before invoking the sink, and still return the final assembled result.

usage()

@type usage() :: Dsxir.Cost.t()

Callbacks

embed(config, list, opts)

(optional)
@callback embed(config(), [String.t()], opts()) ::
  {:ok, [[float()]], usage()} | {:error, term()}

generate_object(config, messages, schema, opts)

(optional)
@callback generate_object(config(), messages(), Zoi.schema(), opts()) ::
  {:ok, map(), usage()} | {:error, term()}

generate_text(config, messages, opts)

@callback generate_text(config(), messages(), opts()) ::
  {:ok, String.t(), usage()} | {:error, term()}

Functions

embed(inputs, opts \\ [])

@spec embed([String.t()], opts()) :: {:ok, [[float()]], usage()} | {:error, term()}

Dispatch an embed call to the impl module currently active in Dsxir.Settings. Per-call opts are merged on top of the config. Raises Dsxir.Errors.Invalid.Configuration when :lm is unset, malformed, or the configured impl does not implement the optional embed/3 callback. Emits [:dsxir, :lm, :embed, :stop] on a successful result.

empty_usage()

@spec empty_usage() :: Dsxir.Cost.t()

Zero-valued Dsxir.Cost used when the upstream LM reported no usage.

generate_object(messages, schema, opts \\ [])

@spec generate_object(messages(), Zoi.schema(), opts()) ::
  {:ok, map(), usage()} | {:error, term()}

Dispatch a generate_object call to the impl module currently active in Dsxir.Settings, requesting a structured object validated against schema.

Per-call opts are merged on top of the config from settings. Raises Dsxir.Errors.Invalid.Configuration when :lm is unset, malformed, or when the configured impl does not implement the optional generate_object/4 callback.

generate_text(messages, opts \\ [])

@spec generate_text(messages(), opts()) ::
  {:ok, String.t(), usage()} | {:error, term()}

Dispatch a generate_text call to the impl module currently active in Dsxir.Settings. Per-call opts are merged on top of the config from settings. Raises Dsxir.Errors.Invalid.Configuration when :lm is unset or malformed.