Skip to main content

SQLite-backed context store for Axio

Project description

axio-context-sqlite

PyPI Python License: MIT

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 writer
  • PRAGMA busy_timeout=5000 - waits up to 5 seconds before raising a lock error
  • PRAGMA 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

axio_context_sqlite-0.9.2.tar.gz (7.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

axio_context_sqlite-0.9.2-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

File details

Details for the file axio_context_sqlite-0.9.2.tar.gz.

File metadata

  • Download URL: axio_context_sqlite-0.9.2.tar.gz
  • Upload date:
  • Size: 7.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for axio_context_sqlite-0.9.2.tar.gz
Algorithm Hash digest
SHA256 51559bfc33cfb1f7344440ed8e00651b5b5c8392f20c44eeac904e19c73230a2
MD5 0eecc8b174b6d0be0ff1b089d09ea2de
BLAKE2b-256 c5088094a794317ed31467a36e0c030a56cabc9c7df19005f790fe5d0da5fdd5

See more details on using hashes here.

Provenance

The following attestation bundles were made for axio_context_sqlite-0.9.2.tar.gz:

Publisher: publish.yml on mosquito/axio-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file axio_context_sqlite-0.9.2-py3-none-any.whl.

File metadata

File hashes

Hashes for axio_context_sqlite-0.9.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4dc09f5180ad5253662975c3c377b5594c460fc6bf2c6736e8bb73f58e0ca0fb
MD5 6f65e82277e5691d98d9e5c910f7b012
BLAKE2b-256 6a3fbf00d1aea6891a53efbe352c97ab7cc1d95b373ea5f55b7b63d1d1decfda

See more details on using hashes here.

Provenance

The following attestation bundles were made for axio_context_sqlite-0.9.2-py3-none-any.whl:

Publisher: publish.yml on mosquito/axio-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page