Skip to main content
ReasonBlocks integrates with the OpenAI Agents SDK two ways depending on how much of the pipeline you want:
  • rb.openai_model(default_model, ...) — wraps any openai-agents Model so the agent runs FSM step scoring, server-side monitor steering, E-trace injection, and (with a model_factory) model routing on every get_response call. This is the parity path with the LangChain middleware.
  • rb.openai_hooks(...) — telemetry-only RunHooks adapter. Use this when you want dashboard rows + token / tool capture but don’t need steering. Cheaper and stays out of the model path entirely.
The make_openai_tools factory for CodebaseMemory + ImportGraph works alongside either entry point.

Path 1: full steering with rb.openai_model

1

Install

2

Build a wrapped Model

Pass an underlying Model instance (typically OpenAIChatCompletionsModel or OpenAIResponsesModel) and an optional model_factory to enable FSM-driven model routing.
Without model_factory, routing overrides log to the step entry but the wrapped default model is always used. With it, the wrapper builds and caches alternates lazily.
3

Use as the agent's model + run

wrapped is itself a sync and async context manager that flushes the live-telemetry emitter on exit.
4

Inspect the step log

The wrapper exposes its SteeringSession. Read wrapped.session.step_log after the run for per-step difficulty, FSM state, monitors fired, injection text, model id used, tokens, and latency.
Streaming via stream_response is currently a pass-through to the wrapped model — no steering is applied to streamed responses in the first cut. Non-streaming get_response calls run the full pipeline.

Path 2: telemetry-only with rb.openai_hooks

Use this when you want dashboard rows but don’t want the wrapper sitting in front of model calls.
1

Install

2

Initialize ReasonBlocks

3

Build hooks and run the agent

rb.openai_hooks(...) returns a ReasonBlocksHooks instance — a RunHooks subclass that is also a sync and async context manager. Pass it to Runner.run (or Runner.run_sync).
4

Tag runs for the dashboard

rb.openai_hooks(...) accepts the same identifying fields as rb.middleware().
5

Track failures

Exceptions that escape the with/async with block are recorded as failure: <ExceptionType>. To mark an explicit logical failure when the agent returns normally, call hooks.mark_failure(reason=...) before exit:

What gets captured

The hooks subscribe to the openai-agents lifecycle:
  • on_agent_start emits run_start once.
  • on_llm_end accumulates input + output tokens from each LLM response.
  • on_tool_start stamps a per-tool start time.
  • on_tool_end emits a step event with the tool name, observation (truncated to 8000 chars), latency, and accumulated tokens. Tokens are attributed to the first tool call after each LLM response; subsequent calls in the same response stamp 0. The total across the run is exact.
  • on_agent_end emits run_finish with outcome="success" (overridable via mark_failure).
  • __exit__ / __aexit__ flushes a failure outcome if an exception escaped, then closes the emitter.

Add CodebaseMemory tools

make_openai_tools returns function_tool-decorated callables ready for Agent(tools=[...]). Same contract as the LangChain factory — only the framework decoration differs.
The factory adds up to three tools: recall_findings, store_finding, and (when graph is provided) impact_analysis. See CodebaseMemory for the storage API.
ImportGraph.build_from_files requires networkx. Install with pip install networkx.

Complete example

Each hooks object — and each wrapped from rb.openai_model(...) — is single-use. Call the factory again for the next run.

Which to pick

If you adopt rb.openai_model, you don’t also need rb.openai_hooks — the wrapper emits the same run_start / step / run_finish telemetry from inside the steering pipeline.