SQLite-backed context store for Axio
Project description
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
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 axio_context_sqlite-0.8.0.tar.gz.
File metadata
- Download URL: axio_context_sqlite-0.8.0.tar.gz
- Upload date:
- Size: 7.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efa969e4b3f6a0cf8ae86a0a1bfbb2a74657c14a28ce37bc66f5db859196505c
|
|
| MD5 |
20b17df60da0e0533da294cb02e41f0c
|
|
| BLAKE2b-256 |
2d7d298e0d3d0fd090cf587d7708820eeac4e86bd29c1ac0808ca82ae56572c3
|
Provenance
The following attestation bundles were made for axio_context_sqlite-0.8.0.tar.gz:
Publisher:
publish.yml on mosquito/axio-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axio_context_sqlite-0.8.0.tar.gz -
Subject digest:
efa969e4b3f6a0cf8ae86a0a1bfbb2a74657c14a28ce37bc66f5db859196505c - Sigstore transparency entry: 1394928828
- Sigstore integration time:
-
Permalink:
mosquito/axio-agent@f2ea4baa20d62e0ce1aa4ab367343d55b5bad2e8 -
Branch / Tag:
refs/tags/0.8.0 - Owner: https://github.com/mosquito
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f2ea4baa20d62e0ce1aa4ab367343d55b5bad2e8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file axio_context_sqlite-0.8.0-py3-none-any.whl.
File metadata
- Download URL: axio_context_sqlite-0.8.0-py3-none-any.whl
- Upload date:
- Size: 6.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4bf683f791dd6dc6acc1d9e26ab9f4824d7872ac745f85dbeed0bfefff4305d
|
|
| MD5 |
d442ded499c50b52dda19707f472fef4
|
|
| BLAKE2b-256 |
aebf2fab470c59bb52b3cce3a4006bbbb0930fcabd9acf16d635e213909902f4
|
Provenance
The following attestation bundles were made for axio_context_sqlite-0.8.0-py3-none-any.whl:
Publisher:
publish.yml on mosquito/axio-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axio_context_sqlite-0.8.0-py3-none-any.whl -
Subject digest:
e4bf683f791dd6dc6acc1d9e26ab9f4824d7872ac745f85dbeed0bfefff4305d - Sigstore transparency entry: 1394928844
- Sigstore integration time:
-
Permalink:
mosquito/axio-agent@f2ea4baa20d62e0ce1aa4ab367343d55b5bad2e8 -
Branch / Tag:
refs/tags/0.8.0 - Owner: https://github.com/mosquito
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f2ea4baa20d62e0ce1aa4ab367343d55b5bad2e8 -
Trigger Event:
release
-
Statement type: