What's Changed
NeMo Guardrails 0.24.0 substantially expands the built-in rails available through IORails. IORails can now execute 59 of the library's 67 action-backed input and output surfaces, including community integrations and rails that transform content, while sharing the same underlying rail implementations with LLMRails.
Three related foundations make this possible:
RailOutcome: decide once, render many. A rail action returns one engine-neutral allow, block, or transform result that either LLMRails or IORails can enforce.- Rail manifests: declare, don't infer. Built-in rails describe their configuration, actions, execution surfaces, requirements, and privacy properties so both engines can discover and use them without maintaining separate support lists.
- Shared outbound HTTP. Built-in integrations now use a common client boundary for connection pooling, retries, TLS, error handling, lifecycle management, and privacy-safe tracing and metrics.
This release also adds F5 Guardrails integration, server health endpoints, multiple namespaced self-check rails, output checking through /v1/checks, and extensive correctness improvements for streaming, provider errors, reasoning responses, and OpenAI-compatible server requests.
Breaking changes
- Custom actions using
@action(output_mapping=...)must remove that argument and return an explicitRailOutcomefrom the action. - Install
transformersandtorchdirectly instead of using the removedhf-classifierextra. - IORails calls that supply generation options now return
GenerationResponse, and message lists must be passed withmessages=rather than positionally. - Custom Colang 1 flows using the former space-separated Cleanlab, Fiddler, or GCP action names must use their snake_case names.
/v1/checksnow selects a server-loaded configuration throughconfig_idor the server default instead of accepting inline configuration.- Chat Completions requests must use supported role-specific OpenAI message shapes; internal event payloads, unexpected fields, and audio requests are rejected.
🚀 Features
- (actions) Add the engine-neutral
RailOutcomeallow, block, and transform contract (#2150) - (rails) Add the typed rail manifest contract (#2157)
- (http) Add the canonical outbound HTTP client and request lifecycle (#2209, #2210)
- (http) Add outbound client tracing and metrics (#2219)
- (iorails) Execute blocking rail outcomes directly (#2264)
- (iorails) Apply transforming rail outcomes to input and output content (#2288)
- (iorails) Add message checks (#2059)
- (iorails) [breaking] Return
GenerationResponsefrom non-streaminggenerate()andgenerate_async()calls when options are supplied; pass message lists withmessages=instead of positionally (#2178) - (self-check) Run multiple self-check rails with per-rail namespaced task prompts (#1874, #2175)
- (server) Add output-rail checking mode to
/v1/checks(#2205) - (server) Add
/v1/healthand/healthzhealth-check endpoints (#2169) - (llm) Add shared model telemetry and an instrumented model decorator (#2214)
- (library) Add F5 Guardrails integration (#2105)
🐛 Bug Fixes
- (streaming) Fail closed when rail actions fail (#2152)
- (library) [breaking] Make bundled manifest flows portable across Colang versions; custom Colang 1 flows using legacy space-separated Cleanlab, Fiddler, or GCP action names must switch to snake_case names (#2185)
- (actions) Make
RailDecisionJSON serializable (#2194) - (iorails) Preserve normalized usage and provider metadata in
include_metadata=Truestreams (#2198) - (iorails) Honor model-level
default_headersin non-streaming and streaming HTTP requests (#2220) - (server) [breaking] Remove inline configuration from
/v1/checks; select a server-loaded configuration withconfig_idor use the server default (#2228) - (server) Return OpenAI-compatible HTTP error envelopes while preserving provider status, code, parameter, and retry metadata (#1832)
- (server) Return HTTP 400 for thread IDs without a datastore and preserve the configured main model API-key field during request model injection (#2240)
- (server) Honor request-level stop parameters and reject chat messages that omit a role before dispatch (#2266)
- (llm) Preserve streaming usage on terminal chunks (#2295)
- (content-safety) Surface response parsing errors instead of silently allowing malformed results (#2294)
- (checks) Reject unsatisfiable
rail_typeswith HTTP 422 instead of silently passing (#2276) - (iorails) Propagate
default_queryparameters in model HTTP requests (#2296) - (server) Preserve configured main model fields when a request specifies a model (#2298)
- (iorails) Map provider, timeout, connection, response, and streaming failures to safe client errors while preserving HTTP status and retry metadata (#2306)
- (server) [breaking] Validate Chat Completions messages by role and reject internal event payloads, unexpected fields, and unsupported audio requests; send only supported OpenAI-compatible message shapes (#2311)
- (server) Inline
<think>tags when reasoning content is present (#2316) - (iorails) Handle reasoning-only non-streaming responses (#2317)
- (iorails) Distinguish policy blocks from rail execution failures so callers can identify retryable provider outages (#2318)
💼 Other
- (dependencies) [breaking] Remove the
hf-classifierinstall extra and its packages fromall; installtransformersandtorchdirectly for the local classifier backend (#2137)
🚜 Refactor
- (actions) [breaking] Migrate built-in rail actions and streaming bypasses to
RailOutcomeand remove@action(output_mapping=...); custom rail actions usingoutput_mappingmust return explicitRailOutcomedecisions (#2151) - (http) Migrate built-in integration request helpers and vendor actions to the canonical managed HTTP client lifecycle (#2211, #2212)
- (iorails) Migrate IORails to manifest-compiled
RailOutcomeactions with shared model and HTTP dependencies (#2241, #2246, #2253, #2261, #2286)
📚 Documentation
- (actions) Document
RailOutcome-based rail actions (#2258) - (rails) Document rail manifests and action-backed surfaces (#2259)
- (http) Document canonical outbound HTTP clients (#2260)
- (iorails) Document per-surface LLMRails and IORails compatibility, fallback conditions, and configuration-dependent rail support (#2330)
New Contributors
- @ciarancourtney made their first contribution in #2105
- @fcanogab made their first contribution in #2192
- @yixinh-nv made their first contribution in #2307
Full Changelog: v0.23.0...v0.24.0