rushdb 2.9.0__tar.gz → 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {rushdb-2.9.0 → rushdb-3.0.0}/.env.example +0 -0
  2. {rushdb-2.9.0 → rushdb-3.0.0}/.github/workflows/ci.yml +26 -11
  3. {rushdb-2.9.0 → rushdb-3.0.0}/.gitignore +0 -0
  4. {rushdb-2.9.0 → rushdb-3.0.0}/CODE_OF_CONDUCT.md +0 -0
  5. {rushdb-2.9.0 → rushdb-3.0.0}/CONTRIBUTING.md +1 -1
  6. {rushdb-2.9.0 → rushdb-3.0.0}/LICENSE +0 -0
  7. {rushdb-2.9.0 → rushdb-3.0.0}/PKG-INFO +123 -15
  8. {rushdb-2.9.0 → rushdb-3.0.0}/README.md +120 -1
  9. {rushdb-2.9.0 → rushdb-3.0.0}/pyproject.toml +8 -22
  10. {rushdb-2.9.0 → rushdb-3.0.0}/rushdb-logo.svg +0 -0
  11. {rushdb-2.9.0 → rushdb-3.0.0}/src/__init__.py +0 -0
  12. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/__init__.py +13 -1
  13. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/__init__.py +4 -0
  14. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/ai.py +59 -26
  15. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/base.py +0 -0
  16. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/labels.py +0 -0
  17. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/properties.py +0 -0
  18. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/query.py +3 -4
  19. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/records.py +153 -34
  20. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/relationship_patterns.py +0 -0
  21. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/relationships.py +0 -0
  22. rushdb-3.0.0/src/rushdb/api/text_indexes.py +63 -0
  23. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/api/transactions.py +7 -3
  24. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/client.py +58 -19
  25. rushdb-3.0.0/src/rushdb/common.py +65 -0
  26. rushdb-3.0.0/src/rushdb/direct/__init__.py +5 -0
  27. rushdb-3.0.0/src/rushdb/direct/capabilities.py +38 -0
  28. rushdb-3.0.0/src/rushdb/direct/engine.py +79 -0
  29. rushdb-3.0.0/src/rushdb/direct/router.py +1436 -0
  30. rushdb-3.0.0/src/rushdb/direct/schema.py +204 -0
  31. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/models/__init__.py +0 -0
  32. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/models/api_response.py +0 -0
  33. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/models/property.py +0 -0
  34. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/models/record.py +5 -2
  35. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/models/relationship.py +0 -0
  36. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/models/result.py +20 -0
  37. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/models/search_query.py +2 -3
  38. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/models/transaction.py +0 -0
  39. {rushdb-2.9.0 → rushdb-3.0.0}/src/rushdb/utils/token_prefix.py +0 -0
  40. {rushdb-2.9.0 → rushdb-3.0.0}/tests/__init__.py +0 -0
  41. rushdb-3.0.0/tests/test_ai_vector_search.py +117 -0
  42. {rushdb-2.9.0 → rushdb-3.0.0}/tests/test_base_setup.py +0 -0
  43. {rushdb-2.9.0 → rushdb-3.0.0}/tests/test_create_import.py +0 -0
  44. rushdb-3.0.0/tests/test_direct_mode.py +585 -0
  45. rushdb-3.0.0/tests/test_direct_mode_live.py +190 -0
  46. {rushdb-2.9.0 → rushdb-3.0.0}/tests/test_relationship_patterns.py +0 -0
  47. {rushdb-2.9.0 → rushdb-3.0.0}/tests/test_search_query.py +0 -0
  48. {rushdb-2.9.0 → rushdb-3.0.0}/tests/test_search_result.py +0 -0
  49. rushdb-3.0.0/uv.lock +832 -0
  50. rushdb-2.9.0/src/rushdb/common.py +0 -33
  51. rushdb-2.9.0/uv.lock +0 -1004
File without changes
@@ -13,7 +13,7 @@ jobs:
13
13
  runs-on: ubuntu-latest
14
14
  strategy:
15
15
  matrix:
16
- python-version: ["3.8", "3.9", "3.10", "3.11"]
16
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
17
17
 
18
18
  steps:
19
19
  - uses: actions/checkout@v4
@@ -43,7 +43,7 @@ jobs:
43
43
  run: |
44
44
  uv run pytest
45
45
 
46
- publish:
46
+ build:
47
47
  if: startsWith(github.ref, 'refs/tags/v')
48
48
  runs-on: ubuntu-latest
49
49
  needs: test
@@ -61,13 +61,28 @@ jobs:
61
61
  with:
62
62
  version: "latest"
63
63
 
64
- - name: Install dependencies
65
- run: |
66
- uv sync --dev
64
+ - name: Build distributions
65
+ run: uv build
67
66
 
68
- - name: Build and publish
69
- env:
70
- UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
71
- run: |
72
- uv build
73
- uv publish
67
+ - name: Upload distributions
68
+ uses: actions/upload-artifact@v4
69
+ with:
70
+ name: dist
71
+ path: dist/
72
+
73
+ publish:
74
+ if: startsWith(github.ref, 'refs/tags/v')
75
+ runs-on: ubuntu-latest
76
+ needs: build
77
+ permissions:
78
+ id-token: write
79
+
80
+ steps:
81
+ - name: Download distributions
82
+ uses: actions/download-artifact@v4
83
+ with:
84
+ name: dist
85
+ path: dist/
86
+
87
+ - name: Publish to PyPI
88
+ uses: pypa/gh-action-pypi-publish@release/v1
File without changes
File without changes
@@ -15,7 +15,7 @@ When reporting an issue, include the following information:
15
15
 
16
16
  - Specify the version of RushDB you are using:
17
17
  - **Cloud**: Mention if you are using the latest cloud version.
18
- - **Self-hosted**: Provide the tag from Docker Hub or the SDK version.
18
+ - **Self-hosted engine (direct mode)**: Provide the engine version (`rushdb --version`) and the SDK version.
19
19
 
20
20
  3. **Steps to Reproduce**
21
21
 
File without changes
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: rushdb
3
- Version: 2.9.0
3
+ Version: 3.0.0
4
4
  Summary: RushDB Python SDK — memory layer for AI agents and modern apps
5
5
  Project-URL: Homepage, https://github.com/rush-db/rushdb-python
6
6
  Project-URL: Repository, https://github.com/rush-db/rushdb-python
@@ -9,18 +9,7 @@ Author-email: RushDB Team <hi@rushdb.com>
9
9
  License: Apache-2.0
10
10
  License-File: LICENSE
11
11
  Keywords: agent memory,agent-memory,ai agents,ai memory,ai-agents,ai-memory,cloud,database,embedding,embeddings,graph,graph database,graph-database,json normalization,json-normalization,knowledge graph,knowledge-graph,llm memory,llm-memory,mcp,memory layer,memory-layer,no-schema,persistence,rag,relationships,rest api,rest-api,retrieval augmented generation,rush db,rush-db,rushdb,schema-less,schemaless,self-hosted,vector search,vector-search
12
- Requires-Python: >=3.8
13
- Requires-Dist: python-dotenv>=1.0.0
14
- Requires-Dist: requests>=2.31.0
15
- Provides-Extra: dev
16
- Requires-Dist: black>=23.7.0; extra == 'dev'
17
- Requires-Dist: isort>=5.12.0; extra == 'dev'
18
- Requires-Dist: mypy>=1.4.1; extra == 'dev'
19
- Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
20
- Requires-Dist: pytest>=7.4.0; extra == 'dev'
21
- Requires-Dist: ruff>=0.0.280; extra == 'dev'
22
- Requires-Dist: types-python-dateutil>=2.8.19.14; extra == 'dev'
23
- Requires-Dist: types-requests>=2.31.0.1; extra == 'dev'
12
+ Requires-Python: >=3.10
24
13
  Description-Content-Type: text/markdown
25
14
 
26
15
  <div align="center">
@@ -62,6 +51,64 @@ pip install rushdb
62
51
 
63
52
  ---
64
53
 
54
+ ## RushDB Cloud or a self-hosted engine
55
+
56
+ The SDK works with RushDB in one of two ways:
57
+
58
+ | | RushDB Cloud | Self-hosted RushDB engine (direct mode) |
59
+ | --- | --- | --- |
60
+ | What you run | nothing: the managed service at [app.rushdb.com](https://app.rushdb.com) | one `rushdb` binary, on your own infrastructure |
61
+ | Connect with | an API key | the engine URL and the engine token |
62
+
63
+ The engine is what you can self-host. RushDB Cloud runs that engine for you and adds the dashboard,
64
+ managed embeddings and the AI features (natural-language search, relationship-pattern suggestions),
65
+ which exist only in RushDB Cloud.
66
+
67
+ ```python
68
+ from rushdb import RushDB
69
+
70
+ # RushDB Cloud
71
+ db = RushDB("RUSHDB_API_KEY")
72
+
73
+ # A self-hosted engine
74
+ db = RushDB(
75
+ "ENGINE_TOKEN",
76
+ direct=True,
77
+ engine_url="http://127.0.0.1:3000",
78
+ scope="tenant-1", # only for an engine started with --multitenant
79
+ )
80
+ ```
81
+
82
+ What each offers:
83
+
84
+ | Feature | Cloud | Self-hosted engine |
85
+ | --- | :---: | :---: |
86
+ | Records: create, read, update, set, upsert, delete, `find` with `where`, `orderBy`, `select`, `groupBy` | ✓ | ✓ |
87
+ | Relationships: `attach`/`detach`, `relationships.create_many`/`delete_many`/`find` | ✓ | ✓ |
88
+ | Labels, properties, property values | ✓ | ✓ |
89
+ | Import JSON and CSV, export CSV | ✓ | ✓ |
90
+ | External vector indexes; vector search with a `queryVector` you supply | ✓ | ✓ |
91
+ | Raw openCypher (`query.raw`; the engine needs `--languages cypher`) | ✓ | ✓ |
92
+ | Schema (`ai.get_schema`, `ai.get_schema_markdown`) | ✓ | ✓ |
93
+ | Keyword (BM25) search (`records.text_search`), text indexes (`text_indexes.*`), hybrid search | ✓ | ✓ |
94
+ | Transactions | ✓ | record creates, updates, sets, deletes by id, attaches and imports are staged; other writes refuse a transaction |
95
+ | Managed embeddings: managed indexes, `records.vector_search` by text `query` | ✓ | — |
96
+ | Natural-language search (`ai.search`) | ✓ | — |
97
+ | Relationship-pattern suggestions (`relationships.patterns.*`) | ✓ | — |
98
+ | Project settings (`settings.get`), dashboard, team access | ✓ | — |
99
+
100
+ In direct mode a Cloud-only method raises `CloudOnlyError` (with `method` and `reason`) before
101
+ sending anything, and no request ever goes to RushDB Cloud. A write the engine cannot stage into a
102
+ transaction raises `DirectModeError`, also before sending anything. The list is available in code:
103
+
104
+ ```python
105
+ from rushdb import CLOUD_ONLY_METHODS, CloudOnlyError, is_cloud_only_method
106
+ ```
107
+
108
+ `db.engine.execute()` runs any Protocol v1 operation directly.
109
+
110
+ ---
111
+
65
112
  ## Agent memory in 3 lines
66
113
 
67
114
  Get an API key at [app.rushdb.com](https://app.rushdb.com).
@@ -227,6 +274,67 @@ if result:
227
274
 
228
275
  ---
229
276
 
277
+ ## Vector Search And Smart Search
278
+
279
+ Use `db.records.vector_search()` for direct semantic/vector retrieval over an
280
+ embedding index:
281
+
282
+ ```python
283
+ results = db.records.vector_search({
284
+ 'labels': ['MEMORY'],
285
+ 'propertyName': 'content',
286
+ 'query': 'how agents remember things',
287
+ 'where': {'agent_id': 'agent-42'},
288
+ 'limit': 5,
289
+ })
290
+
291
+ for record in results:
292
+ print(record.score, record.get('content'))
293
+ ```
294
+
295
+ Use `db.ai.search()` when you want RushDB to turn a natural-language request
296
+ into a SearchQuery and execute it:
297
+
298
+ ```python
299
+ results = db.ai.search('Find active memories about Q4 results for agent-42')
300
+ print(results.search_query)
301
+ ```
302
+
303
+ `db.ai.search({...})` still works as a deprecated vector-search alias, but new
304
+ code should use `db.records.vector_search({...})`.
305
+
306
+ ## Keyword And Hybrid Search
307
+
308
+ Declare a BM25 text index, then search it by keywords:
309
+
310
+ ```python
311
+ db.text_indexes.create({'label': 'MEMORY', 'property': 'content'})
312
+
313
+ results = db.records.text_search({
314
+ 'query': 'quarterly results',
315
+ 'labels': ['MEMORY'],
316
+ 'where': {'agent_id': 'agent-42'},
317
+ 'limit': 5,
318
+ })
319
+ print(results.total, results.meta['textSearch'])
320
+ ```
321
+
322
+ Add a `text` leg to a vector search to fuse keyword and vector ranking. `fusion`
323
+ is `rrf` (default) or `dbsf`; `weight` and `prefetchLimit` tune each leg:
324
+
325
+ ```python
326
+ results = db.records.vector_search({
327
+ 'labels': ['MEMORY'],
328
+ 'propertyName': 'content',
329
+ 'queryVector': embedding,
330
+ 'text': {'query': 'quarterly results', 'weight': 0.5},
331
+ 'fusion': 'dbsf',
332
+ 'limit': 5,
333
+ })
334
+ ```
335
+
336
+ ---
337
+
230
338
  ## Record API
231
339
 
232
340
  ```python
@@ -273,7 +381,7 @@ from rushdb import RushDB
273
381
 
274
382
  db = RushDB(
275
383
  'RUSHDB_API_KEY',
276
- url='http://your-rushdb-server.com/api/v1', # default: https://api.rushdb.com/api/v1
384
+ url='https://api.rushdb.com/api/v1', # a different RushDB Cloud API endpoint; this is the default
277
385
  timeout=30,
278
386
  )
279
387
  ```
@@ -37,6 +37,64 @@ pip install rushdb
37
37
 
38
38
  ---
39
39
 
40
+ ## RushDB Cloud or a self-hosted engine
41
+
42
+ The SDK works with RushDB in one of two ways:
43
+
44
+ | | RushDB Cloud | Self-hosted RushDB engine (direct mode) |
45
+ | --- | --- | --- |
46
+ | What you run | nothing: the managed service at [app.rushdb.com](https://app.rushdb.com) | one `rushdb` binary, on your own infrastructure |
47
+ | Connect with | an API key | the engine URL and the engine token |
48
+
49
+ The engine is what you can self-host. RushDB Cloud runs that engine for you and adds the dashboard,
50
+ managed embeddings and the AI features (natural-language search, relationship-pattern suggestions),
51
+ which exist only in RushDB Cloud.
52
+
53
+ ```python
54
+ from rushdb import RushDB
55
+
56
+ # RushDB Cloud
57
+ db = RushDB("RUSHDB_API_KEY")
58
+
59
+ # A self-hosted engine
60
+ db = RushDB(
61
+ "ENGINE_TOKEN",
62
+ direct=True,
63
+ engine_url="http://127.0.0.1:3000",
64
+ scope="tenant-1", # only for an engine started with --multitenant
65
+ )
66
+ ```
67
+
68
+ What each offers:
69
+
70
+ | Feature | Cloud | Self-hosted engine |
71
+ | --- | :---: | :---: |
72
+ | Records: create, read, update, set, upsert, delete, `find` with `where`, `orderBy`, `select`, `groupBy` | ✓ | ✓ |
73
+ | Relationships: `attach`/`detach`, `relationships.create_many`/`delete_many`/`find` | ✓ | ✓ |
74
+ | Labels, properties, property values | ✓ | ✓ |
75
+ | Import JSON and CSV, export CSV | ✓ | ✓ |
76
+ | External vector indexes; vector search with a `queryVector` you supply | ✓ | ✓ |
77
+ | Raw openCypher (`query.raw`; the engine needs `--languages cypher`) | ✓ | ✓ |
78
+ | Schema (`ai.get_schema`, `ai.get_schema_markdown`) | ✓ | ✓ |
79
+ | Keyword (BM25) search (`records.text_search`), text indexes (`text_indexes.*`), hybrid search | ✓ | ✓ |
80
+ | Transactions | ✓ | record creates, updates, sets, deletes by id, attaches and imports are staged; other writes refuse a transaction |
81
+ | Managed embeddings: managed indexes, `records.vector_search` by text `query` | ✓ | — |
82
+ | Natural-language search (`ai.search`) | ✓ | — |
83
+ | Relationship-pattern suggestions (`relationships.patterns.*`) | ✓ | — |
84
+ | Project settings (`settings.get`), dashboard, team access | ✓ | — |
85
+
86
+ In direct mode a Cloud-only method raises `CloudOnlyError` (with `method` and `reason`) before
87
+ sending anything, and no request ever goes to RushDB Cloud. A write the engine cannot stage into a
88
+ transaction raises `DirectModeError`, also before sending anything. The list is available in code:
89
+
90
+ ```python
91
+ from rushdb import CLOUD_ONLY_METHODS, CloudOnlyError, is_cloud_only_method
92
+ ```
93
+
94
+ `db.engine.execute()` runs any Protocol v1 operation directly.
95
+
96
+ ---
97
+
40
98
  ## Agent memory in 3 lines
41
99
 
42
100
  Get an API key at [app.rushdb.com](https://app.rushdb.com).
@@ -202,6 +260,67 @@ if result:
202
260
 
203
261
  ---
204
262
 
263
+ ## Vector Search And Smart Search
264
+
265
+ Use `db.records.vector_search()` for direct semantic/vector retrieval over an
266
+ embedding index:
267
+
268
+ ```python
269
+ results = db.records.vector_search({
270
+ 'labels': ['MEMORY'],
271
+ 'propertyName': 'content',
272
+ 'query': 'how agents remember things',
273
+ 'where': {'agent_id': 'agent-42'},
274
+ 'limit': 5,
275
+ })
276
+
277
+ for record in results:
278
+ print(record.score, record.get('content'))
279
+ ```
280
+
281
+ Use `db.ai.search()` when you want RushDB to turn a natural-language request
282
+ into a SearchQuery and execute it:
283
+
284
+ ```python
285
+ results = db.ai.search('Find active memories about Q4 results for agent-42')
286
+ print(results.search_query)
287
+ ```
288
+
289
+ `db.ai.search({...})` still works as a deprecated vector-search alias, but new
290
+ code should use `db.records.vector_search({...})`.
291
+
292
+ ## Keyword And Hybrid Search
293
+
294
+ Declare a BM25 text index, then search it by keywords:
295
+
296
+ ```python
297
+ db.text_indexes.create({'label': 'MEMORY', 'property': 'content'})
298
+
299
+ results = db.records.text_search({
300
+ 'query': 'quarterly results',
301
+ 'labels': ['MEMORY'],
302
+ 'where': {'agent_id': 'agent-42'},
303
+ 'limit': 5,
304
+ })
305
+ print(results.total, results.meta['textSearch'])
306
+ ```
307
+
308
+ Add a `text` leg to a vector search to fuse keyword and vector ranking. `fusion`
309
+ is `rrf` (default) or `dbsf`; `weight` and `prefetchLimit` tune each leg:
310
+
311
+ ```python
312
+ results = db.records.vector_search({
313
+ 'labels': ['MEMORY'],
314
+ 'propertyName': 'content',
315
+ 'queryVector': embedding,
316
+ 'text': {'query': 'quarterly results', 'weight': 0.5},
317
+ 'fusion': 'dbsf',
318
+ 'limit': 5,
319
+ })
320
+ ```
321
+
322
+ ---
323
+
205
324
  ## Record API
206
325
 
207
326
  ```python
@@ -248,7 +367,7 @@ from rushdb import RushDB
248
367
 
249
368
  db = RushDB(
250
369
  'RUSHDB_API_KEY',
251
- url='http://your-rushdb-server.com/api/v1', # default: https://api.rushdb.com/api/v1
370
+ url='https://api.rushdb.com/api/v1', # a different RushDB Cloud API endpoint; this is the default
252
371
  timeout=30,
253
372
  )
254
373
  ```
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "rushdb"
3
- version = "2.9.0"
3
+ version = "3.0.0"
4
4
  description = "RushDB Python SDK — memory layer for AI agents and modern apps"
5
5
  authors = [
6
6
  {name = "RushDB Team", email = "hi@rushdb.com"}
7
7
  ]
8
8
  license = {text = "Apache-2.0"}
9
9
  readme = "README.md"
10
- requires-python = ">=3.8"
10
+ requires-python = ">=3.10"
11
11
  keywords = [
12
12
  "rushdb",
13
13
  "database",
@@ -47,28 +47,13 @@ keywords = [
47
47
  "rush-db",
48
48
  "rush db"
49
49
  ]
50
- dependencies = [
51
- "python-dotenv>=1.0.0",
52
- "requests>=2.31.0"
53
- ]
50
+ dependencies = []
54
51
 
55
52
  [project.urls]
56
53
  Homepage = "https://github.com/rush-db/rushdb-python"
57
54
  Repository = "https://github.com/rush-db/rushdb-python"
58
55
  Documentation = "https://docs.rushdb.com"
59
56
 
60
- [project.optional-dependencies]
61
- dev = [
62
- "black>=23.7.0",
63
- "isort>=5.12.0",
64
- "ruff>=0.0.280",
65
- "mypy>=1.4.1",
66
- "pytest>=7.4.0",
67
- "pytest-cov>=4.1.0",
68
- "types-requests>=2.31.0.1",
69
- "types-python-dateutil>=2.8.19.14"
70
- ]
71
-
72
57
  [build-system]
73
58
  requires = ["hatchling"]
74
59
  build-backend = "hatchling.build"
@@ -84,12 +69,13 @@ profile = "black"
84
69
 
85
70
  [dependency-groups]
86
71
  dev = [
87
- "black>=24.8.0",
72
+ "black>=26.3.1",
88
73
  "isort>=5.13.2",
89
74
  "mypy>=1.14.1",
90
- "pytest>=8.3.5",
75
+ "pygments>=2.20.0",
76
+ "pytest>=9.0.3",
91
77
  "pytest-cov>=5.0.0",
92
- "ruff>=0.12.1",
78
+ "python-dotenv>=1.2.2",
79
+ "ruff>=0.12.1,<0.13",
93
80
  "types-python-dateutil>=2.9.0.20241206",
94
- "types-requests>=2.32.0.20241016",
95
81
  ]
File without changes
File without changes
@@ -8,8 +8,14 @@ from .api.query import QueryAPI
8
8
  from .api.records import pick_record_id
9
9
  from .api.relationship_patterns import RelationshipPatternsAPI
10
10
  from .api.relationships import RelationsAPI
11
+ from .api.text_indexes import TextIndexesAPI
11
12
  from .client import RushDB
12
- from .common import NonUniqueResultError, RushDBError
13
+ from .common import CloudOnlyError, DirectModeError, NonUniqueResultError, RushDBError
14
+ from .direct.capabilities import (
15
+ CLOUD_ONLY_FORMS,
16
+ CLOUD_ONLY_METHODS,
17
+ is_cloud_only_method,
18
+ )
13
19
  from .models.api_response import ApiResponse
14
20
  from .models.property import Property
15
21
  from .models.record import Record, RecordTarget, RelationTarget
@@ -31,6 +37,11 @@ from .models.search_query import (
31
37
  from .models.transaction import Transaction
32
38
 
33
39
  __all__ = [
40
+ "CLOUD_ONLY_FORMS",
41
+ "CLOUD_ONLY_METHODS",
42
+ "CloudOnlyError",
43
+ "DirectModeError",
44
+ "is_cloud_only_method",
34
45
  "RushDB",
35
46
  "RushDBError",
36
47
  "NonUniqueResultError",
@@ -57,4 +68,5 @@ __all__ = [
57
68
  "RelationshipPatternsAPI",
58
69
  "ApiResponse",
59
70
  "AIAPI",
71
+ "TextIndexesAPI",
60
72
  ]
@@ -1,12 +1,15 @@
1
+ from .ai import AIAPI
1
2
  from .labels import LabelsAPI
2
3
  from .properties import PropertiesAPI
3
4
  from .query import QueryAPI
4
5
  from .records import RecordsAPI
5
6
  from .relationship_patterns import RelationshipPatternsAPI
6
7
  from .relationships import RelationsAPI
8
+ from .text_indexes import TextIndexesAPI
7
9
  from .transactions import TransactionsAPI
8
10
 
9
11
  __all__ = [
12
+ "AIAPI",
10
13
  "RecordsAPI",
11
14
  "PropertiesAPI",
12
15
  "LabelsAPI",
@@ -14,4 +17,5 @@ __all__ = [
14
17
  "QueryAPI",
15
18
  "RelationsAPI",
16
19
  "RelationshipPatternsAPI",
20
+ "TextIndexesAPI",
17
21
  ]
@@ -1,13 +1,16 @@
1
1
  """AI API for RushDB Python SDK.
2
2
 
3
- Provides methods for graph schema exploration, semantic vector search,
3
+ Provides methods for AI-assisted graph exploration, smart search,
4
4
  and embedding index management.
5
5
  """
6
6
 
7
- from typing import TYPE_CHECKING, Any, Dict, Optional, Union
7
+ import warnings
8
+ from typing import TYPE_CHECKING, Any, Dict, Optional, Union, cast
8
9
 
9
10
  from ..models.api_response import ApiResponse
10
11
  from ..models.record import Record
12
+ from ..models.result import RecordSearchResult
13
+ from ..models.search_query import SearchQuery
11
14
  from ..models.transaction import Transaction
12
15
  from .base import BaseAPI
13
16
 
@@ -124,7 +127,12 @@ class AIAPI(BaseAPI):
124
127
 
125
128
  >>> db = RushDB(api_key="...")
126
129
  >>> schema = db.ai.get_schema()
127
- >>> results = db.ai.search({"query": "fast cars", "propertyName": "description"})
130
+ >>> results = db.ai.search("books about fast cars")
131
+ >>> vectors = db.records.vector_search({
132
+ ... "query": "fast cars",
133
+ ... "propertyName": "description",
134
+ ... "labels": ["Book"],
135
+ ... })
128
136
  >>> db.ai.indexes.create({"propertyName": "description", "label": "Book"})
129
137
  """
130
138
 
@@ -145,7 +153,7 @@ class AIAPI(BaseAPI):
145
153
  indexes exist for that property — each entry exposes ``id``,
146
154
  ``sourceType``, ``similarityFunction``, ``dimensions``, ``status``, and
147
155
  ``modelKey``. A non-empty ``vectorIndexes`` list means the property is
148
- queryable with ``db.ai.search()``.
156
+ queryable with ``db.records.vector_search()``.
149
157
 
150
158
  Args:
151
159
  params: Optional filter. Pass ``{"labels": ["Label1"]}`` to scope
@@ -214,35 +222,60 @@ class AIAPI(BaseAPI):
214
222
  total=response.get("total"),
215
223
  )
216
224
 
217
- def search(self, params: Dict[str, Any]) -> ApiResponse:
218
- """Perform semantic (vector) search over indexed record properties.
225
+ def search(
226
+ self,
227
+ prompt: Union[str, Dict[str, Any]],
228
+ current_query: Optional[SearchQuery] = None,
229
+ transaction: Optional[Union[Transaction, str]] = None,
230
+ ) -> RecordSearchResult:
231
+ """Perform AI-assisted smart search from natural language.
219
232
 
220
- **Direct vector-index mode** (default, fast): used when no ``where``
221
- filter and at most one ``labels`` entry. Queries the shared global
222
- vector index directly.
233
+ RushDB converts ``prompt`` into a SearchQuery using the project schema,
234
+ executes it, and returns matching records with the generated query
235
+ attached to ``result.search_query``.
223
236
 
224
- **Prefilter mode** (exact, slower): activated when a ``where``
225
- filter is supplied or ``labels`` contains more than one value.
226
- Candidates are first narrowed by MATCH/WHERE, then ranked by exact
227
- cosine similarity.
237
+ Use ``db.records.vector_search({...})`` for direct vector similarity
238
+ over embedding indexes.
228
239
 
229
240
  Args:
230
- params: Search parameters. Expected keys:
231
-
232
- - ``query`` (str): The natural-language query text.
233
- - ``propertyName`` (str): Property that has been embedded.
234
- - ``labels`` (list[str], optional): Scope to specific labels.
235
- - ``where`` (dict, optional): Additional property filters.
236
- - ``limit`` (int, optional): Maximum number of results.
241
+ prompt: Natural-language search request. Passing a dict is
242
+ deprecated and delegates to ``db.records.vector_search``.
243
+ current_query: Optional current SearchQuery context from a
244
+ dashboard/query-builder session.
245
+ transaction: Optional transaction context.
237
246
 
238
247
  Returns:
239
- ApiResponse: Response whose ``data`` is a list of semantic search
240
- result objects (each includes the matched record and a score).
248
+ RecordSearchResult: Matching records. The generated SearchQuery is
249
+ available as ``result.search_query`` and server warnings as
250
+ ``result.warnings``.
241
251
  """
242
- response = self.client._make_request("POST", "/ai/search", params)
252
+ if isinstance(prompt, dict):
253
+ warnings.warn(
254
+ "db.ai.search({...}) is deprecated for vector search; "
255
+ "use db.records.vector_search({...}) instead.",
256
+ DeprecationWarning,
257
+ stacklevel=2,
258
+ )
259
+ return self.client.records.vector_search(prompt, transaction=transaction)
260
+
261
+ headers = Transaction._build_transaction_header(transaction)
262
+ generated = self.client._make_request(
263
+ "POST",
264
+ "/ai/search-query",
265
+ {"prompt": prompt, "currentQuery": current_query},
266
+ headers,
267
+ )
268
+ generated_data = generated.get("data") or {}
269
+ search_query = generated_data.get("searchQuery") or {}
270
+
271
+ response = self.client._make_request(
272
+ "POST", "/records/search", search_query, headers
273
+ )
243
274
  records = [Record(self.client, item) for item in response.get("data", [])]
244
- return ApiResponse(
275
+ return RecordSearchResult(
245
276
  data=records,
246
- success=response.get("success", True),
247
- total=response.get("total"),
277
+ total=response.get("total", len(records)),
278
+ search_query=cast(SearchQuery, search_query),
279
+ client=self.client,
280
+ warnings=generated_data.get("warnings") or [],
248
281
  )
File without changes
File without changes
@@ -5,11 +5,10 @@ from .base import BaseAPI
5
5
 
6
6
 
7
7
  class QueryAPI(BaseAPI):
8
- """API client for executing raw Cypher queries (cloud-only).
8
+ """API client for executing raw openCypher queries.
9
9
 
10
- This endpoint is only available when using the RushDB managed cloud
11
- service or when your project is connected to a custom database through
12
- RushDB Cloud. It will not function for self-hosted or local-only deployments.
10
+ Works on RushDB Cloud and on a self-hosted RushDB engine in direct mode
11
+ (the engine must be started with ``--languages cypher``).
13
12
 
14
13
  Example:
15
14
  >>> from rushdb import RushDB