datarobot_genai.core.agents.reasoning
reasoning
Framework-agnostic normalization of reasoning/thinking content blocks.
Reasoning models (Claude extended thinking, Qwen, OpenAI o1, GPT-OSS, DeepSeek)
expose reasoning as native list-form content blocks —
[{"type": "thinking", ...}, {"type": "text", ...}] (Anthropic/Bedrock SDK
pass-through). These helpers normalize that (and plain-string or list content)
into typed (kind, delta) pairs so each framework adapter can route thinking
to AG-UI Reasoning events and text to text events without re-implementing the
parsing. They live in core (rather than a single framework package) so
independent adapters can share them without leaf-to-leaf imports, and they carry
no framework dependency.
The OpenAI-compatible flat shape (reasoning hoisted to
additional_kwargs["reasoning_content"]) is framework-specific and handled by
the per-adapter wrappers, e.g. datarobot_genai.langgraph.reasoning.
iter_content_blocks
iter_content_blocks(content: str | list[Any] | None) -> Iterator[tuple[Literal['text', 'thinking'], str]]
Yield typed (kind, delta) pairs for any AIMessage/ToolMessage content shape.
Normalizes the union of shapes LangChain/LiteLLM produce for AIMessage.content:
plain string, list of strings, or list of structured blocks. Thinking and
reasoning blocks both map to ("thinking", delta). Empty deltas are filtered
so callers never need to emit zero-content events.
A list item that is neither a string nor a block dict is malformed for every
framework we support, so it raises ValueError to surface the unexpected
format immediately rather than silently dropping content. A well-formed block
whose type we do not route (e.g. tool_use, which agents handle via
their own tool-call path) is skipped at debug: those are recognized,
non-renderable blocks, not format errors.
Source code in datarobot_genai/core/agents/reasoning.py
flatten_to_text
Collapse any content shape to its text portion, dropping thinking blocks.
wrap_reasoning
Prepend reasoning to content as a <reasoning>...</reasoning> block.
Returns the reasoning block followed by the answer text. content may be None
or empty (e.g. a tool-call-only assistant turn), in which case only the reasoning
block remains (trailing whitespace stripped).