ainative-python 2.0.0__tar.gz → 3.1.1__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 (46) hide show
  1. {ainative_python-2.0.0 → ainative_python-3.1.1}/PKG-INFO +9 -8
  2. {ainative_python-2.0.0 → ainative_python-3.1.1}/README.md +4 -4
  3. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/__init__.py +6 -1
  4. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/auth.py +1 -1
  5. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/zerodb/analytics.py +54 -75
  6. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/zerodb/memory.py +67 -53
  7. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/zerodb/projects.py +2 -2
  8. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/zerodb/tables.py +42 -16
  9. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/zerodb/vectors.py +15 -14
  10. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative_python.egg-info/PKG-INFO +9 -8
  11. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative_python.egg-info/SOURCES.txt +1 -3
  12. {ainative_python-2.0.0 → ainative_python-3.1.1}/setup.py +5 -4
  13. ainative_python-3.1.1/tests/test_setup_metadata.py +70 -0
  14. ainative_python-2.0.0/tests/test_agent_operations.py +0 -587
  15. ainative_python-2.0.0/tests/test_cli.py +0 -545
  16. ainative_python-2.0.0/tests/test_tables.py +0 -439
  17. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/agent_coordination.py +0 -0
  18. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/agent_identity_system.py +0 -0
  19. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/agent_learning.py +0 -0
  20. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/agent_orchestration.py +0 -0
  21. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/agent_state.py +0 -0
  22. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/agent_swarm/__init__.py +0 -0
  23. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/cli.py +0 -0
  24. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/cli_utils/__init__.py +0 -0
  25. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/cli_utils/diff.py +0 -0
  26. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/cli_utils/formatters.py +0 -0
  27. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/client.py +0 -0
  28. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/__init__.py +0 -0
  29. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/agents.py +0 -0
  30. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/coordination.py +0 -0
  31. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/inspect.py +0 -0
  32. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/learning.py +0 -0
  33. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/local.py +0 -0
  34. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/state.py +0 -0
  35. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/swarm.py +0 -0
  36. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/sync.py +0 -0
  37. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/commands/tasks.py +0 -0
  38. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/exceptions.py +0 -0
  39. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative/zerodb/__init__.py +0 -0
  40. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative_python.egg-info/dependency_links.txt +0 -0
  41. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative_python.egg-info/entry_points.txt +0 -0
  42. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative_python.egg-info/not-zip-safe +0 -0
  43. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative_python.egg-info/requires.txt +0 -0
  44. {ainative_python-2.0.0 → ainative_python-3.1.1}/ainative_python.egg-info/top_level.txt +0 -0
  45. {ainative_python-2.0.0 → ainative_python-3.1.1}/setup.cfg +0 -0
  46. {ainative_python-2.0.0 → ainative_python-3.1.1}/tests/test_new_cli_commands.py +0 -0
@@ -1,14 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ainative-python
3
- Version: 2.0.0
3
+ Version: 3.1.1
4
4
  Summary: Official Python SDK for AINative Studio APIs with ZeroDB Local support
5
- Home-page: https://github.com/ainative/ainative-python
5
+ Home-page: https://ainative.studio
6
6
  Author: AINative Team
7
7
  Author-email: support@ainative.studio
8
+ Project-URL: Homepage, https://ainative.studio
8
9
  Project-URL: Documentation, https://docs.ainative.studio/sdk/python
9
10
  Project-URL: API Reference, https://api.ainative.studio/docs-enhanced
10
- Project-URL: Bug Reports, https://github.com/ainative/studio/issues
11
- Project-URL: Source, https://github.com/ainative/ainative-python
11
+ Project-URL: Bug Reports, https://github.com/AINative-Studio/core/issues
12
+ Project-URL: Source, https://github.com/AINative-Studio/core/tree/main/developer-tools/sdks/python
12
13
  Keywords: ainative,database,vector,embedding,ai,ml,machine learning,artificial intelligence,api,sdk,zerodb,agent swarm,postgresql,vector search,nosql,table operations,mongodb-style,crud
13
14
  Classifier: Development Status :: 3 - Alpha
14
15
  Classifier: Intended Audience :: Developers
@@ -90,7 +91,7 @@ pip install ainative-python
90
91
 
91
92
  For development version:
92
93
  ```bash
93
- pip install git+https://github.com/ainative/ainative-python.git
94
+ pip install git+https://github.com/AINative-Studio/core.git#subdirectory=developer-tools/sdks/python
94
95
  ```
95
96
 
96
97
  ## Quick Start
@@ -501,8 +502,8 @@ Full examples are available in the [examples/](examples/) directory:
501
502
 
502
503
  ```bash
503
504
  # Clone repository
504
- git clone https://github.com/ainative/ainative-python.git
505
- cd ainative-python
505
+ git clone https://github.com/AINative-Studio/core.git
506
+ cd core/developer-tools/sdks/python
506
507
 
507
508
  # Install in development mode
508
509
  pip install -e ".[dev]"
@@ -535,7 +536,7 @@ pytest tests/test_zerodb.py
535
536
 
536
537
  - **Documentation**: [https://docs.ainative.studio/sdk/python](https://docs.ainative.studio/sdk/python)
537
538
  - **API Reference**: [https://api.ainative.studio/docs-enhanced](https://api.ainative.studio/docs-enhanced)
538
- - **Issues**: [GitHub Issues](https://github.com/ainative/ainative-python/issues)
539
+ - **Issues**: [GitHub Issues](https://github.com/AINative-Studio/core/issues)
539
540
  - **Discord**: [Join our community](https://discord.gg/ainative)
540
541
 
541
542
  ## License
@@ -19,7 +19,7 @@ pip install ainative-python
19
19
 
20
20
  For development version:
21
21
  ```bash
22
- pip install git+https://github.com/ainative/ainative-python.git
22
+ pip install git+https://github.com/AINative-Studio/core.git#subdirectory=developer-tools/sdks/python
23
23
  ```
24
24
 
25
25
  ## Quick Start
@@ -430,8 +430,8 @@ Full examples are available in the [examples/](examples/) directory:
430
430
 
431
431
  ```bash
432
432
  # Clone repository
433
- git clone https://github.com/ainative/ainative-python.git
434
- cd ainative-python
433
+ git clone https://github.com/AINative-Studio/core.git
434
+ cd core/developer-tools/sdks/python
435
435
 
436
436
  # Install in development mode
437
437
  pip install -e ".[dev]"
@@ -464,7 +464,7 @@ pytest tests/test_zerodb.py
464
464
 
465
465
  - **Documentation**: [https://docs.ainative.studio/sdk/python](https://docs.ainative.studio/sdk/python)
466
466
  - **API Reference**: [https://api.ainative.studio/docs-enhanced](https://api.ainative.studio/docs-enhanced)
467
- - **Issues**: [GitHub Issues](https://github.com/ainative/ainative-python/issues)
467
+ - **Issues**: [GitHub Issues](https://github.com/AINative-Studio/core/issues)
468
468
  - **Discord**: [Join our community](https://discord.gg/ainative)
469
469
 
470
470
  ## License
@@ -2,9 +2,14 @@
2
2
  AINative Python SDK
3
3
 
4
4
  Official Python SDK for AINative Studio APIs including ZeroDB and Agent Swarm operations.
5
+
6
+ ⚠️ BREAKING CHANGES IN v3.0.0:
7
+ - All ZeroDB endpoint paths updated to canonical routes
8
+ - table/memory/analytics methods now require project_id as first parameter
9
+ - See CHANGELOG.md for migration guide
5
10
  """
6
11
 
7
- __version__ = "2.0.0"
12
+ __version__ = "3.1.0"
8
13
  __author__ = "AINative Team"
9
14
  __email__ = "support@ainative.studio"
10
15
 
@@ -56,7 +56,7 @@ class APIKeyAuth:
56
56
 
57
57
  headers = {
58
58
  "X-API-Key": self.config.api_key,
59
- "X-SDK-Version": "0.1.0",
59
+ "X-SDK-Version": "3.0.0",
60
60
  "X-SDK-Language": "Python",
61
61
  }
62
62
 
@@ -13,152 +13,139 @@ if TYPE_CHECKING:
13
13
 
14
14
  class AnalyticsClient:
15
15
  """Client for ZeroDB analytics operations."""
16
-
16
+
17
17
  def __init__(self, client: "AINativeClient"):
18
18
  """
19
19
  Initialize analytics client.
20
-
20
+
21
21
  Args:
22
22
  client: Parent AINative client instance
23
23
  """
24
24
  self.client = client
25
- self.base_path = "/zerodb/analytics"
25
+ # Analytics are accessed via /projects/{project_id}/database/analytics/*
26
+ self.base_path = "/projects"
26
27
 
27
28
  def get_usage(
28
29
  self,
29
- project_id: Optional[str] = None,
30
+ project_id: str,
30
31
  start_date: Optional[datetime] = None,
31
32
  end_date: Optional[datetime] = None,
32
33
  granularity: str = "daily",
33
34
  ) -> Dict[str, Any]:
34
35
  """
35
36
  Get usage analytics.
36
-
37
+
37
38
  Args:
38
- project_id: Optional project ID filter
39
+ project_id: Project ID (required)
39
40
  start_date: Start date for analytics
40
41
  end_date: End date for analytics
41
42
  granularity: Data granularity (hourly, daily, weekly, monthly)
42
-
43
+
43
44
  Returns:
44
45
  Usage analytics data
45
46
  """
46
47
  params = {"granularity": granularity}
47
-
48
- if project_id:
49
- params["project_id"] = project_id
48
+
50
49
  if start_date:
51
50
  params["start_date"] = start_date.isoformat()
52
51
  if end_date:
53
52
  params["end_date"] = end_date.isoformat()
54
-
55
- return self.client.get(f"{self.base_path}/usage", params=params)
53
+
54
+ return self.client.get(f"{self.base_path}/{project_id}/database/analytics/usage", params=params)
56
55
 
57
56
  def get_performance_metrics(
58
57
  self,
59
- project_id: Optional[str] = None,
58
+ project_id: str,
60
59
  metric_type: str = "all",
61
60
  ) -> Dict[str, Any]:
62
61
  """
63
62
  Get performance metrics.
64
-
63
+
65
64
  Args:
66
- project_id: Optional project ID filter
65
+ project_id: Project ID (required)
67
66
  metric_type: Type of metrics (latency, throughput, errors, all)
68
-
67
+
69
68
  Returns:
70
69
  Performance metrics data
71
70
  """
72
71
  params = {"metric_type": metric_type}
73
-
74
- if project_id:
75
- params["project_id"] = project_id
76
-
77
- return self.client.get(f"{self.base_path}/performance", params=params)
72
+
73
+ return self.client.get(f"{self.base_path}/{project_id}/database/analytics/performance", params=params)
78
74
 
79
75
  def get_storage_stats(
80
76
  self,
81
- project_id: Optional[str] = None,
77
+ project_id: str,
82
78
  ) -> Dict[str, Any]:
83
79
  """
84
80
  Get storage statistics.
85
-
81
+
86
82
  Args:
87
- project_id: Optional project ID filter
88
-
83
+ project_id: Project ID (required)
84
+
89
85
  Returns:
90
86
  Storage statistics including size, vector count, etc.
91
87
  """
92
- params = {}
93
- if project_id:
94
- params["project_id"] = project_id
95
-
96
- return self.client.get(f"{self.base_path}/storage", params=params)
88
+ return self.client.get(f"{self.base_path}/{project_id}/database/analytics/storage")
97
89
 
98
90
  def get_query_insights(
99
91
  self,
100
- project_id: Optional[str] = None,
92
+ project_id: str,
101
93
  limit: int = 100,
102
94
  ) -> Dict[str, Any]:
103
95
  """
104
96
  Get query pattern insights.
105
-
97
+
106
98
  Args:
107
- project_id: Optional project ID filter
99
+ project_id: Project ID (required)
108
100
  limit: Maximum number of insights
109
-
101
+
110
102
  Returns:
111
103
  Query insights and patterns
112
104
  """
113
105
  params = {"limit": limit}
114
-
115
- if project_id:
116
- params["project_id"] = project_id
117
-
118
- return self.client.get(f"{self.base_path}/queries", params=params)
106
+
107
+ return self.client.get(f"{self.base_path}/{project_id}/database/analytics/queries", params=params)
119
108
 
120
109
  def get_cost_analysis(
121
110
  self,
122
- project_id: Optional[str] = None,
111
+ project_id: str,
123
112
  start_date: Optional[datetime] = None,
124
113
  end_date: Optional[datetime] = None,
125
114
  ) -> Dict[str, Any]:
126
115
  """
127
116
  Get cost analysis and projections.
128
-
117
+
129
118
  Args:
130
- project_id: Optional project ID filter
119
+ project_id: Project ID (required)
131
120
  start_date: Start date for analysis
132
121
  end_date: End date for analysis
133
-
122
+
134
123
  Returns:
135
124
  Cost analysis data
136
125
  """
137
126
  params = {}
138
-
139
- if project_id:
140
- params["project_id"] = project_id
127
+
141
128
  if start_date:
142
129
  params["start_date"] = start_date.isoformat()
143
130
  if end_date:
144
131
  params["end_date"] = end_date.isoformat()
145
-
146
- return self.client.get(f"{self.base_path}/costs", params=params)
132
+
133
+ return self.client.get(f"{self.base_path}/{project_id}/database/analytics/costs", params=params)
147
134
 
148
135
  def get_trends(
149
136
  self,
137
+ project_id: str,
150
138
  metric: str,
151
- project_id: Optional[str] = None,
152
139
  period: int = 30,
153
140
  ) -> List[Dict[str, Any]]:
154
141
  """
155
142
  Get trend data for specific metrics.
156
-
143
+
157
144
  Args:
145
+ project_id: Project ID (required)
158
146
  metric: Metric name (vectors, queries, storage, errors)
159
- project_id: Optional project ID filter
160
147
  period: Number of days to analyze
161
-
148
+
162
149
  Returns:
163
150
  Trend data points
164
151
  """
@@ -166,54 +153,48 @@ class AnalyticsClient:
166
153
  "metric": metric,
167
154
  "period": period,
168
155
  }
169
-
170
- if project_id:
171
- params["project_id"] = project_id
172
-
173
- response = self.client.get(f"{self.base_path}/trends", params=params)
156
+
157
+ response = self.client.get(f"{self.base_path}/{project_id}/database/analytics/trends", params=params)
174
158
  return response.get("data", [])
175
159
 
176
160
  def get_anomalies(
177
161
  self,
178
- project_id: Optional[str] = None,
162
+ project_id: str,
179
163
  severity: str = "all",
180
164
  ) -> List[Dict[str, Any]]:
181
165
  """
182
166
  Get detected anomalies in usage patterns.
183
-
167
+
184
168
  Args:
185
- project_id: Optional project ID filter
169
+ project_id: Project ID (required)
186
170
  severity: Severity filter (low, medium, high, critical, all)
187
-
171
+
188
172
  Returns:
189
173
  List of detected anomalies
190
174
  """
191
175
  params = {"severity": severity}
192
-
193
- if project_id:
194
- params["project_id"] = project_id
195
-
196
- response = self.client.get(f"{self.base_path}/anomalies", params=params)
176
+
177
+ response = self.client.get(f"{self.base_path}/{project_id}/database/analytics/anomalies", params=params)
197
178
  return response.get("anomalies", [])
198
179
 
199
180
  def export_report(
200
181
  self,
182
+ project_id: str,
201
183
  report_type: str = "summary",
202
- project_id: Optional[str] = None,
203
184
  format: str = "json",
204
185
  start_date: Optional[datetime] = None,
205
186
  end_date: Optional[datetime] = None,
206
187
  ) -> Dict[str, Any]:
207
188
  """
208
189
  Export analytics report.
209
-
190
+
210
191
  Args:
192
+ project_id: Project ID (required)
211
193
  report_type: Type of report (summary, detailed, custom)
212
- project_id: Optional project ID filter
213
194
  format: Export format (json, csv, pdf)
214
195
  start_date: Start date for report
215
196
  end_date: End date for report
216
-
197
+
217
198
  Returns:
218
199
  Report data or download URL
219
200
  """
@@ -221,12 +202,10 @@ class AnalyticsClient:
221
202
  "report_type": report_type,
222
203
  "format": format,
223
204
  }
224
-
225
- if project_id:
226
- data["project_id"] = project_id
205
+
227
206
  if start_date:
228
207
  data["start_date"] = start_date.isoformat()
229
208
  if end_date:
230
209
  data["end_date"] = end_date.isoformat()
231
-
232
- return self.client.post(f"{self.base_path}/export", data=data)
210
+
211
+ return self.client.post(f"{self.base_path}/{project_id}/database/analytics/export", data=data)
@@ -26,39 +26,46 @@ class MemoryClient:
26
26
  def __init__(self, client: "AINativeClient"):
27
27
  """
28
28
  Initialize memory client.
29
-
29
+
30
30
  Args:
31
31
  client: Parent AINative client instance
32
32
  """
33
33
  self.client = client
34
- self.base_path = "/zerodb/memory"
34
+ self.base_path = "/projects"
35
35
 
36
36
  def create(
37
37
  self,
38
+ project_id: str,
38
39
  content: str,
39
40
  title: Optional[str] = None,
40
41
  tags: Optional[List[str]] = None,
41
42
  priority: MemoryPriority = MemoryPriority.MEDIUM,
42
43
  metadata: Optional[Dict[str, Any]] = None,
43
- project_id: Optional[str] = None,
44
44
  user_id: Optional[str] = None,
45
45
  expires_at: Optional[datetime] = None,
46
46
  ) -> Dict[str, Any]:
47
47
  """
48
48
  Create a new memory entry.
49
-
49
+
50
50
  Args:
51
+ project_id: Project ID (required)
51
52
  content: Memory content
52
53
  title: Memory title
53
54
  tags: List of tags
54
55
  priority: Memory priority level
55
56
  metadata: Additional metadata
56
- project_id: Associated project ID
57
57
  user_id: Associated user ID
58
58
  expires_at: Expiration timestamp
59
-
59
+
60
60
  Returns:
61
61
  Created memory details
62
+
63
+ Example:
64
+ >>> memory = client.zerodb.memory.create(
65
+ ... PROJECT_ID,
66
+ ... content="User prefers dark mode",
67
+ ... tags=["preferences", "ui"]
68
+ ... )
62
69
  """
63
70
  data = {
64
71
  "content": content,
@@ -67,21 +74,19 @@ class MemoryClient:
67
74
  "priority": priority.value,
68
75
  "metadata": metadata or {},
69
76
  }
70
-
71
- if project_id:
72
- data["project_id"] = project_id
77
+
73
78
  if user_id:
74
79
  data["user_id"] = user_id
75
80
  if expires_at:
76
81
  data["expires_at"] = expires_at.isoformat()
77
-
78
- return self.client.post(self.base_path, data=data)
82
+
83
+ return self.client.post(f"{self.base_path}/{project_id}/database/memory", data=data)
79
84
 
80
85
  def list(
81
86
  self,
87
+ project_id: str,
82
88
  limit: int = 100,
83
89
  offset: int = 0,
84
- project_id: Optional[str] = None,
85
90
  user_id: Optional[str] = None,
86
91
  tags: Optional[List[str]] = None,
87
92
  priority: Optional[MemoryPriority] = None,
@@ -89,26 +94,27 @@ class MemoryClient:
89
94
  ) -> Dict[str, Any]:
90
95
  """
91
96
  List memory entries.
92
-
97
+
93
98
  Args:
99
+ project_id: Project ID (required)
94
100
  limit: Maximum number of entries to return
95
101
  offset: Number of entries to skip
96
- project_id: Filter by project ID
97
102
  user_id: Filter by user ID
98
103
  tags: Filter by tags
99
104
  priority: Filter by priority
100
105
  search: Search query
101
-
106
+
102
107
  Returns:
103
108
  Dictionary containing memories list and pagination info
109
+
110
+ Example:
111
+ >>> memories = client.zerodb.memory.list(PROJECT_ID, limit=50)
104
112
  """
105
113
  params = {
106
114
  "limit": limit,
107
115
  "offset": offset,
108
116
  }
109
-
110
- if project_id:
111
- params["project_id"] = project_id
117
+
112
118
  if user_id:
113
119
  params["user_id"] = user_id
114
120
  if tags:
@@ -117,23 +123,25 @@ class MemoryClient:
117
123
  params["priority"] = priority.value
118
124
  if search:
119
125
  params["search"] = search
120
-
121
- return self.client.get(f"{self.base_path}ies", params=params)
126
+
127
+ return self.client.get(f"{self.base_path}/{project_id}/database/memory", params=params)
122
128
 
123
- def get(self, memory_id: str) -> Dict[str, Any]:
129
+ def get(self, project_id: str, memory_id: str) -> Dict[str, Any]:
124
130
  """
125
131
  Get a specific memory entry.
126
-
132
+
127
133
  Args:
134
+ project_id: Project ID (required)
128
135
  memory_id: Memory ID
129
-
136
+
130
137
  Returns:
131
138
  Memory details
132
139
  """
133
- return self.client.get(f"{self.base_path}/{memory_id}")
140
+ return self.client.get(f"{self.base_path}/{project_id}/database/memory/{memory_id}")
134
141
 
135
142
  def update(
136
143
  self,
144
+ project_id: str,
137
145
  memory_id: str,
138
146
  content: Optional[str] = None,
139
147
  title: Optional[str] = None,
@@ -143,15 +151,16 @@ class MemoryClient:
143
151
  ) -> Dict[str, Any]:
144
152
  """
145
153
  Update a memory entry.
146
-
154
+
147
155
  Args:
156
+ project_id: Project ID (required)
148
157
  memory_id: Memory ID
149
158
  content: New content
150
159
  title: New title
151
160
  tags: New tags
152
161
  priority: New priority
153
162
  metadata: New metadata
154
-
163
+
155
164
  Returns:
156
165
  Updated memory details
157
166
  """
@@ -166,95 +175,100 @@ class MemoryClient:
166
175
  data["priority"] = priority.value
167
176
  if metadata is not None:
168
177
  data["metadata"] = metadata
169
-
170
- return self.client.patch(f"{self.base_path}/{memory_id}", data=data)
178
+
179
+ return self.client.patch(f"{self.base_path}/{project_id}/database/memory/{memory_id}", data=data)
171
180
 
172
- def delete(self, memory_id: str) -> Dict[str, Any]:
181
+ def delete(self, project_id: str, memory_id: str) -> Dict[str, Any]:
173
182
  """
174
183
  Delete a memory entry.
175
-
184
+
176
185
  Args:
186
+ project_id: Project ID (required)
177
187
  memory_id: Memory ID
178
-
188
+
179
189
  Returns:
180
190
  Deletion confirmation
181
191
  """
182
- return self.client.delete(f"{self.base_path}/{memory_id}")
192
+ return self.client.delete(f"{self.base_path}/{project_id}/database/memory/{memory_id}")
183
193
 
184
194
  def search(
185
195
  self,
196
+ project_id: str,
186
197
  query: str,
187
198
  limit: int = 10,
188
- project_id: Optional[str] = None,
189
199
  user_id: Optional[str] = None,
190
200
  semantic: bool = True,
191
201
  ) -> List[Dict[str, Any]]:
192
202
  """
193
203
  Search memories using text or semantic search.
194
-
204
+
195
205
  Args:
206
+ project_id: Project ID (required)
196
207
  query: Search query
197
208
  limit: Maximum number of results
198
- project_id: Filter by project ID
199
209
  user_id: Filter by user ID
200
210
  semantic: Use semantic search (if False, uses text search)
201
-
211
+
202
212
  Returns:
203
213
  List of matching memories
214
+
215
+ Example:
216
+ >>> results = client.zerodb.memory.search(
217
+ ... PROJECT_ID,
218
+ ... query="What does user prefer?",
219
+ ... top_k=5
220
+ ... )
204
221
  """
205
222
  data = {
206
223
  "query": query,
207
224
  "limit": limit,
208
225
  "semantic": semantic,
209
226
  }
210
-
211
- if project_id:
212
- data["project_id"] = project_id
227
+
213
228
  if user_id:
214
229
  data["user_id"] = user_id
215
-
216
- response = self.client.post(f"{self.base_path}/search", data=data)
230
+
231
+ response = self.client.post(f"{self.base_path}/{project_id}/database/memory/search", data=data)
217
232
  return response.get("results", [])
218
233
 
219
234
  def bulk_create(
220
235
  self,
236
+ project_id: str,
221
237
  memories: List[Dict[str, Any]],
222
- project_id: Optional[str] = None,
223
238
  ) -> Dict[str, Any]:
224
239
  """
225
240
  Create multiple memory entries at once.
226
-
241
+
227
242
  Args:
243
+ project_id: Project ID (required)
228
244
  memories: List of memory data dictionaries
229
- project_id: Project ID for all memories
230
-
245
+
231
246
  Returns:
232
247
  Bulk creation result
233
248
  """
234
249
  data = {
235
250
  "memories": memories,
236
251
  }
237
-
238
- if project_id:
239
- data["project_id"] = project_id
240
-
241
- return self.client.post(f"{self.base_path}/bulk", data=data)
252
+
253
+ return self.client.post(f"{self.base_path}/{project_id}/database/memory/bulk", data=data)
242
254
 
243
255
  def get_related(
244
256
  self,
257
+ project_id: str,
245
258
  memory_id: str,
246
259
  limit: int = 5,
247
260
  ) -> List[Dict[str, Any]]:
248
261
  """
249
262
  Get memories related to a specific memory.
250
-
263
+
251
264
  Args:
265
+ project_id: Project ID (required)
252
266
  memory_id: Memory ID
253
267
  limit: Maximum number of related memories
254
-
268
+
255
269
  Returns:
256
270
  List of related memories
257
271
  """
258
272
  params = {"limit": limit}
259
- response = self.client.get(f"{self.base_path}/{memory_id}/related", params=params)
273
+ response = self.client.get(f"{self.base_path}/{project_id}/database/memory/{memory_id}/related", params=params)
260
274
  return response.get("memories", [])
@@ -26,12 +26,12 @@ class ProjectsClient:
26
26
  def __init__(self, client: "AINativeClient"):
27
27
  """
28
28
  Initialize projects client.
29
-
29
+
30
30
  Args:
31
31
  client: Parent AINative client instance
32
32
  """
33
33
  self.client = client
34
- self.base_path = "/zerodb/projects"
34
+ self.base_path = "/projects"
35
35
 
36
36
  def list(
37
37
  self,