kailash 0.6.3__py3-none-any.whl → 0.6.5__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.
- kailash/__init__.py +3 -3
- kailash/api/custom_nodes_secure.py +3 -3
- kailash/api/gateway.py +1 -1
- kailash/api/studio.py +1 -1
- kailash/api/workflow_api.py +2 -2
- kailash/core/resilience/bulkhead.py +475 -0
- kailash/core/resilience/circuit_breaker.py +92 -10
- kailash/core/resilience/health_monitor.py +578 -0
- kailash/edge/discovery.py +86 -0
- kailash/mcp_server/__init__.py +309 -33
- kailash/mcp_server/advanced_features.py +1022 -0
- kailash/mcp_server/ai_registry_server.py +27 -2
- kailash/mcp_server/auth.py +789 -0
- kailash/mcp_server/client.py +645 -378
- kailash/mcp_server/discovery.py +1593 -0
- kailash/mcp_server/errors.py +673 -0
- kailash/mcp_server/oauth.py +1727 -0
- kailash/mcp_server/protocol.py +1126 -0
- kailash/mcp_server/registry_integration.py +587 -0
- kailash/mcp_server/server.py +1228 -96
- kailash/mcp_server/transports.py +1169 -0
- kailash/mcp_server/utils/__init__.py +6 -1
- kailash/mcp_server/utils/cache.py +250 -7
- kailash/middleware/auth/auth_manager.py +3 -3
- kailash/middleware/communication/api_gateway.py +1 -1
- kailash/middleware/communication/realtime.py +1 -1
- kailash/middleware/mcp/enhanced_server.py +1 -1
- kailash/nodes/__init__.py +2 -0
- kailash/nodes/admin/audit_log.py +6 -6
- kailash/nodes/admin/permission_check.py +8 -8
- kailash/nodes/admin/role_management.py +32 -28
- kailash/nodes/admin/schema.sql +6 -1
- kailash/nodes/admin/schema_manager.py +13 -13
- kailash/nodes/admin/security_event.py +15 -15
- kailash/nodes/admin/tenant_isolation.py +3 -3
- kailash/nodes/admin/transaction_utils.py +3 -3
- kailash/nodes/admin/user_management.py +21 -21
- kailash/nodes/ai/a2a.py +11 -11
- kailash/nodes/ai/ai_providers.py +9 -12
- kailash/nodes/ai/embedding_generator.py +13 -14
- kailash/nodes/ai/intelligent_agent_orchestrator.py +19 -19
- kailash/nodes/ai/iterative_llm_agent.py +2 -2
- kailash/nodes/ai/llm_agent.py +210 -33
- kailash/nodes/ai/self_organizing.py +2 -2
- kailash/nodes/alerts/discord.py +4 -4
- kailash/nodes/api/graphql.py +6 -6
- kailash/nodes/api/http.py +10 -10
- kailash/nodes/api/rate_limiting.py +4 -4
- kailash/nodes/api/rest.py +15 -15
- kailash/nodes/auth/mfa.py +3 -3
- kailash/nodes/auth/risk_assessment.py +2 -2
- kailash/nodes/auth/session_management.py +5 -5
- kailash/nodes/auth/sso.py +143 -0
- kailash/nodes/base.py +8 -2
- kailash/nodes/base_async.py +16 -2
- kailash/nodes/base_with_acl.py +2 -2
- kailash/nodes/cache/__init__.py +9 -0
- kailash/nodes/cache/cache.py +1172 -0
- kailash/nodes/cache/cache_invalidation.py +874 -0
- kailash/nodes/cache/redis_pool_manager.py +595 -0
- kailash/nodes/code/async_python.py +2 -1
- kailash/nodes/code/python.py +194 -30
- kailash/nodes/compliance/data_retention.py +6 -6
- kailash/nodes/compliance/gdpr.py +5 -5
- kailash/nodes/data/__init__.py +10 -0
- kailash/nodes/data/async_sql.py +1956 -129
- kailash/nodes/data/optimistic_locking.py +906 -0
- kailash/nodes/data/readers.py +8 -8
- kailash/nodes/data/redis.py +378 -0
- kailash/nodes/data/sql.py +314 -3
- kailash/nodes/data/streaming.py +21 -0
- kailash/nodes/enterprise/__init__.py +8 -0
- kailash/nodes/enterprise/audit_logger.py +285 -0
- kailash/nodes/enterprise/batch_processor.py +22 -3
- kailash/nodes/enterprise/data_lineage.py +1 -1
- kailash/nodes/enterprise/mcp_executor.py +205 -0
- kailash/nodes/enterprise/service_discovery.py +150 -0
- kailash/nodes/enterprise/tenant_assignment.py +108 -0
- kailash/nodes/logic/async_operations.py +2 -2
- kailash/nodes/logic/convergence.py +1 -1
- kailash/nodes/logic/operations.py +1 -1
- kailash/nodes/monitoring/__init__.py +11 -1
- kailash/nodes/monitoring/health_check.py +456 -0
- kailash/nodes/monitoring/log_processor.py +817 -0
- kailash/nodes/monitoring/metrics_collector.py +627 -0
- kailash/nodes/monitoring/performance_benchmark.py +137 -11
- kailash/nodes/rag/advanced.py +7 -7
- kailash/nodes/rag/agentic.py +49 -2
- kailash/nodes/rag/conversational.py +3 -3
- kailash/nodes/rag/evaluation.py +3 -3
- kailash/nodes/rag/federated.py +3 -3
- kailash/nodes/rag/graph.py +3 -3
- kailash/nodes/rag/multimodal.py +3 -3
- kailash/nodes/rag/optimized.py +5 -5
- kailash/nodes/rag/privacy.py +3 -3
- kailash/nodes/rag/query_processing.py +6 -6
- kailash/nodes/rag/realtime.py +1 -1
- kailash/nodes/rag/registry.py +1 -1
- kailash/nodes/rag/router.py +1 -1
- kailash/nodes/rag/similarity.py +7 -7
- kailash/nodes/rag/strategies.py +4 -4
- kailash/nodes/security/abac_evaluator.py +6 -6
- kailash/nodes/security/behavior_analysis.py +5 -5
- kailash/nodes/security/credential_manager.py +1 -1
- kailash/nodes/security/rotating_credentials.py +11 -11
- kailash/nodes/security/threat_detection.py +8 -8
- kailash/nodes/testing/credential_testing.py +2 -2
- kailash/nodes/transform/processors.py +5 -5
- kailash/runtime/local.py +163 -9
- kailash/runtime/parameter_injection.py +425 -0
- kailash/runtime/parameter_injector.py +657 -0
- kailash/runtime/testing.py +2 -2
- kailash/testing/fixtures.py +2 -2
- kailash/workflow/builder.py +99 -14
- kailash/workflow/builder_improvements.py +207 -0
- kailash/workflow/input_handling.py +170 -0
- {kailash-0.6.3.dist-info → kailash-0.6.5.dist-info}/METADATA +22 -9
- {kailash-0.6.3.dist-info → kailash-0.6.5.dist-info}/RECORD +122 -95
- {kailash-0.6.3.dist-info → kailash-0.6.5.dist-info}/WHEEL +0 -0
- {kailash-0.6.3.dist-info → kailash-0.6.5.dist-info}/entry_points.txt +0 -0
- {kailash-0.6.3.dist-info → kailash-0.6.5.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.6.3.dist-info → kailash-0.6.5.dist-info}/top_level.txt +0 -0
@@ -208,7 +208,7 @@ class UserManagementNode(Node):
|
|
208
208
|
... },
|
209
209
|
... tenant_id="company"
|
210
210
|
... )
|
211
|
-
>>> result = node.
|
211
|
+
>>> result = node.execute()
|
212
212
|
>>> user_id = result["user"]["user_id"]
|
213
213
|
|
214
214
|
>>> # Update user profile
|
@@ -221,7 +221,7 @@ class UserManagementNode(Node):
|
|
221
221
|
... },
|
222
222
|
... tenant_id="company"
|
223
223
|
... )
|
224
|
-
>>> result = node.
|
224
|
+
>>> result = node.execute()
|
225
225
|
|
226
226
|
>>> # Bulk create users
|
227
227
|
>>> node = UserManagementNode(
|
@@ -232,7 +232,7 @@ class UserManagementNode(Node):
|
|
232
232
|
... ],
|
233
233
|
... tenant_id="company"
|
234
234
|
... )
|
235
|
-
>>> result = node.
|
235
|
+
>>> result = node.execute()
|
236
236
|
>>> created_count = result["bulk_result"]["created_count"]
|
237
237
|
"""
|
238
238
|
|
@@ -511,7 +511,7 @@ class UserManagementNode(Node):
|
|
511
511
|
"""
|
512
512
|
|
513
513
|
try:
|
514
|
-
self._db_node.
|
514
|
+
self._db_node.execute(
|
515
515
|
query=insert_query,
|
516
516
|
parameters=[
|
517
517
|
user.user_id,
|
@@ -561,7 +561,7 @@ class UserManagementNode(Node):
|
|
561
561
|
WHERE user_id = $1 AND tenant_id = $2
|
562
562
|
"""
|
563
563
|
|
564
|
-
result = self._db_node.
|
564
|
+
result = self._db_node.execute(
|
565
565
|
query=query, parameters=[user_id, tenant_id], result_format="dict"
|
566
566
|
)
|
567
567
|
|
@@ -624,7 +624,7 @@ class UserManagementNode(Node):
|
|
624
624
|
WHERE email = $1 AND tenant_id = $2
|
625
625
|
"""
|
626
626
|
|
627
|
-
result = self._db_node.
|
627
|
+
result = self._db_node.execute(
|
628
628
|
query=query, parameters=[email, tenant_id], result_format="dict"
|
629
629
|
)
|
630
630
|
|
@@ -661,7 +661,7 @@ class UserManagementNode(Node):
|
|
661
661
|
WHERE username = $1 AND tenant_id = $2
|
662
662
|
"""
|
663
663
|
|
664
|
-
result = self._db_node.
|
664
|
+
result = self._db_node.execute(
|
665
665
|
query=query, parameters=[username, tenant_id], result_format="dict"
|
666
666
|
)
|
667
667
|
|
@@ -751,7 +751,7 @@ class UserManagementNode(Node):
|
|
751
751
|
"""
|
752
752
|
|
753
753
|
try:
|
754
|
-
self._db_node.
|
754
|
+
self._db_node.execute(query=update_query, parameters=parameters)
|
755
755
|
|
756
756
|
# Get updated user
|
757
757
|
updated_user = self._get_user_by_id(user_id, tenant_id)
|
@@ -788,7 +788,7 @@ class UserManagementNode(Node):
|
|
788
788
|
"""
|
789
789
|
|
790
790
|
try:
|
791
|
-
self._db_node.
|
791
|
+
self._db_node.execute(query=delete_query, parameters=[user_id, tenant_id])
|
792
792
|
|
793
793
|
return {
|
794
794
|
"result": {
|
@@ -845,12 +845,12 @@ class UserManagementNode(Node):
|
|
845
845
|
|
846
846
|
try:
|
847
847
|
# Get users
|
848
|
-
result = self._db_node.
|
848
|
+
result = self._db_node.execute(
|
849
849
|
query=list_query, parameters=parameters, result_format="dict"
|
850
850
|
)
|
851
851
|
|
852
852
|
# Get total count
|
853
|
-
count_result = self._db_node.
|
853
|
+
count_result = self._db_node.execute(
|
854
854
|
query=count_query, parameters=parameters[:-2], result_format="dict"
|
855
855
|
)
|
856
856
|
|
@@ -920,7 +920,7 @@ class UserManagementNode(Node):
|
|
920
920
|
"""
|
921
921
|
|
922
922
|
try:
|
923
|
-
self._db_node.
|
923
|
+
self._db_node.execute(
|
924
924
|
query=update_query, parameters=[new_status.value, user_id, tenant_id]
|
925
925
|
)
|
926
926
|
|
@@ -952,7 +952,7 @@ class UserManagementNode(Node):
|
|
952
952
|
"""
|
953
953
|
|
954
954
|
try:
|
955
|
-
self._db_node.
|
955
|
+
self._db_node.execute(
|
956
956
|
query=update_query, parameters=[password_hash, user_id, tenant_id]
|
957
957
|
)
|
958
958
|
|
@@ -1141,7 +1141,7 @@ class UserManagementNode(Node):
|
|
1141
1141
|
WHERE role_id IN ({placeholders}) AND tenant_id = ${len(user.roles) + 1}
|
1142
1142
|
"""
|
1143
1143
|
|
1144
|
-
result = self._db_node.
|
1144
|
+
result = self._db_node.execute(
|
1145
1145
|
query=role_query,
|
1146
1146
|
parameters=user.roles + [tenant_id],
|
1147
1147
|
result_format="dict",
|
@@ -1207,7 +1207,7 @@ class UserManagementNode(Node):
|
|
1207
1207
|
search_pattern = f"%{search_query}%"
|
1208
1208
|
|
1209
1209
|
try:
|
1210
|
-
result = self._db_node.
|
1210
|
+
result = self._db_node.execute(
|
1211
1211
|
query=query,
|
1212
1212
|
parameters=[tenant_id, search_pattern, limit, offset],
|
1213
1213
|
result_format="dict",
|
@@ -1350,7 +1350,7 @@ class UserManagementNode(Node):
|
|
1350
1350
|
)
|
1351
1351
|
"""
|
1352
1352
|
|
1353
|
-
result = self._db_node.
|
1353
|
+
result = self._db_node.execute(
|
1354
1354
|
operation="execute",
|
1355
1355
|
query=store_token_query,
|
1356
1356
|
parameters={
|
@@ -1387,7 +1387,7 @@ class UserManagementNode(Node):
|
|
1387
1387
|
AND expires_at > CURRENT_TIMESTAMP
|
1388
1388
|
"""
|
1389
1389
|
|
1390
|
-
result = self._db_node.
|
1390
|
+
result = self._db_node.execute(
|
1391
1391
|
operation="query",
|
1392
1392
|
query=verify_query,
|
1393
1393
|
parameters={"token": token, "tenant_id": tenant_id},
|
@@ -1408,7 +1408,7 @@ class UserManagementNode(Node):
|
|
1408
1408
|
AND tenant_id = :tenant_id
|
1409
1409
|
"""
|
1410
1410
|
|
1411
|
-
update_result = self._db_node.
|
1411
|
+
update_result = self._db_node.execute(
|
1412
1412
|
operation="execute",
|
1413
1413
|
query=update_query,
|
1414
1414
|
parameters={
|
@@ -1424,7 +1424,7 @@ class UserManagementNode(Node):
|
|
1424
1424
|
WHERE session_id = :token
|
1425
1425
|
"""
|
1426
1426
|
|
1427
|
-
self._db_node.
|
1427
|
+
self._db_node.execute(
|
1428
1428
|
operation="execute", query=delete_token_query, parameters={"token": token}
|
1429
1429
|
)
|
1430
1430
|
|
@@ -1461,7 +1461,7 @@ class UserManagementNode(Node):
|
|
1461
1461
|
else:
|
1462
1462
|
raise NodeValidationError("Either username or email must be provided")
|
1463
1463
|
|
1464
|
-
result = self._db_node.
|
1464
|
+
result = self._db_node.execute(
|
1465
1465
|
operation="query", query=auth_query, parameters=params
|
1466
1466
|
)
|
1467
1467
|
|
@@ -1487,7 +1487,7 @@ class UserManagementNode(Node):
|
|
1487
1487
|
WHERE user_id = :user_id
|
1488
1488
|
"""
|
1489
1489
|
|
1490
|
-
self._db_node.
|
1490
|
+
self._db_node.execute(
|
1491
1491
|
operation="execute",
|
1492
1492
|
query=update_login_query,
|
1493
1493
|
parameters={"user_id": user_data["user_id"]},
|
kailash/nodes/ai/a2a.py
CHANGED
@@ -74,7 +74,7 @@ class SharedMemoryPoolNode(Node):
|
|
74
74
|
>>> memory_pool = SharedMemoryPoolNode()
|
75
75
|
>>>
|
76
76
|
>>> # Write memory from an agent
|
77
|
-
>>> result = memory_pool.
|
77
|
+
>>> result = memory_pool.execute(
|
78
78
|
... action="write",
|
79
79
|
... agent_id="researcher_001",
|
80
80
|
... content="Found correlation between X and Y",
|
@@ -86,7 +86,7 @@ class SharedMemoryPoolNode(Node):
|
|
86
86
|
>>> assert result["memory_id"] is not None
|
87
87
|
>>>
|
88
88
|
>>> # Read with attention filter
|
89
|
-
>>> memories = memory_pool.
|
89
|
+
>>> memories = memory_pool.execute(
|
90
90
|
... action="read",
|
91
91
|
... agent_id="analyst_001",
|
92
92
|
... attention_filter={
|
@@ -98,14 +98,14 @@ class SharedMemoryPoolNode(Node):
|
|
98
98
|
>>> assert len(memories["memories"]) > 0
|
99
99
|
>>>
|
100
100
|
>>> # Subscribe to specific segments
|
101
|
-
>>> memory_pool.
|
101
|
+
>>> memory_pool.execute(
|
102
102
|
... action="subscribe",
|
103
103
|
... agent_id="monitor_001",
|
104
104
|
... segments=["findings", "alerts"]
|
105
105
|
... )
|
106
106
|
>>>
|
107
107
|
>>> # Semantic query across all memories
|
108
|
-
>>> results = memory_pool.
|
108
|
+
>>> results = memory_pool.execute(
|
109
109
|
... action="query",
|
110
110
|
... query="correlation analysis",
|
111
111
|
... top_k=3
|
@@ -530,7 +530,7 @@ class A2AAgentNode(LLMAgentNode):
|
|
530
530
|
>>> agent = A2AAgentNode()
|
531
531
|
>>>
|
532
532
|
>>> # Execute with A2A features
|
533
|
-
>>> result = agent.
|
533
|
+
>>> result = agent.execute(
|
534
534
|
... agent_id="researcher_001",
|
535
535
|
... agent_role="research_specialist",
|
536
536
|
... provider="openai",
|
@@ -659,7 +659,7 @@ class A2AAgentNode(LLMAgentNode):
|
|
659
659
|
# Read from shared memory if available
|
660
660
|
shared_context = []
|
661
661
|
if memory_pool:
|
662
|
-
memory_result = memory_pool.
|
662
|
+
memory_result = memory_pool.execute(
|
663
663
|
action="read", agent_id=agent_id, attention_filter=attention_filter
|
664
664
|
)
|
665
665
|
if memory_result.get("success"):
|
@@ -723,7 +723,7 @@ Relevant shared context from other agents:
|
|
723
723
|
)
|
724
724
|
|
725
725
|
# Write to memory pool with enhanced context
|
726
|
-
memory_pool.
|
726
|
+
memory_pool.execute(
|
727
727
|
action="write",
|
728
728
|
agent_id=agent_id,
|
729
729
|
content=insight["content"],
|
@@ -1197,7 +1197,7 @@ class A2ACoordinatorNode(CycleAwareNode):
|
|
1197
1197
|
>>> coordinator = A2ACoordinatorNode()
|
1198
1198
|
>>>
|
1199
1199
|
>>> # Register agents
|
1200
|
-
>>> coordinator.
|
1200
|
+
>>> coordinator.execute(
|
1201
1201
|
... action="register",
|
1202
1202
|
... agent_info={
|
1203
1203
|
... "id": "analyst_001",
|
@@ -1207,7 +1207,7 @@ class A2ACoordinatorNode(CycleAwareNode):
|
|
1207
1207
|
... )
|
1208
1208
|
>>>
|
1209
1209
|
>>> # Delegate task with best match strategy
|
1210
|
-
>>> result = coordinator.
|
1210
|
+
>>> result = coordinator.execute(
|
1211
1211
|
... action="delegate",
|
1212
1212
|
... task={
|
1213
1213
|
... "type": "analysis",
|
@@ -1225,7 +1225,7 @@ class A2ACoordinatorNode(CycleAwareNode):
|
|
1225
1225
|
>>> assert result["assigned_agent"] == "analyst_001"
|
1226
1226
|
>>>
|
1227
1227
|
>>> # Build consensus among agents
|
1228
|
-
>>> consensus_result = coordinator.
|
1228
|
+
>>> consensus_result = coordinator.execute(
|
1229
1229
|
... action="consensus",
|
1230
1230
|
... proposal="Implement new feature X",
|
1231
1231
|
... voting_agents=["agent1", "agent2", "agent3"],
|
@@ -1324,7 +1324,7 @@ class A2ACoordinatorNode(CycleAwareNode):
|
|
1324
1324
|
|
1325
1325
|
Examples:
|
1326
1326
|
>>> coordinator = A2ACoordinatorNode()
|
1327
|
-
>>> result = coordinator.
|
1327
|
+
>>> result = coordinator.execute(context,
|
1328
1328
|
... action=\"delegate\",
|
1329
1329
|
... task={\"type\": \"analysis\", \"required_skills\": [\"data\"]},
|
1330
1330
|
... coordination_strategy=\"best_match\"
|
kailash/nodes/ai/ai_providers.py
CHANGED
@@ -1624,18 +1624,16 @@ def get_provider(
|
|
1624
1624
|
|
1625
1625
|
>>> # Get chat-only provider
|
1626
1626
|
>>> chat_provider = get_provider("anthropic", "chat")
|
1627
|
-
response = chat_provider.chat(messages, model="claude-3-sonnet")
|
1627
|
+
>>> response = chat_provider.chat(messages, model="claude-3-sonnet")
|
1628
1628
|
|
1629
|
-
Get embedding-only provider
|
1629
|
+
>>> # Get embedding-only provider
|
1630
|
+
>>> embed_provider = get_provider("cohere", "embeddings")
|
1631
|
+
>>> embeddings = embed_provider.embed(texts, model="embed-english-v3.0")
|
1630
1632
|
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
provider = get_provider("ollama")
|
1637
|
-
capabilities = provider.get_capabilities()
|
1638
|
-
print(f"Chat: {capabilities['chat']}, Embeddings: {capabilities['embeddings']}")
|
1633
|
+
>>> # Check provider capabilities
|
1634
|
+
>>> provider = get_provider("ollama")
|
1635
|
+
>>> capabilities = provider.get_capabilities()
|
1636
|
+
>>> print(f"Chat: {capabilities['chat']}, Embeddings: {capabilities['embeddings']}")
|
1639
1637
|
"""
|
1640
1638
|
provider_class = PROVIDERS.get(provider_name.lower())
|
1641
1639
|
if not provider_class:
|
@@ -1685,8 +1683,7 @@ def get_available_providers(
|
|
1685
1683
|
>>> chat_providers = get_available_providers("chat")
|
1686
1684
|
|
1687
1685
|
>>> # Get only embedding providers
|
1688
|
-
|
1689
|
-
embed_providers = get_available_providers("embeddings")
|
1686
|
+
>>> embed_providers = get_available_providers("embeddings")
|
1690
1687
|
"""
|
1691
1688
|
results = {}
|
1692
1689
|
|
@@ -63,7 +63,7 @@ class EmbeddingGeneratorNode(Node):
|
|
63
63
|
Examples:
|
64
64
|
>>> # Single text embedding
|
65
65
|
>>> embedder = EmbeddingGeneratorNode()
|
66
|
-
>>> result = embedder.
|
66
|
+
>>> result = embedder.execute(
|
67
67
|
... provider="openai",
|
68
68
|
... model="text-embedding-3-large",
|
69
69
|
... input_text="This is a sample document to embed",
|
@@ -72,7 +72,7 @@ class EmbeddingGeneratorNode(Node):
|
|
72
72
|
|
73
73
|
>>> # Batch document embedding
|
74
74
|
>>> batch_embedder = EmbeddingGeneratorNode()
|
75
|
-
>>> result = batch_embedder.
|
75
|
+
>>> result = batch_embedder.execute(
|
76
76
|
... provider="huggingface",
|
77
77
|
... model="sentence-transformers/all-MiniLM-L6-v2",
|
78
78
|
... input_texts=[
|
@@ -87,24 +87,23 @@ class EmbeddingGeneratorNode(Node):
|
|
87
87
|
|
88
88
|
>>> # Similarity calculation
|
89
89
|
>>> similarity = EmbeddingGeneratorNode()
|
90
|
-
>>> result = similarity.
|
90
|
+
>>> result = similarity.execute(
|
91
91
|
... operation="calculate_similarity",
|
92
92
|
... embedding_1=[0.1, 0.2, 0.3], # ... removed for doctest
|
93
93
|
... embedding_2=[0.15, 0.25, 0.35], # ... removed for doctest
|
94
94
|
... similarity_metric="cosine"
|
95
95
|
... )
|
96
96
|
|
97
|
-
Cached embedding with MCP integration
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
)
|
97
|
+
>>> # Cached embedding with MCP integration
|
98
|
+
>>> mcp_embedder = EmbeddingGeneratorNode()
|
99
|
+
>>> result = mcp_embedder.execute(
|
100
|
+
... provider="azure",
|
101
|
+
... model="text-embedding-3-small",
|
102
|
+
... mcp_resource_uri="data://documents/knowledge_base.json",
|
103
|
+
... operation="embed_mcp_resource",
|
104
|
+
... cache_ttl=3600,
|
105
|
+
... chunk_size=512
|
106
|
+
... )
|
108
107
|
"""
|
109
108
|
|
110
109
|
def get_parameters(self) -> dict[str, NodeParameter]:
|
@@ -95,7 +95,7 @@ class IntelligentCacheNode(Node):
|
|
95
95
|
>>> cache = IntelligentCacheNode()
|
96
96
|
>>>
|
97
97
|
>>> # Cache an expensive MCP tool call result
|
98
|
-
>>> result = cache.
|
98
|
+
>>> result = cache.execute(
|
99
99
|
... action="cache",
|
100
100
|
... cache_key="weather_api_nyc_20240106",
|
101
101
|
... data={"temperature": 72, "humidity": 65, "conditions": "sunny"},
|
@@ -110,7 +110,7 @@ class IntelligentCacheNode(Node):
|
|
110
110
|
>>> assert result["success"] == True
|
111
111
|
>>>
|
112
112
|
>>> # Direct cache hit by key
|
113
|
-
>>> cached = cache.
|
113
|
+
>>> cached = cache.execute(
|
114
114
|
... action="get",
|
115
115
|
... cache_key="weather_api_nyc_20240106"
|
116
116
|
... )
|
@@ -118,7 +118,7 @@ class IntelligentCacheNode(Node):
|
|
118
118
|
>>> assert cached["data"]["temperature"] == 72
|
119
119
|
>>>
|
120
120
|
>>> # Semantic similarity hit (uses simple string matching in this mock implementation)
|
121
|
-
>>> similar = cache.
|
121
|
+
>>> similar = cache.execute(
|
122
122
|
... action="get",
|
123
123
|
... query="weather nyc", # Simple match
|
124
124
|
... similarity_threshold=0.3
|
@@ -127,7 +127,7 @@ class IntelligentCacheNode(Node):
|
|
127
127
|
>>> has_hit = similar.get("hit", False)
|
128
128
|
>>>
|
129
129
|
>>> # Cache statistics
|
130
|
-
>>> stats = cache.
|
130
|
+
>>> stats = cache.execute(action="stats")
|
131
131
|
>>> assert "stats" in stats
|
132
132
|
>>> assert "hit_rate" in stats["stats"]
|
133
133
|
"""
|
@@ -704,7 +704,7 @@ class MCPAgentNode(SelfOrganizingAgentNode):
|
|
704
704
|
|
705
705
|
try:
|
706
706
|
client = server_info["client"]
|
707
|
-
result = client.
|
707
|
+
result = client.execute(
|
708
708
|
server_config=server_info["config"],
|
709
709
|
operation="call_tool",
|
710
710
|
tool_name=tool_name,
|
@@ -789,7 +789,7 @@ class QueryAnalysisNode(Node):
|
|
789
789
|
>>> analyzer = QueryAnalysisNode()
|
790
790
|
>>>
|
791
791
|
>>> # Analyze a complex multi-domain query
|
792
|
-
>>> result = analyzer.
|
792
|
+
>>> result = analyzer.execute(
|
793
793
|
... query="Analyze our Q4 sales data, identify underperforming regions, and create a recovery strategy with timeline",
|
794
794
|
... context={
|
795
795
|
... "domain": "business_strategy",
|
@@ -810,7 +810,7 @@ class QueryAnalysisNode(Node):
|
|
810
810
|
>>> assert result["analysis"]["team_suggestion"]["suggested_size"] >= 3
|
811
811
|
>>>
|
812
812
|
>>> # Simple query analysis
|
813
|
-
>>> simple = analyzer.
|
813
|
+
>>> simple = analyzer.execute(
|
814
814
|
... query="What is the current temperature?",
|
815
815
|
... context={"domain": "weather"}
|
816
816
|
... )
|
@@ -1402,7 +1402,7 @@ class OrchestrationManagerNode(Node):
|
|
1402
1402
|
def _analyze_query(self, query: str, context: dict, mcp_servers: list) -> dict:
|
1403
1403
|
"""Analyze the incoming query."""
|
1404
1404
|
analyzer = QueryAnalysisNode()
|
1405
|
-
return analyzer.
|
1405
|
+
return analyzer.execute(query=query, context=context, mcp_servers=mcp_servers)
|
1406
1406
|
|
1407
1407
|
def _setup_infrastructure(
|
1408
1408
|
self, pool_size: int, mcp_servers: list, enable_caching: bool
|
@@ -1503,7 +1503,7 @@ class OrchestrationManagerNode(Node):
|
|
1503
1503
|
spec = agent_specializations[i % len(agent_specializations)]
|
1504
1504
|
|
1505
1505
|
# Register agent with pool manager
|
1506
|
-
registration = pool_manager.
|
1506
|
+
registration = pool_manager.execute(
|
1507
1507
|
action="register",
|
1508
1508
|
agent_id=f"agent_{spec['role']}_{i:03d}",
|
1509
1509
|
capabilities=spec["capabilities"],
|
@@ -1543,7 +1543,7 @@ class OrchestrationManagerNode(Node):
|
|
1543
1543
|
|
1544
1544
|
team_formation = TeamFormationNode()
|
1545
1545
|
|
1546
|
-
return team_formation.
|
1546
|
+
return team_formation.execute(
|
1547
1547
|
problem_analysis=analysis,
|
1548
1548
|
available_agents=agent_pool,
|
1549
1549
|
formation_strategy=strategy,
|
@@ -1577,7 +1577,7 @@ class OrchestrationManagerNode(Node):
|
|
1577
1577
|
information_results.append(agent_result)
|
1578
1578
|
|
1579
1579
|
# Store in memory
|
1580
|
-
solution_memory.
|
1580
|
+
solution_memory.execute(
|
1581
1581
|
action="write",
|
1582
1582
|
agent_id=agent["id"],
|
1583
1583
|
content=agent_result,
|
@@ -1593,7 +1593,7 @@ class OrchestrationManagerNode(Node):
|
|
1593
1593
|
for cap in ["analysis", "machine_learning", "processing"]
|
1594
1594
|
):
|
1595
1595
|
# Get previous information
|
1596
|
-
memory_result = solution_memory.
|
1596
|
+
memory_result = solution_memory.execute(
|
1597
1597
|
action="read",
|
1598
1598
|
agent_id=agent["id"],
|
1599
1599
|
attention_filter={"tags": ["information"], "threshold": 0.3},
|
@@ -1605,7 +1605,7 @@ class OrchestrationManagerNode(Node):
|
|
1605
1605
|
)
|
1606
1606
|
analysis_results.append(agent_result)
|
1607
1607
|
|
1608
|
-
solution_memory.
|
1608
|
+
solution_memory.execute(
|
1609
1609
|
action="write",
|
1610
1610
|
agent_id=agent["id"],
|
1611
1611
|
content=agent_result,
|
@@ -1621,7 +1621,7 @@ class OrchestrationManagerNode(Node):
|
|
1621
1621
|
for cap in ["synthesis", "writing", "coordination"]
|
1622
1622
|
):
|
1623
1623
|
# Get all previous work
|
1624
|
-
memory_result = solution_memory.
|
1624
|
+
memory_result = solution_memory.execute(
|
1625
1625
|
action="read",
|
1626
1626
|
agent_id=agent["id"],
|
1627
1627
|
attention_filter={"threshold": 0.2},
|
@@ -1661,7 +1661,7 @@ class OrchestrationManagerNode(Node):
|
|
1661
1661
|
cache_key = f"{agent_id}_{hashlib.md5(task.encode()).hexdigest()[:8]}"
|
1662
1662
|
|
1663
1663
|
if cache:
|
1664
|
-
cached_result = cache.
|
1664
|
+
cached_result = cache.execute(
|
1665
1665
|
action="get", cache_key=cache_key, query=task, similarity_threshold=0.7
|
1666
1666
|
)
|
1667
1667
|
|
@@ -1693,7 +1693,7 @@ class OrchestrationManagerNode(Node):
|
|
1693
1693
|
|
1694
1694
|
# Cache the result
|
1695
1695
|
if cache:
|
1696
|
-
cache.
|
1696
|
+
cache.execute(
|
1697
1697
|
action="cache",
|
1698
1698
|
cache_key=cache_key,
|
1699
1699
|
data=result,
|
@@ -1729,7 +1729,7 @@ class OrchestrationManagerNode(Node):
|
|
1729
1729
|
"""Evaluate solution quality."""
|
1730
1730
|
evaluator = SolutionEvaluatorNode()
|
1731
1731
|
|
1732
|
-
return evaluator.
|
1732
|
+
return evaluator.execute(
|
1733
1733
|
solution=solution["final_solution"],
|
1734
1734
|
problem_requirements={
|
1735
1735
|
"quality_threshold": quality_threshold,
|
@@ -1848,7 +1848,7 @@ class ConvergenceDetectorNode(Node):
|
|
1848
1848
|
>>> detector = ConvergenceDetectorNode()
|
1849
1849
|
>>>
|
1850
1850
|
>>> # Typical convergence detection scenario
|
1851
|
-
>>> result = detector.
|
1851
|
+
>>> result = detector.execute(
|
1852
1852
|
... solution_history=[
|
1853
1853
|
... {
|
1854
1854
|
... "iteration": 1,
|
@@ -1888,7 +1888,7 @@ class ConvergenceDetectorNode(Node):
|
|
1888
1888
|
... {"evaluation": {"overall_score": 0.71}, "duration": 95},
|
1889
1889
|
... {"evaluation": {"overall_score": 0.715}, "duration": 90}
|
1890
1890
|
... ]
|
1891
|
-
>>> result2 = detector.
|
1891
|
+
>>> result2 = detector.execute(
|
1892
1892
|
... solution_history=stagnant_history,
|
1893
1893
|
... quality_threshold=0.9,
|
1894
1894
|
... improvement_threshold=0.05,
|
@@ -92,14 +92,14 @@ class IterativeLLMAgentNode(LLMAgentNode):
|
|
92
92
|
Examples:
|
93
93
|
>>> # Basic iterative agent
|
94
94
|
>>> agent = IterativeLLMAgentNode()
|
95
|
-
>>> result = agent.
|
95
|
+
>>> result = agent.execute(
|
96
96
|
... messages=[{"role": "user", "content": "Find and analyze healthcare AI trends"}],
|
97
97
|
... mcp_servers=["http://localhost:8080"],
|
98
98
|
... max_iterations=3
|
99
99
|
... )
|
100
100
|
|
101
101
|
>>> # Advanced iterative agent with custom convergence
|
102
|
-
>>> result = agent.
|
102
|
+
>>> result = agent.execute(
|
103
103
|
... messages=[{"role": "user", "content": "Research and recommend AI implementation strategy"}],
|
104
104
|
... mcp_servers=["http://ai-registry:8080", "http://knowledge-base:8081"],
|
105
105
|
... max_iterations=5,
|