InfoLang memory Session for the OpenAI Agents SDK.
Project description
infolang-openai-agents
An OpenAI Agents SDK Session
implementation backed by InfoLang semantic memory. Drop
InfoLangSession into any Agent/Runner call and conversation history is
stored in (and recalled from) InfoLang instead of living only in process
memory.
Repository:
InfoLang-Inc/infolang-openai-agents. Package:infolang-openai-agents(PyPI).
Install
pip install infolang-openai-agents
This pulls in the infolang SDK (>=0.2.0) and openai-agents (>=0.18.0)
as dependencies.
Note: at the time of writing,
infolangitself has not yet been published to PyPI. Until it is, install both from source:pip install "infolang @ git+ssh://git@github.com/InfoLang-Inc/infolang-sdk-python.git" pip install "infolang-openai-agents @ git+ssh://git@github.com/InfoLang-Inc/infolang-openai-agents.git"
Quickstart
import asyncio
from agents import Agent, Runner
from infolang_openai_agents import InfoLangSession
async def main() -> None:
# INFOLANG_API_KEY resolved from the environment (or pass api_key="il_live_...").
# session_id "demo-user-42" maps to the InfoLang namespace
# "oa-session-demo-user-42" by default.
async with InfoLangSession("demo-user-42") as session:
agent = Agent(name="Assistant", instructions="Be concise.")
result = await Runner.run(
agent, "My favorite color is teal. Remember that.", session=session
)
print(result.final_output)
# A second run against the same session recalls the earlier turn.
result = await Runner.run(agent, "What's my favorite color?", session=session)
print(result.final_output)
asyncio.run(main())
A full runnable version is in examples/quickstart.py.
How it maps onto InfoLang
- One session = one InfoLang namespace. By default the namespace is
f"{namespace_prefix}{session_id}"(namespace_prefix="oa-session-"); passnamespace=to control it directly, e.g. to intentionally share one namespace across session ids. - Items are written with
remember_batch. EachTResponseInputItemis JSON-serialized and stored as the memorytext, tagged withsource="openai-agents-sdk"(override viasource=). - Items are read with
list_recent.pop_item/get_itemslist the namespace's memories and delete viaforget.clear_sessionusesreset_namespace(list + forget loop until empty).
Ordering semantics — read this before relying on it
The InfoLang runtime's GET /v1/memories (list_recent) route has an
untyped, undocumented response (additionalProperties: true in the
runtime's OpenAPI spec, no created_at field, no ordering guarantee, and no
pagination cursor). Two tradeoffs follow directly from that, and this library
handles the first honestly and discloses the second rather than papering over
it:
-
We do not trust server-side order. Every item is wrapped in an envelope carrying a sequence key generated locally (
time.time_ns()with a process-local monotonic floor, so it never collides or goes backwards within one process) before it's written.get_items/pop_itemsort by that key, not by whatever orderlist_recenthands records back in. This gives genuine insertion-order semantics for the common case: one process (or several, on clocks that roughly agree) appending to a session. Cross-process ordering under significant clock skew between concurrent writers to the same session is the one case this doesn't fully solve — most agent sessions have a single writer, so this is rarely relevant. -
There is a real cap on how much history is visible,
max_items(default 1000). Becauselist_recenthas no pagination cursor, this library cannot enumerate more thanmax_itemsrecords in one call without deleting as it goes (which is exactly whatreset_namespace/clear_sessiondoes, and whyclear_sessioncan drain an arbitrarily large namespace but reads cannot). If a session accumulates more thanmax_itemsstored items,get_items(limit=None)will not return the full history — only the newestmax_itemsare visible, silently omitting older ones (they still exist in InfoLang and remain queryable viarecall/investigate, just not through thisSession'sget_items). Raisemax_itemsat construction time if your sessions run long:InfoLangSession(session_id, max_items=5000). -
pop_itemandget_itemscost isO(session size), notO(1), because both need the full (capped) listing to determine "most recent." Fine for typical agent conversation lengths; not a good fit for extremely chatty sessions with tight latency budgets on every turn.
If your use case needs strict, unbounded, cheap ordering guarantees, the
bundled agents.memory.SQLiteSession (backed by an AUTOINCREMENT primary
key) will always be more precise than any REST-backed implementation without
a native ordering/cursor primitive. InfoLangSession trades that off for
memory that's durable, shared, and recallable outside the Session protocol
too (e.g. via client.recall(...) for semantic search over the same items).
Configuration
InfoLangSession(
session_id: str,
*,
client: AsyncInfoLang | None = None, # reuse an existing client instead of owning one
namespace: str | None = None, # override the derived namespace entirely
namespace_prefix: str = "oa-session-",
max_items: int = 1000,
source: str = "openai-agents-sdk",
session_settings: SessionSettings | None = None, # default get_items() limit
**client_kwargs, # forwarded to AsyncInfoLang(...) if client= is omitted
)
Credentials, when client= is not supplied, resolve the same way the
infolang SDK always does: api_key=/dev_key=/auth= kwargs, or the
INFOLANG_API_KEY / INFOLANG_DEV_KEY / INFOLANG_BASE_URL environment
variables.
InfoLangSession owns (and closes) the AsyncInfoLang client it constructs
for itself; use async with InfoLangSession(...) as session: or call
await session.aclose() explicitly. If you pass client=, this session never
closes it — you own that client's lifecycle.
Development
pip install -e ".[dev]"
ruff check .
mypy
pytest
Unit tests mock the HTTP layer (respx) against a small in-memory fake of
the il-runtime memory routes and cover all four Session methods plus edge
cases: empty session, pop_item on an empty session, clear_session
idempotency, get_items(limit=0), records not written by this library, and a
concurrent-delete race on pop_item.
An optional live smoke test (tests/test_live_smoke.py) exercises the real
InfoLang API end to end. It's skipped unless INFOLANG_API_KEY is set, only
ever touches namespaces prefixed ittest-openai-, and cleans up after itself:
INFOLANG_API_KEY=il_live_... pytest tests/test_live_smoke.py -v
Links
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file infolang_openai_agents-0.1.0.tar.gz.
File metadata
- Download URL: infolang_openai_agents-0.1.0.tar.gz
- Upload date:
- Size: 18.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2a8bcf06992b88599580b340ce0a2d2b7ab9407e43e462c691a3b37797231d9
|
|
| MD5 |
c675ea6a696d9d17873c5ebfa54ddc74
|
|
| BLAKE2b-256 |
645b528dc7cfce7d71619e7cbd9698817e2d9d6666ad7619e2f5d58a48ce333c
|
File details
Details for the file infolang_openai_agents-0.1.0-py3-none-any.whl.
File metadata
- Download URL: infolang_openai_agents-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0352c7d26e614d684006952bc1ef40d6b2af25b9f853a23fd3354fb6f6f9e7b3
|
|
| MD5 |
d7b45ef42bdde2ab528c44578b5d4d77
|
|
| BLAKE2b-256 |
93ecd2c74b72e56f095f69637a49ee224ce0caa507bcd90996438b8d30b9f234
|