Skip to main content

pydantic-ai-pixeltable

CI PyPI License

Pydantic AI Harness integration for Pixeltable. Two independent layers:

  • PixeltableMemoryStore: persist Harness Memory in a Pixeltable table (same Memory(store) slot as FileStore)
  • Pixeltable: read-only catalog tools (list_tables, describe_table, query_table, similarity_search) over tables you already have

Neither requires the other. Requires Pixeltable >= 0.7.8 and pydantic-ai-harness >= 0.29.0.

This is an interoperability bridge. Native Pixeltable agents still use a TableModel and computed columns.

How it fits together

Native backend (FileStore)                 This package (Pixeltable)

Memory(FileStore)                          Memory(PixeltableMemoryStore)
  └ .agent-memory/                           └ pxt table 'harness.memory'
      ├ main/MEMORY.md                           ├ kind='file' rows  path, content, version
      ├ ... (one .md per memory path)            └ kind='op' rows    '__op__/<id>' receipts
      └ .memory-store.sqlite3                  same catalog as your data; inspect via store.table
          (versions + operation journal)
                                           Pixeltable(tables=[...])  (optional, independent)
                                             └ your existing tables/views, incl. pxt.Document and
                                               embedding indexes -> query_table, similarity_search

Unique to this backend: memory rows are ordinary catalog rows. store.search stays lexical (the Harness contract), but through store.table you can add an embedding index on content and run Pixeltable similarity queries over memory, or join it with the rest of the catalog.

Installation

pip install pydantic-ai-pixeltable

The examples use an Anthropic model; add its client with pip install "pydantic-ai-slim[anthropic]".

Quick Start

Memory in the catalog, plus read-only tools over the tables you already have:

from pydantic_ai import Agent
from pydantic_ai_harness import Memory, ToolOutputLimits
from pydantic_ai_pixeltable import Pixeltable, PixeltableMemoryStore

agent = Agent(
    "anthropic:claude-sonnet-4-6",
    capabilities=[
        Memory(PixeltableMemoryStore(table_name="harness.memory")),
        Pixeltable(tables=["my_app.doc_chunks"]),
        ToolOutputLimits(),
    ],
)

Prefer FileStore (or PostgresMemoryStore) when the notebook does not need to live in the catalog; the choice is per project.

tables is a required allowlist of table paths or directory prefixes. Pass tables=["*"] to allow the whole catalog, including the memory table and its __op__ receipt payloads.

Two Pixeltable(...) instances share id="pixeltable" and merge by narrowing: an entry survives only when every capability covers it, and a disjoint merge raises. A capability passed to a single run replaces the agent's rather than merging with it, so it can widen the allowlist. pydantic-ai-chdb also registers list_tables and describe_table; wrap one side in PrefixTools when you pair them.

Catalog tools

Pixeltable does not create tables or insert rows. Point it at a table or view that already has data, plus an embedding index for similarity_search.

  • query_table filters with equality only ({"status": "open"}); timestamp, date, and UUID values are ISO strings. Media, array, and binary columns reject non-null filters, and computed columns that are not stored reject all filters.
  • similarity_search calls column.similarity(string=query) and needs an embedding index on that column.
  • Output is bounded by max_rows and max_chars: an oversized value is cut (ending in ...) rather than dropping its row, and the minimal {"table", "rows", "truncated"} envelope is always returned, even when max_chars is set below its size. Default columns skip media, array, binary, and computed columns that are not stored (they would recompute per query); a named media column returns a file URL, not a blob.

Declare the tables and index on a TableModel in app.py; pxt schema update creates them:

import pixeltable as pxt
import pixeltable.functions as pxtf
from pixeltable.functions.huggingface import sentence_transformer

TableModel = pxt.model_base()
embed_fn = sentence_transformer.using(model_id="intfloat/multilingual-e5-large-instruct")


class Docs(TableModel, name="docs"):
    document: pxt.Document


class Chunks(
    TableModel,
    name="doc_chunks",
    base=Docs,
    iterator=pxtf.document.document_splitter(Docs.document, separators="paragraph"),
):
    __indexes__ = [pxt.EmbeddingIndex(text, embedding=embed_fn, name="chunks_embed")]  # type: ignore[name-defined]
pxt init
pxt schema update app.py my_app

A notebook or REPL can still call create_table, create_view, and add_embedding_index. Do not put those calls in app.py.

YAML spec

agent = Agent.from_spec(
    {
        "model": "anthropic:claude-sonnet-4-6",
        "capabilities": [{"Pixeltable": {"tables": ["my_app.doc_chunks"]}}],
    },
    custom_capability_types=[Pixeltable],
)

The short form {"Pixeltable": ["my_app.doc_chunks"]} passes the allowlist alone. Without custom_capability_types=[Pixeltable], Agent.from_spec does not know the class.

Memory store

  • The table is created on first use; you do not run pxt schema update for it.
  • Each path is one row (kind == "file"); operation receipts are rows under __op__/. Path roots __meta__ and __op__ are reserved.
  • Compare-and-set: expected_version must equal the row's version. Versions are unique UUID strings, not monotonic. A stale version raises MemoryConflictError.
  • Operation receipts are journaled __op__ rows: the intended mutation is recorded before it is applied, so a mid-write crash rolls forward or replays cleanly instead of double-applying.
  • Paths are limited to 255 characters, since the primary-key index covers the first 256.
  • Pixeltable keeps old row versions for every update and delete, and receipts are never pruned, so the table grows with history.
  • Memory(PixeltableMemoryStore) is Python-only. Harness YAML backends are memory, file, and sqlite.
  • This package emits no telemetry of its own; the memory.* spans come from the Harness Memory capability.

Escape hatch: .table

store = PixeltableMemoryStore(table_name="harness.memory")
t = store.table
t.where(t.kind == "file").select(t.path, t.content, t.version).collect()

Use .table to query. A raw t.update of content is not a Memory write: the version does not change, and the next compare-and-set can overwrite it.

Measured results

Pixeltable 0.7.8 on embedded PostgreSQL, ~20k rows per test, laptop hardware (pytest tests/test_stress.py -v -m expensive):

Operation Time
list_paths, limit 50, prefix holding 18k of 20k files ~115 ms
search (lexical), 100-file scan bound, same prefix ~125 ms
CAS write under contention (200 tasks, 4 paths) ~5 ms per attempt, exactly 4 winners
query_table equality filter, limit 20 over 20k rows ~10 ms
similarity_search top-3 over 20k indexed rows ~8 ms
Embedding index build over 20k rows ~2.8 s

list_paths and search sort every path under the prefix in Python, because database ordering depends on collation, so their cost grows with the files in that namespace, not with the whole table.

Development

pip install -e ".[dev]"
pytest tests/ -v
pytest tests/test_stress.py -v -m expensive
ruff check . && ruff format --check .

pytest tests/ -v skips @pytest.mark.expensive (~20k-row Memory and catalog volume).

License

Apache 2.0

Metadata

Release files for pydantic-ai-pixeltable 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydantic-ai-pixeltable 0.3.0
File Size Uploaded
pydantic_ai_pixeltable-0.3.0.tar.gz 37.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pydantic-ai-pixeltable 0.3.0
File Interpreter ABI Platform
pydantic_ai_pixeltable-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 61.8 kB

Release files / pydantic_ai_pixeltable-0.3.0.tar.gz

Download URL pydantic_ai_pixeltable-0.3.0.tar.gz
Size 37.9 kB
Tags Source
SHA-256 checksum
How to use checksums
b66608678eca3add7f3a9a5bc12adb56b6b743b4a116118b25bba1270280f3c1
BLAKE2b-256 checksum
How to use checksums
32c624d3f18881d1a0f4e1635e219e6edbd2db2336dd14aa6291b68cb871dc59
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 23, 2026.

Transparency log

Release files / pydantic_ai_pixeltable-0.3.0-py3-none-any.whl

Download URL pydantic_ai_pixeltable-0.3.0-py3-none-any.whl
Size 23.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
35405905e2967f7d723e066bf996dbc30290db1fc6bb58a054847c14b85aac52
BLAKE2b-256 checksum
How to use checksums
915aa49eccc0259245d47a4dfae585f31e24085101f31aa2153b3fa8047db171
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 23, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page