Skip to content

OpenAI Agents SDK

Verified 2026-08-19 — PASS, 6s. Session persistence: native SQLiteSession.

SQLiteSession is keyed on the session id and works across processes, so resume needs no code of your own.


import sys, os, asyncio
sys.path.insert(0, os.path.expanduser("~/agenttests"))
import azcfg, hetool
from agents import Agent, Runner, SQLiteSession, OpenAIChatCompletionsModel, function_tool
from openai import AsyncOpenAI
DB = os.path.expanduser("~/agenttests/openai_agents/sessions.db")
@function_tool
def get_working_folder() -> str:
"""Return the agent's current working folder (absolute path)."""
return hetool.get_working_folder()
@function_tool
def run_shell(command: str) -> str:
"""Run a shell command in the working folder and return its output."""
return hetool.run_shell(command)
async def invoke(sid, message):
c = azcfg.load()
client = AsyncOpenAI(base_url=c["base_url"], api_key=c["api_key"])
agent = Agent(name="assistant",
instructions="Be concise. Use tools for operational questions.",
model=OpenAIChatCompletionsModel(model=c["model"], openai_client=client),
tools=[get_working_folder, run_shell])
session = SQLiteSession(sid, DB) # native cross-process history keyed by sid
result = await Runner.run(agent, message, session=session)
return str(result.final_output).strip()

{
"type": "process",
"file": "/home/you/openai_agents/.venv/bin/python3",
"nativeSession": true,
"argsNew": ["/home/you/he_adapter.py", "/home/you/openai_agents_session.py", "", "{message}"],
"argsResume": ["/home/you/he_adapter.py", "/home/you/openai_agents_session.py", "{sessionId}", "{message}"],
"replyField": "result",
"sessionIdField": "session_id",
"approve": false,
"workdir": "/home/you/work",
"proxy": { "shape": "openai", "baseUrlEnv": "OPENAI_BASE_URL", "keyEnv": "OPENAI_API_KEY",
"modelEnv": "OPENAI_MODEL", "model": "<route>|<provider model>" }
}

  1. Keep your agent and @function_tool definitions as they are.
  2. Pass HBIA’s sid as the first argument to SQLiteSession.
  3. Build an AsyncOpenAI client from azcfg.load() and wrap it in OpenAIChatCompletionsModel.
  4. Seal the engine, point external.engine at it, restart.

Use OpenAIChatCompletionsModel, not the default. The SDK defaults to the Responses API, which an OpenAI-compatible endpoint generally does not implement. Passing the model id as a bare string gets you the Responses shape and a confusing failure; wrapping it in OpenAIChatCompletionsModel selects chat completions.

Pass the client, not a base URL. The model object takes openai_client=, so construct AsyncOpenAI yourself with the injected route rather than relying on ambient env vars.

SQLiteSession(sid, DB) — session id first, database path second. Reversing them creates a database named after your session.

Tracing is on by default and tries to reach OpenAI’s telemetry endpoint. In a confined spawn with no outbound access it fails harmlessly to stderr, but you can disable it (OPENAI_AGENTS_DISABLE_TRACING=1) to keep logs clean.