voku / agent-graph
Deterministic SQLite graph indexing and shared SQLite runtime support for coding-agent tooling.
Requires
- php: >=8.2
Requires (Dev)
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^11.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 0.3.x-dev
- 0.3.1
- 0.3.0
- 0.2.x-dev
- 0.2.3
- 0.2.2
- 0.2.1
- 0.2.0
- 0.1.0
- dev-release/0.3.1
- dev-fix/release-connection-on-failed-open-v2
- dev-release/tag-0.3.0
- dev-release/prepare-0.3.0
- dev-perf/read-path-and-schema-v2
- dev-release/tag-0.2.3
- dev-release/0.2.3-marker
- dev-release/0.2.3
- dev-feat/read-only-graph-store-29
- dev-fix/release-0.2.2-idempotent-tag
- dev-fix/release-0.2.2-tag-guards
- dev-release/tag-0.2.2
- dev-release/0.2.2-marker
- dev-release/0.2.2
- dev-fix/sqlite-vec-workflow-finalization
- dev-automation/sqlite-vec-0.1.9
- dev-fix/sqlite-vec-version-test-authority
- dev-fix/sqlite-vec-release-digest
- dev-chore/reusable-sqlite-vec-update
- dev-release/tag-0.2.1
- dev-release/0.2.1-marker
- dev-release/0.2.1
- dev-fix/indexed-incoming-query
- dev-release/tag-0.2.0
- dev-release/0.2.0-marker
- dev-release/0.2.0-graph-store
- dev-feat/sqlite-graph-store
- dev-fix/single-file-relation-store
- dev-release/0.2.0
- dev-feat/relation-store
- dev-release-tag/0.1.0
- dev-release-marker/0.1.0
- dev-release/0.1.0
- dev-feat/sqlite-vec-runtime
This package is auto-updated.
Last update: 2026-10-18 21:29:33 UTC
README
Small, deterministic SQLite graph index/query infrastructure for the voku/agent-* toolchain.
The package owns reusable graph storage/query mechanics and shared SQLite runtime assets. Domain semantics stay with their producers: agent-map owns repository/code relations, agent-learning owns learning lineage, and consumers use those owners rather than reading another package's graph database directly.
GraphStore
GraphStore is the primary consumer boundary. Owners project only structural identity into ordered GraphRelation values:
- relation id;
- source id;
- relation kind;
- ordered target ids.
A relation may keep multiple targets. That grouping is part of the evidence and is not flattened into unrelated binary edges.
GraphStore::replace() accepts an iterable<GraphRelation> and replaces the complete derived graph transactionally without requiring callers to allocate a second graph array. The store records opaque source revision/fingerprint provenance so an owner can reject a stale derived database after its canonical data changes.
Reads provide:
- indexed incoming relations;
- indexed outgoing relations;
- unique deterministic neighbours;
- streamed whole-graph relation iteration;
- bounded, cycle-safe incoming/outgoing traversal with explicit truncation.
SQLite rows are an internal normalization. The public relation model stays grouped and domain-neutral.
Structural graph contract
GraphProjection remains the versioned logical projection used by callers that already have an in-memory relation list. GraphProjectionValidator rejects malformed projections before storage. Empty projections fail by default and must be explicitly allowed when an owner legitimately has no relations. Self-relations and unresolved/external target ids remain legal because domain owners decide what those ids mean.
GraphAdjacency remains available as a deterministic in-memory view, but persistent consumers should prefer GraphStore when the point is to avoid decoding or indexing a large relation set in PHP.
SQLite relation store
SqliteRelationStore is the low-level storage implementation behind GraphStore. It preserves relation order and target order, supports optional kind filters, replaces the complete derived graph atomically, records schema/projection provenance, and exposes integrity checks.
Ordinary relation storage stays a single SQLite artifact by default. The package does not force WAL or synchronous tuning without measured evidence. The store is independent from sqlite-vec; relation indexing works without vector support.
Upgrading from 0.2.x to 0.3.0
The derived relation database uses SQLite graph schema version 2. A v1 database from agent-graph 0.2.x cannot be opened using GraphStore::openReadOnly() in 0.3.0. Read-only access fails with a schema-version error and never changes the file.
Rebuild the derived graph using the owning tool (for example, rebuild the agent-map index), or open the existing graph writable once before reading it read-only; a writable open migrates v1 to v2 transactionally. Preserve the canonical source artifacts so the owner can regenerate derived data. Since this is a 0.x minor upgrade, downstream Composer constraints such as ^0.2.3 require an explicit bump to ^0.3.0.
Performance measurements
scripts/benchmark.php builds a deterministic synthetic graph (default 200k relations with high fan-in hubs) and reports median timings plus result checksums. scripts/compare-benchmark.sh [base-ref] runs it against a git ref and the working tree and fails if the checksums differ, so speed-ups cannot silently change query results. Compare several runs; shared machines are noisy. Extra indexes and PRAGMA tuning were measured and are intentionally not applied.
sqlite-vec runtime
agent-graph ships the pinned sqlite-vec loadable SQLite extension used by graph/search consumers on the Linux platforms we actually support:
linux-gnu-x86_64linux-gnu-arm64
The binary is a SQLite extension, not a PHP extension. One platform binary therefore serves all supported PHP versions. voku\AgentGraph\Sqlite\SqliteVecBinary resolves the current platform, verifies the bundled SHA-256 from resources/sqlite-vec/manifest.json, and returns null on unsupported platforms.
An explicit locally supplied binary can be selected with AGENT_GRAPH_SQLITE_VEC.
The bundled binaries are derived from asg017/sqlite-vec; see docs/reference/third-party-notices.md for attribution and licensing.
Scope
This repository should remain boring. It is not an owner of PHP symbols, findings, LearningNotes, embeddings, ranking policy, workflow state, prompt generation, or an untyped metadata bag.