nemoguardrails.llm.call
The shared entry point for invoking an LLM model.
llm_call wraps an :class:~nemoguardrails.types.LLMModel with the project’s
prompt logging, token accounting, reasoning-trace extraction, tool-call capture, and
error wrapping, so every caller gets the same observability and the same
:class:~nemoguardrails.exceptions.LLMCallException contract.
This module deliberately carries no Colang dependency. Built-in rail actions in
nemoguardrails.library call llm_call, and those actions must stay runnable by
engines that have no Colang runtime; tests/llm/test_call_import_graph.py enforces it.
Neighbouring modules: text helpers for interpreting a completion live in
:mod:nemoguardrails.llm.completion_parsing, and the Colang-specific history and event
helpers in :mod:nemoguardrails.actions.llm.utils.
Module Contents
Functions
Data
API
Extract reasoning from <think> tags and remove them from response.content.
This function looks for <think>…</think> tags in the response content, and if found, extracts the reasoning content inside the tags. It has a side-effect: it removes the full reasoning trace and tags from response.content.
Parameters:
The LLM response object
Returns: Optional[str]
The extracted reasoning content, or None if no <think> tags found
Extract text content from response.
Extract an HTTP status code from a provider exception, if present.
Checks, in order:
LLMClientError.status_code(NeMo Guardrails client layer).exception.status_code(OpenAI SDK, httpx).exception.response.status_code(requests-style wrappers).
Returns None when no status can be determined or when the status
is 0 (used by LLMTimeoutError / LLMConnectionError for
client-side failures where no HTTP response was received).
Log the prompt to LLM call info.
Accepts the normalized ChatMessage form as well as raw dicts, because
llm_call logs the prompt before _ensure_chat_messages runs and callers may
already supply ChatMessage objects.
Re-attach reasoning_content to content as a leading <think> block, the inverse of _extract_and_remove_think_tags.
Return a message’s textual content, or "" when it is absent or non-textual.
Multimodal payloads carry a list of content parts rather than a string; those are omitted from the logged prompt, matching the previous dict-only behavior.
Return a message’s role, accepting either a raw dict or a ChatMessage.
Role is a str subclass, so it is returned as-is: it maps correctly through
type_map and supports str methods. Passing it through str() would yield
"Role.USER" because Enum.__str__ wins over the str mixin.
Initialize or update LLM call info in context.
Record the provider’s response id on the current call, when it returned one.
Kept separate from LLMCallInfo.id, which track_llm_call generates client-side:
only this value can be quoted to a provider, and only this value matches
gen_ai.response.id on the OTEL span for the same call, so overloading one field with
both meanings would make log-to-trace correlation unreliable.
Return True and emit a warning if the LLM produced no visible content because it hit the max_tokens budget.
Reasoning models (OpenAI o-series, gpt-5, DeepSeek-R1, Gemini 2.5, Qwen QwQ, etc.) spend output tokens on internal reasoning before emitting visible text. A small max_tokens budget can be fully consumed by the reasoning phase, leaving empty content and finish_reason=“length”. The call succeeds silently and callers that only inspect response.content see nothing. Callers whose downstream parser does not fail safely on empty input (e.g. self_check_facts, whose parser inverts the result) should use the return value to take an explicit fail-safe branch.