kailash 0.6.1__py3-none-any.whl → 0.6.3__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 +1 -1
- kailash/core/actors/connection_actor.py +3 -3
- kailash/gateway/api.py +7 -5
- kailash/gateway/enhanced_gateway.py +1 -1
- kailash/{mcp → mcp_server}/__init__.py +12 -7
- kailash/{mcp → mcp_server}/ai_registry_server.py +2 -2
- kailash/{mcp/server_enhanced.py → mcp_server/server.py} +231 -48
- kailash/{mcp → mcp_server}/servers/ai_registry.py +2 -2
- kailash/{mcp → mcp_server}/utils/__init__.py +1 -6
- kailash/middleware/auth/access_control.py +5 -5
- kailash/middleware/gateway/checkpoint_manager.py +45 -8
- kailash/middleware/mcp/client_integration.py +1 -1
- kailash/middleware/mcp/enhanced_server.py +2 -2
- kailash/nodes/admin/permission_check.py +110 -30
- kailash/nodes/admin/schema.sql +387 -0
- kailash/nodes/admin/tenant_isolation.py +249 -0
- kailash/nodes/admin/transaction_utils.py +244 -0
- kailash/nodes/admin/user_management.py +37 -9
- kailash/nodes/ai/ai_providers.py +55 -3
- kailash/nodes/ai/iterative_llm_agent.py +1 -1
- kailash/nodes/ai/llm_agent.py +118 -16
- kailash/nodes/data/sql.py +24 -0
- kailash/resources/registry.py +6 -0
- kailash/runtime/async_local.py +7 -0
- kailash/utils/export.py +152 -0
- kailash/workflow/builder.py +42 -0
- kailash/workflow/graph.py +86 -17
- kailash/workflow/templates.py +4 -9
- {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/METADATA +3 -2
- {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/RECORD +40 -38
- kailash/mcp/server.py +0 -292
- /kailash/{mcp → mcp_server}/client.py +0 -0
- /kailash/{mcp → mcp_server}/client_new.py +0 -0
- /kailash/{mcp → mcp_server}/utils/cache.py +0 -0
- /kailash/{mcp → mcp_server}/utils/config.py +0 -0
- /kailash/{mcp → mcp_server}/utils/formatters.py +0 -0
- /kailash/{mcp → mcp_server}/utils/metrics.py +0 -0
- {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/WHEEL +0 -0
- {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/entry_points.txt +0 -0
- {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/top_level.txt +0 -0
kailash/workflow/graph.py
CHANGED
@@ -346,18 +346,27 @@ class Workflow:
|
|
346
346
|
# Validate cycle parameters and issue deprecation warning
|
347
347
|
if cycle:
|
348
348
|
# Issue deprecation warning for cycle usage via connect()
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
349
|
+
# Skip warning if called from CycleBuilder (check stack)
|
350
|
+
import inspect
|
351
|
+
|
352
|
+
frame = inspect.currentframe()
|
353
|
+
caller_frame = frame.f_back if frame else None
|
354
|
+
caller_filename = caller_frame.f_code.co_filename if caller_frame else ""
|
355
|
+
|
356
|
+
# Only warn if NOT called from CycleBuilder
|
357
|
+
if "cycle_builder.py" not in caller_filename:
|
358
|
+
warnings.warn(
|
359
|
+
"Using workflow.connect() with cycle=True is deprecated and will be removed in v0.2.0. "
|
360
|
+
"Use the new CycleBuilder API instead:\n"
|
361
|
+
" workflow.create_cycle('cycle_name')\\\n"
|
362
|
+
" .connect(source_node, target_node)\\\n"
|
363
|
+
" .max_iterations(N)\\\n"
|
364
|
+
" .converge_when('condition')\\\n"
|
365
|
+
" .build()\n"
|
366
|
+
"See Phase 5 API documentation for details.",
|
367
|
+
DeprecationWarning,
|
368
|
+
stacklevel=2,
|
369
|
+
)
|
361
370
|
|
362
371
|
# Import enhanced exceptions for better error messaging
|
363
372
|
try:
|
@@ -426,11 +435,20 @@ class Workflow:
|
|
426
435
|
for c in self.connections
|
427
436
|
if c.source_node == source_node and c.target_node == target_node
|
428
437
|
]
|
438
|
+
# Allow multiple connections between same nodes for different mappings
|
439
|
+
# Only reject if it's a duplicate mapping, not just any existing connection
|
429
440
|
if existing_connections and not cycle:
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
441
|
+
# Check if any of the new mappings already exist
|
442
|
+
existing_mappings = set()
|
443
|
+
for conn in existing_connections:
|
444
|
+
existing_mappings.add((conn.source_output, conn.target_input))
|
445
|
+
|
446
|
+
for source_output, target_input in mapping.items():
|
447
|
+
if (source_output, target_input) in existing_mappings:
|
448
|
+
raise ConnectionError(
|
449
|
+
f"Duplicate connection already exists: '{source_node}.{source_output}' -> '{target_node}.{target_input}'. "
|
450
|
+
f"Existing mappings: {[c.model_dump() for c in existing_connections]}"
|
451
|
+
)
|
434
452
|
|
435
453
|
# Create connections (store in self.connections list)
|
436
454
|
for source_output, target_input in mapping.items():
|
@@ -495,7 +513,58 @@ class Workflow:
|
|
495
513
|
}
|
496
514
|
)
|
497
515
|
|
498
|
-
#
|
516
|
+
# CRITICAL FIX: Merge edge data for multiple connections between same nodes
|
517
|
+
# Check if edge already exists and merge mappings
|
518
|
+
existing_edge_data = None
|
519
|
+
if self.graph.has_edge(source_node, target_node):
|
520
|
+
existing_edge_data = self.graph.get_edge_data(source_node, target_node)
|
521
|
+
|
522
|
+
if existing_edge_data and "mapping" in existing_edge_data:
|
523
|
+
# Merge with existing mapping
|
524
|
+
merged_mapping = existing_edge_data["mapping"].copy()
|
525
|
+
merged_mapping.update(mapping)
|
526
|
+
edge_data = {
|
527
|
+
"mapping": merged_mapping, # Merged mapping dictionary
|
528
|
+
}
|
529
|
+
|
530
|
+
# Update backward compatibility fields
|
531
|
+
if len(merged_mapping) == 1:
|
532
|
+
edge_data["from_output"] = list(merged_mapping.keys())[0]
|
533
|
+
edge_data["to_input"] = list(merged_mapping.values())[0]
|
534
|
+
else:
|
535
|
+
edge_data["from_output"] = list(merged_mapping.keys())
|
536
|
+
edge_data["to_input"] = list(merged_mapping.values())
|
537
|
+
|
538
|
+
# Preserve any existing cycle metadata
|
539
|
+
if existing_edge_data.get("cycle"):
|
540
|
+
edge_data.update(
|
541
|
+
{
|
542
|
+
k: v
|
543
|
+
for k, v in existing_edge_data.items()
|
544
|
+
if k not in ["mapping", "from_output", "to_input"]
|
545
|
+
}
|
546
|
+
)
|
547
|
+
else:
|
548
|
+
# No existing edge or no mapping, use new mapping as-is
|
549
|
+
# (edge_data was already set above)
|
550
|
+
pass
|
551
|
+
|
552
|
+
# Add cycle metadata to edge if this is a cycle connection
|
553
|
+
if cycle:
|
554
|
+
edge_data.update(
|
555
|
+
{
|
556
|
+
"cycle": cycle,
|
557
|
+
"max_iterations": max_iterations,
|
558
|
+
"convergence_check": convergence_check,
|
559
|
+
"cycle_id": cycle_id,
|
560
|
+
"timeout": timeout,
|
561
|
+
"memory_limit": memory_limit,
|
562
|
+
"condition": condition,
|
563
|
+
"parent_cycle": parent_cycle,
|
564
|
+
}
|
565
|
+
)
|
566
|
+
|
567
|
+
# Add or update the edge with merged data
|
499
568
|
self.graph.add_edge(source_node, target_node, **edge_data)
|
500
569
|
|
501
570
|
# Enhanced logging for cycles
|
kailash/workflow/templates.py
CHANGED
@@ -176,15 +176,10 @@ class CycleTemplates:
|
|
176
176
|
# Connect processor to evaluator
|
177
177
|
workflow.connect(processor_node, evaluator_node)
|
178
178
|
|
179
|
-
# Close the cycle with convergence condition
|
180
|
-
workflow.connect(
|
181
|
-
evaluator_node,
|
182
|
-
|
183
|
-
cycle=True,
|
184
|
-
max_iterations=max_iterations,
|
185
|
-
convergence_check=convergence,
|
186
|
-
cycle_id=cycle_id,
|
187
|
-
)
|
179
|
+
# Close the cycle with convergence condition using new API
|
180
|
+
workflow.create_cycle(cycle_id).connect(
|
181
|
+
evaluator_node, processor_node
|
182
|
+
).max_iterations(max_iterations).converge_when(convergence).build()
|
188
183
|
|
189
184
|
return cycle_id
|
190
185
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: kailash
|
3
|
-
Version: 0.6.
|
3
|
+
Version: 0.6.3
|
4
4
|
Summary: Python SDK for the Kailash container-node architecture
|
5
5
|
Home-page: https://github.com/integrum/kailash-python-sdk
|
6
6
|
Author: Integrum
|
@@ -21,7 +21,7 @@ Requires-Dist: matplotlib>=3.5
|
|
21
21
|
Requires-Dist: pyyaml>=6.0
|
22
22
|
Requires-Dist: click>=8.0
|
23
23
|
Requires-Dist: pytest>=8.3.5
|
24
|
-
Requires-Dist: mcp[cli]>=1.9.2
|
24
|
+
Requires-Dist: mcp[cli,server]>=1.9.2
|
25
25
|
Requires-Dist: pandas>=2.2.3
|
26
26
|
Requires-Dist: numpy>=2.2.5
|
27
27
|
Requires-Dist: scipy>=1.15.3
|
@@ -64,6 +64,7 @@ Requires-Dist: twilio>=9.6.3
|
|
64
64
|
Requires-Dist: qrcode>=8.2
|
65
65
|
Requires-Dist: aiofiles>=24.1.0
|
66
66
|
Requires-Dist: bcrypt>=4.3.0
|
67
|
+
Requires-Dist: plotly>=6.2.0
|
67
68
|
Provides-Extra: dev
|
68
69
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
69
70
|
Requires-Dist: pytest-cov>=3.0; extra == "dev"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
kailash/__init__.py,sha256=
|
1
|
+
kailash/__init__.py,sha256=8W7LrVttYlpEMHu8_N4a5CilyUWMORrc8rnCbaAJ8HU,1724
|
2
2
|
kailash/__main__.py,sha256=vr7TVE5o16V6LsTmRFKG6RDKUXHpIWYdZ6Dok2HkHnI,198
|
3
3
|
kailash/access_control.py,sha256=2ctdRFeSeu-d7DU04Aovxh6Rt_4t3IyQfkKEjTeQiMM,25519
|
4
4
|
kailash/access_control_abac.py,sha256=FPfa_8PuDP3AxTjdWfiH3ntwWO8NodA0py9W8SE5dno,30263
|
@@ -23,7 +23,7 @@ kailash/config/__init__.py,sha256=9qNwtvXAVV-KkHbuL1ZbtC6yXDtowH4YoFiOP-Qbe-w,63
|
|
23
23
|
kailash/config/database_config.py,sha256=rdlqIP9WUzC0kvAdSjno1LMpu_bEy2v5FgFdgJy-qsc,11588
|
24
24
|
kailash/core/actors/__init__.py,sha256=o8CrwZRTPW5uB3UZiiFtz34n1Q-XBoKNwTz5NMTDQgA,433
|
25
25
|
kailash/core/actors/adaptive_pool_controller.py,sha256=tque9heLsLwjrNlM1wZSAYi1RInv19Z3HTjbozc9XtY,22484
|
26
|
-
kailash/core/actors/connection_actor.py,sha256=
|
26
|
+
kailash/core/actors/connection_actor.py,sha256=M8fOX1a3jvH5PUkfQyk0eBJqCk0SD9KGZCw0TXLON_o,18979
|
27
27
|
kailash/core/actors/supervisor.py,sha256=7_YXm9o4O_xBs5YxsDFt7RjzaMvTbKcK-jd4KPmSt1M,11968
|
28
28
|
kailash/core/ml/__init__.py,sha256=eaD-bmoxMXtwwtKWePsoX1IkcpysX0bMAGyMR7jaAqI,64
|
29
29
|
kailash/core/ml/query_patterns.py,sha256=4wV1pBOwUiK80UTKuMXSoRgR0pojtjg2BMNoa5qWpc0,20290
|
@@ -39,25 +39,24 @@ kailash/edge/compliance.py,sha256=tUiKiib7FjNtZ62ThQIRhxkehOddndTGLu-Y4He7iRQ,31
|
|
39
39
|
kailash/edge/discovery.py,sha256=tEV7W2XVPfEgEOM5oaRAlWAtuXV3M4xM07Z7OcnXZxY,24311
|
40
40
|
kailash/edge/location.py,sha256=ZrG4CqN-taZFo9VDLvZ2z1lNiTHgXcZvzBJS9meXY8k,19717
|
41
41
|
kailash/gateway/__init__.py,sha256=zh2uCsDHi82pZ_tGJklsH_FS-Mx9V31r0hkxk48CM-g,927
|
42
|
-
kailash/gateway/api.py,sha256=
|
43
|
-
kailash/gateway/enhanced_gateway.py,sha256=
|
42
|
+
kailash/gateway/api.py,sha256=xpK8PIamsqQPpKAJwacyV7RA_Snjv2pc_0ljnnU9Oy4,9534
|
43
|
+
kailash/gateway/enhanced_gateway.py,sha256=IlN1XV01FQrF4rGcq_z9LE4uUHAAAQoVsRNToXENen0,13399
|
44
44
|
kailash/gateway/resource_resolver.py,sha256=IC1dceiKfjfUWToYCIBcrUapuR3LlDG6RJ4o7haLY10,7746
|
45
45
|
kailash/gateway/security.py,sha256=kf4Quf6u7dqhs80fQQ982eHbRb4weDKG0DaYNeKntT4,7557
|
46
|
-
kailash/
|
47
|
-
kailash/
|
48
|
-
kailash/
|
49
|
-
kailash/
|
50
|
-
kailash/
|
51
|
-
kailash/
|
52
|
-
kailash/
|
53
|
-
kailash/
|
54
|
-
kailash/
|
55
|
-
kailash/
|
56
|
-
kailash/
|
57
|
-
kailash/mcp/utils/metrics.py,sha256=MNUjWGQyq1EGdeqzAKCCZJNgcWHOyaYAV8MlS2cb-4k,13754
|
46
|
+
kailash/mcp_server/__init__.py,sha256=ETEeaRTqj2xeX07MyaRgcPiaomdLoJ24iNmRbRjJQok,1953
|
47
|
+
kailash/mcp_server/ai_registry_server.py,sha256=BkkZcohRyGlSbiUkpRTaIA6M_yJUgtgtMda-dvbT86s,28118
|
48
|
+
kailash/mcp_server/client.py,sha256=sTouSiuiu1nbahMXSWcP8-mr1k7cqdBCzSxm8G7le-s,16058
|
49
|
+
kailash/mcp_server/client_new.py,sha256=YU671JvAM0uvuX0uhGZCIKI8co3fqz0cs6HqLZ59Xyo,10285
|
50
|
+
kailash/mcp_server/server.py,sha256=z-72J5MKq98_j7zwo0HJMbMI9bp5yuNpyfIzD9N23yw,20600
|
51
|
+
kailash/mcp_server/servers/ai_registry.py,sha256=IdF_keUuJlMsvjLjSAykxxbm46K4qA7eCj7T-lYSrzk,10007
|
52
|
+
kailash/mcp_server/utils/__init__.py,sha256=VjGFpvugTYUxoNgtwVEKkmrkVS3iZ_kIbP4jR1PRM6E,750
|
53
|
+
kailash/mcp_server/utils/cache.py,sha256=dLEseovPaXL4lRzMSw7tqd3tJHwnWfhdZ-HKGyScJXI,8414
|
54
|
+
kailash/mcp_server/utils/config.py,sha256=DyZxgdy3vqI5pwhQ_E-42mhueVGNHiuOtTUOrM9HC_U,8124
|
55
|
+
kailash/mcp_server/utils/formatters.py,sha256=D-2j1nvmprApiUI13HWY-L2_WPSAcJDtVdHcshAuOdo,9740
|
56
|
+
kailash/mcp_server/utils/metrics.py,sha256=MNUjWGQyq1EGdeqzAKCCZJNgcWHOyaYAV8MlS2cb-4k,13754
|
58
57
|
kailash/middleware/__init__.py,sha256=ZGo0qujL-qWn82nIrojY96N1rMPTWFKHumW6CGGpb4Y,10409
|
59
58
|
kailash/middleware/auth/__init__.py,sha256=VkKM8H-zVFx2PLGL7kyxE2IfSiV1HiwveSysbmxMcg0,2077
|
60
|
-
kailash/middleware/auth/access_control.py,sha256=
|
59
|
+
kailash/middleware/auth/access_control.py,sha256=2FwQjp_fZm2fg-V_CIgAN69GGL9YwyZwsbQis0hbW7I,14848
|
61
60
|
kailash/middleware/auth/auth_manager.py,sha256=d1XFJ9jOCrOTwV26qO0b7wBOSbroTvTxaJADII-mCz0,14057
|
62
61
|
kailash/middleware/auth/exceptions.py,sha256=tPDQgaX9nMQ9BJZR3Y5tv2LwLy8pZcUz-uFATQjALRA,2496
|
63
62
|
kailash/middleware/auth/jwt_auth.py,sha256=r4dauFKcoARHj0yb4f4WwBmY9YQpLNBGyk4gdBZEI1k,21626
|
@@ -81,14 +80,14 @@ kailash/middleware/database/models.py,sha256=CJwwUEdgxqBteXqpFJr1tWskjypJxViZXjO
|
|
81
80
|
kailash/middleware/database/repositories.py,sha256=7l2OcAem5sMQxbbnmBR4O22P-OcLv5zEo-4r9fIMl1o,23340
|
82
81
|
kailash/middleware/database/session_manager.py,sha256=Pzj7c2TZnM3GRty2igSaxmLOf0-Fs67NVe2Q5lR_C-Q,379
|
83
82
|
kailash/middleware/gateway/__init__.py,sha256=3R7HkvAadJKYCkDHEXFnOPHJ6yzdj8HpBOHtafStqSE,588
|
84
|
-
kailash/middleware/gateway/checkpoint_manager.py,sha256=
|
83
|
+
kailash/middleware/gateway/checkpoint_manager.py,sha256=zF2ZnHYxQwXmG3d5g7Qwx9pW8tDRTcqV9yh8dvhY95E,15056
|
85
84
|
kailash/middleware/gateway/deduplicator.py,sha256=CblV3fwc7s4wg6KIvypwyNMYL5AuQi9EwtcxVOy64X8,13265
|
86
85
|
kailash/middleware/gateway/durable_gateway.py,sha256=EsIgMNxS_no2W40AXDyE7FmVdnGNU26kBRC5rfnSzoQ,14626
|
87
86
|
kailash/middleware/gateway/durable_request.py,sha256=SCnp-bF0tQX9oahr9reqcZjJ_YhyJkeYYl-un9rJ6lo,15437
|
88
87
|
kailash/middleware/gateway/event_store.py,sha256=A3Kh2MhVVPbXWvjeo550SqEGPiJYyspAfu6Gv7UZzo4,16131
|
89
88
|
kailash/middleware/mcp/__init__.py,sha256=EdZB8zOMSBEEmudRzs8ksz9QZJYWQMEx7Tm1MOwIWnI,922
|
90
|
-
kailash/middleware/mcp/client_integration.py,sha256=
|
91
|
-
kailash/middleware/mcp/enhanced_server.py,sha256=
|
89
|
+
kailash/middleware/mcp/client_integration.py,sha256=dY1RmX-g5E6JzUFuWxk7viuOYIh8bMwoUSvHQMVEsYk,18265
|
90
|
+
kailash/middleware/mcp/enhanced_server.py,sha256=vVd7WE95c-5861VtKfmTZ91iUWFRw-aKEKwHlu6edQo,18467
|
92
91
|
kailash/nodes/__init__.py,sha256=E6CEp1ooq4GgFhKtwVAczOhPt5N3x-AVQ-R0n3_IFyA,936
|
93
92
|
kailash/nodes/base.py,sha256=Fu9c2I5k_Ke192y4fj2NVhf-Y_I0nPr0sDE1zMSRCJY,55417
|
94
93
|
kailash/nodes/base_async.py,sha256=mpntaeFMbUYLIyTvjsb221mXckx_H2dGX2LhxeKhhfA,6569
|
@@ -98,19 +97,22 @@ kailash/nodes/mixins.py,sha256=ncAdNQPe1sphLByeerP6G_s8mjFLt7dM4baiozzIBPA,12083
|
|
98
97
|
kailash/nodes/validation.py,sha256=tuBZRZkDiEdvfeU7JaRB7v2-j1vxPYMJ1gVaJ-PKHRk,12117
|
99
98
|
kailash/nodes/admin/__init__.py,sha256=C9_pK2w0rH6JEV_-roypeasAIyIhEFKKnH-npGBeew0,1508
|
100
99
|
kailash/nodes/admin/audit_log.py,sha256=CSSeWwAK-_hGYXs8eess89wNVju8jvsdNKA1A1946to,41066
|
101
|
-
kailash/nodes/admin/permission_check.py,sha256=
|
100
|
+
kailash/nodes/admin/permission_check.py,sha256=tLz6aGmNp1xV44Wfy_F1RgvGU4te9qzhNOAEpGo9fdU,66564
|
102
101
|
kailash/nodes/admin/role_management.py,sha256=DVkFJU5yQRf_1TxlvmQBhHzCeE5oJQzIjCKjrEfZb1g,72894
|
102
|
+
kailash/nodes/admin/schema.sql,sha256=50V-0NoQmYg66KYVE6rAJxx7LSacCVYs2UvvA1Y9zF0,14028
|
103
103
|
kailash/nodes/admin/schema_manager.py,sha256=U8W8Xn4H5wamEtSq-I9jh54tWQnrLo4vZDKdX3K4bKs,15073
|
104
104
|
kailash/nodes/admin/security_event.py,sha256=We_nGn6_J004b7LQVd0nKU6LmhJ6vyrl5zySC3xVdfo,56336
|
105
|
-
kailash/nodes/admin/
|
105
|
+
kailash/nodes/admin/tenant_isolation.py,sha256=jztFmChohj4ZpwAUdM_z2tKYcFopFtCJ2ViXnlMuvzA,8270
|
106
|
+
kailash/nodes/admin/transaction_utils.py,sha256=La3BLwT2XrYtKesiFRGEYL0dXop6JM5TqPUHLx5DYVs,7884
|
107
|
+
kailash/nodes/admin/user_management.py,sha256=6u0iMyFKvb_zyaQdiKuGemQM65gEeax9wwEjoadb4Ro,54623
|
106
108
|
kailash/nodes/ai/__init__.py,sha256=rslxIS8jlovshiNgWqVzQjD_kfT_3h3Ct03sk-iRe6U,2202
|
107
109
|
kailash/nodes/ai/a2a.py,sha256=QpTPl-Cm6mqzM0unLfqPrgEu964QP47g5p2T4clVPMs,70004
|
108
110
|
kailash/nodes/ai/agents.py,sha256=CRA3cdapQjpuvOniXUh6ZVWAlRxUIepVw1BROW6QzdY,20373
|
109
|
-
kailash/nodes/ai/ai_providers.py,sha256=
|
111
|
+
kailash/nodes/ai/ai_providers.py,sha256=XeDIaYH7PrX8frWCVV6CYFNQXFjHX_61T3eR1yullqs,65355
|
110
112
|
kailash/nodes/ai/embedding_generator.py,sha256=rsos3B6oWrgGTMIbwSWIBzGH9kq3SFVD_-bEDrujBRs,31860
|
111
113
|
kailash/nodes/ai/intelligent_agent_orchestrator.py,sha256=xw44C-CkcNH3SVmEJ49o4oNV3o4ZqjLE9aLpggwoIXs,83021
|
112
|
-
kailash/nodes/ai/iterative_llm_agent.py,sha256=
|
113
|
-
kailash/nodes/ai/llm_agent.py,sha256=
|
114
|
+
kailash/nodes/ai/iterative_llm_agent.py,sha256=14SxTRGGGYRqNC0SFMaKAFplUcsQXAVzXKcjri_0oWM,52891
|
115
|
+
kailash/nodes/ai/llm_agent.py,sha256=0N5NU2HLwbh2_zFxrgwq2FlkVS6fifpEcMSI0BGX7ZQ,82198
|
114
116
|
kailash/nodes/ai/models.py,sha256=wsEeUTuegy87mnLtKgSTg7ggCXvC1n3MsL-iZ4qujHs,16393
|
115
117
|
kailash/nodes/ai/self_organizing.py,sha256=M7yCLkN4I1JCNU7PWuwrqwQSlaG9MJVxYIR44TV52MM,62877
|
116
118
|
kailash/nodes/ai/vision_utils.py,sha256=OHD9cVH_mq0WpJyQkNTj_mpipIVWfSV_bF9eA6CdyeA,4166
|
@@ -151,7 +153,7 @@ kailash/nodes/data/readers.py,sha256=fX82yQSLGPUFbSf6krT_-9gybp6IBnBH-Lcr87aNlHQ
|
|
151
153
|
kailash/nodes/data/retrieval.py,sha256=H8Qb2R64fQ_OeaQBh6jVn7-xLuygiF3fjzbh4ssNOrU,20591
|
152
154
|
kailash/nodes/data/sharepoint_graph.py,sha256=J1_KZQ5s8yXkjGY1PjsMY7T8viKARi3os5P8CXpmn2U,37160
|
153
155
|
kailash/nodes/data/sources.py,sha256=tvgDDDerWELD6QkAm73ciKmNakD_SYMd50idlOjpbF0,3632
|
154
|
-
kailash/nodes/data/sql.py,sha256=
|
156
|
+
kailash/nodes/data/sql.py,sha256=0VfOedQ6UwSiBJtwmMLhAvqQWeakrnB1QNrhjan5jIg,35288
|
155
157
|
kailash/nodes/data/streaming.py,sha256=VE4e3CNuRAdjckV8UXFpkTj3mPLY2cicoZwnkq10ZnE,37163
|
156
158
|
kailash/nodes/data/vector_db.py,sha256=pwCl-3tyk_Cv_VQ8GafgodJ1yM88W1BXCIcYC56XoqU,32056
|
157
159
|
kailash/nodes/data/workflow_connection_pool.py,sha256=o-c-gu4HRtD0i7G6eCLZuOVB4CDJMOXFuL5CbXipZtk,40284
|
@@ -207,10 +209,10 @@ kailash/resources/__init__.py,sha256=JM90kDB7k9wTsd6-2jwm-312SeOaXvavyKnPwQwy4PY
|
|
207
209
|
kailash/resources/factory.py,sha256=CYqBm3EFjTv_Aoqb3AUFT8emJlUrtwAZGCSVLt8K3KA,15824
|
208
210
|
kailash/resources/health.py,sha256=i6XS0HdL6pUYq8SBdRjvchf-oj0sy3JoRLszNylfQJc,9702
|
209
211
|
kailash/resources/reference.py,sha256=RKfXzJFIdid0cLOwsXSmlXq4NhSEci4GO-q3M3qcjA8,7526
|
210
|
-
kailash/resources/registry.py,sha256=
|
212
|
+
kailash/resources/registry.py,sha256=5978e9VcUq0XBi9LRN89swptBSOAOAyNmwe2pxFHMxM,13789
|
211
213
|
kailash/runtime/__init__.py,sha256=CvU-qBMESYYISqFOlYlLsYJrXJu0Gqr4x6yr4Ob_Rng,278
|
212
214
|
kailash/runtime/access_controlled.py,sha256=Td8Fa8oPxEqlb74bDiH_HtT6J-ku0AudvN7mrUZOacc,17219
|
213
|
-
kailash/runtime/async_local.py,sha256=
|
215
|
+
kailash/runtime/async_local.py,sha256=XJyJYWmsezZBmAB8Y8xfAbiytPaY1j_zYU_moABP-3E,30313
|
214
216
|
kailash/runtime/docker.py,sha256=sZknVl1PCGfAZeyc0-exTuKlllSyjYlFIgJoiB3CRNs,23500
|
215
217
|
kailash/runtime/local.py,sha256=i2hnRrk2Ks0Q5jR9SkBhM6d6plJbpH0i7rNkJ8laLCw,39078
|
216
218
|
kailash/runtime/parallel.py,sha256=mz_wPD13-YVc3Q_8HkOs4nPQPdTjnjCcnRL7ZRM70lo,21070
|
@@ -231,7 +233,7 @@ kailash/tracking/storage/base.py,sha256=wWkK1XdrMV0EGxlbFDyfuVnDoIG0tdSPPwz_8iwz
|
|
231
233
|
kailash/tracking/storage/database.py,sha256=O3-qYmgwTccq9jYl25C0L6R398pXPsWkIAoWLL1aZvQ,20048
|
232
234
|
kailash/tracking/storage/filesystem.py,sha256=VhWxNvqf_Ta3mIaGqKuOrcCqQiEvJj7S8NK5yRd1V68,19627
|
233
235
|
kailash/utils/__init__.py,sha256=pFKhHJxU_kyFE9aGT5recw5E-3nbfVF5pMHepBJWB2E,253
|
234
|
-
kailash/utils/export.py,sha256=
|
236
|
+
kailash/utils/export.py,sha256=WBazN03LOCI03TsIElNv31wSZ_uTLPl8THnqdohgyTk,37361
|
235
237
|
kailash/utils/resource_manager.py,sha256=xMgcSogLofUIRpRMXzmK4gxBi2lIqEJ7rn2rsBBm9xo,13209
|
236
238
|
kailash/utils/secure_logging.py,sha256=3iEJt7sXnIgvdiRz8qsx0JbcygrsUf0_C8UHFXLNfcs,11325
|
237
239
|
kailash/utils/templates.py,sha256=1O9mniUTJmZZFkC1gFaWy73pDIZxcawljDIQpPj6G9Q,21977
|
@@ -247,7 +249,7 @@ kailash/visualization/reports.py,sha256=D7kJ0flHr16d-qSEq8vnw20N8u_dgTrXtKVSXVm8
|
|
247
249
|
kailash/workflow/__init__.py,sha256=DDQDE9K6RmbX6479guNLLgjiVVV-gQERRvCEJWSVlsM,1836
|
248
250
|
kailash/workflow/async_builder.py,sha256=iv8bDJHdWAUZ77SyMo6sucd92dTdtXesdxycrSE7mM4,20613
|
249
251
|
kailash/workflow/async_patterns.py,sha256=X0ZDXwr6UAu0WC1xnCB7-0V1-tRbKs9UI4JqaBCB6tE,22824
|
250
|
-
kailash/workflow/builder.py,sha256=
|
252
|
+
kailash/workflow/builder.py,sha256=FTzvso-FWVAcPYs2DOvL3CSEvbxaVbMP3L2T8_wtzbM,12356
|
251
253
|
kailash/workflow/convergence.py,sha256=vfIDR-uNaQE-LVUEzrRtfgKPgX9gL0nLNH-nTg5ra-c,10031
|
252
254
|
kailash/workflow/cycle_analyzer.py,sha256=BGBpgdB-g0-KRI65sVAvHV4lxfoCzMt4uKOHbw8GXT4,32596
|
253
255
|
kailash/workflow/cycle_builder.py,sha256=uWAx8K4ZKMtFC3mWylK4gHT03xeu0xChJlhw50hVqEE,20883
|
@@ -257,7 +259,7 @@ kailash/workflow/cycle_exceptions.py,sha256=4_OLnbEXqIiXKzOc3uh8DzFik4wEHwl8bRZh
|
|
257
259
|
kailash/workflow/cycle_profiler.py,sha256=aEWSCm0Xy15SjgLTpPooVJMzpFhtJWt4livR-3Me4N8,28547
|
258
260
|
kailash/workflow/cycle_state.py,sha256=hzRUvciRreWfS56Cf7ZLQPit_mlPTQDoNTawh8yi-2s,10747
|
259
261
|
kailash/workflow/cyclic_runner.py,sha256=NZqK_GTNbvf-pp08_brvzOlDCytrKscr1XRDy8PD8Is,40816
|
260
|
-
kailash/workflow/graph.py,sha256=
|
262
|
+
kailash/workflow/graph.py,sha256=zRpGLXeuwtuxFBvE7_16c_bB9yqZirM_uwtfD1_MY4g,59272
|
261
263
|
kailash/workflow/mermaid_visualizer.py,sha256=UsQDvxgIAhy-Th7ZzFnbuziaTx1Cd5yUh6S_25DffoQ,22294
|
262
264
|
kailash/workflow/migration.py,sha256=zsmXgbUtOZdjoOx9YoEY0-x7uOY1T-_yQo4MnZjokCQ,31487
|
263
265
|
kailash/workflow/mock_registry.py,sha256=J4gyH8YdhRyhvORDVxGTya0FgDK8iAA8Nonur6p9s-o,1692
|
@@ -265,12 +267,12 @@ kailash/workflow/resilience.py,sha256=Ecef4gBg-QWP369a_xfzQnVWhHryvEcO2RSFVSriLJ
|
|
265
267
|
kailash/workflow/runner.py,sha256=l6jb-H7DwbRlvQ3H3SuTs70rut-u7H3Gi8nybKCEjZU,10795
|
266
268
|
kailash/workflow/safety.py,sha256=pS5GKu7UdkzFZcb16Dn-0jBxjULDU-59_M0CbUVMVyw,11298
|
267
269
|
kailash/workflow/state.py,sha256=UTZxs5-Ona6uvBhx1__i6-RX8gB4qazkBIWE7uyRmWQ,7600
|
268
|
-
kailash/workflow/templates.py,sha256=
|
270
|
+
kailash/workflow/templates.py,sha256=98EN5H4fO9b4xeczk20Hu5L8hNcAuRQNGayT6vnZYCw,48540
|
269
271
|
kailash/workflow/validation.py,sha256=JIbIajWVIaWHSvWtgZ4WUVJaBaUOCz5B9cyTwM--dL4,33060
|
270
272
|
kailash/workflow/visualization.py,sha256=ICMWCWqh5fOQ7eJygbvu2PMWHxe-H5_0epwdZuz8cMw,19737
|
271
|
-
kailash-0.6.
|
272
|
-
kailash-0.6.
|
273
|
-
kailash-0.6.
|
274
|
-
kailash-0.6.
|
275
|
-
kailash-0.6.
|
276
|
-
kailash-0.6.
|
273
|
+
kailash-0.6.3.dist-info/licenses/LICENSE,sha256=Axe6g7bTrJkToK9h9j2SpRUKKNaDZDCo2lQ2zPxCE6s,1065
|
274
|
+
kailash-0.6.3.dist-info/METADATA,sha256=PH0D-ORbBHT7eJjuIEMbrcr1CWNlQpY36Ncy4jGJ-wg,25932
|
275
|
+
kailash-0.6.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
276
|
+
kailash-0.6.3.dist-info/entry_points.txt,sha256=M_q3b8PG5W4XbhSgESzIJjh3_4OBKtZFYFsOdkr2vO4,45
|
277
|
+
kailash-0.6.3.dist-info/top_level.txt,sha256=z7GzH2mxl66498pVf5HKwo5wwfPtt9Aq95uZUpH6JV0,8
|
278
|
+
kailash-0.6.3.dist-info/RECORD,,
|
kailash/mcp/server.py
DELETED
@@ -1,292 +0,0 @@
|
|
1
|
-
"""MCP Server Framework using official Anthropic SDK.
|
2
|
-
|
3
|
-
This module provides a comprehensive framework for creating MCP servers using
|
4
|
-
the official FastMCP framework from Anthropic. Servers run as long-lived
|
5
|
-
services that expose tools, resources, and prompts to MCP clients, enabling
|
6
|
-
dynamic capability extension for AI workflows.
|
7
|
-
|
8
|
-
Note:
|
9
|
-
This module requires the FastMCP framework to be installed.
|
10
|
-
Install with: pip install 'mcp[server]'
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
Basic server with tools:
|
14
|
-
|
15
|
-
>>> from kailash.mcp.server import MCPServer
|
16
|
-
>>> class MyServer(MCPServer):
|
17
|
-
... def setup(self):
|
18
|
-
... @self.add_tool()
|
19
|
-
... def calculate(a: int, b: int) -> int:
|
20
|
-
... return a + b
|
21
|
-
>>> server = MyServer("calculator", port=8080)
|
22
|
-
>>> server.start()
|
23
|
-
|
24
|
-
Quick server creation:
|
25
|
-
|
26
|
-
>>> from kailash.mcp.server import SimpleMCPServer
|
27
|
-
>>> server = SimpleMCPServer("my-tools")
|
28
|
-
>>> @server.tool()
|
29
|
-
... def search(query: str) -> list:
|
30
|
-
... return [f"Result for {query}"]
|
31
|
-
>>> server.start()
|
32
|
-
"""
|
33
|
-
|
34
|
-
import logging
|
35
|
-
from abc import ABC, abstractmethod
|
36
|
-
from collections.abc import Callable
|
37
|
-
|
38
|
-
logger = logging.getLogger(__name__)
|
39
|
-
|
40
|
-
|
41
|
-
class MCPServer(ABC):
|
42
|
-
"""Base class for MCP servers using FastMCP.
|
43
|
-
|
44
|
-
This provides a framework for creating MCP servers that expose
|
45
|
-
tools, resources, and prompts via the Model Context Protocol.
|
46
|
-
|
47
|
-
Examples:
|
48
|
-
Creating a custom server:
|
49
|
-
|
50
|
-
>>> class MyServer(MCPServer):
|
51
|
-
... def setup(self):
|
52
|
-
... @self.add_tool()
|
53
|
-
... def search(query: str) -> str:
|
54
|
-
... return f"Results for: {query}"
|
55
|
-
... @self.add_resource("data://example")
|
56
|
-
... def get_example():
|
57
|
-
... return "Example data"
|
58
|
-
>>> server = MyServer("my-server", port=8080)
|
59
|
-
>>> server.start() # Runs until stopped
|
60
|
-
"""
|
61
|
-
|
62
|
-
def __init__(self, name: str, port: int = 8080, host: str = "localhost"):
|
63
|
-
"""Initialize the MCP server.
|
64
|
-
|
65
|
-
Args:
|
66
|
-
name: Name of the server.
|
67
|
-
port: Port to listen on (default: 8080).
|
68
|
-
host: Host to bind to (default: "localhost").
|
69
|
-
"""
|
70
|
-
self.name = name
|
71
|
-
self.port = port
|
72
|
-
self.host = host
|
73
|
-
self._mcp = None
|
74
|
-
self._running = False
|
75
|
-
|
76
|
-
@abstractmethod
|
77
|
-
def setup(self):
|
78
|
-
"""Setup server tools, resources, and prompts.
|
79
|
-
|
80
|
-
This method should be implemented by subclasses to define
|
81
|
-
the server's capabilities using decorators.
|
82
|
-
|
83
|
-
Note:
|
84
|
-
Use @self.add_tool(), @self.add_resource(uri), and
|
85
|
-
@self.add_prompt(name) decorators to register capabilities.
|
86
|
-
"""
|
87
|
-
|
88
|
-
def add_tool(self):
|
89
|
-
"""Decorator to add a tool to the server.
|
90
|
-
|
91
|
-
Returns:
|
92
|
-
Function decorator for registering tools.
|
93
|
-
|
94
|
-
Examples:
|
95
|
-
>>> @server.add_tool()
|
96
|
-
... def calculate(a: int, b: int) -> int:
|
97
|
-
... '''Add two numbers'''
|
98
|
-
... return a + b
|
99
|
-
"""
|
100
|
-
|
101
|
-
def decorator(func: Callable):
|
102
|
-
if self._mcp is None:
|
103
|
-
self._init_mcp()
|
104
|
-
|
105
|
-
# Use FastMCP's tool decorator
|
106
|
-
return self._mcp.tool()(func)
|
107
|
-
|
108
|
-
return decorator
|
109
|
-
|
110
|
-
def add_resource(self, uri: str):
|
111
|
-
"""Decorator to add a resource to the server.
|
112
|
-
|
113
|
-
Args:
|
114
|
-
uri: URI pattern for the resource (supports wildcards).
|
115
|
-
|
116
|
-
Returns:
|
117
|
-
Function decorator for registering resources.
|
118
|
-
|
119
|
-
Examples:
|
120
|
-
>>> @server.add_resource("file:///data/*")
|
121
|
-
... def get_file(path: str) -> str:
|
122
|
-
... return f"Content of {path}"
|
123
|
-
"""
|
124
|
-
|
125
|
-
def decorator(func: Callable):
|
126
|
-
if self._mcp is None:
|
127
|
-
self._init_mcp()
|
128
|
-
|
129
|
-
# Use FastMCP's resource decorator
|
130
|
-
return self._mcp.resource(uri)(func)
|
131
|
-
|
132
|
-
return decorator
|
133
|
-
|
134
|
-
def add_prompt(self, name: str):
|
135
|
-
"""Decorator to add a prompt template to the server.
|
136
|
-
|
137
|
-
Args:
|
138
|
-
name: Name of the prompt.
|
139
|
-
|
140
|
-
Returns:
|
141
|
-
Function decorator for registering prompts.
|
142
|
-
|
143
|
-
Examples:
|
144
|
-
>>> @server.add_prompt("analyze")
|
145
|
-
... def analyze_prompt(data: str) -> str:
|
146
|
-
... return f"Please analyze the following data: {data}"
|
147
|
-
"""
|
148
|
-
|
149
|
-
def decorator(func: Callable):
|
150
|
-
if self._mcp is None:
|
151
|
-
self._init_mcp()
|
152
|
-
|
153
|
-
# Use FastMCP's prompt decorator
|
154
|
-
return self._mcp.prompt(name)(func)
|
155
|
-
|
156
|
-
return decorator
|
157
|
-
|
158
|
-
def _init_mcp(self):
|
159
|
-
"""Initialize the FastMCP instance."""
|
160
|
-
try:
|
161
|
-
from mcp.server.fastmcp import FastMCP
|
162
|
-
|
163
|
-
self._mcp = FastMCP(self.name)
|
164
|
-
except ImportError:
|
165
|
-
logger.error(
|
166
|
-
"FastMCP not available. Install with: pip install 'mcp[server]'"
|
167
|
-
)
|
168
|
-
raise
|
169
|
-
|
170
|
-
def start(self):
|
171
|
-
"""Start the MCP server.
|
172
|
-
|
173
|
-
This runs the server as a long-lived process until stopped.
|
174
|
-
|
175
|
-
Raises:
|
176
|
-
ImportError: If FastMCP is not available.
|
177
|
-
Exception: If server fails to start.
|
178
|
-
"""
|
179
|
-
if self._mcp is None:
|
180
|
-
self._init_mcp()
|
181
|
-
|
182
|
-
# Run setup to register tools/resources
|
183
|
-
self.setup()
|
184
|
-
|
185
|
-
logger.info(f"Starting MCP server '{self.name}' on {self.host}:{self.port}")
|
186
|
-
self._running = True
|
187
|
-
|
188
|
-
try:
|
189
|
-
# Run the FastMCP server
|
190
|
-
logger.info("Running FastMCP server in stdio mode")
|
191
|
-
self._mcp.run()
|
192
|
-
except Exception as e:
|
193
|
-
logger.error(f"Failed to start server: {e}")
|
194
|
-
raise
|
195
|
-
finally:
|
196
|
-
self._running = False
|
197
|
-
|
198
|
-
def stop(self):
|
199
|
-
"""Stop the MCP server."""
|
200
|
-
logger.info(f"Stopping MCP server '{self.name}'")
|
201
|
-
self._running = False
|
202
|
-
# In a real implementation, we'd need to handle graceful shutdown
|
203
|
-
|
204
|
-
|
205
|
-
class SimpleMCPServer(MCPServer):
|
206
|
-
"""Simple MCP server for basic use cases.
|
207
|
-
|
208
|
-
This provides an easy way to create MCP servers without subclassing.
|
209
|
-
|
210
|
-
Examples:
|
211
|
-
>>> server = SimpleMCPServer("my-server")
|
212
|
-
>>> @server.tool()
|
213
|
-
... def add(a: int, b: int) -> int:
|
214
|
-
... return a + b
|
215
|
-
>>> server.start()
|
216
|
-
"""
|
217
|
-
|
218
|
-
def __init__(self, name: str, port: int = 8080, host: str = "localhost"):
|
219
|
-
"""Initialize the simple MCP server.
|
220
|
-
|
221
|
-
Args:
|
222
|
-
name: Name of the server.
|
223
|
-
port: Port to listen on (default: 8080).
|
224
|
-
host: Host to bind to (default: "localhost").
|
225
|
-
"""
|
226
|
-
super().__init__(name, port, host)
|
227
|
-
self._tools = []
|
228
|
-
self._resources = []
|
229
|
-
self._prompts = []
|
230
|
-
|
231
|
-
def tool(self):
|
232
|
-
"""Decorator to add a tool.
|
233
|
-
|
234
|
-
Returns:
|
235
|
-
Function decorator for registering tools.
|
236
|
-
"""
|
237
|
-
|
238
|
-
def decorator(func):
|
239
|
-
self._tools.append(func)
|
240
|
-
return func
|
241
|
-
|
242
|
-
return decorator
|
243
|
-
|
244
|
-
def resource(self, uri: str):
|
245
|
-
"""Decorator to add a resource.
|
246
|
-
|
247
|
-
Args:
|
248
|
-
uri: URI pattern for the resource.
|
249
|
-
|
250
|
-
Returns:
|
251
|
-
Function decorator for registering resources.
|
252
|
-
"""
|
253
|
-
|
254
|
-
def decorator(func):
|
255
|
-
self._resources.append((uri, func))
|
256
|
-
return func
|
257
|
-
|
258
|
-
return decorator
|
259
|
-
|
260
|
-
def prompt(self, name: str):
|
261
|
-
"""Decorator to add a prompt.
|
262
|
-
|
263
|
-
Args:
|
264
|
-
name: Name of the prompt.
|
265
|
-
|
266
|
-
Returns:
|
267
|
-
Function decorator for registering prompts.
|
268
|
-
"""
|
269
|
-
|
270
|
-
def decorator(func):
|
271
|
-
self._prompts.append((name, func))
|
272
|
-
return func
|
273
|
-
|
274
|
-
return decorator
|
275
|
-
|
276
|
-
def setup(self):
|
277
|
-
"""Setup the server with registered components.
|
278
|
-
|
279
|
-
Registers all tools, resources, and prompts that were decorated
|
280
|
-
before calling start().
|
281
|
-
"""
|
282
|
-
# Register all tools
|
283
|
-
for tool_func in self._tools:
|
284
|
-
self.add_tool()(tool_func)
|
285
|
-
|
286
|
-
# Register all resources
|
287
|
-
for uri, resource_func in self._resources:
|
288
|
-
self.add_resource(uri)(resource_func)
|
289
|
-
|
290
|
-
# Register all prompts
|
291
|
-
for name, prompt_func in self._prompts:
|
292
|
-
self.add_prompt(name)(prompt_func)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|