Stability warning. The upstreamopenai-agentsSDK is pre-1.0: 17 releases in the 7 months leading up tov0.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
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
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 (thesqlite_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 toexamples/integrations/openai_agents/example.py.
CI fails if they diverge.
example.py
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-agentsminor. The nightly skew job flags breakage. khora_recall_toolargument 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_startrecall surfacing. Default behaviour logs hits. Downstream callers will usually want to feed them intoagent.instructionsor 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 isdocs/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.