Skip to main content
Stability warning. The upstream openai-agents SDK is pre-1.0: 17 releases in the 7 months leading up to v0.17. The adapter pins tightly (openai-agents>=0.17,<0.18) and is tagged experimental: expect monthly rework as upstream’s session / hooks / tool surfaces shift. A nightly skew job opens auto-issues when the latest upstream breaks.
khora.integrations.openai_agents exposes three independent primitives a caller mixes and matches against the OpenAI Agents SDK: The three are designed to compose. A typical setup wires all of them into one Agent / Runner call.

Install

This pulls openai-agents>=0.17,<0.18. The adapter is also registered under the khora.integrations entry-point group, so discover() returns it without explicit registration.

Constructors

KhoraSession

KhoraSession is a runtime SessionABC (verified via isinstance in tests). It catches SDK rename drift on construction rather than at the next Runner.run.

khora_recall_tool

Returns a FunctionTool whose only LLM-visible argument is query: str. The bound khora instance, namespace, and recall thresholds are captured by closure. The LLM cannot rewrite them. Drop straight into Agent(tools=[tool]).

KhoraMemoryHooks

KhoraMemoryHooks is plain, since Runner duck-types hook callbacks so the class is accepted without isinstance. Use hooks.as_runhooks() if a static checker insists on a RunHooks subclass.

Mapping

Documents stamped by this adapter use the prefix oai: on their external_id (oai:<session>:<seq>). Foreign documents in the same namespace are silently skipped on read-back.

TResponseInputItem serialisation

The verbatim JSON of every item is preserved: non-text items (function calls, function responses, refusals, reasoning items, …) round-trip exactly. The adapter never tries to “interpret” SDK union variants beyond projecting a human-readable text body onto Document.content so vector recall has something to embed.

Why documents and not chunks?

khora’s chunk storage layout varies per backend (the sqlite_lance embedded stack stores chunks in LanceDB plus a temporal table in SQLite). storage.list_documents is the universally reliable iteration surface, and a Document.metadata dict survives the round trip on every backend. We keep the verbatim item JSON on the document so get_items never needs to peek at chunks.

Quickstart

The block below is byte-identical to examples/integrations/openai_agents/example.py. CI fails if they diverge.
example.py
The block above is enforced byte-identical against examples/integrations/openai_agents/example.py by tools/check_examples_drift.py (CI gate).

Limits and future work

  • SDK skew tolerance. Pinned to one upstream minor. Bump in a deliberate PR per openai-agents minor. The nightly skew job flags breakage.
  • khora_recall_tool argument set. v1 exposes one arg (query). Adding filters (date range, tool-name filter) is a clean addition. Gate them behind explicit factory kwargs so the LLM-visible schema stays minimal.
  • KhoraMemoryHooks.on_agent_start recall surfacing. Default behaviour logs hits. Downstream callers will usually want to feed them into agent.instructions or a system message. Subclass and override.
  • run_compaction (OpenAIResponsesCompactionAwareSession): intentionally NOT implemented in v1. Add when a real caller needs it. The SDK’s protocol-on-top-of-protocol surface is still in flux.

Filename note

The doc file is docs/integrations/openai_agents.md (underscore, not hyphen). tools/check_examples_drift.py derives the framework slug from the Markdown stem and matches it to examples/integrations/<slug>/example.py; since the Python package must be openai_agents (PEP 8 dotted-path), the doc filename has to match.