Registry for stem-native workflow specs + per-agent pipeline instances.
Specs are discovered by scanning a configurable OTP application's module list
for modules matching a prefix that implement WorkflowStem.SpecBehaviour.
Configuration (in config/*.exs):
config :workflow_stem,
spec_discovery: {:my_app, "Elixir.MyApp.Workflows.Specs."}If spec_discovery is not set, defaults to scanning :workflow_stem itself.
This keeps stem enablement ergonomic (no per-workflow config allowlists) while remaining predictable (we only scan the application module list, not the filesystem).
Per-agent pipeline instances
When a spec declares :route primitives (see WorkflowStem.SpecBehaviour),
each agent gets its own compiled ALF pipeline instance keyed on
{agent_id, workflow_handle}. ensure_instance/2 lazily compiles and
caches the module via :persistent_term; release_instance/2 stops and
evicts it (e.g. on persona change / hot-swap).
Specs without routes fall through to the shared static
WorkflowStem.Pipelines.Stepwise pipeline — no per-agent compilation
happens and all existing workflows keep working unchanged.
Summary
Functions
Ensure a pipeline instance exists for {agent_id, workflow_handle} and
return the module to call.
Variant that accepts the spec map directly, bypassing module discovery.
Return a cached pipeline instance module for {agent_id, workflow_handle},
or nil if none has been compiled yet.
Stop and evict a cached pipeline instance. Safe to call even if no
instance was ever compiled. Next ensure_instance/2 call will
re-compile from the current spec.
Functions
Ensure a pipeline instance exists for {agent_id, workflow_handle} and
return the module to call.
Behaviour:
- If the spec declares no
:routeprimitives, returns the sharedWorkflowStem.Pipelines.Stepwisemodule. No per-agent compilation. - Otherwise, compiles (if not already cached) an ALF module via
WorkflowStem.Pipeline.Builder, starts it, caches it, and returns the module.
Variant that accepts the spec map directly, bypassing module discovery.
Useful for callers that already have the spec in hand (e.g. Atrapos
loading a persona YAML) and for tests where the spec module isn't
registered in :application.get_key/2.
Return a cached pipeline instance module for {agent_id, workflow_handle},
or nil if none has been compiled yet.
Stop and evict a cached pipeline instance. Safe to call even if no
instance was ever compiled. Next ensure_instance/2 call will
re-compile from the current spec.
@spec spec_modules() :: [module()]