The Problem
AI agents that rely on retrievalâaugmented generation need constantlyâfresh context. Traditional batch pipelines reâprocess whole corpora, creating latency and âstaleâdataâ gaps that hurt answer relevance and increase compute cost.
What This Does
cocoindex provides an incremental sync engine that watches arbitrary data sources (code, Slack, PDFs, video captions, etc.) and reâindexes only the delta. The core Python package lives under python/cocoindex/_internal/ and implements the declarative pipeline, state tracking, and targetâstore adapters. Rust components in rust/ supply highâperformance vectorâstore backâends and transformation utilities. Example applications in examples/ (e.g., examples/audio_to_text/main.py and examples/amazon_s3_embedding/main.py) show how to wire a source connector to a target such as a Neo4j graph or a vector DB.
How It Is Wired
Execution begins at a concrete script, for instance examples/audio_to_text/main.py. That file:
- Loads configuration from the adjacent
.env(currently committed â see health section). - Instantiates a source connector (
AudioSourceinexamples/audio_to_text/connector.py) and a target sink (EmbeddingStoreinpython/cocoindex/_internal/target_state.py). - Calls
cocoindex._internal.api.run_pipeline(source, target)â the central function inpython/cocoindex/_internal/api.py.
api.run_pipeline orchestrates the flow:
- State handling â via
python/cocoindex/_internal/state.py(creates/updates checkpoint files). - Component execution â each pipeline step is a live component (
python/cocoindex/_internal/live_component.py) that registers a coroutine in the component context (python/cocoindex/_internal/component_ctx.py). - Function wrappers â the heavyâlifting logic resides in
python/cocoindex/_internal/function.py, which contains 1,835 lines of code and is the widest blastâradius module (high cognitive load).
The call graph shows that api.py imports 18 other internal modules while being imported by only two, making it a hub with high instability (0.9) and part of a circular import cycle that also involves __init__.py, component_ctx.py, and context_keys.py. Those cycles increase the risk that a change in one module propagates unexpectedly to many others.
Rust side: benchmarks such as benchmarks/file_summarization/rust/src/main.rs compile the cocoindex core (rust/Cargo.toml) into a binary that calls the same internal API via FFI. The Rust crate provides the vectorâstore implementation (rust/src/vector_store.rs) and is invoked directly from the Python wrapper when a target requires highâthroughput similarity search.
Overall, a typical run follows â4 hops: entry script â API â live component â function â external store (e.g., Neo4j, S3, or a local vector DB). Modules like target_state.py and live_component.py own the sideâeffects (network I/O, file writes); they should be the focus of any change.
How To Use It
# Clone the repository (use the exact URL)
git clone https://github.com/moses-y/cocoindex
cd cocoindex
# Build Rust components
cargo build --release # uses Cargo.toml at repo root
# Install Python parts (example with uv, fallback to pip)
uv pip install -e python/ # editable install, resolves pyproject.toml
# or:
pip install -e python/
# Create a local .env (do NOT commit)
cp .env.lib_debug .env.example
# edit .env to add your source keys (e.g., AWS, Azure) and target creds
# Run an example â audio to text embedding
python examples/audio_to_text/main.py
The repository already contains a Dockerfile (root) for containerised execution; building it will install both Rust and Python layers.
RealâWorld Use
A SaaS product that ingests customer support tickets nightly can embed this engine as follows:
from cocoindex._internal.api import run_pipeline
from my_connectors import TicketSource
from my_targets import PineconeSink
pipeline = run_pipeline(TicketSource(), PineconeSink())
pipeline.start() # processes only new tickets since last run
Only newlyâarrived tickets trigger embedding and upsert operations, keeping the vector index fresh without reâindexing the entire backlog.
Code Health & Issues
- High â GitHub Actions pinned to tags only (
.github/workflows/*). Replace with commit SHAs. - High â Committed
.envfiles (.env.lib_debug, examples/*.env). Remove, add to.gitignore, rotate credentials. - High â CI does not run the test suite despite 170 test files. Add a
pyteststep to the workflows. - High â Docs release workflow pushes directly to
gh-pages. Switch to a PRâbased deployment. - Medium â No dependencyâvulnerability scan in CI. Add
dependency-review-actionorosv-scanner. - Medium â Checkout step keeps credentials; set
persist-credentials: falseinrelease.yml. - Low â Workflow jobs lack explicit
timeout-minutes. Define reasonable limits.
Measured static analysis also found:
- 5 import cycles involving core internal modules (
__init__.py,component_ctx.py,context_keys.py). Break cycles to improve stability. - 46 deepânesting spots (max indentation 8) in files like
function.pyandenvironment.py. Refactor for readability. - Broad exception handling in several internal modules; narrow catches to avoid silent failures.
- Oversized files (
function.pyâ 1,835 lines). Split into focused subâmodules.
No missing license or test framework; a license file is present.
The Bottom Line
cocoindex delivers a functional incremental indexing framework with both Python and Rust components, suitable for production AI agents that need nearârealâtime context. The codebase is modular but suffers from import cycles, overly large core files, and several CI/secretâmanagement hygiene issues that must be addressed before safe deployment in a securityâsensitive environment. Teams comfortable with Pythonâcentric pipelines and willing to clean up the health concerns will find it a valuable foundation.