Skip to content

feat(sdk): update for coordinode-server v0.4.1#47

Merged
polaz merged 25 commits intomainfrom
feat/#46-sdk-v0.4.1-update
Apr 21, 2026
Merged

feat(sdk): update for coordinode-server v0.4.1#47
polaz merged 25 commits intomainfrom
feat/#46-sdk-v0.4.1-update

Conversation

@polaz
Copy link
Copy Markdown
Member

@polaz polaz commented Apr 19, 2026

Summary

Aligns Python SDK with coordinode-server v0.4.1 (breaking proto change upstream) and brings the demo notebooks to a reproducible Colab-ready state.

SDK changes

  • Bump submodules: coordinode-rs → v0.4.1, proto → eb472a4
  • Regenerate proto stubs
  • BREAKING: remove CoordinodeClient.hybrid_text_vector_search() (async + sync) — RPC dropped upstream. Replacement is server-side Cypher scoring: rrf_score() / hybrid_score() / text_score() / text_match() / doc_score() / vec_score(). No compat shim (no external clients)
  • Drop orphan HybridResult class + export (no remaining method returns it)
  • Expose consistency controls on cypher(): read_concern / write_concern / read_preference / after_index — thin string API mapping to ExecuteCypherRequest proto fields, with _normalize_consistency_key guard that rejects blank/non-str keys and bool/negative after_index. Integration test verifies the kwargs round-trip end-to-end

Demo + docs

  • Bump docker-compose image tag to 0.4.1 (root + demo)
  • Colab notebooks pin the coordinode SDK to this PR git ref via _coordinode_spec whenever IN_COLAB is true, regardless of COORDINODE_ADDR — PyPI coordinode can lag the v0.4.1 proto/server, so Colab sessions pointing at a remote server still need the pinned SDK. Outside Colab the SDK resolves from PyPI. coordinode-embedded (Rust build, ~5 min) is installed only when COORDINODE_ADDR is unset — pointless to pay the build cost when using a remote server
  • Guard apt-get install protobuf-compiler with a which protoc check and apt-get update first (Colab apt indexes occasionally go stale)
  • coordinode/README.md: document hybrid search (incl. CREATE TEXT INDEX prerequisite), ATTACH / DETACH DOCUMENT, and the new consistency params. Examples project explicit properties (bare RETURN d returns an integer node id in CoordiNode Cypher)

Connect-cell design (notebooks 00–03)

The connect cell is deliberately two-way only, not three-way:

  • COORDINODE_ADDR set → use that gRPC server. Hard-fail with RuntimeError if health() returns false (closes the failed client first).
  • COORDINODE_ADDR unset → use coordinode-embedded with LocalClient(COORDINODE_EMBEDDED_PATH) (default /content/coordinode-demo.db in Colab, the OS temp dir (tempfile.gettempdir()) locally (portable across Linux/macOS/Windows)).

The earlier auto-probe of localhost:7080 was removed deliberately — it was unreachable in Colab (fresh VMs have nothing on that port), and locally it created an ambiguous third state ("port open but unhealthy") that caused review-loop churn and surprised users with silent embedded fallback. There is no longer any port probe. Use COORDINODE_ADDR=localhost:7080 explicitly when you want the gRPC path; otherwise embedded is the supported default.

Embedded is now file-backed (not :memory:) so the graph persists across cell reruns and is shared between sibling demo notebooks within the same runtime.

Test plan

  • make lint — clean
  • make test-unit — 92 passed (incl. consistency-helper validation tests)
  • make test-integration against v0.4.1 server — 71 passed, 1 xpassed (incl. consistency kwargs round-trip + invalid-value rejection)
  • All 4 demo notebooks executed end-to-end via jupyter nbconvert --execute against v0.4.1 server
  • Colab install path verified via Docker imitation (Ubuntu 22.04 + Python 3.11 + rustup + fake google.colab module): full Rust build of coordinode-embedded succeeds and all 4 notebooks run through the IN_COLAB → embedded branch end-to-end

Closes #46

BREAKING CHANGE: HybridTextVectorSearch RPC removed upstream.

- Bump coordinode-rs submodule to v0.4.1
- Bump proto submodule to eb472a4 (HybridTextVectorSearch removed)
- Remove CoordinodeClient.hybrid_text_vector_search (async + sync) — replaced by Cypher hybrid scoring (rrf_score / hybrid_score / text_score)
- Drop matching integration test
- Bump docker-compose image tag to 0.4.1 (root + demo)
- Re-execute all 4 demo notebooks against v0.4.1

Closes #46
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: dd14c96d-655d-4fe8-94e7-dd3f59469d04

📥 Commits

Reviewing files that changed from the base of the PR and between 9f86b93 and d62e53b.

📒 Files selected for processing (2)
  • coordinode/coordinode/client.py
  • tests/integration/test_sdk.py

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Consistency controls for Cypher queries: read_concern, write_concern, read_preference, after_index
  • Removals

    • Removed hybrid_text_vector_search API and associated HybridResult type
  • Improvements

    • Server and embedded components updated to v0.4.1; embedded demos now use file-backed persistent storage
    • Better validation and error messages for consistency parameters
  • Documentation

    • Added hybrid-search, ATTACH/DETACH DOCUMENT, and consistency control examples in READMEs and demos
  • Tests

    • Added unit tests for consistency helpers and integration tests for Cypher consistency behavior; removed legacy hybrid test
  • Chores

    • Updated tracked submodules and .gitignore entries

Walkthrough

Bumped coordinode/proto submodules and server image to v0.4.1, removed the HybridTextVectorSearch RPC and HybridResult, added validated Cypher consistency kwargs to client cypher(...), updated demos to use a persistent embedded DB and protoc guards, and added/updated tests for consistency helpers and cypher wiring.

Changes

Cohort / File(s) Summary
Submodule pins
coordinode-rs, proto
Updated tracked submodule commits (coordinode-rse0694e5..., protoeb472a4...).
Client API
coordinode/coordinode/client.py, coordinode/coordinode/__init__.py
Removed HybridResult and async/sync hybrid_text_vector_search; added Cypher consistency kwargs (read_concern, write_concern, read_preference, after_index) with validation/mapping helpers; updated cypher(...) signatures and removed HybridResult re-export.
Tests
tests/integration/test_sdk.py, tests/unit/test_consistency_helpers.py
Removed hybrid-search integration test and HybridResult import; added integration tests for cypher consistency wiring and unit tests for _make_read_concern, _make_write_concern, _make_read_preference.
Compose files
demo/docker-compose.yml, docker-compose.yml
Bumped CoordiNode Docker image tag from ghcr.io/structured-world/coordinode:0.3.17ghcr.io/structured-world/coordinode:0.4.1.
Demo notebooks
demo/notebooks/...
demo/notebooks/00_seed_data.ipynb, .../01_llama_index_property_graph.ipynb, .../02_langchain_graph_chain.ipynb, .../03_langgraph_agent.ipynb
Normalized cell IDs; conditional protobuf-compiler install when protoc missing; switched embedded client to file-backed LocalClient(COORDINODE_EMBEDDED_PATH); removed local port probing/fallback; ensure client.close() on failed health checks; updated pinned install specs and UI text/formatting.
Docs / READMEs
coordinode/README.md, demo/README.md
Added Hybrid Search workflow and Consistency Controls docs; removed HNSW qualifier; updated demo version pins to v0.4.1.
Packaging / ignores
.gitignore, coordinode-embedded/.gitignore
Added .claude/ ignore and added *.so, *.pyd, *.dylib ignores in embedded subproject.

Sequence Diagram(s)

sequenceDiagram
    participant Client as AsyncCoordinodeClient.cypher
    participant Helper as ConsistencyHelpers
    participant Server as CoordiNode.ExecuteCypher
    participant Store as Storage/Replicas

    Client->>Helper: validate & map read_concern/read_preference/write_concern/after_index
    Helper-->>Client: proto enum fields or ValueError
    Client->>Server: ExecuteCypher(request with consistency fields)
    Server->>Store: apply concerns / enforce causal/read/write rules
    Store-->>Server: result rows
    Server-->>Client: ExecuteCypherResponse -> parsed result list
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(sdk): update for coordinode-server v0.4.1' clearly and concisely summarizes the main change: aligning the Python SDK with coordinode-server v0.4.1.
Description check ✅ Passed The description comprehensively documents the SDK changes, demo/docs updates, design decisions, and testing results, all directly related to the v0.4.1 update changeset.
Linked Issues check ✅ Passed The PR fully satisfies issue #46: submodules bumped to v0.4.1, proto regenerated from eb472a4, hybrid RPC removed with migration guidance to Cypher functions, demo notebooks updated for Colab reproducibility, consistency controls exposed on cypher() with validation and integration test coverage, and comprehensive testing completed.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to the v0.4.1 update objective: submodule bumps, proto regeneration, RPC removal with replacement documentation, consistency parameter addition, demo notebook updates for Colab, README documentation, and comprehensive test coverage updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#46-sdk-v0.4.1-update

Comment @coderabbitai help to get the list of available commands and usage tips.

@polaz polaz requested a review from Copilot April 19, 2026 10:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns the Python SDK + demos/integration setup with coordinode-server v0.4.1, reflecting the upstream breaking change that removed the hybrid text+vector search RPC.

Changes:

  • Removed CoordinodeClient.hybrid_text_vector_search() (async + sync) and dropped the corresponding integration test.
  • Bumped CoordiNode Docker image tags to 0.4.1 (root + demo compose).
  • Updated demo notebooks (now include executed outputs / execution metadata).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
coordinode/coordinode/client.py Removes the hybrid text+vector search client methods to match upstream RPC removal.
tests/integration/test_sdk.py Drops the integration test and import tied to the removed hybrid search API.
docker-compose.yml Updates the dev/integration stack server image tag to 0.4.1.
demo/docker-compose.yml Updates the demo stack server image tag to 0.4.1.
demo/notebooks/00_seed_data.ipynb Notebook updated with executed outputs/metadata from a recent run.
demo/notebooks/01_llama_index_property_graph.ipynb Notebook updated with executed outputs/metadata from a recent run.
demo/notebooks/02_langchain_graph_chain.ipynb Notebook updated with executed outputs/metadata from a recent run.
demo/notebooks/03_langgraph_agent.ipynb Notebook updated with executed outputs/metadata from a recent run.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread demo/notebooks/03_langgraph_agent.ipynb Outdated
Comment thread demo/notebooks/02_langchain_graph_chain.ipynb Outdated
Comment thread demo/notebooks/01_llama_index_property_graph.ipynb Outdated
Comment thread demo/notebooks/00_seed_data.ipynb Outdated
Comment thread coordinode/coordinode/client.py
- Remove HybridResult class and export from coordinode.__init__ — no
  remaining method returns it after hybrid_text_vector_search() removal
  (hybrid_search on VectorService returns VectorResult)
- Clear execution_count/outputs from all 4 demo notebooks for clean diffs
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns the Python SDK (and demos/tests) with coordinode-server v0.4.1 by removing the dropped hybrid text+vector RPC surface and updating local/demo stacks to run against the new server image.

Changes:

  • Removed HybridResult plus CoordinodeClient.hybrid_text_vector_search() (async + sync) and dropped the corresponding integration test.
  • Bumped CoordiNode Docker image tags in root and demo docker-compose.yml to 0.4.1.
  • Updated demo notebooks (primarily notebook JSON/metadata churn from re-execution/export).

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
coordinode/coordinode/client.py Removes hybrid text+vector search API and its result type to match upstream proto/RPC removal.
coordinode/coordinode/__init__.py Stops exporting HybridResult from the public package surface.
tests/integration/test_sdk.py Removes the integration test that exercised the removed hybrid search API.
docker-compose.yml Pins local integration stack CoordiNode image to 0.4.1.
demo/docker-compose.yml Pins demo stack CoordiNode image to 0.4.1.
demo/notebooks/00_seed_data.ipynb Notebook JSON updated after execution/export.
demo/notebooks/01_llama_index_property_graph.ipynb Notebook JSON updated after execution/export.
demo/notebooks/02_langchain_graph_chain.ipynb Notebook JSON updated after execution/export.
demo/notebooks/03_langgraph_agent.ipynb Notebook JSON updated after execution/export.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread demo/notebooks/03_langgraph_agent.ipynb Outdated
Comment thread demo/notebooks/03_langgraph_agent.ipynb Outdated
Comment thread demo/notebooks/02_langchain_graph_chain.ipynb Outdated
Comment thread demo/notebooks/02_langchain_graph_chain.ipynb Outdated
Comment thread demo/notebooks/01_llama_index_property_graph.ipynb Outdated
Comment thread demo/notebooks/01_llama_index_property_graph.ipynb Outdated
Comment thread demo/notebooks/00_seed_data.ipynb Outdated
Comment thread demo/notebooks/00_seed_data.ipynb Outdated
Remove per-cell execution.* timestamps and trim language_info down to
{name: python}. Prevents diff noise from exact Python patch versions,
UUIDs, and run timestamps on notebook re-execution.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@demo/notebooks/00_seed_data.ipynb`:
- Line 245: Replace repeated literal "Eva Müller" with a single constant to
remove duplication: define a descriptive constant (e.g., EVA_MULLER_NAME) near
the top of the notebook or cell and use that constant in the JSON objects that
currently contain the name (the entries around the strings shown in the diff and
the other occurrences flagged). Update the JSON construction to reference the
constant instead of the hard-coded string so all three occurrences (the ones the
reviewer called out) reuse the same identifier.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f3cc3044-2f0f-4d1f-a52f-8cb61dbe8c1d

📥 Commits

Reviewing files that changed from the base of the PR and between d0b05df and c2ce320.

📒 Files selected for processing (4)
  • demo/notebooks/00_seed_data.ipynb
  • demo/notebooks/01_llama_index_property_graph.ipynb
  • demo/notebooks/02_langchain_graph_chain.ipynb
  • demo/notebooks/03_langgraph_agent.ipynb

Comment thread demo/notebooks/00_seed_data.ipynb
- cypher() now accepts read_concern / write_concern / read_preference /
  after_index — maps to ExecuteCypherRequest.ReadConcern, WriteConcern,
  ReadPreference proto fields. String-based API (e.g. "majority",
  "linearizable") validated against enum maps
- Add _make_read_concern / _make_write_concern / _make_read_preference
  helpers and unit tests
- Bump Colab embedded pin 8da94d6 -> c2ce320 (v0.3.17 -> v0.4.1) in all
  4 demo notebooks
- Update demo/README.md v0.3.17 -> v0.4.1 references
- coordinode/README.md: drop "HNSW coming in v0.4" note, add Hybrid
  Search (rrf_score/text_score/vec_score), ATTACH/DETACH DOCUMENT, and
  Consistency Controls sections

All 75 unit + 69 integration tests green; 4 demo notebooks re-executed
end-to-end against v0.4.1 server.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 19, 2026

Tip

For best results, initiate chat on the files or code changes.

@polaz: Understood — that's a good point about notebook cell independence. Repeating literal values like "Eva Müller" across cells is the correct pattern here to avoid cross-cell NameErrors when cells are re-run out of order. I'll remember this for future notebook reviews.

(ᵔᴥᵔ)


✏️ Learnings added
Learnt from: polaz
URL: https://github.com/structured-world/coordinode-python/pull/47

Timestamp: 2026-04-19T12:10:36.422Z
Learning: In the `structured-world/coordinode-python` repository's demo notebooks (e.g., `demo/notebooks/`), repeated string literals (such as node/entity names like `"Eva Müller"`) across cells are intentional. Notebook cells are designed to be run independently and out of order, so extracting shared values into a module-level constant defined in one cell would cause a `NameError` when users re-run a later cell without having executed the definition cell first. Do not flag such duplication as a code smell in notebook context.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: polaz
Repo: structured-world/coordinode-python PR: 18
File: llama-index-coordinode/pyproject.toml:25-25
Timestamp: 2026-04-09T19:03:31.417Z
Learning: In the `coordinode-python` repository, the Python package dependency `coordinode` (PyPI) is distinct from the CoordiNode Rust database server (`structured-world/coordinode` on GitHub). The Python SDK (`coordinode` on PyPI) reached v0.4.x stability (v0.4.0–v0.4.4 released April 9, 2026), while the Rust server's latest release is v0.3.0. Web searches for "coordinode" may return the Rust server GitHub repo instead of the PyPI package — always verify against PyPI directly for Python dependency constraints in this repo.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 37
File: demo/docker-compose.yml:42-43
Timestamp: 2026-04-15T23:53:03.424Z
Learning: In `demo/docker-compose.yml` (structured-world/coordinode-python), `install-sdk.sh` does NOT need to install `coordinode-embedded`. The Jupyter container always has `COORDINODE_ADDR=coordinode:7080` set via docker-compose environment, so the notebooks' embedded fallback (`from coordinode_embedded import LocalClient`) is never reached in Docker Compose. In Colab, notebooks install `coordinode-embedded` themselves via the `IN_COLAB and not COORDINODE_ADDR` guard in cell 0. Do not flag the absence of `coordinode-embedded` from `install-sdk.sh` as a bug.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@coordinode/coordinode/client.py`:
- Around line 1007-1036: The helpers accept blank/non-string keys and coerce
bool/invalid after_index values; add a small guard function (e.g.
_normalize_consistency_key(key: Any, name: str) -> str) that raises ValueError
for None, non-str, or blank strings and returns key.lower(); call it from
_make_read_concern, _make_write_concern, and _make_read_preference instead of
using .lower() directly; additionally validate after_index in _make_read_concern
to reject bools, non-integers, and negatives (raise ValueError) rather than
coercing via int(); update unit tests to cover blank strings for all three
helpers and invalid after_index cases (bool, non-int, negative).

In `@demo/notebooks/01_llama_index_property_graph.ipynb`:
- Line 89: Pin the top-level "coordinode" pip install to the same SDK version as
the embedded package (or unpin both) to avoid mixing the
git+https://github.com/structured-world/coordinode-python@c2ce32064dd7f6495f0998049c0cc2f6f7a5767d#subdirectory=coordinode-embedded
install with an unpinned coordinode from PyPI; locate the notebook cell that
installs "coordinode" and "coordinode-embedded" and make them consistent by
either specifying the matching release/version for "coordinode" (the release
that corresponds to the embedded commit) or removing the explicit commit pin so
both resolve together, and apply the same change to the other demo notebook
install cells.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5308ba00-1064-4e41-86e3-139615496b49

📥 Commits

Reviewing files that changed from the base of the PR and between c2ce320 and 8d69841.

📒 Files selected for processing (8)
  • coordinode/README.md
  • coordinode/coordinode/client.py
  • demo/README.md
  • demo/notebooks/00_seed_data.ipynb
  • demo/notebooks/01_llama_index_property_graph.ipynb
  • demo/notebooks/02_langchain_graph_chain.ipynb
  • demo/notebooks/03_langgraph_agent.ipynb
  • tests/unit/test_consistency_helpers.py

Comment thread coordinode/coordinode/client.py Outdated
Comment thread demo/notebooks/01_llama_index_property_graph.ipynb Outdated
polaz added 2 commits April 19, 2026 15:32
coordinode-raft uses prost-build which requires protoc at build time.
Colab runtime doesn't always have protobuf-compiler preinstalled, so
the existing install block failed with:

  Error: Could not find `protoc`.

Add an apt-get step inside the IN_COLAB branch before the rustup/maturin
invocation. Verified end-to-end in an Ubuntu 22.04 Docker imitation of
the Colab runtime — all 4 notebooks execute successfully through the
embedded path.
…in Colab

- Consistency helpers now share a _normalize_consistency_key guard that
  rejects None, non-str, blank/whitespace keys. after_index rejects bool,
  non-int, and negative values. Previously an empty string silently
  downgraded to defaults, True was coerced to 1, and non-string inputs
  crashed with AttributeError instead of ValueError.
- Add unit tests covering blank strings, bool/negative/non-int
  after_index, and numeric inputs for all three helpers.
- demo notebooks: pin the top-level coordinode SDK to the same git ref as
  coordinode-embedded inside the IN_COLAB branch (previously bare
  "coordinode" from PyPI could resolve to an incompatible newer release).
- .gitignore: exclude .claude/ (session lock artefacts).
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
demo/notebooks/03_langgraph_agent.ipynb (1)

169-183: ⚠️ Potential issue | 🟠 Major

Do not silently fall back to embedded when the default gRPC port is reachable but unhealthy.

If localhost:7080 is open and client.health() fails, this notebook now switches to LocalClient(":memory:"). That masks a real server problem and makes the session write to ephemeral in-memory storage instead of the database the user expected.

🐛 Suggested fix
     if _port_open(grpc_port):
         COORDINODE_ADDR = f"localhost:{grpc_port}"
         from coordinode import CoordinodeClient

         client = CoordinodeClient(COORDINODE_ADDR)
-        if client.health():
-            print(f"Connected to {COORDINODE_ADDR}")
-            _use_embedded = False
-        else:
-            # Port is open but not a CoordiNode server — fall through to embedded.
-            client.close()
+        if not client.health():
+            client.close()
+            raise RuntimeError(f"CoordiNode at {COORDINODE_ADDR} is not serving health checks")
+        print(f"Connected to {COORDINODE_ADDR}")
+        _use_embedded = False
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demo/notebooks/03_langgraph_agent.ipynb` around lines 169 - 183, The notebook
currently treats an open gRPC port as success but then silently falls back to
embedded when CoordinodeClient(COORDINODE_ADDR).health() returns false; change
this so that when _port_open(grpc_port) is true and client.health() is false you
do not set _use_embedded to True or switch to LocalClient(":memory:")
silently—instead surface the failure (throw an exception or print a clear error
and stop) and include COORDINODE_ADDR and the health check result; locate the
logic around _port_open, grpc_port, COORDINODE_ADDR, CoordinodeClient,
client.health(), client.close(), and _use_embedded and replace the silent
fallback with explicit error handling or user-facing message so the user is not
pointed at ephemeral in-memory storage unknowingly.
♻️ Duplicate comments (1)
demo/notebooks/03_langgraph_agent.ipynb (1)

44-47: ⚠️ Potential issue | 🟠 Major

Pin coordinode to the same git ref here too.

This notebook still installs coordinode-embedded from c2ce320... but later resolves plain coordinode from PyPI. In a fresh Colab runtime that can reintroduce the SDK/embedded skew the other notebooks already fixed.

♻️ Suggested fix
 _EMBEDDED_PIP_SPEC = (
     "git+https://github.com/structured-world/coordinode-python.git"
     "@c2ce32064dd7f6495f0998049c0cc2f6f7a5767d#subdirectory=coordinode-embedded"
 )
+_SDK_PIP_SPEC = (
+    "git+https://github.com/structured-world/coordinode-python.git"
+    "@c2ce32064dd7f6495f0998049c0cc2f6f7a5767d#subdirectory=coordinode"
+)
@@
 subprocess.run(
     [
         sys.executable,
         "-m",
         "pip",
         "install",
         "-q",
-        "coordinode",
+        _SDK_PIP_SPEC if IN_COLAB and not os.environ.get("COORDINODE_ADDR") else "coordinode",
         "langchain-community",
         "langchain-openai",
         "langgraph",
         "nest_asyncio",
     ],

Based on learnings: in the CoordiNode demo notebooks under demo/notebooks/0[0-3]_*.ipynb, inside the if IN_COLAB and not COORDINODE_ADDR guard block, coordinode must be pinned to the exact same git commit ref as coordinode-embedded.

Also applies to: 98-113

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demo/notebooks/03_langgraph_agent.ipynb` around lines 44 - 47, The notebook
installs coordinode-embedded from a specific git ref but later lets plain
"coordinode" resolve from PyPI; update the IN_COLAB && not COORDINODE_ADDR
install block so that the plain "coordinode" package is pinned to the identical
git commit ref used for _EMBEDDED_PIP_SPEC (i.e., use the same commit hash in
the coordinode install spec), ensuring both _EMBEDDED_PIP_SPEC and the
coordinode install entry reference the same git URL/ref so the SDK and embedded
package versions match.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@demo/notebooks/03_langgraph_agent.ipynb`:
- Around line 169-183: The notebook currently treats an open gRPC port as
success but then silently falls back to embedded when
CoordinodeClient(COORDINODE_ADDR).health() returns false; change this so that
when _port_open(grpc_port) is true and client.health() is false you do not set
_use_embedded to True or switch to LocalClient(":memory:") silently—instead
surface the failure (throw an exception or print a clear error and stop) and
include COORDINODE_ADDR and the health check result; locate the logic around
_port_open, grpc_port, COORDINODE_ADDR, CoordinodeClient, client.health(),
client.close(), and _use_embedded and replace the silent fallback with explicit
error handling or user-facing message so the user is not pointed at ephemeral
in-memory storage unknowingly.

---

Duplicate comments:
In `@demo/notebooks/03_langgraph_agent.ipynb`:
- Around line 44-47: The notebook installs coordinode-embedded from a specific
git ref but later lets plain "coordinode" resolve from PyPI; update the IN_COLAB
&& not COORDINODE_ADDR install block so that the plain "coordinode" package is
pinned to the identical git commit ref used for _EMBEDDED_PIP_SPEC (i.e., use
the same commit hash in the coordinode install spec), ensuring both
_EMBEDDED_PIP_SPEC and the coordinode install entry reference the same git
URL/ref so the SDK and embedded package versions match.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7cb82439-104c-4623-aa36-4a2a7c5c82b6

📥 Commits

Reviewing files that changed from the base of the PR and between 8d69841 and 4175e96.

📒 Files selected for processing (7)
  • .gitignore
  • coordinode/coordinode/client.py
  • demo/notebooks/00_seed_data.ipynb
  • demo/notebooks/01_llama_index_property_graph.ipynb
  • demo/notebooks/02_langchain_graph_chain.ipynb
  • demo/notebooks/03_langgraph_agent.ipynb
  • tests/unit/test_consistency_helpers.py

…healthy-port fallback

- Add _SDK_PIP_SPEC alongside _EMBEDDED_PIP_SPEC; use the pinned spec in
  the Colab branch so the SDK and embedded package resolve to the same
  git commit. Outside Colab the unpinned "coordinode" still comes from
  PyPI (editable installs / released wheels).
- Port-probe fallback path now prints an explicit WARNING before
  switching to LocalClient(":memory:") — previously the silent close()
  could surprise a user who expected the local server to be used.
@polaz
Copy link
Copy Markdown
Member Author

polaz commented Apr 19, 2026

@coderabbitai Re: review body items on 03_langgraph_agent.ipynb — both fixed in 4f6a797:

  1. Duplicate (44-47): added _SDK_PIP_SPEC alongside _EMBEDDED_PIP_SPEC and switched the Colab branch to pin both from the same git ref.
  2. Outside-diff (169-183): port-probe fallback now prints an explicit WARNING: port X open but health check failed — falling back to embedded before switching to LocalClient(':memory:'), instead of a silent client.close().

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 19, 2026

Tip

For best results, initiate chat on the files or code changes.

@polaz: Both fixes look good, thanks for the update!

  1. _SDK_PIP_SPEC co-pinning (lines 44-47): Aligns with the co-pinning pattern already established across the other notebooks — coordinode and coordinode-embedded now always resolve from the same git ref in the Colab path.
  2. Port-probe fallback warning (lines 169-183): The explicit WARNING message makes the silent fallback-to-embedded behaviour visible, which is much more debuggable for users who hit that edge case.

Note: As a reminder, these were review-body (outside-diff) comments, so I'm unable to auto-resolve them via the GitHub API — you may want to dismiss them manually from the UI.


🧠 Learnings used
Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-19T12:10:36.422Z
Learning: In the `structured-world/coordinode-python` repository's demo notebooks (e.g., `demo/notebooks/`), repeated string literals (such as node/entity names like `"Eva Müller"`) across cells are intentional. Notebook cells are designed to be run independently and out of order, so extracting shared values into a module-level constant defined in one cell would cause a `NameError` when users re-run a later cell without having executed the definition cell first. Do not flag such duplication as a code smell in notebook context.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 47
File: demo/notebooks/01_llama_index_property_graph.ipynb:89-89
Timestamp: 2026-04-19T12:36:25.632Z
Learning: In `structured-world/coordinode-python` demo notebooks (e.g., `demo/notebooks/0[0-3]_*.ipynb`), within the `IN_COLAB and not COORDINODE_ADDR` guard block, `coordinode` (the PyPI package) must be pinned to the same git commit ref as `coordinode-embedded` (e.g., `git+https://github.com/structured-world/coordinode-python.git@<commit>#subdirectory=coordinode` alongside `#subdirectory=coordinode-embedded`). Leaving `coordinode` unpinned risks resolving to PyPI latest (e.g., 0.5.0) which may be incompatible with the pinned embedded build. Both packages must be co-pinned in all 4 demo notebooks.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 37
File: demo/docker-compose.yml:42-43
Timestamp: 2026-04-15T23:53:03.424Z
Learning: In `demo/docker-compose.yml` (structured-world/coordinode-python), `install-sdk.sh` does NOT need to install `coordinode-embedded`. The Jupyter container always has `COORDINODE_ADDR=coordinode:7080` set via docker-compose environment, so the notebooks' embedded fallback (`from coordinode_embedded import LocalClient`) is never reached in Docker Compose. In Colab, notebooks install `coordinode-embedded` themselves via the `IN_COLAB and not COORDINODE_ADDR` guard in cell 0. Do not flag the absence of `coordinode-embedded` from `install-sdk.sh` as a bug.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 36
File: demo/notebooks/03_langgraph_agent.ipynb:226-238
Timestamp: 2026-04-15T13:26:53.932Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), the `save_fact` tool constructs a Cypher relationship type by inline string interpolation (`relation.upper().replace(' ', '_')`). This is intentional for readability in a pedagogical/demo context. The maintainer (polaz) explicitly declined to add a sanitizing regex or validation guard, noting that it adds indirection without benefit in a tutorial notebook. Do not flag this as a Cypher injection issue in future reviews of this file.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T05:54:14.419Z
Learning: In `demo/notebooks/02_langchain_graph_chain.ipynb` (and other demo notebooks in `structured-world/coordinode-python`), LangChain dependency versions are intentionally NOT pinned. These notebooks are designed to work with current LangChain releases, and pinning would require ongoing maintenance on every release and could break Colab installs as packages age out of PyPI availability windows. This is a deliberate decision by maintainer polaz.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 37
File: demo/notebooks/03_langgraph_agent.ipynb:250-256
Timestamp: 2026-04-16T00:36:37.962Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), the `query_facts` tool's session-scope guard (`_SESSION_WHERE_SCOPE_RE` / `_SESSION_NODE_SCOPE_RE`) intentionally checks that AT LEAST ONE node pattern carries session scope — it does NOT perform a full per-alias check. The Cartesian-product bypass (e.g., `MATCH (n), (m {session: $sess}) RETURN n`) is a known, documented limitation (NOTE comment in the code). A complete per-alias AST check is explicitly out of scope for this demo safety guard. Maintainer polaz confirmed the design: demo notebooks rely on server-side row-level security for production isolation, not client-side regex. Do not flag this as a session-isolation gap in future reviews.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T13:27:14.016Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), CoordiNode's Cypher engine does NOT support path variable binding (`MATCH p=(...)`), `nodes(p)`, or `relationships(p)`. Variable-length path traversal queries (e.g., `MATCH (n)-[*1..k]->(m)`) must use session constraints on both endpoints (`n` and `m`) directly. This is the maximum session isolation achievable without path variable support, and is the intentional design for the `find_related` tool. Do not flag the absence of path variable filtering as a session-isolation gap in future reviews of this file.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-08T10:40:11.507Z
Learning: In the coordinode-python repository, "outside-diff range" review comments posted in the review body (not as inline PR comments) cannot be individually resolved via the GitHub API. These appear in the second review pass when lines fall outside the current diff.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-14T23:21:52.969Z
Learning: In `structured-world/coordinode-python`, the `coordinode-rs` submodule may be intentionally pinned to a post-release changelog commit (e.g., SHA `8dc198f`, the commit immediately following the v0.3.13 release commit) when the upstream coordinode-rs repository has not yet created the corresponding git tag. This is a deliberate interim pinning strategy by maintainer polaz; the submodule will be updated to the official release tag once it is created. Do not flag this as an issue requiring a change.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 18
File: llama-index-coordinode/pyproject.toml:25-25
Timestamp: 2026-04-09T19:03:31.417Z
Learning: In the `coordinode-python` repository, the Python package dependency `coordinode` (PyPI) is distinct from the CoordiNode Rust database server (`structured-world/coordinode` on GitHub). The Python SDK (`coordinode` on PyPI) reached v0.4.x stability (v0.4.0–v0.4.4 released April 9, 2026), while the Rust server's latest release is v0.3.0. Web searches for "coordinode" may return the Rust server GitHub repo instead of the PyPI package — always verify against PyPI directly for Python dependency constraints in this repo.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T10:06:55.983Z
Learning: In `tests/integration/test_sdk.py` (`structured-world/coordinode-python`), FTS (full-text search) indexing in CoordiNode requires an explicit `CREATE TEXT INDEX` DDL call (`client.create_text_index(...)`) regardless of whether the graph is schema-free or schema-strict. `create_label()` is NOT required for schema-free graphs, but `create_text_index()` IS required. Without an explicit text index, `text_search()` and `hybrid_text_vector_search()` return `[]` — confirmed by `test_text_search_empty_for_unindexed_label`. Auto-indexing of schema-free graph text properties is NOT guaranteed (as of at least v0.3.15). The FTS integration tests (`test_text_search_returns_results`, `test_text_search_fuzzy`, `test_hybrid_text_vector_search_returns_results`) all explicitly call `create_text_index()` in their setup.

@polaz
Copy link
Copy Markdown
Member Author

polaz commented Apr 19, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 19, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (3)
demo/notebooks/00_seed_data.ipynb (1)

122-134: ⚠️ Potential issue | 🟠 Major

Avoid reintroducing a floating SDK version here.

Line 129 installs bare coordinode even though the Colab branch above already pinned the SDK to the same git ref as coordinode-embedded. That makes the version lock incidental instead of explicit and can put this seed notebook back on a different SDK than the embedded engine it just built.

♻️ Proposed fix
-        "coordinode",
+        (
+            "git+https://github.com/structured-world/coordinode-python.git@c2ce32064dd7f6495f0998049c0cc2f6f7a5767d#subdirectory=coordinode"
+            if IN_COLAB and not os.environ.get("COORDINODE_ADDR")
+            else "coordinode"
+        ),

Based on learnings, the demo notebooks must keep coordinode and coordinode-embedded pinned to the same git ref inside the Colab embedded branch.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demo/notebooks/00_seed_data.ipynb` around lines 122 - 134, The subprocess.run
call that installs "coordinode" currently installs the bare package which can
drift from the git ref used for "coordinode-embedded"; modify the arguments
passed to subprocess.run (the list containing sys.executable, "-m", "pip",
"install", "-q", "coordinode", "nest_asyncio") to pin "coordinode" to the same
git ref used for "coordinode-embedded" (e.g., replace the plain "coordinode"
entry with the identical git URL or reflike string used earlier), ensuring both
packages use the exact same version/ref.
demo/notebooks/01_llama_index_property_graph.ipynb (1)

114-128: ⚠️ Potential issue | 🟠 Major

Don't reinstall an unpinned coordinode after the Colab pin.

Line 121 adds a floating coordinode requirement after the IN_COLAB and not COORDINODE_ADDR branch already installed the SDK from the c2ce320... git ref. That makes the embedded/SDK lockstep depend on pip resolver behavior again, so this notebook can drift off the same commit that coordinode-embedded was built from.

♻️ Proposed fix
-        "coordinode",
+        (
+            "git+https://github.com/structured-world/coordinode-python.git@c2ce32064dd7f6495f0998049c0cc2f6f7a5767d#subdirectory=coordinode"
+            if IN_COLAB and not os.environ.get("COORDINODE_ADDR")
+            else "coordinode"
+        ),

Based on learnings, the demo notebooks must keep coordinode and coordinode-embedded pinned to the same git ref inside the Colab embedded branch.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demo/notebooks/01_llama_index_property_graph.ipynb` around lines 114 - 128,
The pip install invocation using subprocess.run installs an unpinned
"coordinode" which overrides the Colab branch that already installed the SDK
from a specific git ref (see the IN_COLAB and not COORDINODE_ADDR branch);
remove or replace the floating "coordinode" entry in the install list inside the
subprocess.run call so it no longer installs an unpinned package, and instead
ensure the install list either omits "coordinode" or installs "coordinode"
pinned to the same git ref used for "coordinode-embedded" (keep the rest of the
packages like "llama-index-graph-stores-coordinode", "llama-index-core", and
"nest_asyncio" unchanged).
demo/notebooks/02_langchain_graph_chain.ipynb (1)

114-130: ⚠️ Potential issue | 🟠 Major

Keep the Colab SDK install pinned in the shared pip step.

Line 121 reintroduces unpinned coordinode immediately after the Colab branch pinned it to the same c2ce320... ref as coordinode-embedded. That leaves version alignment up to pip's resolver instead of the notebook, which is exactly the skew this PR is trying to avoid.

♻️ Proposed fix
-        "coordinode",
+        (
+            "git+https://github.com/structured-world/coordinode-python.git@c2ce32064dd7f6495f0998049c0cc2f6f7a5767d#subdirectory=coordinode"
+            if IN_COLAB and not os.environ.get("COORDINODE_ADDR")
+            else "coordinode"
+        ),

Based on learnings, the demo notebooks must keep coordinode and coordinode-embedded pinned to the same git ref inside the Colab embedded branch.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demo/notebooks/02_langchain_graph_chain.ipynb` around lines 114 - 130, The
pip install invocation built in the subprocess.run call reintroduces an unpinned
"coordinode" entry; change that argument in the pip args list inside the
subprocess.run call to the same git-ref pin used earlier (replace "coordinode"
with the matching
git+https://github.com/structured-world/coordinode-python.git@c2ce32064dd7f6495f0998049c0cc2f6f7a5767d#subdirectory=coordinode)
so both coordinode and coordinode-embedded are pinned to the same commit; this
lives in the list literal passed to subprocess.run in the notebook cell.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@demo/notebooks/00_seed_data.ipynb`:
- Around line 122-134: The subprocess.run call that installs "coordinode"
currently installs the bare package which can drift from the git ref used for
"coordinode-embedded"; modify the arguments passed to subprocess.run (the list
containing sys.executable, "-m", "pip", "install", "-q", "coordinode",
"nest_asyncio") to pin "coordinode" to the same git ref used for
"coordinode-embedded" (e.g., replace the plain "coordinode" entry with the
identical git URL or reflike string used earlier), ensuring both packages use
the exact same version/ref.

In `@demo/notebooks/01_llama_index_property_graph.ipynb`:
- Around line 114-128: The pip install invocation using subprocess.run installs
an unpinned "coordinode" which overrides the Colab branch that already installed
the SDK from a specific git ref (see the IN_COLAB and not COORDINODE_ADDR
branch); remove or replace the floating "coordinode" entry in the install list
inside the subprocess.run call so it no longer installs an unpinned package, and
instead ensure the install list either omits "coordinode" or installs
"coordinode" pinned to the same git ref used for "coordinode-embedded" (keep the
rest of the packages like "llama-index-graph-stores-coordinode",
"llama-index-core", and "nest_asyncio" unchanged).

In `@demo/notebooks/02_langchain_graph_chain.ipynb`:
- Around line 114-130: The pip install invocation built in the subprocess.run
call reintroduces an unpinned "coordinode" entry; change that argument in the
pip args list inside the subprocess.run call to the same git-ref pin used
earlier (replace "coordinode" with the matching
git+https://github.com/structured-world/coordinode-python.git@c2ce32064dd7f6495f0998049c0cc2f6f7a5767d#subdirectory=coordinode)
so both coordinode and coordinode-embedded are pinned to the same commit; this
lives in the list literal passed to subprocess.run in the notebook cell.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 73b6423d-1535-4e28-8f06-23dad355c632

📥 Commits

Reviewing files that changed from the base of the PR and between 8d69841 and 4f6a797.

📒 Files selected for processing (7)
  • .gitignore
  • coordinode/coordinode/client.py
  • demo/notebooks/00_seed_data.ipynb
  • demo/notebooks/01_llama_index_property_graph.ipynb
  • demo/notebooks/02_langchain_graph_chain.ipynb
  • demo/notebooks/03_langgraph_agent.ipynb
  • tests/unit/test_consistency_helpers.py

Previous fix installed coordinode from the git pin inside IN_COLAB, but
the unconditional subprocess.run at the end of the cell still installed
bare "coordinode" from PyPI — pip treated this as an upgrade and
overrode the pinned version with whatever PyPI resolved to.

Align 00/01/02 with 03's pattern: single _coordinode_spec variable that
evaluates to the git-pin URL when IN_COLAB else bare "coordinode" for
local dev.
@polaz
Copy link
Copy Markdown
Member Author

polaz commented Apr 19, 2026

@coderabbitai Fixed in c8cea55 — removed the unconditional unpinned coordinode install in 00/01/02. Now all 4 notebooks use a single _coordinode_spec variable that resolves to the pinned git URL when IN_COLAB, else bare coordinode.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 19, 2026

Tip

For best results, initiate chat on the files or code changes.

@polaz: Confirmed — the _coordinode_spec pattern is a cleaner solution than the dual separate install lines. A single conditional variable that resolves to the pinned git URL in Colab and falls back to bare coordinode elsewhere eliminates the risk of the two install paths drifting out of sync in any of the four notebooks.


✏️ Learnings added
Learnt from: polaz
URL: https://github.com/structured-world/coordinode-python/pull/47

Timestamp: 2026-04-19T13:12:25.498Z
Learning: In `structured-world/coordinode-python` demo notebooks (`demo/notebooks/0[0-3]_*.ipynb`), the `coordinode` SDK is installed via a `_coordinode_spec` variable (set in cell 0) that resolves to the pinned git URL `git+https://github.com/structured-world/coordinode-python.git@<commit>#subdirectory=coordinode` when `IN_COLAB`, and bare `coordinode` otherwise. This single variable is then passed to the pip install call, ensuring the embedded and SDK packages are always co-pinned from the same git ref in Colab without maintaining two separate install lines. Do not flag the absence of a separate unconditional `coordinode` install as a missing dependency — the `_coordinode_spec` variable handles this correctly in all 4 notebooks.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: polaz
Repo: structured-world/coordinode-python PR: 47
File: demo/notebooks/01_llama_index_property_graph.ipynb:89-89
Timestamp: 2026-04-19T12:36:25.632Z
Learning: In `structured-world/coordinode-python` demo notebooks (e.g., `demo/notebooks/0[0-3]_*.ipynb`), within the `IN_COLAB and not COORDINODE_ADDR` guard block, `coordinode` (the PyPI package) must be pinned to the same git commit ref as `coordinode-embedded` (e.g., `git+https://github.com/structured-world/coordinode-python.git@<commit>#subdirectory=coordinode` alongside `#subdirectory=coordinode-embedded`). Leaving `coordinode` unpinned risks resolving to PyPI latest (e.g., 0.5.0) which may be incompatible with the pinned embedded build. Both packages must be co-pinned in all 4 demo notebooks.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 37
File: demo/docker-compose.yml:42-43
Timestamp: 2026-04-15T23:53:03.424Z
Learning: In `demo/docker-compose.yml` (structured-world/coordinode-python), `install-sdk.sh` does NOT need to install `coordinode-embedded`. The Jupyter container always has `COORDINODE_ADDR=coordinode:7080` set via docker-compose environment, so the notebooks' embedded fallback (`from coordinode_embedded import LocalClient`) is never reached in Docker Compose. In Colab, notebooks install `coordinode-embedded` themselves via the `IN_COLAB and not COORDINODE_ADDR` guard in cell 0. Do not flag the absence of `coordinode-embedded` from `install-sdk.sh` as a bug.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T05:54:14.419Z
Learning: In `demo/notebooks/02_langchain_graph_chain.ipynb` (and other demo notebooks in `structured-world/coordinode-python`), LangChain dependency versions are intentionally NOT pinned. These notebooks are designed to work with current LangChain releases, and pinning would require ongoing maintenance on every release and could break Colab installs as packages age out of PyPI availability windows. This is a deliberate decision by maintainer polaz.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-19T12:10:36.422Z
Learning: In the `structured-world/coordinode-python` repository's demo notebooks (e.g., `demo/notebooks/`), repeated string literals (such as node/entity names like `"Eva Müller"`) across cells are intentional. Notebook cells are designed to be run independently and out of order, so extracting shared values into a module-level constant defined in one cell would cause a `NameError` when users re-run a later cell without having executed the definition cell first. Do not flag such duplication as a code smell in notebook context.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-14T23:21:52.969Z
Learning: In `structured-world/coordinode-python`, the `coordinode-rs` submodule may be intentionally pinned to a post-release changelog commit (e.g., SHA `8dc198f`, the commit immediately following the v0.3.13 release commit) when the upstream coordinode-rs repository has not yet created the corresponding git tag. This is a deliberate interim pinning strategy by maintainer polaz; the submodule will be updated to the official release tag once it is created. Do not flag this as an issue requiring a change.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 36
File: demo/notebooks/03_langgraph_agent.ipynb:226-238
Timestamp: 2026-04-15T13:26:53.932Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), the `save_fact` tool constructs a Cypher relationship type by inline string interpolation (`relation.upper().replace(' ', '_')`). This is intentional for readability in a pedagogical/demo context. The maintainer (polaz) explicitly declined to add a sanitizing regex or validation guard, noting that it adds indirection without benefit in a tutorial notebook. Do not flag this as a Cypher injection issue in future reviews of this file.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 37
File: demo/notebooks/03_langgraph_agent.ipynb:250-256
Timestamp: 2026-04-16T00:36:37.962Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), the `query_facts` tool's session-scope guard (`_SESSION_WHERE_SCOPE_RE` / `_SESSION_NODE_SCOPE_RE`) intentionally checks that AT LEAST ONE node pattern carries session scope — it does NOT perform a full per-alias check. The Cartesian-product bypass (e.g., `MATCH (n), (m {session: $sess}) RETURN n`) is a known, documented limitation (NOTE comment in the code). A complete per-alias AST check is explicitly out of scope for this demo safety guard. Maintainer polaz confirmed the design: demo notebooks rely on server-side row-level security for production isolation, not client-side regex. Do not flag this as a session-isolation gap in future reviews.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T13:27:14.016Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), CoordiNode's Cypher engine does NOT support path variable binding (`MATCH p=(...)`), `nodes(p)`, or `relationships(p)`. Variable-length path traversal queries (e.g., `MATCH (n)-[*1..k]->(m)`) must use session constraints on both endpoints (`n` and `m`) directly. This is the maximum session isolation achievable without path variable support, and is the intentional design for the `find_related` tool. Do not flag the absence of path variable filtering as a session-isolation gap in future reviews of this file.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 18
File: llama-index-coordinode/pyproject.toml:25-25
Timestamp: 2026-04-09T19:03:31.417Z
Learning: In the `coordinode-python` repository, the Python package dependency `coordinode` (PyPI) is distinct from the CoordiNode Rust database server (`structured-world/coordinode` on GitHub). The Python SDK (`coordinode` on PyPI) reached v0.4.x stability (v0.4.0–v0.4.4 released April 9, 2026), while the Rust server's latest release is v0.3.0. Web searches for "coordinode" may return the Rust server GitHub repo instead of the PyPI package — always verify against PyPI directly for Python dependency constraints in this repo.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 25
File: tests/integration/adapters/test_llama_index.py:159-180
Timestamp: 2026-04-12T09:55:48.630Z
Learning: In `tests/integration/adapters/test_llama_index.py`, the `vector_search` RPC in CoordiNode does not return node properties. Therefore, integration tests for `vector_query()` must assert against the internal CoordiNode node ID (captured from a `CREATE ... RETURN n` Cypher response) using `ChunkNode.id_`, rather than application-level property fields like `id`. This is the correct pattern for seeded-node identity assertions in vector query tests.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 36
File: demo/notebooks/00_seed_data.ipynb:54-65
Timestamp: 2026-04-13T20:13:32.387Z
Learning: In the `coordinode-python` repository, `coordinode-embedded` is an alternative in-process transport (Rust engine via maturin), not a wrapper around the `coordinode` PyPI package. It declares no dependency on `coordinode`. Demo notebooks must explicitly install both packages when supporting both embedded and gRPC server-backed (`CoordinodeClient`) modes.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T10:06:55.983Z
Learning: In `tests/integration/test_sdk.py` (`structured-world/coordinode-python`), FTS (full-text search) indexing in CoordiNode requires an explicit `CREATE TEXT INDEX` DDL call (`client.create_text_index(...)`) regardless of whether the graph is schema-free or schema-strict. `create_label()` is NOT required for schema-free graphs, but `create_text_index()` IS required. Without an explicit text index, `text_search()` and `hybrid_text_vector_search()` return `[]` — confirmed by `test_text_search_empty_for_unindexed_label`. Auto-indexing of schema-free graph text properties is NOT guaranteed (as of at least v0.3.15). The FTS integration tests (`test_text_search_returns_results`, `test_text_search_fuzzy`, `test_hybrid_text_vector_search_returns_results`) all explicitly call `create_text_index()` in their setup.

@polaz
Copy link
Copy Markdown
Member Author

polaz commented Apr 19, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 19, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

- _coordinode_spec now uses `IN_COLAB and not os.environ.get("COORDINODE_ADDR")`
  matching the embedded install gate. Previously, a Colab user with
  COORDINODE_ADDR pointed at their own server would still install the SDK
  from the git pin unnecessarily.
- 03 port-probe: when port 7080 is open but health check fails, raise
  RuntimeError instead of silently falling through to LocalClient(":memory:").
  A listening port is a strong signal the user expected a real server —
  masking the failure by writing to ephemeral in-memory storage is surprising
  and hides real problems.
@polaz
Copy link
Copy Markdown
Member Author

polaz commented Apr 19, 2026

@coderabbitai Further fixed in 5957b8b:

  1. Pin conditional now matches the embedded install gate — _coordinode_spec uses IN_COLAB and not os.environ.get("COORDINODE_ADDR") so a Colab user who set a remote server doesn't waste time pulling the SDK from git.
  2. 03 unhealthy-port: replaced print(WARNING) + silent fallback with a hard raise RuntimeError — a listening port 7080 is a strong signal the user expected a real server, and masking the failure with ephemeral in-memory storage is surprising.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 19, 2026

Tip

For best results, initiate chat on the files or code changes.

@polaz: Both fixes are well-reasoned, thanks for the follow-through!

  1. _coordinode_spec guard alignment: Mirroring the IN_COLAB and not os.environ.get("COORDINODE_ADDR") condition from the embedded install gate is the right call — a Colab user who has COORDINODE_ADDR set is connecting to a real server and shouldn't have pip re-resolve the SDK from git on every runtime startup.
  2. Hard raise RuntimeError on unhealthy port 7080: Agreed this is the correct UX. A port that is listening but fails the health check is almost certainly a version mismatch or misconfiguration, not an absent server — silently falling back to ephemeral in-memory storage would cause confusing data-loss bugs that are very hard to diagnose. The hard failure surfaces the problem immediately.

✏️ Learnings added
Learnt from: polaz
URL: https://github.com/structured-world/coordinode-python/pull/47

Timestamp: 2026-04-19T13:34:12.439Z
Learning: In `structured-world/coordinode-python` demo notebooks (`demo/notebooks/0[0-3]_*.ipynb`), the `coordinode` SDK is installed via a `_coordinode_spec` variable (set in cell 0). The condition guarding the git-pin path is `IN_COLAB and not os.environ.get("COORDINODE_ADDR")` — matching the same gate used for the `coordinode-embedded` install — so that Colab users who have set `COORDINODE_ADDR` (pointing at a remote server) are not forced to pull the SDK from git. When the condition is true, `_coordinode_spec` resolves to the pinned git URL `git+https://github.com/structured-world/coordinode-python.git@<commit>#subdirectory=coordinode`; otherwise it falls back to bare `coordinode`. Do not flag the absence of a separate unconditional `coordinode` install as a missing dependency — the `_coordinode_spec` variable handles this correctly in all 4 notebooks.

Learnt from: polaz
URL: https://github.com/structured-world/coordinode-python/pull/47

Timestamp: 2026-04-19T13:34:12.439Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), the port-7080 health-check fallback raises a hard `RuntimeError` (rather than printing a warning and silently falling back to `LocalClient(':memory:')`) when port 7080 is listening but the CoordiNode health check fails. This is intentional: a listening-but-unhealthy port is a strong signal of a server misconfiguration or version mismatch, and silent in-memory fallback would mask the failure with data-loss behaviour. Do not suggest softening this to a warning-plus-fallback in future reviews.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


⛔ Learnings removed
Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-19T13:12:25.498Z
Learning: In `structured-world/coordinode-python` demo notebooks (`demo/notebooks/0[0-3]_*.ipynb`), the `coordinode` SDK is installed via a `_coordinode_spec` variable (set in cell 0) that resolves to the pinned git URL `git+https://github.com/structured-world/coordinode-python.git@<commit>#subdirectory=coordinode` when `IN_COLAB`, and bare `coordinode` otherwise. This single variable is then passed to the pip install call, ensuring the embedded and SDK packages are always co-pinned from the same git ref in Colab without maintaining two separate install lines. Do not flag the absence of a separate unconditional `coordinode` install as a missing dependency — the `_coordinode_spec` variable handles this correctly in all 4 notebooks.

🧠 Learnings used
Learnt from: polaz
Repo: structured-world/coordinode-python PR: 47
File: demo/notebooks/01_llama_index_property_graph.ipynb:89-89
Timestamp: 2026-04-19T12:36:25.632Z
Learning: In `structured-world/coordinode-python` demo notebooks (e.g., `demo/notebooks/0[0-3]_*.ipynb`), within the `IN_COLAB and not COORDINODE_ADDR` guard block, `coordinode` (the PyPI package) must be pinned to the same git commit ref as `coordinode-embedded` (e.g., `git+https://github.com/structured-world/coordinode-python.git@<commit>#subdirectory=coordinode` alongside `#subdirectory=coordinode-embedded`). Leaving `coordinode` unpinned risks resolving to PyPI latest (e.g., 0.5.0) which may be incompatible with the pinned embedded build. Both packages must be co-pinned in all 4 demo notebooks.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-19T13:12:25.498Z
Learning: In `structured-world/coordinode-python` demo notebooks (`demo/notebooks/0[0-3]_*.ipynb`), the `coordinode` SDK is installed via a `_coordinode_spec` variable (set in cell 0) that resolves to the pinned git URL `git+https://github.com/structured-world/coordinode-python.git@<commit>#subdirectory=coordinode` when `IN_COLAB`, and bare `coordinode` otherwise. This single variable is then passed to the pip install call, ensuring the embedded and SDK packages are always co-pinned from the same git ref in Colab without maintaining two separate install lines. Do not flag the absence of a separate unconditional `coordinode` install as a missing dependency — the `_coordinode_spec` variable handles this correctly in all 4 notebooks.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 37
File: demo/docker-compose.yml:42-43
Timestamp: 2026-04-15T23:53:03.424Z
Learning: In `demo/docker-compose.yml` (structured-world/coordinode-python), `install-sdk.sh` does NOT need to install `coordinode-embedded`. The Jupyter container always has `COORDINODE_ADDR=coordinode:7080` set via docker-compose environment, so the notebooks' embedded fallback (`from coordinode_embedded import LocalClient`) is never reached in Docker Compose. In Colab, notebooks install `coordinode-embedded` themselves via the `IN_COLAB and not COORDINODE_ADDR` guard in cell 0. Do not flag the absence of `coordinode-embedded` from `install-sdk.sh` as a bug.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 37
File: demo/notebooks/03_langgraph_agent.ipynb:250-256
Timestamp: 2026-04-16T00:36:37.962Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), the `query_facts` tool's session-scope guard (`_SESSION_WHERE_SCOPE_RE` / `_SESSION_NODE_SCOPE_RE`) intentionally checks that AT LEAST ONE node pattern carries session scope — it does NOT perform a full per-alias check. The Cartesian-product bypass (e.g., `MATCH (n), (m {session: $sess}) RETURN n`) is a known, documented limitation (NOTE comment in the code). A complete per-alias AST check is explicitly out of scope for this demo safety guard. Maintainer polaz confirmed the design: demo notebooks rely on server-side row-level security for production isolation, not client-side regex. Do not flag this as a session-isolation gap in future reviews.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T05:54:14.419Z
Learning: In `demo/notebooks/02_langchain_graph_chain.ipynb` (and other demo notebooks in `structured-world/coordinode-python`), LangChain dependency versions are intentionally NOT pinned. These notebooks are designed to work with current LangChain releases, and pinning would require ongoing maintenance on every release and could break Colab installs as packages age out of PyPI availability windows. This is a deliberate decision by maintainer polaz.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T13:27:14.016Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), CoordiNode's Cypher engine does NOT support path variable binding (`MATCH p=(...)`), `nodes(p)`, or `relationships(p)`. Variable-length path traversal queries (e.g., `MATCH (n)-[*1..k]->(m)`) must use session constraints on both endpoints (`n` and `m`) directly. This is the maximum session isolation achievable without path variable support, and is the intentional design for the `find_related` tool. Do not flag the absence of path variable filtering as a session-isolation gap in future reviews of this file.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 25
File: tests/integration/adapters/test_llama_index.py:159-180
Timestamp: 2026-04-12T09:55:48.630Z
Learning: In `tests/integration/adapters/test_llama_index.py`, the `vector_search` RPC in CoordiNode does not return node properties. Therefore, integration tests for `vector_query()` must assert against the internal CoordiNode node ID (captured from a `CREATE ... RETURN n` Cypher response) using `ChunkNode.id_`, rather than application-level property fields like `id`. This is the correct pattern for seeded-node identity assertions in vector query tests.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-19T12:10:36.422Z
Learning: In the `structured-world/coordinode-python` repository's demo notebooks (e.g., `demo/notebooks/`), repeated string literals (such as node/entity names like `"Eva Müller"`) across cells are intentional. Notebook cells are designed to be run independently and out of order, so extracting shared values into a module-level constant defined in one cell would cause a `NameError` when users re-run a later cell without having executed the definition cell first. Do not flag such duplication as a code smell in notebook context.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 36
File: demo/notebooks/03_langgraph_agent.ipynb:226-238
Timestamp: 2026-04-15T13:26:53.932Z
Learning: In `demo/notebooks/03_langgraph_agent.ipynb` (structured-world/coordinode-python), the `save_fact` tool constructs a Cypher relationship type by inline string interpolation (`relation.upper().replace(' ', '_')`). This is intentional for readability in a pedagogical/demo context. The maintainer (polaz) explicitly declined to add a sanitizing regex or validation guard, noting that it adds indirection without benefit in a tutorial notebook. Do not flag this as a Cypher injection issue in future reviews of this file.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-14T23:21:52.969Z
Learning: In `structured-world/coordinode-python`, the `coordinode-rs` submodule may be intentionally pinned to a post-release changelog commit (e.g., SHA `8dc198f`, the commit immediately following the v0.3.13 release commit) when the upstream coordinode-rs repository has not yet created the corresponding git tag. This is a deliberate interim pinning strategy by maintainer polaz; the submodule will be updated to the official release tag once it is created. Do not flag this as an issue requiring a change.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 18
File: llama-index-coordinode/pyproject.toml:25-25
Timestamp: 2026-04-09T19:03:31.417Z
Learning: In the `coordinode-python` repository, the Python package dependency `coordinode` (PyPI) is distinct from the CoordiNode Rust database server (`structured-world/coordinode` on GitHub). The Python SDK (`coordinode` on PyPI) reached v0.4.x stability (v0.4.0–v0.4.4 released April 9, 2026), while the Rust server's latest release is v0.3.0. Web searches for "coordinode" may return the Rust server GitHub repo instead of the PyPI package — always verify against PyPI directly for Python dependency constraints in this repo.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 0
File: :0-0
Timestamp: 2026-04-15T10:06:55.983Z
Learning: In `tests/integration/test_sdk.py` (`structured-world/coordinode-python`), FTS (full-text search) indexing in CoordiNode requires an explicit `CREATE TEXT INDEX` DDL call (`client.create_text_index(...)`) regardless of whether the graph is schema-free or schema-strict. `create_label()` is NOT required for schema-free graphs, but `create_text_index()` IS required. Without an explicit text index, `text_search()` and `hybrid_text_vector_search()` return `[]` — confirmed by `test_text_search_empty_for_unindexed_label`. Auto-indexing of schema-free graph text properties is NOT guaranteed (as of at least v0.3.15). The FTS integration tests (`test_text_search_returns_results`, `test_text_search_fuzzy`, `test_hybrid_text_vector_search_returns_results`) all explicitly call `create_text_index()` in their setup.

Learnt from: polaz
Repo: structured-world/coordinode-python PR: 36
File: demo/notebooks/00_seed_data.ipynb:54-65
Timestamp: 2026-04-13T20:13:32.387Z
Learning: In the `coordinode-python` repository, `coordinode-embedded` is an alternative in-process transport (Rust engine via maturin), not a wrapper around the `coordinode` PyPI package. It declares no dependency on `coordinode`. Demo notebooks must explicitly install both packages when supporting both embedded and gRPC server-backed (`CoordinodeClient`) modes.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns the Python SDK and demo materials with coordinode-server v0.4.1, including upstream proto changes (notably removal of the HybridTextVectorSearch RPC) and new Cypher consistency controls, plus Colab-oriented notebook reproducibility updates.

Changes:

  • Remove hybrid_text_vector_search() + HybridResult from the SDK and tests to match upstream proto/RPC removal.
  • Add cypher() consistency kwargs (read_concern, write_concern, read_preference, after_index) with validation helpers + unit/integration coverage.
  • Update docker-compose image tags to 0.4.1 and refactor demo notebooks for explicit gRPC vs embedded connection behavior + Colab install flow.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/unit/test_consistency_helpers.py Adds unit tests for new consistency helper validation/mapping.
tests/integration/test_sdk.py Removes hybrid search integration test; adds end-to-end coverage for consistency kwargs and invalid-value rejection.
docker-compose.yml Bumps server image tag to ghcr.io/structured-world/coordinode:0.4.1.
demo/notebooks/00_seed_data.ipynb Updates Colab install/connect flow; switches embedded DB to file-backed path for persistence across reruns/notebooks.
demo/notebooks/01_llama_index_property_graph.ipynb Updates Colab install/connect flow and embedded adapter formatting; uses file-backed embedded DB.
demo/notebooks/02_langchain_graph_chain.ipynb Updates Colab install/connect flow and embedded adapter formatting; uses file-backed embedded DB.
demo/notebooks/03_langgraph_agent.ipynb Updates Colab install/connect flow; removes localhost probing; uses file-backed embedded DB.
demo/docker-compose.yml Bumps demo compose server image tag to 0.4.1.
demo/README.md Updates demo documentation to reference v0.4.1.
coordinode/coordinode/client.py Removes hybrid search RPC client method; adds consistency kwargs + mapping/validation helpers.
coordinode/coordinode/__init__.py Removes HybridResult export.
coordinode/README.md Documents Cypher-based hybrid scoring functions + new consistency kwargs; updates examples.
coordinode-embedded/.gitignore Adds ignore for *.so artifacts from local builds.
.gitignore Ignores .claude/ directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread demo/notebooks/01_llama_index_property_graph.ipynb Outdated
Comment thread demo/notebooks/02_langchain_graph_chain.ipynb
Comment thread coordinode-embedded/.gitignore
Comment thread tests/integration/test_sdk.py Outdated
Comment thread demo/notebooks/03_langgraph_agent.ipynb Outdated
Comment thread demo/notebooks/00_seed_data.ipynb Outdated
…ores, drop created flag

- Demo notebooks: pin _coordinode_spec whenever IN_COLAB, regardless of
  COORDINODE_ADDR. PyPI coordinode can lag the server/proto version used
  in this demo, so Colab sessions connecting to a remote server were at
  risk of installing an incompatible SDK.
- coordinode-embedded/.gitignore: add *.pyd (Windows) and *.dylib (macOS
  non-extension builds) alongside *.so so local builds on any platform
  do not leak into commits.
- tests/integration/test_sdk.py::test_cypher_accepts_consistency_kwargs:
  drop the `created` flag — the DELETE is idempotent (no-op when nothing
  matches), so unconditional cleanup is simpler and safer.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@demo/notebooks/00_seed_data.ipynb`:
- Around line 114-126: The current logic sets _coordinode_spec to the Colab git
install whenever IN_COLAB is true, ignoring COORDINODE_ADDR; update the
conditional so the git install is used only when IN_COLAB and not
COORDINODE_ADDR (i.e., guard the git spec with IN_COLAB and not
COORDINODE_ADDR), then ensure the subsequent subprocess.run call still installs
_coordinode_spec; reference the symbols _coordinode_spec, IN_COLAB,
COORDINODE_ADDR and the pip install invocation to locate where to change the
condition.
- Around line 457-458: The final success print statements (the two print calls
that currently output "✓ Demo data seeded." and the instruction about reusing
COORDINODE_ADDR) are misleading for embedded file-backed mode; update the second
message to mention both ways sibling notebooks can share data: by pointing them
to the same file-backed embedded DB path (the shared file used by the demo seed)
or by connecting via an explicit COORDINODE_ADDR. Modify the printed text
emitted by those print(...) calls to clearly list both options and any variable
name users should set for the embedded path or server address.

In `@demo/notebooks/01_llama_index_property_graph.ipynb`:
- Around line 104-116: The _coordinode_spec selection currently uses only
IN_COLAB and forces the git install; change the condition to check both IN_COLAB
and absence of COORDINODE_ADDR (i.e., IN_COLAB and not COORDINODE_ADDR) so that
when COORDINODE_ADDR is set the normal "coordinode" package path is used; update
the _coordinode_spec assignment referenced where subprocess.run installs
_coordinode_spec accordingly.

In `@demo/notebooks/02_langchain_graph_chain.ipynb`:
- Around line 104-118: The _coordinode_spec assignment currently uses only
IN_COLAB to choose the git install, causing a git install even when
COORDINODE_ADDR is set; change the guard so the git spec is used only when
IN_COLAB is true AND COORDINODE_ADDR is falsy (i.e., use condition IN_COLAB and
not COORDINODE_ADDR) before calling subprocess.run that installs
_coordinode_spec (and the langchain-coordinode package), ensuring remote-server
users with COORDINODE_ADDR set are not forced onto the git install path.

In `@demo/notebooks/03_langgraph_agent.ipynb`:
- Around line 105-113: Change the condition that chooses the pip spec so the
git-pinned SDK install only happens when running in Colab and no remote
coordinode address is set: update the assignment for _coordinode_spec to use
_SDK_PIP_SPEC only when IN_COLAB and not COORDINODE_ADDR, otherwise use the
default "coordinode", and keep the subsequent subprocess.run([... ,
_coordinode_spec, ...]) unchanged so remote-server Colab sessions won’t force
the git install.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c5a2c550-7108-4df9-aea1-c7a80dbd4d7f

📥 Commits

Reviewing files that changed from the base of the PR and between 8f88a67 and 10ab38d.

📒 Files selected for processing (6)
  • coordinode-embedded/.gitignore
  • demo/notebooks/00_seed_data.ipynb
  • demo/notebooks/01_llama_index_property_graph.ipynb
  • demo/notebooks/02_langchain_graph_chain.ipynb
  • demo/notebooks/03_langgraph_agent.ipynb
  • tests/integration/test_sdk.py

Comment thread demo/notebooks/00_seed_data.ipynb
Comment thread demo/notebooks/00_seed_data.ipynb Outdated
Comment thread demo/notebooks/01_llama_index_property_graph.ipynb
Comment thread demo/notebooks/02_langchain_graph_chain.ipynb Outdated
Comment thread demo/notebooks/03_langgraph_agent.ipynb
polaz added 2 commits April 20, 2026 12:58
Previously the final print in 00_seed_data.ipynb only told users to reuse
COORDINODE_ADDR, which is misleading for the default embedded workflow.
Now lists both paths: open sibling notebooks against the same
COORDINODE_EMBEDDED_PATH file, or point them at the same running server
via COORDINODE_ADDR.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@demo/notebooks/00_seed_data.ipynb`:
- Around line 159-191: The seed routine currently generates a fresh DEMO_TAG and
only deletes rows for that tag, which causes duplicate demo entities when using
the persistent LocalClient (COORDINODE_EMBEDDED_PATH); change the logic around
DEMO_TAG so that when client is an embedded LocalClient you use a stable default
tag (e.g., "demo") or, before inserting seed data, run a cleanup that deletes
all rows where demo=true (or the demo marker column) regardless of tag; update
the DEMO_TAG assignment and the teardown/cleanup block that currently deletes by
tag to either set the constant stable tag for embedded mode or to perform a
global demo-row deletion to ensure reseeding is idempotent.
- Around line 161-167: The default COORDINODE_EMBEDDED_PATH fallback should use
the OS temp dir instead of hard-coding "/tmp"; update the
COORDINODE_EMBEDDED_PATH assignment to use tempfile.gettempdir() when "/content"
is not present, and build the path with os.path.join to produce a portable path
(keep the existing "/content/coordinode-demo.db" choice for Colab when
os.path.isdir("/content") is true). Locate the COORDINODE_EMBEDDED_PATH variable
in the notebook and replace the hard-coded "/tmp/coordinode-demo.db" fallback
accordingly (also apply the same change to the sibling notebooks where the same
block is copied).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2027579e-8ec2-487f-a6a0-2c365a945140

📥 Commits

Reviewing files that changed from the base of the PR and between 10ab38d and 15e6a20.

📒 Files selected for processing (4)
  • demo/notebooks/00_seed_data.ipynb
  • demo/notebooks/01_llama_index_property_graph.ipynb
  • demo/notebooks/02_langchain_graph_chain.ipynb
  • demo/notebooks/03_langgraph_agent.ipynb

Comment thread demo/notebooks/00_seed_data.ipynb Outdated
Comment thread demo/notebooks/00_seed_data.ipynb
polaz added 2 commits April 20, 2026 13:17
- 00_seed_data.ipynb DEMO_TAG: use a stable "seed_data" tag in embedded
  mode so reseeds cleanly replace prior data via the existing
  DETACH DELETE cleanup. Server mode keeps the UUID-suffixed tag so
  parallel runs sharing a DB remain isolated.
- All 4 notebooks: replace hard-coded "/tmp/coordinode-demo.db" fallback
  with `os.path.join(tempfile.gettempdir(), "coordinode-demo.db")` so the
  default path works on native Windows where /tmp does not exist.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns the Python SDK and demos with coordinode-server v0.4.1, removing the upstream-dropped hybrid RPC and adding new Cypher consistency controls; also updates demo notebooks/compose files for Colab-ready, reproducible runs.

Changes:

  • Remove hybrid_text_vector_search() / HybridResult and replace guidance with server-side Cypher hybrid scoring.
  • Add cypher() consistency kwargs (read_concern, write_concern, read_preference, after_index) plus unit/integration coverage.
  • Update Docker image tags and demo notebooks to use v0.4.1 + file-backed embedded DB + improved Colab install flow.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
coordinode/coordinode/client.py Removes HybridResult + hybrid RPC; adds cypher consistency kwargs and mapping/validation helpers.
coordinode/coordinode/__init__.py Drops HybridResult export to match removed API.
tests/unit/test_consistency_helpers.py Adds unit tests for consistency helper validation and enum mapping.
tests/integration/test_sdk.py Replaces hybrid RPC integration test with cypher consistency kwargs tests.
coordinode/README.md Documents Cypher-based hybrid search + ATTACH/DETACH DOCUMENT + new consistency params.
docker-compose.yml Bumps server image tag to 0.4.1.
demo/docker-compose.yml Bumps demo server image tag to 0.4.1.
demo/README.md Updates demo documentation to reference v0.4.1.
demo/notebooks/00_seed_data.ipynb Switches embedded mode to file-backed DB + Colab install updates + clearer connect semantics.
demo/notebooks/01_llama_index_property_graph.ipynb Colab install pinning updates + file-backed embedded connect path + formatting tweaks.
demo/notebooks/02_langchain_graph_chain.ipynb Colab install pinning updates + file-backed embedded connect path + formatting tweaks.
demo/notebooks/03_langgraph_agent.ipynb Colab install pinning updates + new explicit connect behavior (no port probe) + file-backed embedded mode.
coordinode-embedded/.gitignore Ignores native extension artifacts (.so/.pyd/.dylib).
.gitignore Ignores .claude/ directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread coordinode/coordinode/client.py
Comment thread demo/notebooks/03_langgraph_agent.ipynb
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@demo/notebooks/00_seed_data.ipynb`:
- Around line 14-19: Update the user-facing guidance to avoid hard-coding
“/tmp”; reference the OS temp directory or show the actual
COORDINODE_EMBEDDED_PATH value instead. Locate the notebook cells that mention
`/tmp/coordinode-demo.db` (related to COORDINODE_EMBEDDED_PATH and the
tempfile.gettempdir() usage) and replace the static path text with language like
“the OS temp directory” or programmatically print the COORDINODE_EMBEDDED_PATH
variable so users see the real path on their platform; apply the same change to
the other occurrences noted (around the cells corresponding to lines 147-149 and
467-470).
- Around line 60-62: When COORDINODE_ADDR is unset the notebook attempts to use
LocalClient but the install cell only installs coordinode-embedded in Colab,
making local runs fail; update the install logic so when COORDINODE_ADDR is not
set and not running in Colab the notebook either installs the
coordinode-embedded package locally (not just in IN_COLAB) or updates the
connect cell to clearly require and import the separate coordinode-embedded
package before constructing LocalClient; specifically modify the install cell
that checks IN_COLAB and the connect cell that constructs LocalClient (and the
ImportError message) to reference coordinode-embedded and to provide a local
install instruction/path for non-Colab runs so the LocalClient path is actually
provisioned.

In `@demo/notebooks/01_llama_index_property_graph.ipynb`:
- Around line 104-108: The comment about `coordinode` being "installed without
pins" is misleading because the `_coordinode_spec` assignment pins `coordinode`
to a specific git commit when `IN_COLAB` is true; update the explanatory comment
to reflect that behavior (mention `_coordinode_spec` and `IN_COLAB`) or change
`_coordinode_spec` to match the comment; specifically either adjust the comment
above `_coordinode_spec` to state that in Colab we install a pinned git commit
of `coordinode`, or remove the git-commit pinning logic in `_coordinode_spec` so
it truly installs without pins.

In `@demo/notebooks/02_langchain_graph_chain.ipynb`:
- Around line 44-45: The notebook incorrectly assumes installing
coordinode-embedded only in Colab suffices for the LocalClient fallback when
COORDINODE_ADDR is unset; change the notebook so that when COORDINODE_ADDR is
not set it either (a) installs/coaxes the user to install the separate
coordinode-embedded package for local embedded mode (same step as the Colab
install but gated for non-IN_COLAB runs) or (b) clearly informs the user that
local embedded mode requires a separate manual install and does not suggest
rerunning the Colab-only cell. Update the logic and messaging around
COORDINODE_ADDR, IN_COLAB, and LocalClient to ensure the notebook offers a valid
install path for coordinode-embedded (or an explicit manual-install note) and
adjust the same pattern at the other occurrence noted (lines 219-225).

In `@demo/notebooks/03_langgraph_agent.ipynb`:
- Around line 53-54: The notebook claims that leaving COORDINODE_ADDR unset will
fall back to embedded, but the install step only runs when IN_COLAB is true so a
fresh local run without a server will fail; update the logic around
COORDINODE_ADDR/IN_COLAB to either (a) attempt to pip-install or import
coordinode-embedded when COORDINODE_ADDR is unset regardless of IN_COLAB, or (b)
explicitly surface a clear error and explicit install instruction for local runs
instead of suggesting the Colab-only cell fixes it; check for the presence of
the coordinode-embedded package (handle ImportError) and adjust the messaging or
install behavior in the notebook cells referenced (COORDINODE_ADDR, IN_COLAB,
coordinode-embedded) so the embedded path is actually provisioned or documented
correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d71a357a-590a-4663-bb8f-f19b205f7c18

📥 Commits

Reviewing files that changed from the base of the PR and between 10ab38d and ced47e8.

📒 Files selected for processing (4)
  • demo/notebooks/00_seed_data.ipynb
  • demo/notebooks/01_llama_index_property_graph.ipynb
  • demo/notebooks/02_langchain_graph_chain.ipynb
  • demo/notebooks/03_langgraph_agent.ipynb

Comment thread demo/notebooks/00_seed_data.ipynb
Comment thread demo/notebooks/00_seed_data.ipynb
Comment thread demo/notebooks/01_llama_index_property_graph.ipynb
Comment thread demo/notebooks/02_langchain_graph_chain.ipynb
Comment thread demo/notebooks/03_langgraph_agent.ipynb
polaz added 2 commits April 20, 2026 14:28
…stall path

- cypher() now raises ValueError client-side when after_index > 0 is
  combined with non-majority write_concern. The server rejects this
  combination; surfacing it earlier gives a clearer error and matches
  the documented contract. Unit coverage added.
- Notebook ImportError message on missing coordinode-embedded now lists
  the explicit local install path (git+ pip install from the repo
  subdirectory, Rust toolchain note, ~5 min build) alongside the Colab
  install-cell hint and the server-mode escape hatch.
- Notebook 00 markdown drops the hard-coded /tmp fallback phrasing;
  success print shows the runtime COORDINODE_EMBEDDED_PATH verbatim.
- Notebook 01/02 comment block now accurately describes coordinode as
  git-pinned in Colab and unpinned outside, rather than claiming it is
  always unpinned.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@coordinode/coordinode/client.py`:
- Around line 278-285: The causal-read validation currently lowercases
write_concern without stripping whitespace, which can mis-handle values like "
majority "; update the check to normalize write_concern the same way as
elsewhere (either call _normalize_consistency_key(write_concern) or use
(write_concern or "").strip().lower()) when evaluating after_index and
write_concern so the conditional uses consistent normalization with
_normalize_consistency_key; adjust the conditional that raises ValueError to use
that normalized value for comparison.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e3e09ee8-202a-46c9-8ca3-7e0e5d9eebe3

📥 Commits

Reviewing files that changed from the base of the PR and between ced47e8 and f6c3f50.

📒 Files selected for processing (6)
  • coordinode/coordinode/client.py
  • demo/notebooks/00_seed_data.ipynb
  • demo/notebooks/01_llama_index_property_graph.ipynb
  • demo/notebooks/02_langchain_graph_chain.ipynb
  • demo/notebooks/03_langgraph_agent.ipynb
  • tests/integration/test_sdk.py

Comment thread coordinode/coordinode/client.py
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Python SDK and demo assets to align with coordinode-server v0.4.1, including removing an upstream-dropped RPC and adding new Cypher consistency controls.

Changes:

  • Remove hybrid text+vector search API (hybrid_text_vector_search) and related result type/export.
  • Add read_concern / write_concern / read_preference / after_index kwargs to cypher() with normalization helpers and unit/integration tests.
  • Update demo notebooks + compose files for v0.4.1 and improve Colab/embedded reproducibility (pinned SDK in Colab, file-backed embedded DB, protoc install guard).

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
coordinode/coordinode/client.py Removes hybrid RPC API and adds Cypher consistency kwargs + helper normalization/mapping.
coordinode/coordinode/__init__.py Removes HybridResult export from public package surface.
tests/unit/test_consistency_helpers.py Adds unit coverage for consistency helper validation/mapping.
tests/integration/test_sdk.py Replaces hybrid-search integration test with end-to-end consistency-kwargs test coverage.
coordinode/README.md Documents Cypher-based hybrid scoring functions, ATTACH/DETACH DOCUMENT, and consistency controls.
docker-compose.yml Bumps server image tag to 0.4.1.
demo/docker-compose.yml Bumps demo server image tag to 0.4.1.
demo/README.md Updates demo docs to reference v0.4.1.
demo/notebooks/00_seed_data.ipynb Colab pin + embedded file-backed DB path + install/connect behavior updates.
demo/notebooks/01_llama_index_property_graph.ipynb Same Colab pin + connect-cell embedded behavior changes and formatting cleanup.
demo/notebooks/02_langchain_graph_chain.ipynb Same Colab pin + connect-cell embedded behavior changes and formatting cleanup.
demo/notebooks/03_langgraph_agent.ipynb Same Colab pin + connect-cell embedded behavior changes and formatting cleanup.
coordinode-embedded/.gitignore Ignores compiled extension artifacts (.so/.pyd/.dylib).
.gitignore Ignores .claude/ directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread coordinode/coordinode/client.py
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Python SDK and demo materials to stay compatible with coordinode-server v0.4.1, including removing an upstream-dropped hybrid RPC and adding new Cypher consistency controls.

Changes:

  • Remove hybrid_text_vector_search() (sync + async) and the HybridResult type/export to match upstream proto/API removals.
  • Add cypher() consistency kwargs (read_concern, write_concern, read_preference, after_index) with validation + unit/integration coverage.
  • Refresh demo notebooks and docker-compose configs for v0.4.1 and improve Colab reproducibility (pinned SDK install in Colab; embedded mode is file-backed).

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/unit/test_consistency_helpers.py Adds unit tests for new consistency helper functions and validation behavior.
tests/integration/test_sdk.py Removes hybrid search integration test and adds integration tests for consistency kwargs + invalid-value rejection.
docker-compose.yml Bumps root CoordiNode server image tag to 0.4.1.
demo/notebooks/00_seed_data.ipynb Updates Colab install/connect logic, pins SDK in Colab, and switches embedded DB to a persistent file path.
demo/notebooks/01_llama_index_property_graph.ipynb Updates Colab install/connect logic and embedded persistence; keeps adapters working with embedded mode.
demo/notebooks/02_langchain_graph_chain.ipynb Same Colab pinning + embedded persistence updates; refactors embedded adapter cell formatting.
demo/notebooks/03_langgraph_agent.ipynb Pins SDK in Colab, removes localhost probing, and uses file-backed embedded DB for persistence.
demo/docker-compose.yml Bumps demo stack server image tag to 0.4.1.
demo/README.md Updates demo documentation to reference v0.4.1 server/embedded versions.
coordinode/coordinode/client.py Removes hybrid RPC client methods and adds Cypher consistency kwargs + normalization helpers.
coordinode/coordinode/__init__.py Removes HybridResult from package exports.
coordinode/README.md Documents hybrid search via Cypher scoring functions + new consistency controls.
coordinode-embedded/.gitignore Ignores platform-specific shared library artifacts (.so/.pyd/.dylib).
.gitignore Ignores .claude/ directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread coordinode/README.md
@polaz polaz merged commit 7b426c0 into main Apr 21, 2026
12 checks passed
@polaz polaz deleted the feat/#46-sdk-v0.4.1-update branch April 21, 2026 06:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(sdk): update SDK for coordinode-server v0.4.1 API

2 participants