nemoguardrails.guardrails.compiled_rail

View as Markdown

Manifest-driven rail execution for IORails.

A CompiledRail is the executable unit behind one configured flow string. It is built once, at engine construction. It resolves the flow’s RailSurface from the manifest catalog, imports the library action the surface declares, and freezes a plan for filling that action’s parameters. Thereafter each request is one await action(**kwargs) and the returned RailOutcome is passed back to the caller unchanged.

Module Contents

Classes

NameDescription
CompiledRailOne configured flow, resolved to a library action and ready to run.
RailCompilationErrorA configured flow cannot be turned into an executable rail.
RailDependenciesRuntime collaborators a rail action may declare as parameters.
RailExecutionOne rail run: its engine-neutral verdict, plus every model call the action made.
_BoundParameterOne action parameter and the value the manifest says fills it.
_ContextParameterOne action parameter and the conversation variable that fills it, per request.

Functions

NameDescription
_accepted_parametersReturn the parameter names action accepts by name.
_accepts_arbitrary_keywordsWhether action has a **kwargs catch-all, so any keyword can be passed to it.
_binding_source_keyReturn a non-literal binding’s source key, or fail compilation naming the parameter.
_context_parametersPlan the bindings filled from the request’s own conversation variables.
_frozen_parametersFreeze the bindings whose values are known at compile time: literals and $params.
_hf_classifier_runs_locallyWhether the selected classifier runs in-process, per backends.get_backend.
_history_before_current_turnThe turns preceding the one being checked.
_is_installedWhether distribution is installed, without importing it.
_jailbreak_detection_runs_locallyWhether jailbreak detection runs in-process, which it does with no endpoint configured.
_llm_calls_fromPull the LLMCallInfo records out of a processing-log sink.
_owning_manifestReturn the manifest declaring surface, or None if the catalog has no owner for it.
_rail_config_sectionReturn rails.config.<name> from a RailsConfig, or None when it is not configured.
_reject_missing_dependenciesFail compilation when a rail’s optional dependency is declared but not installed.
_reject_unaccepted_bindingsFail compilation when the manifest binds a parameter the action cannot be passed.
_reject_unconfigured_modelsFail compilation when a rail names a model type the configuration does not declare.
_request_contextBuild the conversation variables for one request.
_resolve_surfaceFind the manifest surface for flow, or explain why there is not one.
_unapplicable_transform_reasonReport a surface declaring a rewrite IORails has nowhere to put.
_unsupported_context_keysReturn declared context variables that IORails cannot construct.
_unsupported_context_reasonReport context requirements outside IORails’ request contract.
_unsupported_rail_reasonManually edited blocklist of unsupported rails with reasons why
compile_railCompile one configured flow string into an executable rail.
messages_to_eventsConvert IORails messages into the event shapes conversation-history actions read.
unservable_reasonWhy flow cannot run under manifest-driven execution, or None when it can.
unsupported_surface_reasonWhy manifest-driven execution cannot run surface, or None when it can.

Data

_BOT_UTTERANCE_EVENT

_CONTEXT_KEYS

_LOCAL_BACKEND_CHECKS

_REWRITABLE_TARGET

_SURFACE_SUPPORT_CHECKS

_SYSTEM_MESSAGE_EVENT

_USER_MESSAGE_EVENT

log

API

class nemoguardrails.guardrails.compiled_rail.CompiledRail(
flow: str,
action: typing.Callable[..., typing.Any],
accepted: frozenset[str]
)

One configured flow, resolved to a library action and ready to run.

surface_name
str

The manifest surface name, without any $param= suffix.

transform_target
Optional[TransformTarget]

The variable the manifest says this rail may rewrite, which is how it is scheduled.

nemoguardrails.guardrails.compiled_rail.CompiledRail._call_kwargs(
bot_response: typing.Optional[str]
) -> dict[str, typing.Any]

Assemble the action’s arguments from its declared parameters and the manifest.

nemoguardrails.guardrails.compiled_rail.CompiledRail._invoke(
bot_response: typing.Optional[str]
) -> typing.Any
async

Call the action, awaiting it only if it is asynchronous.

Two shipped library actions are plain def (the guardrails_ai validators), so an unconditional await would raise TypeError on every request and the fail-closed envelope would report a working rail as a block. ActionDispatcher has always made the same allowance for LLMRails.

nemoguardrails.guardrails.compiled_rail.CompiledRail._request_dependencies(
) -> dict[str, typing.Any]

Every value injectable by parameter name; the caller filters against the signature.

nemoguardrails.guardrails.compiled_rail.CompiledRail.execute(
bot_response: typing.Optional[str] = None
async

Execute the rail, returning its verdict and the model calls it made.

A fresh processing_log_var sink is installed around the action, so llm_calls holds this rail’s calls and only this rail’s — live calls, cache hits and jailbreak’s NIM call all append there, and a rail that reaches no model appends nothing.

nemoguardrails.guardrails.compiled_rail.CompiledRail.run(
bot_response: typing.Optional[str] = None
async

Execute the rail and return its engine-neutral verdict.

nemoguardrails.guardrails.compiled_rail.CompiledRail.with_runtime_dependencies(
) -> 'CompiledRail'

Return the same execution plan with its runtime collaborators finalized.

class nemoguardrails.guardrails.compiled_rail.RailCompilationError()
Exception

Bases: Exception

A configured flow cannot be turned into an executable rail.

Raised while compiling, never while serving a request: a rail that fails mid-request produces a blocking outcome through rail_guard instead. The message is user-facing — it is why a config is not servable — so name the flow and what is wrong with it.

class nemoguardrails.guardrails.compiled_rail.RailDependencies(
llms: typing.Mapping[str, typing.Any],
llm_task_manager: typing.Any,
config: typing.Any,
model_caches: typing.Optional[typing.Mapping[str, typing.Any]] = None,
http_client: typing.Optional['HTTPClient'] = None,
tracer: typing.Optional['Tracer'] = None
)
Dataclass

Runtime collaborators a rail action may declare as parameters.

Injection is by parameter name, matching how the Colang runtimes supply the same values to the same actions. An action receives only what its signature declares.

http_client
Optional['HTTPClient'] = None
llms
Mapping[str, Any]
model_caches
Optional[Mapping[str, Any]] = None
tracer
Optional['Tracer'] = None
class nemoguardrails.guardrails.compiled_rail.RailExecution(
llm_calls: tuple['LLMCallInfo', ...] = ()
)
Dataclass

One rail run: its engine-neutral verdict, plus every model call the action made.

The caller converts outcome into its own result type; CompiledRail never does.

llm_calls
tuple['LLMCallInfo', ...] = ()
outcome
RailOutcome
class nemoguardrails.guardrails.compiled_rail._BoundParameter(
action_param: str,
value: typing.Any,
resource: typing.Optional[nemoguardrails.manifests.BindingResource] = None
)
Dataclass

One action parameter and the value the manifest says fills it.

action_param
str
resource
Optional[BindingResource] = None
class nemoguardrails.guardrails.compiled_rail._ContextParameter(
action_param: str,
key: str
)
Dataclass

One action parameter and the conversation variable that fills it, per request.

Unlike a literal or a surface parameter this cannot be frozen at compile time: its value is the request’s own text, so freezing it would pin every later request to the first one.

action_param
str
key
str
nemoguardrails.guardrails.compiled_rail._accepted_parameters(
action: typing.Callable[..., typing.Any]
) -> frozenset[str]

Return the parameter names action accepts by name.

**kwargs is excluded deliberately: a catch-all would otherwise look like a parameter called kwargs and be handed the wrong value.

nemoguardrails.guardrails.compiled_rail._accepts_arbitrary_keywords(
action: typing.Callable[..., typing.Any]
) -> bool

Whether action has a **kwargs catch-all, so any keyword can be passed to it.

nemoguardrails.guardrails.compiled_rail._binding_source_key(
flow: str
) -> str

Return a non-literal binding’s source key, or fail compilation naming the parameter.

nemoguardrails.guardrails.compiled_rail._context_parameters(
flow: str

Plan the bindings filled from the request’s own conversation variables.

A context binding maps one variable onto a specific action parameter, which is not the same as injecting the whole context dict: user_message reaches an action that calls the parameter text or user_prompt.

nemoguardrails.guardrails.compiled_rail._frozen_parameters(
params: typing.Mapping[str, str],
flow: str

Freeze the bindings whose values are known at compile time: literals and $params.

nemoguardrails.guardrails.compiled_rail._hf_classifier_runs_locally(
config: typing.Any,
params: typing.Mapping[str, str]
) -> bool

Whether the selected classifier runs in-process, per backends.get_backend.

nemoguardrails.guardrails.compiled_rail._history_before_current_turn(

The turns preceding the one being checked.

Actions append the checked turn themselves, from their bound user_message, and always at the end. So the history stops short of it: emitting it here would hand the model the same turn twice, and emitting what follows it — an assistant reply in a check() transcript, say — would place a later turn ahead of it and reorder the conversation. With no user turn to check, every message is history.

nemoguardrails.guardrails.compiled_rail._is_installed(
distribution: str
) -> bool

Whether distribution is installed, without importing it.

nemoguardrails.guardrails.compiled_rail._jailbreak_detection_runs_locally(
config: typing.Any,
params: typing.Mapping[str, str]
) -> bool

Whether jailbreak detection runs in-process, which it does with no endpoint configured.

nemoguardrails.guardrails.compiled_rail._llm_calls_from(
sink: list[dict[str, typing.Any]]
) -> tuple['LLMCallInfo', ...]

Pull the LLMCallInfo records out of a processing-log sink.

nemoguardrails.guardrails.compiled_rail._owning_manifest(
catalog: 'RailCatalog'
) -> typing.Optional[typing.Any]

Return the manifest declaring surface, or None if the catalog has no owner for it.

nemoguardrails.guardrails.compiled_rail._rail_config_section(
config: typing.Any,
name: str
) -> typing.Any

Return rails.config.<name> from a RailsConfig, or None when it is not configured.

nemoguardrails.guardrails.compiled_rail._reject_missing_dependencies(
catalog: 'RailCatalog',
flow: str,
config: typing.Any,
params: typing.Mapping[str, str]
) -> None

Fail compilation when a rail’s optional dependency is declared but not installed.

Library actions import their optional dependency lazily, inside the function, as nemoguardrails/AGENTS.md requires. Nothing therefore fails until a request arrives, and the fail-closed envelope turns the ImportError into a block — so a config missing an extra is indistinguishable, to the caller, from one whose rail genuinely tripped. Refusing at compile time reports it once, as the configuration error it is.

A manifest offering both an in-process and a remote backend is enforced only when the configuration selects the in-process one; see _LOCAL_BACKEND_CHECKS.

Checked by distribution rather than by import, so it costs no import and needs no mapping from a package name to a module name — guardrails-ai imports as guardrails.

nemoguardrails.guardrails.compiled_rail._reject_unaccepted_bindings(
action: typing.Callable[..., typing.Any],
bound_params: typing.Sequence[str],
accepted: frozenset[str],
flow: str
) -> None

Fail compilation when the manifest binds a parameter the action cannot be passed.

Note the asymmetry with injection, which is easy to get wrong. Injection ignores **kwargs because “should this be offered?” must come from declared parameters, or a catch-all gets handed every dependency. This asks “can this be passed?”, which a catch-all always can — so reusing the injection set here refuses actions that work.

nemoguardrails.guardrails.compiled_rail._reject_unconfigured_models(
flow: str
) -> None

Fail compilation when a rail names a model type the configuration does not declare.

Model bindings identify this dependency explicitly. This covers both a configurable $model= and a model type baked into the manifest without coupling compilation to the action parameter’s name.

nemoguardrails.guardrails.compiled_rail._request_context(
bot_response: typing.Optional[str]
) -> dict[str, str]

Build the conversation variables for one request.

nemoguardrails.guardrails.compiled_rail._resolve_surface(
flow: str,
catalog: 'RailCatalog'
) -> tuple[nemoguardrails.manifests.RailSurface, dict[str, str]]

Find the manifest surface for flow, or explain why there is not one.

nemoguardrails.guardrails.compiled_rail._unapplicable_transform_reason(
) -> typing.Optional[str]

Report a surface declaring a rewrite IORails has nowhere to put.

Refuses nothing today: every shipped surface agrees with its direction, and no schema rule makes it.

nemoguardrails.guardrails.compiled_rail._unsupported_context_keys(
) -> tuple[str, ...]

Return declared context variables that IORails cannot construct.

nemoguardrails.guardrails.compiled_rail._unsupported_context_reason(
) -> typing.Optional[str]

Report context requirements outside IORails’ request contract.

nemoguardrails.guardrails.compiled_rail._unsupported_rail_reason(
) -> typing.Optional[str]

Manually edited blocklist of unsupported rails with reasons why

nemoguardrails.guardrails.compiled_rail.compile_rail(
flow: str,
catalog: typing.Optional['RailCatalog'] = None

Compile one configured flow string into an executable rail.

Unservable rails raise a RailCompilationError, validated at compile time.

nemoguardrails.guardrails.compiled_rail.messages_to_events(
) -> list[dict[str, typing.Any]]

Convert IORails messages into the event shapes conversation-history actions read. Used by actions which are tightly-coupled with colang event definitions for backwards-compatibility.

nemoguardrails.guardrails.compiled_rail.unservable_reason(
flow: str,
catalog: typing.Optional['RailCatalog'] = None
) -> typing.Optional[str]

Why flow cannot run under manifest-driven execution, or None when it can.

nemoguardrails.guardrails.compiled_rail.unsupported_surface_reason(
) -> typing.Optional[str]

Why manifest-driven execution cannot run surface, or None when it can.

nemoguardrails.guardrails.compiled_rail._BOT_UTTERANCE_EVENT = 'StartUtteranceBotAction'
nemoguardrails.guardrails.compiled_rail._CONTEXT_KEYS = ('user_message', 'bot_message')
nemoguardrails.guardrails.compiled_rail._LOCAL_BACKEND_CHECKS: dict[str, Callable[[Any, Mapping[str, str]], bool]] = {'hf_classifier': _hf_classifier_runs_locally, 'jailbreak_detection': _jailbreak...
nemoguardrails.guardrails.compiled_rail._REWRITABLE_TARGET: dict[RailDirection, TransformTarget] = {RailDirection.INPUT: TransformTarget.USER_MESSAGE, RailDirection.OUTPUT: Transf...
nemoguardrails.guardrails.compiled_rail._SURFACE_SUPPORT_CHECKS: tuple[Callable[[RailSurface], Optional[str]], ...] = (_unapplicable_transform_reason, _unsupported_context_reason, _unsupported_rail_...
nemoguardrails.guardrails.compiled_rail._SYSTEM_MESSAGE_EVENT = 'SystemMessage'
nemoguardrails.guardrails.compiled_rail._USER_MESSAGE_EVENT = 'UserMessage'
nemoguardrails.guardrails.compiled_rail.log = logging.getLogger(__name__)