Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
584ddeb
feat(client): track the 0.5.1 proto and drop the stand-in messages
polaz Aug 29, 2026
0d2324d
feat(client): expose the 0.5 write, read and bulk-insert surface
polaz Aug 29, 2026
71f0674
fix(demo): unblock the notebook stack and stop the install cell shado…
polaz Aug 29, 2026
6847261
fix(demo): make the container run the mounted SDK instead of a release
polaz Aug 29, 2026
7d93c52
fix(embedded): convert the Value variants 0.5 added
polaz Aug 29, 2026
a6215be
chore(demo): record why the SDK install cannot be binary-only
polaz Aug 29, 2026
a3bc740
fix(demo): make the agent guards linear and land the pip suppression
polaz Aug 30, 2026
bc73b5f
fix(demo): move the stack to the server release that does not crash
polaz Aug 30, 2026
616e90c
feat(demo): notebook for what 0.5 added, and correct the time-travel …
polaz Aug 30, 2026
4bd0dc2
feat(client): decode the path and multi-vector wire types
polaz Aug 30, 2026
d29abb9
fix(client): make a timestamped read a snapshot read
polaz Aug 30, 2026
f9c6372
fix(demo): make the install cell survive a fresh environment
polaz Aug 30, 2026
d7b26ed
fix(build): generate proto stubs where they are actually missing
polaz Aug 30, 2026
6a6dfd0
build: track the server release this checkout is built for
polaz Aug 30, 2026
4f0f5c4
fix(sdk): keep a multi-vector a multi-vector on re-encode
polaz Aug 30, 2026
7177975
fix(langchain): expose the schema accessors GraphStore declares
polaz Aug 30, 2026
b45e51f
build(deps): raise floors to what the shipped stubs require
polaz Aug 30, 2026
20ba8de
fix(build): let the pip install path work without uv
polaz Aug 30, 2026
09cecaa
build: pin the server image by digest and track v0.5.3
polaz Aug 30, 2026
b299982
fix(demo): run the notebooks on current langchain and a real server
polaz Aug 30, 2026
fb66a61
fix(demo): say which notebook needs a server and check both time views
polaz Aug 30, 2026
57f3995
test(demo): check the session guard against the queries that fooled it
polaz Aug 30, 2026
f34c7c2
fix(sdk): refuse a causal fence together with a pinned read
polaz Aug 30, 2026
f0b07d4
build: drive the pip install path through one interpreter
polaz Aug 30, 2026
90e5b0b
fix(demo): blank inert Cypher syntax before the session-scope check
polaz Aug 30, 2026
f2c072f
fix(embedded): keep a multi-vector a multi-vector on re-encode
polaz Aug 30, 2026
9520ef9
fix(demo): require every MATCH to carry its own session scope
polaz Aug 30, 2026
d6e4e35
build(embedded): record the engine versions the submodule now pins
polaz Aug 30, 2026
5309c8e
build: track the v0.5.4 server release
polaz Aug 30, 2026
9e1f5c2
refactor(demo): drop the workarounds v0.5.4 makes unnecessary
polaz Aug 30, 2026
5673cf6
build: track the v0.5.5 server release
polaz Aug 31, 2026
1020975
build(embedded): record the engine versions the submodule now pins
polaz Aug 31, 2026
1f2b843
fix(demo): reject a session scope that OR or NOT undoes
polaz Aug 31, 2026
4a8b338
fix(demo): bootstrap on the client surface, not on import alone
polaz Aug 31, 2026
fa910b1
docs(client): say why the schema type map mirrors the wire enum
polaz Aug 31, 2026
230eff8
ci: resolve from the lockfile and install wheels only
polaz Aug 31, 2026
979e676
fix(demo): tie a WHERE scope to an alias its own MATCH binds
polaz Aug 31, 2026
c2025b9
fix(demo): drop the import caches where the install happens
polaz Aug 31, 2026
a8fa5b3
fix(embedded): keep a path a path on re-encode
polaz Aug 31, 2026
5ec3390
build: point the quick-start stack at the tested server
polaz Aug 31, 2026
29a07bf
fix(embedded): keep the value tags in a standalone install
polaz Aug 31, 2026
d7782b2
ci: run every extension-backed test in the wheel job
polaz Aug 31, 2026
04dfe20
fix(demo): scope every node a MATCH names, not just one of them
polaz Aug 31, 2026
56d718e
docs(ci): record why --no-build keeps the workspace installable
polaz Aug 31, 2026
b2587c4
fix(demo): bound the work the scope guard will do on one query
polaz Aug 31, 2026
0d48159
build(embedded): put the compiled extension in the release cycle
polaz Aug 31, 2026
48a89ac
refactor(demo): isolate the agent notebook by database, not by filter
polaz Aug 31, 2026
bbce887
fix(client): reject at_timestamp=0 instead of silently unpinning the …
polaz Aug 31, 2026
52b4305
perf(embedded): stop paying per value in the conversion layer
polaz Aug 31, 2026
9cc1f93
fix(demo): bound query_facts again after the guard came out
polaz Aug 31, 2026
bdc52c3
refactor(types): move the path encoding out of the value dispatch
polaz Aug 31, 2026
3f0c65d
refactor(types): move the sequence encoding out of the value dispatch…
polaz Aug 31, 2026
b3684a6
fix(embedded): remember the tag lookup only when it succeeds
polaz Aug 31, 2026
398384a
fix(demo): cap the rows, not the query text
polaz Aug 31, 2026
8618bdf
fix(demo): give the agent back a memory that survives a restart
polaz Aug 31, 2026
a25bcbc
docs(demo): correct what the published wheel actually cannot do
polaz Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 37 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,21 @@
with:
python-version: "3.11"

- run: uv sync
- run: uv run ruff check coordinode/ langchain-coordinode/ llama-index-coordinode/ tests/
- run: uv run ruff format --check coordinode/ langchain-coordinode/ llama-index-coordinode/ tests/
# --locked fails the job when uv.lock does not match pyproject, so CI
# resolves exactly what a developer resolved rather than picking up a
# newer release mid-run. --no-build installs from wheels only, which
# keeps a dependency's setup.py from executing on the runner.
#
# The editable workspace members install regardless: --no-build refuses
# source distributions of dependencies, not a local editable install.
# Verified both ways, since the flag reads as though it would block them:
# a sync with an empty UV_CACHE_DIR into a fresh environment installs
# coordinode, langchain-coordinode and llama-index-graph-stores-coordinode
# and imports them, and every job below has run green with the flag on a
# clean runner. Remove it only with evidence, not on the wording.
- run: uv sync --locked --no-build
Comment thread
polaz marked this conversation as resolved.
- run: uv run --locked --no-build ruff check coordinode/ langchain-coordinode/ llama-index-coordinode/ tests/
- run: uv run --locked --no-build ruff format --check coordinode/ langchain-coordinode/ llama-index-coordinode/ tests/

test:
name: Test (Python ${{ matrix.python-version }})
Expand All @@ -37,13 +49,13 @@
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: uv sync --all-packages
run: uv sync --locked --no-build --all-packages

- name: Generate proto stubs
run: uv run make proto
run: uv run --locked --no-build make proto

- name: Unit tests
run: uv run pytest tests/unit/ -v
run: uv run --locked --no-build pytest tests/unit/ -v

build-embedded:
name: Build embedded (CI check)
Expand Down Expand Up @@ -83,8 +95,17 @@
WHL=$(ls dist/coordinode_embedded-*.whl | head -1)
test -n "$WHL"
uv venv --python 3.12 /tmp/test-venv
uv pip install --python /tmp/test-venv/bin/python "$WHL" numpy pytest pytest-timeout
OUTPUT=$(/tmp/test-venv/bin/python -m pytest tests/unit/test_hnsw.py -v --strict-markers -ra 2>&1)
# Pinned to the versions uv.lock already resolves for the workspace,
# so this throwaway venv tests against the same stack as the other
# jobs instead of whatever is newest on PyPI that morning.
uv pip install --python /tmp/test-venv/bin/python "$WHL" \

Check warning on line 101 in .github/workflows/ci.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Using dependencies without locking resolved versions is security-sensitive.

See more on https://sonarcloud.io/project/issues?id=structured-world_coordinode-python&issues=AaBXb_AAKbjxbBtqb5Tj&open=AaBXb_AAKbjxbBtqb5Tj&pullRequest=80
numpy==2.4.6 pytest==9.1.1 pytest-timeout==2.4.0
# Every test file that needs the extension belongs here: the main
# `test` job skips them all for want of a wheel, so a file left out
# of this list runs in no job at all.
OUTPUT=$(/tmp/test-venv/bin/python -m pytest \
tests/unit/test_hnsw.py tests/unit/test_embedded_values.py \
-v --strict-markers -ra 2>&1)
echo "$OUTPUT"
# `-ra` prints a "SKIPPED [N]" short summary header when anything was
# skipped; importorskip-based skip also surfaces this way. Use the
Expand All @@ -104,7 +125,11 @@
runs-on: ubuntu-latest
services:
coordinode:
image: ghcr.io/structured-world/coordinode:latest
# Pinned by digest, not by tag: the proto submodule pins a server
# version, and a tag can be re-pushed, so `:0.5.5` alone does not name
# one fixed server. The digest below is 0.5.5; bump both together with
# the submodule.
image: ghcr.io/structured-world/coordinode@sha256:8d3554be7680aa2cea7b6e773037aee97513865f4698b6df0ffc2daf845c42b8
ports:
- 7080:7080
- 7084:7084
Expand Down Expand Up @@ -134,10 +159,10 @@

- name: Install + generate proto
run: |
uv sync --all-packages
uv run make proto
uv sync --locked --no-build --all-packages
uv run --locked --no-build make proto

- name: Integration tests
env:
COORDINODE_ADDR: "localhost:7080"
run: uv run pytest tests/integration/ -v --timeout=30
run: uv run --locked --no-build pytest tests/integration/ -v --timeout=30
38 changes: 31 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,33 @@

PROTO_SRC := proto
PROTO_OUT := coordinode/coordinode/_proto
PYTHON ?= python3
# grpcio-tools lives in the synced environment, so both the include-path probe
# below and the generation itself have to run through the same interpreter.
# A bare python3 finds neither.
PYTHON ?= uv run python
Comment thread
polaz marked this conversation as resolved.
Comment thread
polaz marked this conversation as resolved.

# Well-known types that ship with grpc_tools. The proto submodule vendors its
# own google/protobuf/descriptor.proto so the Rust build works on hosts without
# protobuf-devel; that copy is older than what this protoc expects and, if it
# wins the include search, generation dies with "Malformed descriptor.proto
# doesn't contain google.protobuf.FeatureSet". Searching here first keeps
# descriptor.proto on protoc's own copy while google/api/* still resolves from
# the submodule, which is the only place it exists.
# Deferred, not `:=`: an immediate assignment would shell out to $(PYTHON) on
# every make invocation, including `make clean` on a machine with no uv.
GRPC_INC = $(shell $(PYTHON) -c "import grpc_tools, os; print(os.path.join(os.path.dirname(grpc_tools.__file__), '_proto'))")

# Generate gRPC stubs from proto submodule into coordinode/_proto/
proto:
@echo "==> Generating proto stubs..."
@mkdir -p $(PROTO_OUT)
$(PYTHON) -m grpc_tools.protoc \
-I"$(GRPC_INC)" \
-I$(PROTO_SRC) \
--python_out=$(PROTO_OUT) \
--grpc_python_out=$(PROTO_OUT) \
--pyi_out=$(PROTO_OUT) \
$$(find $(PROTO_SRC) -name '*.proto')
$$(find $(PROTO_SRC) -name '*.proto' -not -path '$(PROTO_SRC)/google/protobuf/*')
@# Add __init__.py to every generated package directory
@find $(PROTO_OUT) -type d -exec touch {}/__init__.py \;
@# Fix absolute imports in all generated pb2 files (grpc_tools generates absolute paths)
Expand All @@ -34,12 +49,21 @@ install:
uv sync
$(MAKE) proto

# Install using pip (alternative — works without uv)
# Install using pip (alternative that works without uv).
#
# PIP_PYTHON, not a bare `pip`: the whole point of this target is a machine
# with no uv, and there `pip` and `python3` can be two different interpreters
# (a pip from 3.11 on PATH ahead of a 3.13 python3, say). Installing through
# one and generating stubs with the other puts grpcio-tools in an environment
# the generation step cannot see. Everything below goes through the same
# interpreter, and `make install-pip PIP_PYTHON=python3.12` picks another.
PIP_PYTHON ?= python3

install-pip:
pip install -e "coordinode[dev]"
pip install -e langchain-coordinode/
pip install -e llama-index-coordinode/
$(MAKE) proto
$(PIP_PYTHON) -m pip install -e "coordinode[dev]"
$(PIP_PYTHON) -m pip install -e langchain-coordinode/
$(PIP_PYTHON) -m pip install -e llama-index-coordinode/
$(MAKE) proto PYTHON="$(PIP_PYTHON)"

test: proto-check test-unit

Expand Down
Loading
Loading