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.
Files changed (41) hide show
  1. kailash/__init__.py +1 -1
  2. kailash/core/actors/connection_actor.py +3 -3
  3. kailash/gateway/api.py +7 -5
  4. kailash/gateway/enhanced_gateway.py +1 -1
  5. kailash/{mcp → mcp_server}/__init__.py +12 -7
  6. kailash/{mcp → mcp_server}/ai_registry_server.py +2 -2
  7. kailash/{mcp/server_enhanced.py → mcp_server/server.py} +231 -48
  8. kailash/{mcp → mcp_server}/servers/ai_registry.py +2 -2
  9. kailash/{mcp → mcp_server}/utils/__init__.py +1 -6
  10. kailash/middleware/auth/access_control.py +5 -5
  11. kailash/middleware/gateway/checkpoint_manager.py +45 -8
  12. kailash/middleware/mcp/client_integration.py +1 -1
  13. kailash/middleware/mcp/enhanced_server.py +2 -2
  14. kailash/nodes/admin/permission_check.py +110 -30
  15. kailash/nodes/admin/schema.sql +387 -0
  16. kailash/nodes/admin/tenant_isolation.py +249 -0
  17. kailash/nodes/admin/transaction_utils.py +244 -0
  18. kailash/nodes/admin/user_management.py +37 -9
  19. kailash/nodes/ai/ai_providers.py +55 -3
  20. kailash/nodes/ai/iterative_llm_agent.py +1 -1
  21. kailash/nodes/ai/llm_agent.py +118 -16
  22. kailash/nodes/data/sql.py +24 -0
  23. kailash/resources/registry.py +6 -0
  24. kailash/runtime/async_local.py +7 -0
  25. kailash/utils/export.py +152 -0
  26. kailash/workflow/builder.py +42 -0
  27. kailash/workflow/graph.py +86 -17
  28. kailash/workflow/templates.py +4 -9
  29. {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/METADATA +3 -2
  30. {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/RECORD +40 -38
  31. kailash/mcp/server.py +0 -292
  32. /kailash/{mcp → mcp_server}/client.py +0 -0
  33. /kailash/{mcp → mcp_server}/client_new.py +0 -0
  34. /kailash/{mcp → mcp_server}/utils/cache.py +0 -0
  35. /kailash/{mcp → mcp_server}/utils/config.py +0 -0
  36. /kailash/{mcp → mcp_server}/utils/formatters.py +0 -0
  37. /kailash/{mcp → mcp_server}/utils/metrics.py +0 -0
  38. {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/WHEEL +0 -0
  39. {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/entry_points.txt +0 -0
  40. {kailash-0.6.1.dist-info → kailash-0.6.3.dist-info}/licenses/LICENSE +0 -0
  41. {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
- warnings.warn(
350
- "Using workflow.connect() with cycle=True is deprecated and will be removed in v0.2.0. "
351
- "Use the new CycleBuilder API instead:\n"
352
- " workflow.create_cycle('cycle_name')\\\n"
353
- " .connect(source_node, target_node)\\\n"
354
- " .max_iterations(N)\\\n"
355
- " .converge_when('condition')\\\n"
356
- " .build()\n"
357
- "See Phase 5 API documentation for details.",
358
- DeprecationWarning,
359
- stacklevel=2,
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
- raise ConnectionError(
431
- f"Connection already exists between '{source_node}' and '{target_node}'. "
432
- f"Existing mappings: {[c.model_dump() for c in existing_connections]}"
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
- # Add or update the edge (NetworkX will update if edge exists)
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
@@ -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
- processor_node,
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.1
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=3ymX4NjOkCaHdw8nCAxgzBLwNu5hIc9i8zWgOMBRmEg,1724
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=TFqlYPEnV8Hjmc706tdRzEw9pBJs2OieH8UeaOrWYIo,18949
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=rvbqV85Av1w7b0FsOg9pulcguu1Oq0D37t029N-tqsA,9478
43
- kailash/gateway/enhanced_gateway.py,sha256=WYs56k31VLRbfryeRwuiahDAL59aHk99eGrmGtvuD0A,13389
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/mcp/__init__.py,sha256=jQHP7EVT126QXmi0TqR1mU3QNrUeEB4oIC4sD4B2a8c,1813
47
- kailash/mcp/ai_registry_server.py,sha256=9pOzJnJFpxJnZPfLo2QvVZ5yvAq5IRqzXPbQL1rL1ns,28104
48
- kailash/mcp/client.py,sha256=sTouSiuiu1nbahMXSWcP8-mr1k7cqdBCzSxm8G7le-s,16058
49
- kailash/mcp/client_new.py,sha256=YU671JvAM0uvuX0uhGZCIKI8co3fqz0cs6HqLZ59Xyo,10285
50
- kailash/mcp/server.py,sha256=aWU0DHj89FN_eEgH6aVjA05WjthugrXMHdPlgwJ6kZg,8246
51
- kailash/mcp/server_enhanced.py,sha256=lRIDSNs0c8urMq_SURwi7eBhTWKa-rq2FAB8xZf9CwI,14724
52
- kailash/mcp/servers/ai_registry.py,sha256=7k17ld0DUQYL476N5EbiNpPy8D0HqPRhrl8Wk1ajjj8,9992
53
- kailash/mcp/utils/__init__.py,sha256=R20N-iiKXUPxc9MOh6vPO1vIfkPmwhEQ5KNFgGd4xSs,771
54
- kailash/mcp/utils/cache.py,sha256=dLEseovPaXL4lRzMSw7tqd3tJHwnWfhdZ-HKGyScJXI,8414
55
- kailash/mcp/utils/config.py,sha256=DyZxgdy3vqI5pwhQ_E-42mhueVGNHiuOtTUOrM9HC_U,8124
56
- kailash/mcp/utils/formatters.py,sha256=D-2j1nvmprApiUI13HWY-L2_WPSAcJDtVdHcshAuOdo,9740
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=6Z09mPyeTb1VBi2C4wRlyqNaJN0lR-me6GMwxDaoR5c,14954
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=kSX90UeSI4gN4aaLa__BOMxIUhNpl0PJ3wGxa7KUCdQ,13606
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=opzhB5TUts_ND8gARXh93nKCc1u4kwo6SqNMMWqMcSU,18258
91
- kailash/middleware/mcp/enhanced_server.py,sha256=XUjQt0KyRX207FVYAFenkYHa_K8FWWKquROgXQWkoOQ,18453
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=0SY1PojT3kymhE8hjkXlY6t0OuESDGjJl3IkB8lnUlA,63109
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/user_management.py,sha256=yoOee8auya9CMiXfDMPH_9A83OdaoJ0B_Sc72sto88w,53702
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=XK7AzC8uL8nIxukZs6bxX4g75vcxCbehefgvR4QJgXk,62824
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=pv54W_YDfDPDl6DJf0ul9_rs2mL2kE_C59sSAJ4CRn8,52884
113
- kailash/nodes/ai/llm_agent.py,sha256=Beb07UNzCvPjHLTgYG9HeGsmuAXGLPjcExY30DghBfA,77566
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=3On6JatlXvGrp2D4MdObX_l_H3CIEoHxqoPUoSfXYso,34426
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=4qXk4rdsPeaUgwizLakq1TG9cLCNuKQGd313vCIstnw,13504
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=Ebk3-pDij804YCQST7izXzqC0QWAS5--X_pnNqiwNxQ,29900
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=HViwFBtg20VnGBC9gQjHcnu44wQ1u2vOZMXR8EtfGvw,31913
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=CPnfNHlL4HKsX58BI4kOv-CLNrFa_7cg_0lBqqVByYw,10779
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=gknGNgv3Z6FyNno90jZLGHZ0tTdiUx0_HAy6bEWh6OQ,56156
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=MTIMHGyQML6omLbqeKDbTVIVykfXG6pIFWTTsGBUHN0,48591
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.1.dist-info/licenses/LICENSE,sha256=Axe6g7bTrJkToK9h9j2SpRUKKNaDZDCo2lQ2zPxCE6s,1065
272
- kailash-0.6.1.dist-info/METADATA,sha256=uYAx8RZ-rKdgoXsNC0jOUmdDIJ8or0CTEm7eWW6z2BA,25896
273
- kailash-0.6.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
274
- kailash-0.6.1.dist-info/entry_points.txt,sha256=M_q3b8PG5W4XbhSgESzIJjh3_4OBKtZFYFsOdkr2vO4,45
275
- kailash-0.6.1.dist-info/top_level.txt,sha256=z7GzH2mxl66498pVf5HKwo5wwfPtt9Aq95uZUpH6JV0,8
276
- kailash-0.6.1.dist-info/RECORD,,
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