axio-context-sqlite
SQLite-backed persistent context store for axio.
Installation
pip install axio-context-sqlite
Usage
connect(db_path)
Open (or create) a SQLite database at db_path and initialise the schema.
Returns an aiosqlite.Connection. The caller is responsible for closing it.
async def main():
conn = await connect("~/.axio/chat.db")
# ... use the connection ...
await conn.close()
The helper enables WAL journal mode and a 5-second busy timeout so concurrent readers and a single writer can safely share the same database file.
SQLiteContextStore(conn, session_id, project=None, db_name="axio_context")
Create a context store bound to one session.
| Parameter | Type | Default | Description |
|---|---|---|---|
conn |
aiosqlite.Connection |
- | Open database connection (from connect()) |
session_id |
str |
- | Unique identifier for this conversation session |
project |
str | None |
str(Path.cwd().resolve()) |
Logical project scope used to group and list sessions. Defaults to the current working directory. |
db_name |
str |
"axio_context" |
Prefix used for the database table names (axio_context_messages, axio_context_tokens). |
Open a connection with connect(), then create a SQLiteContextStore bound to a
session. The caller owns the connection and is responsible for closing it.
import asyncio
import tempfile
import pathlib
from axio_context_sqlite import connect, SQLiteContextStore
from axio.messages import Message
from axio.blocks import TextBlock
async def main() -> None:
conn = await connect(pathlib.Path(tempfile.mkdtemp()) / "chat.db")
try:
store = SQLiteContextStore(conn, session_id="my-session")
await store.append(Message(role="user", content=[TextBlock(text="Hello")]))
history = await store.get_history()
assert len(history) == 1
finally:
await conn.close()
asyncio.run(main())
SQLiteContextStore implements the axio.context.ContextStore ABC and persists
conversation history across process restarts. Multiple sessions can coexist in
the same database file, isolated by session_id and project.
Storage and compression
Message content is stored as serialized JSON. Payloads larger than 512 bytes
are automatically compressed with gzip (compresslevel 6) and stored
base64-encoded with a gzip: prefix. Smaller payloads are stored as-is with a
plain: prefix. Decompression happens transparently on read - callers never
see the encoded form.
SQLite performance settings
Every connection opened by connect() is configured with:
PRAGMA journal_mode=WAL- enables concurrent readers alongside one writerPRAGMA busy_timeout=5000- waits up to 5 seconds before raising a lock errorPRAGMA synchronous=NORMAL- balances durability and write throughput
Agent integration
import asyncio
import tempfile
import pathlib
from axio.agent import Agent
from axio_context_sqlite import connect, SQLiteContextStore
async def main() -> None:
conn = await connect(pathlib.Path(tempfile.mkdtemp()) / "chat.db")
try:
ctx = SQLiteContextStore(conn, session_id="main")
agent = Agent(system="You are helpful.", tools=[], transport=transport)
result = await agent.run("Hello!", ctx)
assert result == "Hi!"
finally:
await conn.close()
asyncio.run(main())
Listing sessions
import asyncio
import tempfile
import pathlib
from axio_context_sqlite import connect, SQLiteContextStore
from axio.messages import Message
from axio.blocks import TextBlock
async def main() -> None:
conn = await connect(pathlib.Path(tempfile.mkdtemp()) / "chat.db")
try:
store = SQLiteContextStore(conn, session_id="main", project="/myproject")
await store.append(Message(role="user", content=[TextBlock(text="hi")]))
sessions = await store.list_sessions()
for s in sessions:
print(s.session_id, s.preview, s.message_count)
assert len(sessions) == 1
finally:
await conn.close()
asyncio.run(main())
Token accounting
add_context_tokens(input_tokens, output_tokens) atomically increments the
stored token counts for the current session and project using a SQL UPSERT
(INSERT ... ON CONFLICT DO UPDATE SET ... = ... + excluded....). This is safe
to call concurrently from multiple coroutines without an application-level lock.
set_context_tokens() replaces the counts unconditionally, and
get_context_tokens() returns a (input_tokens, output_tokens) tuple.
Forking
fork() copies the current session's messages into a new session - useful for
branching conversations without affecting the original:
import asyncio
import tempfile
import pathlib
from axio_context_sqlite import connect, SQLiteContextStore
from axio.messages import Message
from axio.blocks import TextBlock
async def main() -> None:
conn = await connect(pathlib.Path(tempfile.mkdtemp()) / "chat.db")
try:
store = SQLiteContextStore(conn, session_id="main")
await store.append(Message(role="user", content=[TextBlock(text="original")]))
branch = await store.fork()
assert branch.session_id != store.session_id
assert len(await branch.get_history()) == 1
finally:
await conn.close()
asyncio.run(main())
License
MIT
Metadata
Release files for axio-context-sqlite 0.11.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| axio_context_sqlite-0.11.3.tar.gz | 7.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| axio_context_sqlite-0.11.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 13.6 kB
Release files / axio_context_sqlite-0.11.3.tar.gz
| Download URL | axio_context_sqlite-0.11.3.tar.gz |
|---|---|
| Size | 7.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fc82b61a5e0aa1ee9324524494bcb08d53545e3570bf6e0f52490bafd691da6b
|
|
BLAKE2b-256 checksum How to use checksums |
60055e3dc5556e111762d4dc42caa2acc965035fea569e2266675d0da6f7c545
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.
Transparency logRelease files / axio_context_sqlite-0.11.3-py3-none-any.whl
| Download URL | axio_context_sqlite-0.11.3-py3-none-any.whl |
|---|---|
| Size | 6.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a64783ffccb26251ad04bc0624388c341d1fb02635a89bacf9b976963687a20b
|
|
BLAKE2b-256 checksum How to use checksums |
3c4c8a137c9fcbbfd130e94484fa6ba8b8c528ef485e18934267d4f1ab6b1d2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.
Transparency log