Skip to content

SDK Compatibility

AF is built on top of the OpenAI Agents SDK. This page documents the relationship and boundaries.

Design Principle

AF does not reinvent the SDK. It adds:

  • Callable form for agents (agent(prompt))
  • Execution modifiers (.stream(), .silent(), .isolated(), .snapshot())
  • Automatic boundary management (phase())
  • Session injection via Runner

Everything else comes from the SDK.

SDK Pass-Through

All Agent arguments pass directly to the SDK:

# AF
import agentic_flow as af

agent = af.Agent(
    name="assistant",
    instructions="Help the user.",
    model="gpt-5.2",
    model_settings=ModelSettings(reasoning=Reasoning(effort="medium")),
    tools=[my_tool],
)

# Internally creates:
from agents import Agent as SDKAgent

sdk_agent = SDKAgent(
    name="assistant",
    instructions="Help the user.",
    model="gpt-5.2",
    model_settings=ModelSettings(reasoning=Reasoning(effort="medium")),
    tools=[my_tool],
)

This means:

  • Future SDK arguments work automatically
  • No need for AF updates when SDK changes
  • No aliasing or normalization of arguments

What Comes From SDK

Feature SDK Class Usage in AF
Agent definition agents.Agent Wrapped by Agent
Execution agents.Runner Called by ExecutionSpec
Streaming agents.Runner.run_streamed Used when .stream()
Session agents.Session Injected by Runner
SQLiteSession agents.SQLiteSession Passed to Runner
StreamEvent agents.StreamEvent Consumed internally (not forwarded to Handler)
ModelSettings agents.ModelSettings Passed through

What AF Adds

Feature Purpose
Agent[T] Callable wrapper, agent(prompt) → ExecutionSpec[T]
ExecutionSpec[T] Declaration/execution separation
phase() Automatic boundary management
Runner Flow execution with injection
.stream() Streaming mode modifier
.silent() Display suppression modifier
.isolated() Context isolation modifier
.snapshot() Read-only context modifier

Session Compatibility

AF uses SDK Session directly:

from agents import SQLiteSession

session = SQLiteSession(session_id="user_123", db_path="chat.db")
runner = af.Runner(flow=my_flow, session=session)

Session methods used:

  • get_items() — Read history (by phase for inheritance)
  • add_items() — Write history (by phase with persist=True)

Handler Events

SDK StreamEvent deltas are consumed internally by execute() and execute_streaming(). They are not forwarded to the handler. Display is always full-text-at-once.

Handler receives AF events only:

import agentic_flow as af

def my_handler(event):
    if isinstance(event, af.PhaseStarted):
        print(f"\n[{event.label}]")
    elif isinstance(event, af.PhaseEnded):
        print(f"  ({event.elapsed_ms}ms)")
    elif isinstance(event, af.AgentResult):
        print(event.content)

AF Event Types

Event When Emitted Key Fields
AgentResult After each agent execution content: Any (full output)
PhaseStarted On phase() entry label: str
PhaseEnded On phase() exit label: str, elapsed_ms: int

Display fallback priority: ChatKit > Handler > print() (mutually exclusive). When no handler or ChatKit context is active, output is printed to stdout.

Tool and Handoff Support

Tools and handoffs work as SDK features:

def search_web(query: str) -> str:
    return f"Results for: {query}"

agent = af.Agent(
    name="researcher",
    instructions="Research topics using search.",
    model="gpt-5.2",
    tools=[search_web],  # Passed to SDK
)

From Flow's perspective, tool calls and handoffs are internal to agent execution. AF doesn't expose or interpret them — they're SDK behavior.

output_type Support

Structured output uses SDK's implementation:

from pydantic import BaseModel

class Analysis(BaseModel):
    sentiment: str

# Passed directly to SDK
agent = af.Agent(
    name="analyzer",
    instructions="Analyze sentiment.",
    output_type=Analysis,  # SDK handles this
    model="gpt-5.2",
)

Multi-Provider Support

AF supports multiple LLM providers through the SDK's built-in multi-provider system.

Quick Start

Provider Agent Definition
OpenAI (default) af.Agent(model="gpt-5.2")
Anthropic (via LiteLLM) af.Agent(model="litellm/anthropic/claude-sonnet-4-20250514")
Google (via LiteLLM) af.Agent(model="litellm/google/gemini-2.0-flash")
Custom RunConfig(model_provider=MyProvider())

Runtime Override

from agents import RunConfig

result = await agent("prompt").run_config(
    RunConfig(model="gpt-5.2")
).stream()

For details, see the Multi-Provider Guide.

Version Compatibility

AF is tested with:

  • openai-agents >= 0.3.2
  • openai-chatkit >= 1.4.0, < 2 (for ChatKit integration)

For production, pin versions:

[project]
dependencies = [
    "agentic-flow>=0.35",
    "openai-agents>=0.3.2",
    "openai-chatkit>=1.4.0,<2",
]

Execution-Time Pass-Through

In addition to Agent definition pass-through, AF supports execution-time parameters via modifiers:

Runner.run() Parameters

SDK Parameter AF Modifier Status
max_turns .max_turns(n) Supported
run_config .run_config(cfg) Supported
context .context(ctx) Supported
previous_response_id .run_kwarg(...) Pass-through
conversation_id .run_kwarg(...) Pass-through
session af.Runner(session=...) Injected

RunConfig Options

Option Description Axis
model Override agent's model WHAT
model_settings Override model settings WHAT
tracing_disabled Disable tracing HOW
trace_include_sensitive_data Include data in traces HOW
workflow_name Name for tracing HOW
input_guardrails Override input guardrails LIMITS
output_guardrails Override output guardrails LIMITS
hooks Run-level hooks WHEN

Example

from agents import RunConfig

# Combine multiple execution-time settings
result = await agent("complex task") \
    .max_turns(10) \
    .context(app_context) \
    .run_config(RunConfig(
        tracing_disabled=True,
        workflow_name="my_workflow",
    )) \
    .stream()

SDK Features Comparison

SDK Feature AF Support Notes
Agent definition Full pass-through All Agent kwargs supported
Multi-Provider Via SDK ModelProvider Use model="litellm/..." or RunConfig(model_provider=...)
Runner.run() params Via modifiers .max_turns(), .context(), etc.
Guardrails Pass-through Via af.Agent() or RunConfig
AgentHooks Pass-through Via af.Agent(hooks=...)
RunHooks Pass-through Via RunConfig
Context (DI) Via .context()
Tracing SDK default Disable via RunConfig
MCP Pass-through Via tools parameter

Non-Goals

Things AF intentionally does not do:

Non-Goal Reason
Replace SDK Session Use SDK's implementation
Custom output parsing SDK handles structured output
Expose handoff details Handoffs are SDK-internal
Modify StreamEvents Forward unchanged
Provide default models Use SDK defaults
Wrap guardrails Use SDK directly
Wrap hooks Use SDK directly
Custom tracing Use SDK tracing
Custom provider abstraction SDK provides ModelProvider and MultiProvider

Architecture

graph TB
    subgraph AF["AF Layer"]
        A(Agent wrapper)
        B(ExecutionSpec)
        C(phase)
        D(Runner)
    end

    subgraph SDK["OpenAI Agents SDK"]
        E(agents.Agent)
        F(agents.Runner)
        G(agents.Session)
        H(agents.StreamEvent)
    end

    A --> E
    B --> F
    D --> G
    C --> H

AF is a thin layer. The SDK does the heavy lifting.