Skip to content

Commit e581683

Browse files
committed
fix(client,demo): align type annotations and query_facts param guard
- create_label (async + sync): widen properties annotation to list[dict] | tuple[dict, ...] | None (matches _build_property_definitions) - HybridResult: add doc comment explaining why .node is absent — proto HybridResult carries only node_id + score by design - query_facts (notebook): reject queries with parameters other than $sess to prevent unbound-parameter runtime errors
1 parent ded059d commit e581683

2 files changed

Lines changed: 14 additions & 4 deletions

File tree

coordinode/coordinode/client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ def __init__(self, proto_result: Any) -> None:
120120
self.node_id: int = proto_result.node_id
121121
# Combined RRF score: text_weight/(60+rank_text) + vector_weight/(60+rank_vec).
122122
self.score: float = proto_result.score
123+
# NOTE: proto HybridResult carries only node_id + score (no embedded Node
124+
# message). A full node is not included by design — the server returns IDs
125+
# for efficiency; callers that need properties should issue a follow-up
126+
# Cypher query: MATCH (n) WHERE id(n) = <node_id> RETURN n.
123127

124128
def __repr__(self) -> str:
125129
return f"HybridResult(node_id={self.node_id}, score={self.score:.6f})"
@@ -527,7 +531,7 @@ def _normalize_schema_mode(schema_mode: str | int, mode_map: dict[str, int]) ->
527531
async def create_label(
528532
self,
529533
name: str,
530-
properties: list[dict[str, Any]] | None = None,
534+
properties: list[dict[str, Any]] | tuple[dict[str, Any], ...] | None = None,
531535
*,
532536
schema_mode: str | int = "strict",
533537
) -> LabelInfo:
@@ -953,7 +957,7 @@ def get_edge_types(self) -> list[EdgeTypeInfo]:
953957
def create_label(
954958
self,
955959
name: str,
956-
properties: list[dict[str, Any]] | None = None,
960+
properties: list[dict[str, Any]] | tuple[dict[str, Any], ...] | None = None,
957961
*,
958962
schema_mode: str | int = "strict",
959963
) -> LabelInfo:

demo/notebooks/03_langgraph_agent.ipynb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,17 @@
260260
" _LIMIT_AT_END_RE = re.compile(r\"\\bLIMIT\\s+(\\d+)\\s*;?\\s*$\", re.IGNORECASE | re.DOTALL)\n",
261261
" def _cap_limit(m):\n",
262262
" return f\"LIMIT {min(int(m.group(1)), 20)}\"\n",
263+
" # Reject queries with parameters other than $sess — only {\"sess\": SESSION} is passed.\n",
264+
" extra_params = sorted(\n",
265+
" {m.group(1) for m in re.finditer(r\"\\$([A-Za-z_][A-Za-z0-9_]*)\", q)} - {\"sess\"}\n",
266+
" )\n",
267+
" if extra_params:\n",
268+
" return f\"Only $sess is supported in query_facts; found additional parameters: {', '.join(extra_params)}\"\n",
263269
" if _LIMIT_AT_END_RE.search(q):\n",
264270
" q = _LIMIT_AT_END_RE.sub(_cap_limit, q)\n",
265271
" elif re.search(r\"\\bLIMIT\\b\", q, re.IGNORECASE):\n",
266-
" # Respect caller-provided non-terminal / parameterized LIMIT clauses\n",
267-
" # (e.g. LIMIT $n); appending a second LIMIT would produce invalid Cypher.\n",
272+
" # Respect caller-provided non-terminal LIMIT clauses;\n",
273+
" # appending a second LIMIT would produce invalid Cypher.\n",
268274
" pass\n",
269275
" else:\n",
270276
" q = q.rstrip().rstrip(\";\") + \" LIMIT 20\"\n",

0 commit comments

Comments
 (0)