Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.osmosis.ai/llms.txt

Use this file to discover all available pages before exploring further.

The Osmosis SDK includes an integration for the OpenAI Agents SDK. Use it when your rollout is built around Agent, Runner.run, sessions, tools, handoffs, or other OpenAI Agents SDK primitives. The integration has three main objects:
ObjectPurpose
OsmosisAgentDrop-in replacement for OpenAI Agents SDK Agent that binds an OsmosisRolloutModel to the active rollout context
OsmosisRolloutModelPlaceholder policy model that OsmosisAgent replaces with the active rollout model
OsmosisMemorySessionIn-memory session that records the runner conversation and exposes it as a rollout sample for grading

Quick Example

from agents import ModelSettings, Runner
from osmosis_ai.rollout import AgentWorkflow, AgentWorkflowContext
from osmosis_ai.rollout.integrations.agents.openai_agents import (
    OsmosisAgent,
    OsmosisMemorySession,
    OsmosisRolloutModel,
)


class OpenAIWorkflow(AgentWorkflow):
    async def run(self, ctx: AgentWorkflowContext) -> None:
        agent = OsmosisAgent(
            name="assistant",
            instructions="Answer the user's request clearly.",
            model=OsmosisRolloutModel(),
            model_settings=ModelSettings(temperature=1.0, max_tokens=4096),
        )
        session = OsmosisMemorySession(name="assistant")
        await Runner.run(
            agent,
            ctx.prompt,
            session=session,
        )
Always pass an OsmosisMemorySession when using OsmosisRolloutModel. The session publishes the sample ID used for rollout headers and persists the conversation that your grader will read. Construct the session inside AgentWorkflow.run() so it registers with the active RolloutContext.

How It Works

1

Construct the agent inside run

OsmosisAgent checks whether the model argument is an OsmosisRolloutModel. If so, it replaces the placeholder with an OsmosisLitellmModel bound to the active RolloutContext.
2

Create a memory session

OsmosisMemorySession registers itself as a sample source on the current RolloutContext. The session name becomes the rollout sample ID.
3

Run the OpenAI agent

Runner.run() interacts with the session through get_items() and add_items(). The session stores the persisted OpenAI Agents SDK items in the canonical Responses API shape.
4

Route policy calls

The resolved model sends requests to the Osmosis chat completions endpoint and injects x-sample-id and x-rollout-id headers for every model call.
5

Collect samples

After run() completes, the backend asks the rollout context for samples. The session returns a RolloutSample containing the runner’s persisted conversation.

Complete Example

This example uses an OpenAI Agents SDK tool and a grader that reads the final assistant text from the session-backed sample.
from agents import ModelSettings, Runner, function_tool
from osmosis_ai.rollout import (
    AgentWorkflow,
    AgentWorkflowContext,
    Grader,
    GraderContext,
)
from osmosis_ai.rollout.integrations.agents.openai_agents import (
    OsmosisAgent,
    OsmosisMemorySession,
    OsmosisRolloutModel,
)


@function_tool
def multiply(a: int, b: int) -> int:
    """Multiply two integers."""
    return a * b


class MultiplyWorkflow(AgentWorkflow):
    async def run(self, ctx: AgentWorkflowContext) -> None:
        agent = OsmosisAgent(
            name="multiply-agent",
            instructions="Use the multiply tool when arithmetic is required.",
            model=OsmosisRolloutModel(),
            model_settings=ModelSettings(temperature=1.0, max_tokens=4096),
            tools=[multiply],
        )
        session = OsmosisMemorySession(name="multiply-agent")
        await Runner.run(
            agent,
            ctx.prompt,
            session=session,
        )


def _last_text(sample) -> str:
    for item in reversed(sample.messages):
        if item.get("role") != "assistant":
            continue
        content = item.get("content", "")
        if isinstance(content, str):
            return content
        if isinstance(content, list):
            for block in content:
                if isinstance(block, dict):
                    text = block.get("text") or block.get("content")
                    if text:
                        return text
    return ""


class MultiplyGrader(Grader):
    async def grade(self, ctx: GraderContext) -> None:
        for sample_id, sample in ctx.samples.items():
            answer = _last_text(sample)
            reward = 1.0 if ctx.label and ctx.label.strip() in answer else 0.0
            ctx.set_sample_reward(sample_id, reward)
OpenAI Agents SDK sessions persist conversation items rather than Strands-style messages. When writing graders for OpenAI Agents rollouts, inspect sample.messages as the runner’s persisted session items.

OsmosisRolloutModel

OsmosisRolloutModel is a placeholder. Do not call it directly and do not pass a fixed policy model name into rollout code. In the workspace templates, sampling options live in OpenAI Agents ModelSettings.
from agents import ModelSettings
from osmosis_ai.rollout.integrations.agents.openai_agents import (
    OsmosisAgent,
    OsmosisRolloutModel,
)

agent = OsmosisAgent(
    name="assistant",
    model=OsmosisRolloutModel(),
    model_settings=ModelSettings(
        temperature=1.0,
        top_p=1.0,
        max_tokens=4096,
    ),
)
At runtime, OsmosisAgent replaces the placeholder with a model that points at the active Osmosis rollout endpoint.
OsmosisRolloutModel is different from the Strands integration’s placeholder constructor. For OpenAI Agents examples, use OsmosisRolloutModel() with ModelSettings(...), not a params={...} dict.

Sessions and Sample IDs

Use exactly one OsmosisMemorySession per Runner.run() call when that run uses OsmosisRolloutModel.
session = OsmosisMemorySession(name="main")
await Runner.run(agent, ctx.prompt, session=session)
The session name is used as the sample ID. If your workflow runs multiple independent agents for the same prompt, give each session a distinct name:
planner_session = OsmosisMemorySession(name="planner")
executor_session = OsmosisMemorySession(name="executor")
Create sessions inside run(). A session created outside the active rollout context cannot be reused inside a rollout run because it was not registered with that context.

Migrating from OpenAI Agents SDK

If you already have an OpenAI Agents SDK workflow, migrate it in four steps:
1

Replace Agent with OsmosisAgent

Change the import and class:
from osmosis_ai.rollout.integrations.agents.openai_agents import OsmosisAgent
Then construct OsmosisAgent(...) instead of Agent(...).
2

Replace the policy model

Replace a fixed model string with an OsmosisRolloutModel placeholder:
from osmosis_ai.rollout.integrations.agents.openai_agents import OsmosisRolloutModel

model = OsmosisRolloutModel()
3

Add an OsmosisMemorySession

Create the session inside AgentWorkflow.run() and pass it to Runner.run():
session = OsmosisMemorySession(name="main")
await Runner.run(agent, ctx.prompt, session=session)
4

Wrap the runner in AgentWorkflow

Put the runner call inside an AgentWorkflow.run() method. Keep your tools, instructions, handoffs, and agent behavior the same unless they depend on out-of-band state.

Local Evaluation

Use the normal eval command:
osmosis eval run configs/eval/<rollout-name>.toml
During eval, the local controller routes openai/osmosis-rollout to the model configured in [llm] in your eval TOML. During training, Osmosis routes the same placeholder to the current training policy.

Next Steps

Building AgentWorkflows

Review the shared AgentWorkflow.run(ctx) contract.

Building Graders

Write reward logic for OpenAI Agents session samples.

Local Evaluation

Run your OpenAI Agents rollout locally before training.