kailash 0.6.5__py3-none-any.whl → 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. kailash/__init__.py +35 -4
  2. kailash/adapters/__init__.py +5 -0
  3. kailash/adapters/mcp_platform_adapter.py +273 -0
  4. kailash/channels/__init__.py +21 -0
  5. kailash/channels/api_channel.py +409 -0
  6. kailash/channels/base.py +271 -0
  7. kailash/channels/cli_channel.py +661 -0
  8. kailash/channels/event_router.py +496 -0
  9. kailash/channels/mcp_channel.py +648 -0
  10. kailash/channels/session.py +423 -0
  11. kailash/mcp_server/discovery.py +1 -1
  12. kailash/middleware/core/agent_ui.py +5 -0
  13. kailash/middleware/mcp/enhanced_server.py +22 -16
  14. kailash/nexus/__init__.py +21 -0
  15. kailash/nexus/factory.py +413 -0
  16. kailash/nexus/gateway.py +545 -0
  17. kailash/nodes/__init__.py +2 -0
  18. kailash/nodes/ai/iterative_llm_agent.py +988 -17
  19. kailash/nodes/ai/llm_agent.py +29 -9
  20. kailash/nodes/api/__init__.py +2 -2
  21. kailash/nodes/api/monitoring.py +1 -1
  22. kailash/nodes/base_async.py +54 -14
  23. kailash/nodes/code/async_python.py +1 -1
  24. kailash/nodes/data/bulk_operations.py +939 -0
  25. kailash/nodes/data/query_builder.py +373 -0
  26. kailash/nodes/data/query_cache.py +512 -0
  27. kailash/nodes/monitoring/__init__.py +10 -0
  28. kailash/nodes/monitoring/deadlock_detector.py +964 -0
  29. kailash/nodes/monitoring/performance_anomaly.py +1078 -0
  30. kailash/nodes/monitoring/race_condition_detector.py +1151 -0
  31. kailash/nodes/monitoring/transaction_metrics.py +790 -0
  32. kailash/nodes/monitoring/transaction_monitor.py +931 -0
  33. kailash/nodes/system/__init__.py +17 -0
  34. kailash/nodes/system/command_parser.py +820 -0
  35. kailash/nodes/transaction/__init__.py +48 -0
  36. kailash/nodes/transaction/distributed_transaction_manager.py +983 -0
  37. kailash/nodes/transaction/saga_coordinator.py +652 -0
  38. kailash/nodes/transaction/saga_state_storage.py +411 -0
  39. kailash/nodes/transaction/saga_step.py +467 -0
  40. kailash/nodes/transaction/transaction_context.py +756 -0
  41. kailash/nodes/transaction/two_phase_commit.py +978 -0
  42. kailash/nodes/transform/processors.py +17 -1
  43. kailash/nodes/validation/__init__.py +21 -0
  44. kailash/nodes/validation/test_executor.py +532 -0
  45. kailash/nodes/validation/validation_nodes.py +447 -0
  46. kailash/resources/factory.py +1 -1
  47. kailash/runtime/async_local.py +84 -21
  48. kailash/runtime/local.py +21 -2
  49. kailash/runtime/parameter_injector.py +187 -31
  50. kailash/security.py +16 -1
  51. kailash/servers/__init__.py +32 -0
  52. kailash/servers/durable_workflow_server.py +430 -0
  53. kailash/servers/enterprise_workflow_server.py +466 -0
  54. kailash/servers/gateway.py +183 -0
  55. kailash/servers/workflow_server.py +290 -0
  56. kailash/utils/data_validation.py +192 -0
  57. kailash/workflow/builder.py +291 -12
  58. kailash/workflow/validation.py +144 -8
  59. {kailash-0.6.5.dist-info → kailash-0.7.0.dist-info}/METADATA +1 -1
  60. {kailash-0.6.5.dist-info → kailash-0.7.0.dist-info}/RECORD +64 -26
  61. {kailash-0.6.5.dist-info → kailash-0.7.0.dist-info}/WHEEL +0 -0
  62. {kailash-0.6.5.dist-info → kailash-0.7.0.dist-info}/entry_points.txt +0 -0
  63. {kailash-0.6.5.dist-info → kailash-0.7.0.dist-info}/licenses/LICENSE +0 -0
  64. {kailash-0.6.5.dist-info → kailash-0.7.0.dist-info}/top_level.txt +0 -0
kailash/__init__.py CHANGED
@@ -3,8 +3,10 @@
3
3
  The Kailash SDK provides a comprehensive framework for creating nodes and workflows
4
4
  that align with container-node architecture while allowing rapid prototyping.
5
5
 
6
- New in v0.6.5: Enterprise AsyncSQL enhancements with optimistic locking, comprehensive
7
- testing improvements, and production-grade documentation.
6
+ New in v0.7.0: Complete DataFlow and Nexus application frameworks, infrastructure hardening
7
+ with 100% E2E test pass rate, enhanced AsyncNode event loop handling, 8 new monitoring operations,
8
+ distributed transactions, QueryBuilder/QueryCache with Redis, and real MCP execution by default.
9
+ Previous v0.6.6: AgentUIMiddleware shared workflow fix, execute() method standardization.
8
10
  """
9
11
 
10
12
  from kailash.nodes.base import Node, NodeMetadata, NodeParameter
@@ -22,6 +24,23 @@ try:
22
24
  AIChatMiddleware,
23
25
  APIGateway,
24
26
  RealtimeMiddleware,
27
+ )
28
+
29
+ # Import Nexus multi-channel framework (v0.6.7+)
30
+ from kailash.nexus import NexusGateway, create_nexus
31
+
32
+ # Import new server classes (v0.6.7+)
33
+ from kailash.servers import (
34
+ DurableWorkflowServer,
35
+ EnterpriseWorkflowServer,
36
+ WorkflowServer,
37
+ )
38
+
39
+ # Import updated create_gateway function with enterprise defaults
40
+ from kailash.servers.gateway import (
41
+ create_basic_gateway,
42
+ create_durable_gateway,
43
+ create_enterprise_gateway,
25
44
  create_gateway,
26
45
  )
27
46
 
@@ -33,7 +52,7 @@ except ImportError:
33
52
  # For backward compatibility
34
53
  WorkflowGraph = Workflow
35
54
 
36
- __version__ = "0.6.4"
55
+ __version__ = "0.7.0"
37
56
 
38
57
  __all__ = [
39
58
  # Core workflow components
@@ -49,14 +68,26 @@ __all__ = [
49
68
  "LocalRuntime",
50
69
  ]
51
70
 
52
- # Add middleware to exports if available
71
+ # Add middleware and servers to exports if available
53
72
  if _MIDDLEWARE_AVAILABLE:
54
73
  __all__.extend(
55
74
  [
75
+ # Legacy middleware
56
76
  "AgentUIMiddleware",
57
77
  "RealtimeMiddleware",
58
78
  "APIGateway",
59
79
  "AIChatMiddleware",
80
+ # New server classes
81
+ "WorkflowServer",
82
+ "DurableWorkflowServer",
83
+ "EnterpriseWorkflowServer",
84
+ # Gateway creation functions
60
85
  "create_gateway",
86
+ "create_enterprise_gateway",
87
+ "create_durable_gateway",
88
+ "create_basic_gateway",
89
+ # Nexus multi-channel framework
90
+ "NexusGateway",
91
+ "create_nexus",
61
92
  ]
62
93
  )
@@ -0,0 +1,5 @@
1
+ """Integration adapters for bridging different component systems in Kailash SDK."""
2
+
3
+ from .mcp_platform_adapter import MCPPlatformAdapter
4
+
5
+ __all__ = ["MCPPlatformAdapter"]
@@ -0,0 +1,273 @@
1
+ """Adapter for bridging mcp_platform and core SDK parameter formats."""
2
+
3
+ import logging
4
+ from typing import Any, Dict, List, Optional, Union
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ class MCPPlatformAdapter:
10
+ """Adapter to translate between mcp_platform and SDK MCP parameter formats."""
11
+
12
+ @staticmethod
13
+ def translate_server_config(platform_config: Dict[str, Any]) -> Dict[str, Any]:
14
+ """Translate mcp_platform server config to SDK format.
15
+
16
+ Args:
17
+ platform_config: Server config from mcp_platform
18
+
19
+ Returns:
20
+ SDK-compatible server config
21
+ """
22
+ if not isinstance(platform_config, dict):
23
+ logger.error(f"Platform config must be dict, got {type(platform_config)}")
24
+ return {}
25
+
26
+ # Extract mcp_platform format: {"transport": "stdio", "command": "...", "args": [...]}
27
+ sdk_config = {}
28
+
29
+ # Map required fields
30
+ if "name" not in platform_config:
31
+ # Generate name from command if not provided
32
+ command = platform_config.get("command", "unknown")
33
+ sdk_config["name"] = command.split("/")[-1].split("\\")[-1]
34
+ else:
35
+ sdk_config["name"] = platform_config["name"]
36
+
37
+ # Transport mapping
38
+ transport = platform_config.get("transport", "stdio")
39
+ sdk_config["transport"] = transport
40
+
41
+ # Command mapping
42
+ if "command" in platform_config:
43
+ sdk_config["command"] = platform_config["command"]
44
+
45
+ # Arguments mapping
46
+ if "args" in platform_config:
47
+ sdk_config["args"] = platform_config["args"]
48
+ elif "arguments" in platform_config:
49
+ sdk_config["args"] = platform_config["arguments"]
50
+
51
+ # Environment mapping
52
+ if "env" in platform_config:
53
+ sdk_config["env"] = platform_config["env"]
54
+ elif "environment" in platform_config:
55
+ sdk_config["env"] = platform_config["environment"]
56
+
57
+ # Server-specific settings
58
+ if "auto_start" in platform_config:
59
+ sdk_config["auto_start"] = platform_config["auto_start"]
60
+
61
+ if "timeout" in platform_config:
62
+ sdk_config["timeout"] = platform_config["timeout"]
63
+
64
+ # Tool list mapping
65
+ if "tools" in platform_config:
66
+ sdk_config["tools"] = platform_config["tools"]
67
+
68
+ logger.debug(f"Translated platform config to SDK format: {sdk_config}")
69
+ return sdk_config
70
+
71
+ @staticmethod
72
+ def translate_mcp_servers_list(
73
+ platform_servers: List[Dict[str, Any]],
74
+ ) -> List[Dict[str, Any]]:
75
+ """Translate list of mcp_platform server configs to SDK format.
76
+
77
+ Args:
78
+ platform_servers: List of server configs from mcp_platform
79
+
80
+ Returns:
81
+ List of SDK-compatible server configs
82
+ """
83
+ if not isinstance(platform_servers, list):
84
+ logger.error(f"Platform servers must be list, got {type(platform_servers)}")
85
+ return []
86
+
87
+ sdk_servers = []
88
+ for i, platform_config in enumerate(platform_servers):
89
+ try:
90
+ sdk_config = MCPPlatformAdapter.translate_server_config(platform_config)
91
+ if sdk_config:
92
+ sdk_servers.append(sdk_config)
93
+ else:
94
+ logger.warning(
95
+ f"Failed to translate server config {i}: {platform_config}"
96
+ )
97
+ except Exception as e:
98
+ logger.error(f"Error translating server config {i}: {e}")
99
+
100
+ return sdk_servers
101
+
102
+ @staticmethod
103
+ def translate_tool_parameters(
104
+ platform_params: Dict[str, Any], tool_schema: Optional[Dict[str, Any]] = None
105
+ ) -> Dict[str, Any]:
106
+ """Translate mcp_platform tool parameters to SDK format.
107
+
108
+ Args:
109
+ platform_params: Parameters from mcp_platform
110
+ tool_schema: Optional tool schema for validation
111
+
112
+ Returns:
113
+ SDK-compatible tool parameters
114
+ """
115
+ if not isinstance(platform_params, dict):
116
+ logger.error(f"Platform params must be dict, got {type(platform_params)}")
117
+ return {}
118
+
119
+ sdk_params = {}
120
+
121
+ # Handle nested server configuration
122
+ if "server_config" in platform_params:
123
+ server_config = platform_params["server_config"]
124
+ sdk_params["mcp_server_config"] = (
125
+ MCPPlatformAdapter.translate_server_config(server_config)
126
+ )
127
+
128
+ # Handle tool-specific parameters
129
+ for key, value in platform_params.items():
130
+ if key == "server_config":
131
+ continue # Already handled above
132
+
133
+ # Parameter name mapping
134
+ if key == "tool_name":
135
+ sdk_params["name"] = value
136
+ elif key == "tool_args":
137
+ sdk_params["arguments"] = value
138
+ elif key == "tool_params":
139
+ sdk_params["parameters"] = value
140
+ else:
141
+ sdk_params[key] = value
142
+
143
+ # Validate against tool schema if provided
144
+ if tool_schema and "parameters" in tool_schema:
145
+ required_params = tool_schema["parameters"].get("required", [])
146
+ missing_params = [p for p in required_params if p not in sdk_params]
147
+ if missing_params:
148
+ logger.warning(f"Missing required tool parameters: {missing_params}")
149
+
150
+ logger.debug(f"Translated tool parameters: {sdk_params}")
151
+ return sdk_params
152
+
153
+ @staticmethod
154
+ def translate_llm_agent_config(platform_config: Dict[str, Any]) -> Dict[str, Any]:
155
+ """Translate mcp_platform LLM agent config to SDK format.
156
+
157
+ Args:
158
+ platform_config: LLM agent config from mcp_platform
159
+
160
+ Returns:
161
+ SDK-compatible LLM agent config
162
+ """
163
+ if not isinstance(platform_config, dict):
164
+ logger.error(f"Platform config must be dict, got {type(platform_config)}")
165
+ return {}
166
+
167
+ sdk_config = platform_config.copy()
168
+
169
+ # Handle mcp_platform server configuration
170
+ if "server_config" in platform_config:
171
+ server_config = platform_config["server_config"]
172
+ if isinstance(server_config, dict):
173
+ # Single server config
174
+ sdk_config["mcp_servers"] = [
175
+ MCPPlatformAdapter.translate_server_config(server_config)
176
+ ]
177
+ elif isinstance(server_config, list):
178
+ # Multiple server configs
179
+ sdk_config["mcp_servers"] = (
180
+ MCPPlatformAdapter.translate_mcp_servers_list(server_config)
181
+ )
182
+
183
+ # Remove the old key
184
+ sdk_config.pop("server_config")
185
+
186
+ # Handle server_configs (plural) as well
187
+ if "server_configs" in platform_config:
188
+ server_configs = platform_config["server_configs"]
189
+ sdk_config["mcp_servers"] = MCPPlatformAdapter.translate_mcp_servers_list(
190
+ server_configs
191
+ )
192
+ sdk_config.pop("server_configs")
193
+
194
+ # Ensure use_real_mcp is set correctly
195
+ if "use_real_mcp" not in sdk_config:
196
+ sdk_config["use_real_mcp"] = True # Default to real MCP execution
197
+
198
+ logger.debug(f"Translated LLM agent config: {sdk_config}")
199
+ return sdk_config
200
+
201
+ @staticmethod
202
+ def validate_integration(
203
+ platform_data: Dict[str, Any], expected_sdk_format: str
204
+ ) -> bool:
205
+ """Validate that platform data can be properly translated to SDK format.
206
+
207
+ Args:
208
+ platform_data: Data from mcp_platform
209
+ expected_sdk_format: Expected SDK format type ("server_config", "tool_params", "llm_config")
210
+
211
+ Returns:
212
+ True if valid for translation, False otherwise
213
+ """
214
+ if not isinstance(platform_data, dict):
215
+ logger.error(f"Platform data must be dict for {expected_sdk_format}")
216
+ return False
217
+
218
+ if expected_sdk_format == "server_config":
219
+ required_fields = ["transport"]
220
+ optional_fields = ["command", "name", "args"]
221
+
222
+ elif expected_sdk_format == "tool_params":
223
+ required_fields = []
224
+ optional_fields = ["tool_name", "tool_args", "server_config"]
225
+
226
+ elif expected_sdk_format == "llm_config":
227
+ required_fields = []
228
+ optional_fields = ["server_config", "server_configs", "mcp_servers"]
229
+
230
+ else:
231
+ logger.error(f"Unknown SDK format: {expected_sdk_format}")
232
+ return False
233
+
234
+ # Check for required fields
235
+ missing_required = [f for f in required_fields if f not in platform_data]
236
+ if missing_required:
237
+ logger.error(
238
+ f"Missing required fields for {expected_sdk_format}: {missing_required}"
239
+ )
240
+ return False
241
+
242
+ # Check if we have at least some relevant fields
243
+ has_relevant_fields = any(
244
+ f in platform_data for f in required_fields + optional_fields
245
+ )
246
+ if not has_relevant_fields:
247
+ logger.warning(f"No relevant fields found for {expected_sdk_format}")
248
+ return False
249
+
250
+ return True
251
+
252
+ @staticmethod
253
+ def create_error_recovery_config(
254
+ original_config: Any, error_msg: str
255
+ ) -> Dict[str, Any]:
256
+ """Create a recovery configuration when translation fails.
257
+
258
+ Args:
259
+ original_config: The original configuration that failed
260
+ error_msg: Error message describing the failure
261
+
262
+ Returns:
263
+ Recovery configuration
264
+ """
265
+ return {
266
+ "name": "error_recovery",
267
+ "transport": "stdio",
268
+ "command": "echo",
269
+ "args": ["Error in MCP configuration"],
270
+ "original_config": original_config,
271
+ "error_message": error_msg,
272
+ "recovery_mode": True,
273
+ }
@@ -0,0 +1,21 @@
1
+ """Channel abstractions for Nexus multi-channel architecture.
2
+
3
+ This module provides the core channel abstractions for the Kailash Nexus framework,
4
+ enabling unified management of API, CLI, and MCP interfaces through a common channel abstraction.
5
+ """
6
+
7
+ from .api_channel import APIChannel
8
+ from .base import Channel, ChannelConfig
9
+ from .cli_channel import CLIChannel
10
+ from .mcp_channel import MCPChannel
11
+ from .session import CrossChannelSession, SessionManager
12
+
13
+ __all__ = [
14
+ "Channel",
15
+ "ChannelConfig",
16
+ "APIChannel",
17
+ "CLIChannel",
18
+ "MCPChannel",
19
+ "SessionManager",
20
+ "CrossChannelSession",
21
+ ]