kailash 0.1.4__py3-none-any.whl → 0.2.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.
- kailash/__init__.py +1 -1
- kailash/access_control.py +740 -0
- kailash/api/__main__.py +6 -0
- kailash/api/auth.py +668 -0
- kailash/api/custom_nodes.py +285 -0
- kailash/api/custom_nodes_secure.py +377 -0
- kailash/api/database.py +620 -0
- kailash/api/studio.py +915 -0
- kailash/api/studio_secure.py +893 -0
- kailash/mcp/__init__.py +53 -0
- kailash/mcp/__main__.py +13 -0
- kailash/mcp/ai_registry_server.py +712 -0
- kailash/mcp/client.py +447 -0
- kailash/mcp/client_new.py +334 -0
- kailash/mcp/server.py +293 -0
- kailash/mcp/server_new.py +336 -0
- kailash/mcp/servers/__init__.py +12 -0
- kailash/mcp/servers/ai_registry.py +289 -0
- kailash/nodes/__init__.py +4 -2
- kailash/nodes/ai/__init__.py +38 -0
- kailash/nodes/ai/a2a.py +1790 -0
- kailash/nodes/ai/agents.py +116 -2
- kailash/nodes/ai/ai_providers.py +206 -8
- kailash/nodes/ai/intelligent_agent_orchestrator.py +2108 -0
- kailash/nodes/ai/iterative_llm_agent.py +1280 -0
- kailash/nodes/ai/llm_agent.py +324 -1
- kailash/nodes/ai/self_organizing.py +1623 -0
- kailash/nodes/api/http.py +106 -25
- kailash/nodes/api/rest.py +116 -21
- kailash/nodes/base.py +15 -2
- kailash/nodes/base_async.py +45 -0
- kailash/nodes/base_cycle_aware.py +374 -0
- kailash/nodes/base_with_acl.py +338 -0
- kailash/nodes/code/python.py +135 -27
- kailash/nodes/data/readers.py +116 -53
- kailash/nodes/data/writers.py +16 -6
- kailash/nodes/logic/__init__.py +8 -0
- kailash/nodes/logic/async_operations.py +48 -9
- kailash/nodes/logic/convergence.py +642 -0
- kailash/nodes/logic/loop.py +153 -0
- kailash/nodes/logic/operations.py +212 -27
- kailash/nodes/logic/workflow.py +26 -18
- kailash/nodes/mixins/__init__.py +11 -0
- kailash/nodes/mixins/mcp.py +228 -0
- kailash/nodes/mixins.py +387 -0
- kailash/nodes/transform/__init__.py +8 -1
- kailash/nodes/transform/processors.py +119 -4
- kailash/runtime/__init__.py +2 -1
- kailash/runtime/access_controlled.py +458 -0
- kailash/runtime/local.py +106 -33
- kailash/runtime/parallel_cyclic.py +529 -0
- kailash/sdk_exceptions.py +90 -5
- kailash/security.py +845 -0
- kailash/tracking/manager.py +38 -15
- kailash/tracking/models.py +1 -1
- kailash/tracking/storage/filesystem.py +30 -2
- kailash/utils/__init__.py +8 -0
- kailash/workflow/__init__.py +18 -0
- kailash/workflow/convergence.py +270 -0
- kailash/workflow/cycle_analyzer.py +768 -0
- kailash/workflow/cycle_builder.py +573 -0
- kailash/workflow/cycle_config.py +709 -0
- kailash/workflow/cycle_debugger.py +760 -0
- kailash/workflow/cycle_exceptions.py +601 -0
- kailash/workflow/cycle_profiler.py +671 -0
- kailash/workflow/cycle_state.py +338 -0
- kailash/workflow/cyclic_runner.py +985 -0
- kailash/workflow/graph.py +500 -39
- kailash/workflow/migration.py +768 -0
- kailash/workflow/safety.py +365 -0
- kailash/workflow/templates.py +744 -0
- kailash/workflow/validation.py +693 -0
- {kailash-0.1.4.dist-info → kailash-0.2.0.dist-info}/METADATA +446 -13
- kailash-0.2.0.dist-info/RECORD +125 -0
- kailash/nodes/mcp/__init__.py +0 -11
- kailash/nodes/mcp/client.py +0 -554
- kailash/nodes/mcp/resource.py +0 -682
- kailash/nodes/mcp/server.py +0 -577
- kailash-0.1.4.dist-info/RECORD +0 -85
- {kailash-0.1.4.dist-info → kailash-0.2.0.dist-info}/WHEEL +0 -0
- {kailash-0.1.4.dist-info → kailash-0.2.0.dist-info}/entry_points.txt +0 -0
- {kailash-0.1.4.dist-info → kailash-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.1.4.dist-info → kailash-0.2.0.dist-info}/top_level.txt +0 -0
kailash/runtime/local.py
CHANGED
@@ -1,4 +1,43 @@
|
|
1
|
-
"""Local
|
1
|
+
"""Enhanced Local Runtime Engine with Comprehensive Cycle Support.
|
2
|
+
|
3
|
+
This module provides a sophisticated local execution engine for workflows with
|
4
|
+
advanced support for both traditional DAG workflows and complex cyclic patterns.
|
5
|
+
It offers comprehensive task tracking, performance monitoring, and debugging
|
6
|
+
capabilities for development and production use.
|
7
|
+
|
8
|
+
Examples:
|
9
|
+
Basic workflow execution:
|
10
|
+
|
11
|
+
>>> from kailash.runtime.local import LocalRuntime
|
12
|
+
>>> runtime = LocalRuntime(debug=True, enable_cycles=True)
|
13
|
+
>>> results = runtime.execute(workflow, parameters={"input": "data"})
|
14
|
+
|
15
|
+
With comprehensive tracking:
|
16
|
+
|
17
|
+
>>> from kailash.tracking import TaskManager
|
18
|
+
>>> runtime = LocalRuntime(enable_cycles=True)
|
19
|
+
>>> task_manager = TaskManager()
|
20
|
+
>>> results = runtime.execute(
|
21
|
+
... workflow,
|
22
|
+
... task_manager=task_manager,
|
23
|
+
... parameters={"initial_value": 10}
|
24
|
+
... )
|
25
|
+
>>> # Access detailed execution information
|
26
|
+
>>> tasks = task_manager.get_tasks_for_workflow(workflow.workflow_id)
|
27
|
+
>>> metrics = task_manager.get_performance_summary()
|
28
|
+
|
29
|
+
Production configuration:
|
30
|
+
|
31
|
+
>>> runtime = LocalRuntime(
|
32
|
+
... debug=False, # Optimized for performance
|
33
|
+
... enable_cycles=True # Support cyclic patterns
|
34
|
+
... )
|
35
|
+
>>> results = runtime.execute(
|
36
|
+
... workflow,
|
37
|
+
... parameters=input_params,
|
38
|
+
... run_id="production_run_001"
|
39
|
+
... )
|
40
|
+
"""
|
2
41
|
|
3
42
|
import logging
|
4
43
|
from datetime import datetime, timezone
|
@@ -16,22 +55,33 @@ from kailash.tracking import TaskManager, TaskStatus
|
|
16
55
|
from kailash.tracking.metrics_collector import MetricsCollector
|
17
56
|
from kailash.tracking.models import TaskMetrics
|
18
57
|
from kailash.workflow import Workflow
|
58
|
+
from kailash.workflow.cyclic_runner import CyclicWorkflowExecutor
|
19
59
|
|
20
60
|
logger = logging.getLogger(__name__)
|
21
61
|
|
22
62
|
|
23
63
|
class LocalRuntime:
|
24
|
-
"""Local execution engine for workflows.
|
64
|
+
"""Local execution engine for workflows.
|
25
65
|
|
26
|
-
|
66
|
+
This class provides a robust, production-ready execution engine that seamlessly
|
67
|
+
handles both traditional workflows and advanced cyclic patterns.
|
68
|
+
"""
|
69
|
+
|
70
|
+
def __init__(self, debug: bool = False, enable_cycles: bool = True):
|
27
71
|
"""Initialize the local runtime.
|
28
72
|
|
29
73
|
Args:
|
30
|
-
debug: Whether to enable debug logging
|
74
|
+
debug: Whether to enable debug logging.
|
75
|
+
enable_cycles: Whether to enable cyclic workflow support.
|
31
76
|
"""
|
32
77
|
self.debug = debug
|
78
|
+
self.enable_cycles = enable_cycles
|
33
79
|
self.logger = logger
|
34
80
|
|
81
|
+
# Initialize cyclic workflow executor if enabled
|
82
|
+
if enable_cycles:
|
83
|
+
self.cyclic_executor = CyclicWorkflowExecutor()
|
84
|
+
|
35
85
|
if debug:
|
36
86
|
self.logger.setLevel(logging.DEBUG)
|
37
87
|
else:
|
@@ -46,16 +96,16 @@ class LocalRuntime:
|
|
46
96
|
"""Execute a workflow locally.
|
47
97
|
|
48
98
|
Args:
|
49
|
-
workflow: Workflow to execute
|
50
|
-
task_manager: Optional task manager for tracking
|
51
|
-
parameters: Optional parameter overrides per node
|
99
|
+
workflow: Workflow to execute.
|
100
|
+
task_manager: Optional task manager for tracking.
|
101
|
+
parameters: Optional parameter overrides per node.
|
52
102
|
|
53
103
|
Returns:
|
54
|
-
Tuple of (results dict, run_id)
|
104
|
+
Tuple of (results dict, run_id).
|
55
105
|
|
56
106
|
Raises:
|
57
|
-
RuntimeExecutionError: If execution fails
|
58
|
-
WorkflowValidationError: If workflow is invalid
|
107
|
+
RuntimeExecutionError: If execution fails.
|
108
|
+
WorkflowValidationError: If workflow is invalid.
|
59
109
|
"""
|
60
110
|
if not workflow:
|
61
111
|
raise RuntimeExecutionError("No workflow provided")
|
@@ -81,13 +131,36 @@ class LocalRuntime:
|
|
81
131
|
self.logger.warning(f"Failed to create task run: {e}")
|
82
132
|
# Continue without tracking
|
83
133
|
|
84
|
-
#
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
134
|
+
# Check for cyclic workflows and delegate accordingly
|
135
|
+
if self.enable_cycles and workflow.has_cycles():
|
136
|
+
self.logger.info(
|
137
|
+
"Cyclic workflow detected, using CyclicWorkflowExecutor"
|
138
|
+
)
|
139
|
+
# Use cyclic executor for workflows with cycles
|
140
|
+
try:
|
141
|
+
# Pass run_id to cyclic executor if available
|
142
|
+
cyclic_results, cyclic_run_id = self.cyclic_executor.execute(
|
143
|
+
workflow, parameters, task_manager, run_id
|
144
|
+
)
|
145
|
+
results = cyclic_results
|
146
|
+
# Update run_id if task manager is being used
|
147
|
+
if not run_id:
|
148
|
+
run_id = cyclic_run_id
|
149
|
+
except Exception as e:
|
150
|
+
raise RuntimeExecutionError(
|
151
|
+
f"Cyclic workflow execution failed: {e}"
|
152
|
+
) from e
|
153
|
+
else:
|
154
|
+
# Execute standard DAG workflow
|
155
|
+
self.logger.info(
|
156
|
+
"Standard DAG workflow detected, using local execution"
|
157
|
+
)
|
158
|
+
results = self._execute_workflow(
|
159
|
+
workflow=workflow,
|
160
|
+
task_manager=task_manager,
|
161
|
+
run_id=run_id,
|
162
|
+
parameters=parameters or {},
|
163
|
+
)
|
91
164
|
|
92
165
|
# Mark run as completed
|
93
166
|
if task_manager and run_id:
|
@@ -131,16 +204,16 @@ class LocalRuntime:
|
|
131
204
|
"""Execute the workflow nodes in topological order.
|
132
205
|
|
133
206
|
Args:
|
134
|
-
workflow: Workflow to execute
|
135
|
-
task_manager: Task manager for tracking
|
136
|
-
run_id: Run ID for tracking
|
137
|
-
parameters: Parameter overrides
|
207
|
+
workflow: Workflow to execute.
|
208
|
+
task_manager: Task manager for tracking.
|
209
|
+
run_id: Run ID for tracking.
|
210
|
+
parameters: Parameter overrides.
|
138
211
|
|
139
212
|
Returns:
|
140
|
-
Dictionary of node results
|
213
|
+
Dictionary of node results.
|
141
214
|
|
142
215
|
Raises:
|
143
|
-
WorkflowExecutionError: If execution fails
|
216
|
+
WorkflowExecutionError: If execution fails.
|
144
217
|
"""
|
145
218
|
# Get execution order
|
146
219
|
try:
|
@@ -304,17 +377,17 @@ class LocalRuntime:
|
|
304
377
|
"""Prepare inputs for a node execution.
|
305
378
|
|
306
379
|
Args:
|
307
|
-
workflow: The workflow being executed
|
308
|
-
node_id: Current node ID
|
309
|
-
node_instance: Current node instance
|
310
|
-
node_outputs: Outputs from previously executed nodes
|
311
|
-
parameters: Parameter overrides
|
380
|
+
workflow: The workflow being executed.
|
381
|
+
node_id: Current node ID.
|
382
|
+
node_instance: Current node instance.
|
383
|
+
node_outputs: Outputs from previously executed nodes.
|
384
|
+
parameters: Parameter overrides.
|
312
385
|
|
313
386
|
Returns:
|
314
|
-
Dictionary of inputs for the node
|
387
|
+
Dictionary of inputs for the node.
|
315
388
|
|
316
389
|
Raises:
|
317
|
-
WorkflowExecutionError: If input preparation fails
|
390
|
+
WorkflowExecutionError: If input preparation fails.
|
318
391
|
"""
|
319
392
|
inputs = {}
|
320
393
|
|
@@ -353,11 +426,11 @@ class LocalRuntime:
|
|
353
426
|
"""Determine if execution should stop when a node fails.
|
354
427
|
|
355
428
|
Args:
|
356
|
-
workflow: The workflow being executed
|
357
|
-
node_id: Failed node ID
|
429
|
+
workflow: The workflow being executed.
|
430
|
+
node_id: Failed node ID.
|
358
431
|
|
359
432
|
Returns:
|
360
|
-
Whether to stop execution
|
433
|
+
Whether to stop execution.
|
361
434
|
"""
|
362
435
|
# Check if any downstream nodes depend on this node
|
363
436
|
has_dependents = workflow.graph.out_degree(node_id) > 0
|