Behaviour and safe dispatcher for executable Imp programs.
An Imp program is any struct whose module implements call/2 and returns
either {:ok, %Imp.Prediction{}} or {:error, reason}. Imp.Module.call/2
is the central boundary used by evaluators, composition modules, streaming,
optimizers, and the public Imp.call/2 facade. It catches callback crashes
and normalizes malformed callback returns so composed workflows can report
failures without losing the rest of the run. A program that raises, throws
or exits returns {:error, {:module_call_failed, module, reason}}, where
reason is the exception struct it raised or {kind, value} for a throw or
an exit; one that returns anything else returns
{:error, {:invalid_module_result, module, inspected}}.
Consumer-defined multi-stage programs may expose named predictors to every
program optimizer by implementing the paired optional callbacks
optimizer_predictors/1 and update_optimizer_predictor/3. Both callbacks
are required together. Predictor names must be unique atoms or strings and
each value must be an Imp.Predict struct. The update callback must
return the same program struct after applying the supplied function to the
named predictor. Imp.ProgramParameters validates this contract before an
optimizer can use it.
Programs may additionally expose arbitrary data-only components with the
paired optimizer_components/1 and update_optimizer_components/2
callbacks. Components carry descriptions, executable constraints, and
dependency identities. The batch update callback must be pure and return the
same program struct; Imp validates the complete change set before invoking it.
Summary
Functions
Calls an Imp executable program and normalizes its result shape.
Executes a program with explicit per-run capabilities when it supports them.
Types
@type optimizer_predictor_entry() :: {optimizer_predictor_name(), optimizer_predictor()} | %{name: optimizer_predictor_name(), predictor: optimizer_predictor()}
Callbacks
@callback call(struct(), map() | keyword()) :: {:ok, Imp.Prediction.t()} | {:error, term()}
@callback execute(struct(), map() | keyword(), Imp.Execution.t()) :: {:ok, Imp.Prediction.t()} | {:error, term()}
@callback optimizer_components(struct()) :: [Imp.Optimizer.Component.t() | map()]
@callback optimizer_predictors(struct()) :: [optimizer_predictor_entry()]
@callback update_optimizer_components(struct(), %{ required(String.t()) => Imp.Optimizer.Parameter.json_value() }) :: struct()
@callback update_optimizer_predictor( struct(), optimizer_predictor_name(), (optimizer_predictor() -> optimizer_predictor()) ) :: struct()
Functions
Calls an Imp executable program and normalizes its result shape.
Successful programs must return a Imp.Prediction:
iex> lm = Imp.LM.Static.new(handler: fn _messages, _opts -> %{answer: "4"} end)
iex> program = Imp.Predict.new("question -> answer", lm: lm)
iex> {:ok, prediction} = Imp.Module.call(program, %{question: "2+2?"})
iex> Imp.Prediction.get(prediction, :answer)
"4"Non-program values are reported as not callable:
iex> Imp.Module.call(%{}, %{question: "q"})
{:error, {:not_callable, %{}}}
Executes a program with explicit per-run capabilities when it supports them.