|
37 | 37 | "id": "d4e5f6a7-0003-0000-0000-000000000003", |
38 | 38 | "metadata": {}, |
39 | 39 | "outputs": [], |
40 | | - "source": "import os, sys, subprocess\n\nIN_COLAB = \"google.colab\" in sys.modules\n\n# Install coordinode-embedded in Colab only (requires Rust build).\nif IN_COLAB and not os.environ.get(\"COORDINODE_ADDR\"):\n # Install Rust toolchain via rustup (https://rustup.rs).\n # Colab's apt packages ship rustc ≤1.75, which cannot build coordinode-embedded\n # (requires Rust ≥1.80 for maturin/pyo3). apt-get is not a viable alternative here.\n # Download the installer to a temp file and execute it explicitly — this avoids\n # piping remote content directly into a shell while maintaining HTTPS/TLS security\n # through Python's default ssl context (cert-verified, TLS 1.2+).\n # SHA256 pinning of rustup-init is intentionally omitted: rustup.rs does not\n # publish a stable per-release checksum for sh.rustup.rs itself (only for\n # platform-specific rustup-init binaries), and pinning a hash here would break\n # silently on every rustup release. The HTTPS/TLS verification + temp-file\n # execution (not piped to shell) is the rustup team's recommended trust model.\n # Skip embedded build if COORDINODE_ADDR is set — user has a gRPC server,\n # no need to spend 5+ minutes building coordinode-embedded from source.\n # The `IN_COLAB` check already guards against local/server environments.\n import ssl as _ssl, tempfile as _tmp, urllib.request as _ur\n\n _ctx = _ssl.create_default_context()\n with _tmp.NamedTemporaryFile(mode=\"wb\", suffix=\".sh\", delete=False) as _f:\n with _ur.urlopen(\"https://sh.rustup.rs\", context=_ctx, timeout=30) as _r:\n _f.write(_r.read())\n _rustup_path = _f.name\n try:\n subprocess.run([\"/bin/sh\", _rustup_path, \"-s\", \"--\", \"-y\", \"-q\"], check=True, timeout=300)\n finally:\n os.unlink(_rustup_path)\n # Add cargo to PATH so maturin/pip can find it.\n _cargo_bin = os.path.expanduser(\"~/.cargo/bin\")\n os.environ[\"PATH\"] = f\"{_cargo_bin}{os.pathsep}{os.environ.get('PATH', '')}\"\n subprocess.run([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"maturin\"], check=True, timeout=300)\n subprocess.run(\n [\n sys.executable,\n \"-m\",\n \"pip\",\n \"install\",\n \"-q\",\n \"git+https://github.com/structured-world/coordinode-python.git@4efc7b287211f4cfcf203ce92c83773d7d72ff61#subdirectory=coordinode-embedded\",\n ],\n check=True,\n timeout=600,\n )\n\nsubprocess.run(\n [\n sys.executable,\n \"-m\",\n \"pip\",\n \"install\",\n \"-q\",\n \"coordinode\",\n \"langchain-coordinode\",\n \"langchain-community\",\n \"langchain-openai\",\n \"langgraph\",\n ],\n check=True,\n timeout=300,\n)\n\nprint(\"SDK installed\")" |
| 40 | + "source": [ |
| 41 | + "import os, sys, subprocess\n", |
| 42 | + "\n", |
| 43 | + "IN_COLAB = \"google.colab\" in sys.modules\n", |
| 44 | + "\n", |
| 45 | + "# Install coordinode-embedded in Colab only (requires Rust build).\n", |
| 46 | + "if IN_COLAB and not os.environ.get(\"COORDINODE_ADDR\"):\n", |
| 47 | + " # Install Rust toolchain via rustup (https://rustup.rs).\n", |
| 48 | + " # Colab's apt packages ship rustc ≤1.75, which cannot build coordinode-embedded\n", |
| 49 | + " # (requires Rust ≥1.80 for maturin/pyo3). apt-get is not a viable alternative here.\n", |
| 50 | + " # Download the installer to a temp file and execute it explicitly — this avoids\n", |
| 51 | + " # piping remote content directly into a shell while maintaining HTTPS/TLS security\n", |
| 52 | + " # through Python's default ssl context (cert-verified, TLS 1.2+).\n", |
| 53 | + " # SHA256 pinning of rustup-init is intentionally omitted: rustup.rs does not\n", |
| 54 | + " # publish a stable per-release checksum for sh.rustup.rs itself (only for\n", |
| 55 | + " # platform-specific rustup-init binaries), and pinning a hash here would break\n", |
| 56 | + " # silently on every rustup release. The HTTPS/TLS verification + temp-file\n", |
| 57 | + " # execution (not piped to shell) is the rustup team's recommended trust model.\n", |
| 58 | + " # Skip embedded build if COORDINODE_ADDR is set — user has a gRPC server,\n", |
| 59 | + " # no need to spend 5+ minutes building coordinode-embedded from source.\n", |
| 60 | + " # The `IN_COLAB` check already guards against local/server environments.\n", |
| 61 | + " import ssl as _ssl, tempfile as _tmp, urllib.request as _ur\n", |
| 62 | + "\n", |
| 63 | + " _ctx = _ssl.create_default_context()\n", |
| 64 | + " with _tmp.NamedTemporaryFile(mode=\"wb\", suffix=\".sh\", delete=False) as _f:\n", |
| 65 | + " with _ur.urlopen(\"https://sh.rustup.rs\", context=_ctx, timeout=30) as _r:\n", |
| 66 | + " _f.write(_r.read())\n", |
| 67 | + " _rustup_path = _f.name\n", |
| 68 | + " try:\n", |
| 69 | + " subprocess.run([\"/bin/sh\", _rustup_path, \"-s\", \"--\", \"-y\", \"-q\"], check=True, timeout=300)\n", |
| 70 | + " finally:\n", |
| 71 | + " os.unlink(_rustup_path)\n", |
| 72 | + " # Add cargo to PATH so maturin/pip can find it.\n", |
| 73 | + " _cargo_bin = os.path.expanduser(\"~/.cargo/bin\")\n", |
| 74 | + " os.environ[\"PATH\"] = f\"{_cargo_bin}{os.pathsep}{os.environ.get('PATH', '')}\"\n", |
| 75 | + " subprocess.run([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"maturin\"], check=True, timeout=300)\n", |
| 76 | + " subprocess.run(\n", |
| 77 | + " [\n", |
| 78 | + " sys.executable,\n", |
| 79 | + " \"-m\",\n", |
| 80 | + " \"pip\",\n", |
| 81 | + " \"install\",\n", |
| 82 | + " \"-q\",\n", |
| 83 | + " \"git+https://github.com/structured-world/coordinode-python.git@4efc7b287211f4cfcf203ce92c83773d7d72ff61#subdirectory=coordinode-embedded\",\n", |
| 84 | + " ],\n", |
| 85 | + " check=True,\n", |
| 86 | + " timeout=600,\n", |
| 87 | + " )\n", |
| 88 | + "\n", |
| 89 | + "subprocess.run(\n", |
| 90 | + " [\n", |
| 91 | + " sys.executable,\n", |
| 92 | + " \"-m\",\n", |
| 93 | + " \"pip\",\n", |
| 94 | + " \"install\",\n", |
| 95 | + " \"-q\",\n", |
| 96 | + " \"coordinode\",\n", |
| 97 | + " \"langchain-coordinode\",\n", |
| 98 | + " \"langchain-community\",\n", |
| 99 | + " \"langchain-openai\",\n", |
| 100 | + " \"langgraph\",\n", |
| 101 | + " \"nest_asyncio\",\n", |
| 102 | + " ],\n", |
| 103 | + " check=True,\n", |
| 104 | + " timeout=300,\n", |
| 105 | + ")\n", |
| 106 | + "\n", |
| 107 | + "import nest_asyncio\n", |
| 108 | + "nest_asyncio.apply()\n", |
| 109 | + "\n", |
| 110 | + "print(\"SDK installed\")" |
| 111 | + ] |
41 | 112 | }, |
42 | 113 | { |
43 | 114 | "cell_type": "markdown", |
|
199 | 270 | " \"\"\"Find all entities reachable from entity_name within the given number of hops (max 3).\"\"\"\n", |
200 | 271 | " safe_depth = max(1, min(int(depth), 3))\n", |
201 | 272 | " rows = client.cypher(\n", |
202 | | - " f\"MATCH p=(n:Entity {{name: $name, session: $sess}})-[*1..{safe_depth}]->(m:Entity {{session: $sess}}) \"\n", |
203 | | - " \"WHERE ALL(x IN nodes(p) WHERE x.session = $sess) \"\n", |
204 | | - " \"RETURN m.name AS related, type(last(relationships(p))) AS via LIMIT 20\",\n", |
| 273 | + " f\"MATCH (n:Entity {{name: $name, session: $sess}})-[*1..{safe_depth}]->(m:Entity {{session: $sess}}) \"\n", |
| 274 | + " \"RETURN DISTINCT m.name AS related LIMIT 20\",\n", |
205 | 275 | " params={\"name\": entity_name, \"sess\": SESSION},\n", |
206 | 276 | " )\n", |
207 | 277 | " if not rows:\n", |
208 | 278 | " return f\"No related entities found for {entity_name}\"\n", |
209 | | - " return \"\\n\".join(f\"{r['via']} -> {r['related']}\" for r in rows)\n", |
| 279 | + " return \"\\n\".join(r['related'] for r in rows)\n", |
210 | 280 | "\n", |
211 | 281 | "\n", |
212 | 282 | "@tool\n", |
|
0 commit comments