daita-agents 0.1.0__py3-none-any.whl
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.
Potentially problematic release.
This version of daita-agents might be problematic. Click here for more details.
- daita/__init__.py +208 -0
- daita/agents/__init__.py +33 -0
- daita/agents/base.py +722 -0
- daita/agents/substrate.py +895 -0
- daita/cli/__init__.py +145 -0
- daita/cli/__main__.py +7 -0
- daita/cli/ascii_art.py +44 -0
- daita/cli/core/__init__.py +0 -0
- daita/cli/core/create.py +254 -0
- daita/cli/core/deploy.py +473 -0
- daita/cli/core/deployments.py +309 -0
- daita/cli/core/import_detector.py +219 -0
- daita/cli/core/init.py +382 -0
- daita/cli/core/logs.py +239 -0
- daita/cli/core/managed_deploy.py +709 -0
- daita/cli/core/run.py +648 -0
- daita/cli/core/status.py +421 -0
- daita/cli/core/test.py +239 -0
- daita/cli/core/webhooks.py +172 -0
- daita/cli/main.py +588 -0
- daita/cli/utils.py +541 -0
- daita/config/__init__.py +62 -0
- daita/config/base.py +159 -0
- daita/config/settings.py +184 -0
- daita/core/__init__.py +262 -0
- daita/core/decision_tracing.py +701 -0
- daita/core/exceptions.py +480 -0
- daita/core/focus.py +251 -0
- daita/core/interfaces.py +76 -0
- daita/core/plugin_tracing.py +550 -0
- daita/core/relay.py +695 -0
- daita/core/reliability.py +381 -0
- daita/core/scaling.py +444 -0
- daita/core/tools.py +402 -0
- daita/core/tracing.py +770 -0
- daita/core/workflow.py +1084 -0
- daita/display/__init__.py +1 -0
- daita/display/console.py +160 -0
- daita/execution/__init__.py +58 -0
- daita/execution/client.py +856 -0
- daita/execution/exceptions.py +92 -0
- daita/execution/models.py +317 -0
- daita/llm/__init__.py +60 -0
- daita/llm/anthropic.py +166 -0
- daita/llm/base.py +373 -0
- daita/llm/factory.py +101 -0
- daita/llm/gemini.py +152 -0
- daita/llm/grok.py +114 -0
- daita/llm/mock.py +135 -0
- daita/llm/openai.py +109 -0
- daita/plugins/__init__.py +141 -0
- daita/plugins/base.py +37 -0
- daita/plugins/base_db.py +167 -0
- daita/plugins/elasticsearch.py +844 -0
- daita/plugins/mcp.py +481 -0
- daita/plugins/mongodb.py +510 -0
- daita/plugins/mysql.py +351 -0
- daita/plugins/postgresql.py +331 -0
- daita/plugins/redis_messaging.py +500 -0
- daita/plugins/rest.py +529 -0
- daita/plugins/s3.py +761 -0
- daita/plugins/slack.py +729 -0
- daita/utils/__init__.py +18 -0
- daita_agents-0.1.0.dist-info/METADATA +350 -0
- daita_agents-0.1.0.dist-info/RECORD +69 -0
- daita_agents-0.1.0.dist-info/WHEEL +5 -0
- daita_agents-0.1.0.dist-info/entry_points.txt +2 -0
- daita_agents-0.1.0.dist-info/licenses/LICENSE +56 -0
- daita_agents-0.1.0.dist-info/top_level.txt +1 -0
daita/plugins/mongodb.py
ADDED
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MongoDB plugin for Daita Agents.
|
|
3
|
+
|
|
4
|
+
Simple MongoDB connection and querying - no over-engineering.
|
|
5
|
+
"""
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Any, Dict, List, Optional, Union, TYPE_CHECKING
|
|
8
|
+
from .base_db import BaseDatabasePlugin
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ..core.tools import AgentTool
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
class MongoDBPlugin(BaseDatabasePlugin):
|
|
16
|
+
"""
|
|
17
|
+
MongoDB plugin for agents with standardized connection management.
|
|
18
|
+
|
|
19
|
+
Inherits common database functionality from BaseDatabasePlugin.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
host: str = "localhost",
|
|
25
|
+
port: int = 27017,
|
|
26
|
+
database: str = "",
|
|
27
|
+
username: Optional[str] = None,
|
|
28
|
+
password: Optional[str] = None,
|
|
29
|
+
connection_string: Optional[str] = None,
|
|
30
|
+
**kwargs
|
|
31
|
+
):
|
|
32
|
+
"""
|
|
33
|
+
Initialize MongoDB connection.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
host: MongoDB host
|
|
37
|
+
port: MongoDB port
|
|
38
|
+
database: Database name
|
|
39
|
+
username: Optional username
|
|
40
|
+
password: Optional password
|
|
41
|
+
connection_string: Full connection string (overrides individual params)
|
|
42
|
+
**kwargs: Additional motor configuration
|
|
43
|
+
"""
|
|
44
|
+
if connection_string:
|
|
45
|
+
self.connection_string = connection_string
|
|
46
|
+
else:
|
|
47
|
+
if username and password:
|
|
48
|
+
self.connection_string = f"mongodb://{username}:{password}@{host}:{port}/{database}"
|
|
49
|
+
else:
|
|
50
|
+
self.connection_string = f"mongodb://{host}:{port}/{database}"
|
|
51
|
+
|
|
52
|
+
self.database_name = database
|
|
53
|
+
|
|
54
|
+
self.client_config = {
|
|
55
|
+
'maxPoolSize': kwargs.get('max_pool_size', 10),
|
|
56
|
+
'minPoolSize': kwargs.get('min_pool_size', 1),
|
|
57
|
+
'serverSelectionTimeoutMS': kwargs.get('server_timeout', 30000),
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Initialize base class with all config
|
|
61
|
+
super().__init__(
|
|
62
|
+
host=host, port=port, database=database,
|
|
63
|
+
username=username, connection_string=connection_string,
|
|
64
|
+
**kwargs
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
logger.debug(f"MongoDB plugin configured for {host}:{port}/{database}")
|
|
68
|
+
|
|
69
|
+
async def connect(self):
|
|
70
|
+
"""Connect to MongoDB."""
|
|
71
|
+
if self._client is not None:
|
|
72
|
+
return # Already connected
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
import motor.motor_asyncio
|
|
76
|
+
|
|
77
|
+
self._client = motor.motor_asyncio.AsyncIOMotorClient(
|
|
78
|
+
self.connection_string,
|
|
79
|
+
**self.client_config
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Test connection
|
|
83
|
+
await self._client.admin.command('ping')
|
|
84
|
+
|
|
85
|
+
# Get database
|
|
86
|
+
self._db = self._client[self.database_name]
|
|
87
|
+
|
|
88
|
+
logger.info(f"Connected to MongoDB database '{self.database_name}'")
|
|
89
|
+
except ImportError:
|
|
90
|
+
self._handle_connection_error(
|
|
91
|
+
ImportError("motor not installed. Run: pip install motor"),
|
|
92
|
+
"connection"
|
|
93
|
+
)
|
|
94
|
+
except Exception as e:
|
|
95
|
+
self._handle_connection_error(e, "connection")
|
|
96
|
+
|
|
97
|
+
async def disconnect(self):
|
|
98
|
+
"""Disconnect from MongoDB."""
|
|
99
|
+
if self._client:
|
|
100
|
+
self._client.close()
|
|
101
|
+
self._client = None
|
|
102
|
+
self._db = None
|
|
103
|
+
logger.info("Disconnected from MongoDB")
|
|
104
|
+
|
|
105
|
+
async def find(
|
|
106
|
+
self,
|
|
107
|
+
collection: str,
|
|
108
|
+
filter_doc: Optional[Dict[str, Any]] = None,
|
|
109
|
+
limit: Optional[int] = None,
|
|
110
|
+
skip: Optional[int] = None,
|
|
111
|
+
sort: Optional[List[tuple]] = None
|
|
112
|
+
) -> List[Dict[str, Any]]:
|
|
113
|
+
"""
|
|
114
|
+
Find documents in a collection.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
collection: Collection name
|
|
118
|
+
filter_doc: Query filter (defaults to {} for all documents)
|
|
119
|
+
limit: Maximum number of documents to return
|
|
120
|
+
skip: Number of documents to skip
|
|
121
|
+
sort: Sort specification as list of (field, direction) tuples
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
List of documents
|
|
125
|
+
|
|
126
|
+
Example:
|
|
127
|
+
# Find all users
|
|
128
|
+
users = await db.find("users")
|
|
129
|
+
|
|
130
|
+
# Find users in a specific city
|
|
131
|
+
users = await db.find("users", {"city": "New York"})
|
|
132
|
+
|
|
133
|
+
# Find with pagination and sorting
|
|
134
|
+
users = await db.find("users",
|
|
135
|
+
filter_doc={"age": {"$gte": 18}},
|
|
136
|
+
sort=[("name", 1)],
|
|
137
|
+
limit=10,
|
|
138
|
+
skip=20)
|
|
139
|
+
"""
|
|
140
|
+
# Only auto-connect if client/db is None - allows manual mocking
|
|
141
|
+
if self._client is None or self._db is None:
|
|
142
|
+
await self.connect()
|
|
143
|
+
|
|
144
|
+
filter_doc = filter_doc or {}
|
|
145
|
+
|
|
146
|
+
cursor = self._db[collection].find(filter_doc)
|
|
147
|
+
|
|
148
|
+
# Apply cursor modifications - these return the cursor object
|
|
149
|
+
if sort:
|
|
150
|
+
cursor = cursor.sort(sort)
|
|
151
|
+
if skip:
|
|
152
|
+
cursor = cursor.skip(skip)
|
|
153
|
+
if limit:
|
|
154
|
+
cursor = cursor.limit(limit)
|
|
155
|
+
|
|
156
|
+
# Convert cursor to list and handle ObjectId
|
|
157
|
+
results = await cursor.to_list(length=None)
|
|
158
|
+
|
|
159
|
+
# Convert ObjectId to string for JSON serialization
|
|
160
|
+
for doc in results:
|
|
161
|
+
if '_id' in doc:
|
|
162
|
+
doc['_id'] = str(doc['_id'])
|
|
163
|
+
|
|
164
|
+
return results
|
|
165
|
+
|
|
166
|
+
async def insert(self, collection: str, document: Dict[str, Any]) -> str:
|
|
167
|
+
"""
|
|
168
|
+
Insert a single document.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
collection: Collection name
|
|
172
|
+
document: Document to insert
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
Inserted document ID as string
|
|
176
|
+
"""
|
|
177
|
+
# Only auto-connect if client/db is None - allows manual mocking
|
|
178
|
+
if self._client is None or self._db is None:
|
|
179
|
+
await self.connect()
|
|
180
|
+
|
|
181
|
+
result = await self._db[collection].insert_one(document)
|
|
182
|
+
return str(result.inserted_id)
|
|
183
|
+
|
|
184
|
+
async def insert_many(self, collection: str, documents: List[Dict[str, Any]]) -> List[str]:
|
|
185
|
+
"""
|
|
186
|
+
Insert multiple documents.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
collection: Collection name
|
|
190
|
+
documents: List of documents to insert
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
List of inserted document IDs as strings
|
|
194
|
+
"""
|
|
195
|
+
if not documents:
|
|
196
|
+
return []
|
|
197
|
+
|
|
198
|
+
# Only auto-connect if client/db is None - allows manual mocking
|
|
199
|
+
if self._client is None or self._db is None:
|
|
200
|
+
await self.connect()
|
|
201
|
+
|
|
202
|
+
result = await self._db[collection].insert_many(documents)
|
|
203
|
+
return [str(doc_id) for doc_id in result.inserted_ids]
|
|
204
|
+
|
|
205
|
+
async def update(
|
|
206
|
+
self,
|
|
207
|
+
collection: str,
|
|
208
|
+
filter_doc: Dict[str, Any],
|
|
209
|
+
update_doc: Dict[str, Any],
|
|
210
|
+
upsert: bool = False
|
|
211
|
+
) -> Dict[str, Any]:
|
|
212
|
+
"""
|
|
213
|
+
Update documents.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
collection: Collection name
|
|
217
|
+
filter_doc: Filter to match documents
|
|
218
|
+
update_doc: Update operations (use $set, $inc, etc.)
|
|
219
|
+
upsert: Create document if not found
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
Update result info
|
|
223
|
+
|
|
224
|
+
Example:
|
|
225
|
+
result = await db.update("users",
|
|
226
|
+
{"name": "John"},
|
|
227
|
+
{"$set": {"age": 30}})
|
|
228
|
+
"""
|
|
229
|
+
# Only auto-connect if client/db is None - allows manual mocking
|
|
230
|
+
if self._client is None or self._db is None:
|
|
231
|
+
await self.connect()
|
|
232
|
+
|
|
233
|
+
result = await self._db[collection].update_many(
|
|
234
|
+
filter_doc,
|
|
235
|
+
update_doc,
|
|
236
|
+
upsert=upsert
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
'matched_count': result.matched_count,
|
|
241
|
+
'modified_count': result.modified_count,
|
|
242
|
+
'upserted_id': str(result.upserted_id) if result.upserted_id else None
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async def delete(self, collection: str, filter_doc: Dict[str, Any]) -> int:
|
|
246
|
+
"""
|
|
247
|
+
Delete documents.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
collection: Collection name
|
|
251
|
+
filter_doc: Filter to match documents to delete
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
Number of deleted documents
|
|
255
|
+
"""
|
|
256
|
+
# Only auto-connect if client/db is None - allows manual mocking
|
|
257
|
+
if self._client is None or self._db is None:
|
|
258
|
+
await self.connect()
|
|
259
|
+
|
|
260
|
+
result = await self._db[collection].delete_many(filter_doc)
|
|
261
|
+
return result.deleted_count
|
|
262
|
+
|
|
263
|
+
async def count(self, collection: str, filter_doc: Optional[Dict[str, Any]] = None) -> int:
|
|
264
|
+
"""
|
|
265
|
+
Count documents in collection.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
collection: Collection name
|
|
269
|
+
filter_doc: Optional filter
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
Document count
|
|
273
|
+
"""
|
|
274
|
+
# Only auto-connect if client/db is None - allows manual mocking
|
|
275
|
+
if self._client is None or self._db is None:
|
|
276
|
+
await self.connect()
|
|
277
|
+
|
|
278
|
+
filter_doc = filter_doc or {}
|
|
279
|
+
return await self._db[collection].count_documents(filter_doc)
|
|
280
|
+
|
|
281
|
+
async def collections(self) -> List[str]:
|
|
282
|
+
"""List all collections in the database."""
|
|
283
|
+
# Only auto-connect if client/db is None - allows manual mocking
|
|
284
|
+
if self._client is None or self._db is None:
|
|
285
|
+
await self.connect()
|
|
286
|
+
|
|
287
|
+
collections = await self._db.list_collection_names()
|
|
288
|
+
return sorted(collections)
|
|
289
|
+
|
|
290
|
+
async def aggregate(self, collection: str, pipeline: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
291
|
+
"""
|
|
292
|
+
Run aggregation pipeline.
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
collection: Collection name
|
|
296
|
+
pipeline: Aggregation pipeline
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
Aggregation results
|
|
300
|
+
|
|
301
|
+
Example:
|
|
302
|
+
pipeline = [
|
|
303
|
+
{"$match": {"status": "active"}},
|
|
304
|
+
{"$group": {"_id": "$department", "count": {"$sum": 1}}}
|
|
305
|
+
]
|
|
306
|
+
results = await db.aggregate("employees", pipeline)
|
|
307
|
+
"""
|
|
308
|
+
# Only auto-connect if client/db is None - allows manual mocking
|
|
309
|
+
if self._client is None or self._db is None:
|
|
310
|
+
await self.connect()
|
|
311
|
+
|
|
312
|
+
cursor = self._db[collection].aggregate(pipeline)
|
|
313
|
+
results = await cursor.to_list(length=None)
|
|
314
|
+
|
|
315
|
+
# Convert ObjectId to string
|
|
316
|
+
for doc in results:
|
|
317
|
+
if '_id' in doc and hasattr(doc['_id'], 'binary'):
|
|
318
|
+
doc['_id'] = str(doc['_id'])
|
|
319
|
+
|
|
320
|
+
return results
|
|
321
|
+
|
|
322
|
+
def get_tools(self) -> List['AgentTool']:
|
|
323
|
+
"""
|
|
324
|
+
Expose MongoDB operations as agent tools.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
List of AgentTool instances for database operations
|
|
328
|
+
"""
|
|
329
|
+
from ..core.tools import AgentTool
|
|
330
|
+
|
|
331
|
+
return [
|
|
332
|
+
AgentTool(
|
|
333
|
+
name="find_documents",
|
|
334
|
+
description="Find documents in a MongoDB collection. Returns matching documents as a list.",
|
|
335
|
+
parameters={
|
|
336
|
+
"collection": {
|
|
337
|
+
"type": "string",
|
|
338
|
+
"description": "Collection name to search in",
|
|
339
|
+
"required": True
|
|
340
|
+
},
|
|
341
|
+
"filter": {
|
|
342
|
+
"type": "object",
|
|
343
|
+
"description": "MongoDB query filter (e.g., {\"status\": \"active\"}). Empty object {} matches all documents.",
|
|
344
|
+
"required": False
|
|
345
|
+
},
|
|
346
|
+
"limit": {
|
|
347
|
+
"type": "integer",
|
|
348
|
+
"description": "Maximum number of documents to return",
|
|
349
|
+
"required": False
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
handler=self._tool_find,
|
|
353
|
+
category="database",
|
|
354
|
+
source="plugin",
|
|
355
|
+
plugin_name="MongoDB",
|
|
356
|
+
timeout_seconds=60
|
|
357
|
+
),
|
|
358
|
+
AgentTool(
|
|
359
|
+
name="insert_document",
|
|
360
|
+
description="Insert a single document into a MongoDB collection. Returns the inserted document ID.",
|
|
361
|
+
parameters={
|
|
362
|
+
"collection": {
|
|
363
|
+
"type": "string",
|
|
364
|
+
"description": "Collection name to insert into",
|
|
365
|
+
"required": True
|
|
366
|
+
},
|
|
367
|
+
"document": {
|
|
368
|
+
"type": "object",
|
|
369
|
+
"description": "Document data to insert as JSON object",
|
|
370
|
+
"required": True
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
handler=self._tool_insert,
|
|
374
|
+
category="database",
|
|
375
|
+
source="plugin",
|
|
376
|
+
plugin_name="MongoDB",
|
|
377
|
+
timeout_seconds=30
|
|
378
|
+
),
|
|
379
|
+
AgentTool(
|
|
380
|
+
name="update_documents",
|
|
381
|
+
description="Update documents in a MongoDB collection. Returns the count of matched and modified documents.",
|
|
382
|
+
parameters={
|
|
383
|
+
"collection": {
|
|
384
|
+
"type": "string",
|
|
385
|
+
"description": "Collection name",
|
|
386
|
+
"required": True
|
|
387
|
+
},
|
|
388
|
+
"filter": {
|
|
389
|
+
"type": "object",
|
|
390
|
+
"description": "Query filter to match documents to update",
|
|
391
|
+
"required": True
|
|
392
|
+
},
|
|
393
|
+
"update": {
|
|
394
|
+
"type": "object",
|
|
395
|
+
"description": "Update operations (e.g., {\"$set\": {\"status\": \"completed\"}})",
|
|
396
|
+
"required": True
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
handler=self._tool_update,
|
|
400
|
+
category="database",
|
|
401
|
+
source="plugin",
|
|
402
|
+
plugin_name="MongoDB",
|
|
403
|
+
timeout_seconds=60
|
|
404
|
+
),
|
|
405
|
+
AgentTool(
|
|
406
|
+
name="delete_documents",
|
|
407
|
+
description="Delete documents from a MongoDB collection. Returns the count of deleted documents.",
|
|
408
|
+
parameters={
|
|
409
|
+
"collection": {
|
|
410
|
+
"type": "string",
|
|
411
|
+
"description": "Collection name",
|
|
412
|
+
"required": True
|
|
413
|
+
},
|
|
414
|
+
"filter": {
|
|
415
|
+
"type": "object",
|
|
416
|
+
"description": "Query filter to match documents to delete",
|
|
417
|
+
"required": True
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
handler=self._tool_delete,
|
|
421
|
+
category="database",
|
|
422
|
+
source="plugin",
|
|
423
|
+
plugin_name="MongoDB",
|
|
424
|
+
timeout_seconds=60
|
|
425
|
+
),
|
|
426
|
+
AgentTool(
|
|
427
|
+
name="list_collections",
|
|
428
|
+
description="List all collections in the MongoDB database",
|
|
429
|
+
parameters={},
|
|
430
|
+
handler=self._tool_list_collections,
|
|
431
|
+
category="database",
|
|
432
|
+
source="plugin",
|
|
433
|
+
plugin_name="MongoDB",
|
|
434
|
+
timeout_seconds=30
|
|
435
|
+
)
|
|
436
|
+
]
|
|
437
|
+
|
|
438
|
+
async def _tool_find(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
439
|
+
"""Tool handler for find_documents"""
|
|
440
|
+
collection = args.get("collection")
|
|
441
|
+
filter_doc = args.get("filter", {})
|
|
442
|
+
limit = args.get("limit")
|
|
443
|
+
|
|
444
|
+
results = await self.find(
|
|
445
|
+
collection=collection,
|
|
446
|
+
filter_doc=filter_doc,
|
|
447
|
+
limit=limit
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
return {
|
|
451
|
+
"success": True,
|
|
452
|
+
"documents": results,
|
|
453
|
+
"count": len(results)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
async def _tool_insert(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
457
|
+
"""Tool handler for insert_document"""
|
|
458
|
+
collection = args.get("collection")
|
|
459
|
+
document = args.get("document")
|
|
460
|
+
|
|
461
|
+
inserted_id = await self.insert(collection, document)
|
|
462
|
+
|
|
463
|
+
return {
|
|
464
|
+
"success": True,
|
|
465
|
+
"inserted_id": inserted_id,
|
|
466
|
+
"collection": collection
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
async def _tool_update(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
470
|
+
"""Tool handler for update_documents"""
|
|
471
|
+
collection = args.get("collection")
|
|
472
|
+
filter_doc = args.get("filter")
|
|
473
|
+
update_doc = args.get("update")
|
|
474
|
+
|
|
475
|
+
result = await self.update(collection, filter_doc, update_doc)
|
|
476
|
+
|
|
477
|
+
return {
|
|
478
|
+
"success": True,
|
|
479
|
+
"matched_count": result["matched_count"],
|
|
480
|
+
"modified_count": result["modified_count"],
|
|
481
|
+
"collection": collection
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
async def _tool_delete(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
485
|
+
"""Tool handler for delete_documents"""
|
|
486
|
+
collection = args.get("collection")
|
|
487
|
+
filter_doc = args.get("filter")
|
|
488
|
+
|
|
489
|
+
deleted_count = await self.delete(collection, filter_doc)
|
|
490
|
+
|
|
491
|
+
return {
|
|
492
|
+
"success": True,
|
|
493
|
+
"deleted_count": deleted_count,
|
|
494
|
+
"collection": collection
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
async def _tool_list_collections(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
498
|
+
"""Tool handler for list_collections"""
|
|
499
|
+
collections = await self.collections()
|
|
500
|
+
|
|
501
|
+
return {
|
|
502
|
+
"success": True,
|
|
503
|
+
"collections": collections,
|
|
504
|
+
"count": len(collections)
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
def mongodb(**kwargs) -> MongoDBPlugin:
|
|
509
|
+
"""Create MongoDB plugin with simplified interface."""
|
|
510
|
+
return MongoDBPlugin(**kwargs)
|