kailash 0.3.0__py3-none-any.whl → 0.3.1__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 +40 -39
- kailash/api/auth.py +26 -32
- kailash/api/custom_nodes.py +29 -29
- kailash/api/custom_nodes_secure.py +35 -35
- kailash/api/database.py +17 -17
- kailash/api/gateway.py +19 -19
- kailash/api/mcp_integration.py +24 -23
- kailash/api/studio.py +45 -45
- kailash/api/workflow_api.py +8 -8
- kailash/cli/commands.py +5 -8
- kailash/manifest.py +42 -42
- kailash/mcp/__init__.py +1 -1
- kailash/mcp/ai_registry_server.py +20 -20
- kailash/mcp/client.py +9 -11
- kailash/mcp/client_new.py +10 -10
- kailash/mcp/server.py +1 -2
- kailash/mcp/server_enhanced.py +449 -0
- kailash/mcp/servers/ai_registry.py +6 -6
- kailash/mcp/utils/__init__.py +31 -0
- kailash/mcp/utils/cache.py +267 -0
- kailash/mcp/utils/config.py +263 -0
- kailash/mcp/utils/formatters.py +293 -0
- kailash/mcp/utils/metrics.py +418 -0
- kailash/nodes/ai/agents.py +9 -9
- kailash/nodes/ai/ai_providers.py +33 -34
- kailash/nodes/ai/embedding_generator.py +31 -32
- kailash/nodes/ai/intelligent_agent_orchestrator.py +62 -66
- kailash/nodes/ai/iterative_llm_agent.py +48 -48
- kailash/nodes/ai/llm_agent.py +32 -33
- kailash/nodes/ai/models.py +13 -13
- kailash/nodes/ai/self_organizing.py +44 -44
- kailash/nodes/api/auth.py +11 -11
- kailash/nodes/api/graphql.py +13 -13
- kailash/nodes/api/http.py +19 -19
- kailash/nodes/api/monitoring.py +20 -20
- kailash/nodes/api/rate_limiting.py +9 -13
- kailash/nodes/api/rest.py +29 -29
- kailash/nodes/api/security.py +44 -47
- kailash/nodes/base.py +21 -23
- kailash/nodes/base_async.py +7 -7
- kailash/nodes/base_cycle_aware.py +12 -12
- kailash/nodes/base_with_acl.py +5 -5
- kailash/nodes/code/python.py +56 -55
- kailash/nodes/data/directory.py +6 -6
- kailash/nodes/data/event_generation.py +10 -10
- kailash/nodes/data/file_discovery.py +28 -31
- kailash/nodes/data/readers.py +8 -8
- kailash/nodes/data/retrieval.py +10 -10
- kailash/nodes/data/sharepoint_graph.py +17 -17
- kailash/nodes/data/sources.py +5 -5
- kailash/nodes/data/sql.py +13 -13
- kailash/nodes/data/streaming.py +25 -25
- kailash/nodes/data/vector_db.py +22 -22
- kailash/nodes/data/writers.py +7 -7
- kailash/nodes/logic/async_operations.py +17 -17
- kailash/nodes/logic/convergence.py +11 -11
- kailash/nodes/logic/loop.py +4 -4
- kailash/nodes/logic/operations.py +11 -11
- kailash/nodes/logic/workflow.py +8 -9
- kailash/nodes/mixins/mcp.py +17 -17
- kailash/nodes/mixins.py +8 -10
- kailash/nodes/transform/chunkers.py +3 -3
- kailash/nodes/transform/formatters.py +7 -7
- kailash/nodes/transform/processors.py +10 -10
- kailash/runtime/access_controlled.py +18 -18
- kailash/runtime/async_local.py +17 -19
- kailash/runtime/docker.py +20 -22
- kailash/runtime/local.py +16 -16
- kailash/runtime/parallel.py +23 -23
- kailash/runtime/parallel_cyclic.py +27 -27
- kailash/runtime/runner.py +6 -6
- kailash/runtime/testing.py +20 -20
- kailash/sdk_exceptions.py +0 -58
- kailash/security.py +14 -26
- kailash/tracking/manager.py +38 -38
- kailash/tracking/metrics_collector.py +15 -14
- kailash/tracking/models.py +53 -53
- kailash/tracking/storage/base.py +7 -17
- kailash/tracking/storage/database.py +22 -23
- kailash/tracking/storage/filesystem.py +38 -40
- kailash/utils/export.py +21 -21
- kailash/utils/templates.py +2 -3
- kailash/visualization/api.py +30 -34
- kailash/visualization/dashboard.py +17 -17
- kailash/visualization/performance.py +16 -16
- kailash/visualization/reports.py +25 -27
- kailash/workflow/builder.py +8 -8
- kailash/workflow/convergence.py +13 -12
- kailash/workflow/cycle_analyzer.py +30 -32
- kailash/workflow/cycle_builder.py +12 -12
- kailash/workflow/cycle_config.py +16 -15
- kailash/workflow/cycle_debugger.py +40 -40
- kailash/workflow/cycle_exceptions.py +29 -29
- kailash/workflow/cycle_profiler.py +21 -21
- kailash/workflow/cycle_state.py +20 -22
- kailash/workflow/cyclic_runner.py +44 -44
- kailash/workflow/graph.py +40 -40
- kailash/workflow/mermaid_visualizer.py +9 -11
- kailash/workflow/migration.py +22 -22
- kailash/workflow/mock_registry.py +6 -6
- kailash/workflow/runner.py +9 -9
- kailash/workflow/safety.py +12 -13
- kailash/workflow/state.py +8 -11
- kailash/workflow/templates.py +19 -19
- kailash/workflow/validation.py +14 -14
- kailash/workflow/visualization.py +22 -22
- {kailash-0.3.0.dist-info → kailash-0.3.1.dist-info}/METADATA +53 -5
- kailash-0.3.1.dist-info/RECORD +136 -0
- kailash-0.3.0.dist-info/RECORD +0 -130
- {kailash-0.3.0.dist-info → kailash-0.3.1.dist-info}/WHEEL +0 -0
- {kailash-0.3.0.dist-info → kailash-0.3.1.dist-info}/entry_points.txt +0 -0
- {kailash-0.3.0.dist-info → kailash-0.3.1.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.3.0.dist-info → kailash-0.3.1.dist-info}/top_level.txt +0 -0
kailash/workflow/convergence.py
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
import logging
|
4
4
|
from abc import ABC, abstractmethod
|
5
|
-
from
|
5
|
+
from collections.abc import Callable
|
6
|
+
from typing import TYPE_CHECKING, Any
|
6
7
|
|
7
8
|
if TYPE_CHECKING:
|
8
9
|
from kailash.workflow.cycle_state import CycleState
|
@@ -14,7 +15,7 @@ class ConvergenceCondition(ABC):
|
|
14
15
|
"""Base class for cycle convergence conditions."""
|
15
16
|
|
16
17
|
@abstractmethod
|
17
|
-
def evaluate(self, results:
|
18
|
+
def evaluate(self, results: dict[str, Any], cycle_state: "CycleState") -> bool:
|
18
19
|
"""Evaluate if cycle should terminate.
|
19
20
|
|
20
21
|
Args:
|
@@ -48,7 +49,7 @@ class ExpressionCondition(ConvergenceCondition):
|
|
48
49
|
"""
|
49
50
|
self.expression = expression
|
50
51
|
|
51
|
-
def evaluate(self, results:
|
52
|
+
def evaluate(self, results: dict[str, Any], cycle_state: "CycleState") -> bool:
|
52
53
|
"""Evaluate expression with results and cycle state context."""
|
53
54
|
# Create evaluation context
|
54
55
|
context = {
|
@@ -117,8 +118,8 @@ class CallbackCondition(ConvergenceCondition):
|
|
117
118
|
|
118
119
|
def __init__(
|
119
120
|
self,
|
120
|
-
callback: Callable[[
|
121
|
-
name:
|
121
|
+
callback: Callable[[dict[str, Any], "CycleState"], bool],
|
122
|
+
name: str | None = None,
|
122
123
|
):
|
123
124
|
"""Initialize with callback function.
|
124
125
|
|
@@ -129,7 +130,7 @@ class CallbackCondition(ConvergenceCondition):
|
|
129
130
|
self.callback = callback
|
130
131
|
self.name = name or callback.__name__
|
131
132
|
|
132
|
-
def evaluate(self, results:
|
133
|
+
def evaluate(self, results: dict[str, Any], cycle_state: "CycleState") -> bool:
|
133
134
|
"""Evaluate callback with results and cycle state."""
|
134
135
|
try:
|
135
136
|
return self.callback(results, cycle_state)
|
@@ -154,7 +155,7 @@ class MaxIterationsCondition(ConvergenceCondition):
|
|
154
155
|
"""
|
155
156
|
self.max_iterations = max_iterations
|
156
157
|
|
157
|
-
def evaluate(self, results:
|
158
|
+
def evaluate(self, results: dict[str, Any], cycle_state: "CycleState") -> bool:
|
158
159
|
"""Check if maximum iterations reached."""
|
159
160
|
return cycle_state.iteration >= self.max_iterations
|
160
161
|
|
@@ -166,7 +167,7 @@ class MaxIterationsCondition(ConvergenceCondition):
|
|
166
167
|
class CompoundCondition(ConvergenceCondition):
|
167
168
|
"""Combine multiple conditions with AND/OR logic."""
|
168
169
|
|
169
|
-
def __init__(self, conditions:
|
170
|
+
def __init__(self, conditions: list[ConvergenceCondition], operator: str = "OR"):
|
170
171
|
"""Initialize with list of conditions.
|
171
172
|
|
172
173
|
Args:
|
@@ -178,7 +179,7 @@ class CompoundCondition(ConvergenceCondition):
|
|
178
179
|
if self.operator not in ["AND", "OR"]:
|
179
180
|
raise ValueError("Operator must be 'AND' or 'OR'")
|
180
181
|
|
181
|
-
def evaluate(self, results:
|
182
|
+
def evaluate(self, results: dict[str, Any], cycle_state: "CycleState") -> bool:
|
182
183
|
"""Evaluate all conditions with specified operator."""
|
183
184
|
evaluations = [cond.evaluate(results, cycle_state) for cond in self.conditions]
|
184
185
|
|
@@ -196,7 +197,7 @@ class CompoundCondition(ConvergenceCondition):
|
|
196
197
|
class AdaptiveCondition(ConvergenceCondition):
|
197
198
|
"""Adaptive convergence that changes based on iteration progress."""
|
198
199
|
|
199
|
-
def __init__(self, stages:
|
200
|
+
def __init__(self, stages: list[tuple[int, ConvergenceCondition]]):
|
200
201
|
"""Initialize with stages of conditions.
|
201
202
|
|
202
203
|
Args:
|
@@ -205,7 +206,7 @@ class AdaptiveCondition(ConvergenceCondition):
|
|
205
206
|
"""
|
206
207
|
self.stages = sorted(stages, key=lambda x: x[0])
|
207
208
|
|
208
|
-
def evaluate(self, results:
|
209
|
+
def evaluate(self, results: dict[str, Any], cycle_state: "CycleState") -> bool:
|
209
210
|
"""Evaluate condition based on current iteration stage."""
|
210
211
|
current_iteration = cycle_state.iteration
|
211
212
|
|
@@ -229,7 +230,7 @@ class AdaptiveCondition(ConvergenceCondition):
|
|
229
230
|
|
230
231
|
|
231
232
|
def create_convergence_condition(
|
232
|
-
spec:
|
233
|
+
spec: str | int | Callable | dict,
|
233
234
|
) -> ConvergenceCondition:
|
234
235
|
"""Factory function to create convergence conditions from various specs.
|
235
236
|
|
@@ -36,7 +36,7 @@ import json
|
|
36
36
|
import logging
|
37
37
|
from datetime import datetime
|
38
38
|
from pathlib import Path
|
39
|
-
from typing import Any
|
39
|
+
from typing import Any
|
40
40
|
|
41
41
|
from kailash.workflow.cycle_debugger import CycleDebugger, CycleExecutionTrace
|
42
42
|
from kailash.workflow.cycle_profiler import CycleProfiler
|
@@ -70,7 +70,7 @@ class CycleAnalyzer:
|
|
70
70
|
analysis_level: str = "standard",
|
71
71
|
enable_profiling: bool = True,
|
72
72
|
enable_debugging: bool = True,
|
73
|
-
output_directory:
|
73
|
+
output_directory: str | None = None,
|
74
74
|
):
|
75
75
|
"""
|
76
76
|
Initialize cycle analyzer.
|
@@ -113,9 +113,9 @@ class CycleAnalyzer:
|
|
113
113
|
)
|
114
114
|
|
115
115
|
# Analysis session tracking
|
116
|
-
self.current_session:
|
117
|
-
self.session_traces:
|
118
|
-
self.analysis_history:
|
116
|
+
self.current_session: str | None = None
|
117
|
+
self.session_traces: list[CycleExecutionTrace] = []
|
118
|
+
self.analysis_history: list[dict[str, Any]] = []
|
119
119
|
|
120
120
|
# Create output directory if specified
|
121
121
|
if self.output_directory:
|
@@ -149,10 +149,10 @@ class CycleAnalyzer:
|
|
149
149
|
self,
|
150
150
|
cycle_id: str,
|
151
151
|
workflow_id: str,
|
152
|
-
max_iterations:
|
153
|
-
timeout:
|
154
|
-
convergence_condition:
|
155
|
-
) ->
|
152
|
+
max_iterations: int | None = None,
|
153
|
+
timeout: float | None = None,
|
154
|
+
convergence_condition: str | None = None,
|
155
|
+
) -> CycleExecutionTrace | None:
|
156
156
|
"""
|
157
157
|
Start analysis for a new cycle execution.
|
158
158
|
|
@@ -193,10 +193,10 @@ class CycleAnalyzer:
|
|
193
193
|
def track_iteration(
|
194
194
|
self,
|
195
195
|
trace: CycleExecutionTrace,
|
196
|
-
input_data:
|
197
|
-
output_data:
|
198
|
-
convergence_value:
|
199
|
-
node_executions:
|
196
|
+
input_data: dict[str, Any],
|
197
|
+
output_data: dict[str, Any],
|
198
|
+
convergence_value: float | None = None,
|
199
|
+
node_executions: list[str] | None = None,
|
200
200
|
):
|
201
201
|
"""
|
202
202
|
Track a single cycle iteration with input/output data.
|
@@ -234,7 +234,7 @@ class CycleAnalyzer:
|
|
234
234
|
trace: CycleExecutionTrace,
|
235
235
|
converged: bool,
|
236
236
|
termination_reason: str,
|
237
|
-
convergence_iteration:
|
237
|
+
convergence_iteration: int | None = None,
|
238
238
|
):
|
239
239
|
"""
|
240
240
|
Complete cycle analysis and generate insights.
|
@@ -276,7 +276,7 @@ class CycleAnalyzer:
|
|
276
276
|
if self.analysis_level == "comprehensive":
|
277
277
|
self._generate_immediate_insights(trace)
|
278
278
|
|
279
|
-
def generate_cycle_report(self, trace: CycleExecutionTrace) ->
|
279
|
+
def generate_cycle_report(self, trace: CycleExecutionTrace) -> dict[str, Any]:
|
280
280
|
"""
|
281
281
|
Generate comprehensive report for a single cycle.
|
282
282
|
|
@@ -333,9 +333,7 @@ class CycleAnalyzer:
|
|
333
333
|
|
334
334
|
return report
|
335
335
|
|
336
|
-
def generate_session_report(
|
337
|
-
self, session_id: Optional[str] = None
|
338
|
-
) -> Dict[str, Any]:
|
336
|
+
def generate_session_report(self, session_id: str | None = None) -> dict[str, Any]:
|
339
337
|
"""
|
340
338
|
Generate comprehensive report for an analysis session.
|
341
339
|
|
@@ -414,7 +412,7 @@ class CycleAnalyzer:
|
|
414
412
|
|
415
413
|
return report
|
416
414
|
|
417
|
-
def get_real_time_metrics(self, trace: CycleExecutionTrace) ->
|
415
|
+
def get_real_time_metrics(self, trace: CycleExecutionTrace) -> dict[str, Any]:
|
418
416
|
"""
|
419
417
|
Get real-time metrics for an active cycle.
|
420
418
|
|
@@ -487,7 +485,7 @@ class CycleAnalyzer:
|
|
487
485
|
|
488
486
|
def export_analysis_data(
|
489
487
|
self,
|
490
|
-
filepath:
|
488
|
+
filepath: str | None = None,
|
491
489
|
format: str = "json",
|
492
490
|
include_traces: bool = True,
|
493
491
|
):
|
@@ -605,7 +603,7 @@ class CycleAnalyzer:
|
|
605
603
|
f"Slow iterations detected for cycle '{trace.cycle_id}' - avg: {stats['avg_iteration_time']:.3f}s"
|
606
604
|
)
|
607
605
|
|
608
|
-
def _generate_advanced_analysis(self, trace: CycleExecutionTrace) ->
|
606
|
+
def _generate_advanced_analysis(self, trace: CycleExecutionTrace) -> dict[str, Any]:
|
609
607
|
"""Generate advanced analysis insights for comprehensive mode."""
|
610
608
|
convergence_trend = trace.get_convergence_trend()
|
611
609
|
|
@@ -657,8 +655,8 @@ class CycleAnalyzer:
|
|
657
655
|
}
|
658
656
|
|
659
657
|
def _generate_session_insights(
|
660
|
-
self, traces:
|
661
|
-
) ->
|
658
|
+
self, traces: list[CycleExecutionTrace]
|
659
|
+
) -> dict[str, Any]:
|
662
660
|
"""Generate insights across multiple cycles in a session."""
|
663
661
|
if not traces:
|
664
662
|
return {}
|
@@ -692,7 +690,7 @@ class CycleAnalyzer:
|
|
692
690
|
return insights
|
693
691
|
|
694
692
|
def _calculate_real_time_health_score(
|
695
|
-
self, trace: CycleExecutionTrace, recent_iterations:
|
693
|
+
self, trace: CycleExecutionTrace, recent_iterations: list
|
696
694
|
) -> float:
|
697
695
|
"""Calculate real-time health score for an active cycle."""
|
698
696
|
score_components = []
|
@@ -732,8 +730,8 @@ class CycleAnalyzer:
|
|
732
730
|
)
|
733
731
|
|
734
732
|
def _generate_real_time_alerts(
|
735
|
-
self, trace: CycleExecutionTrace, recent_iterations:
|
736
|
-
) ->
|
733
|
+
self, trace: CycleExecutionTrace, recent_iterations: list
|
734
|
+
) -> list[str]:
|
737
735
|
"""Generate real-time alerts for potential issues."""
|
738
736
|
alerts = []
|
739
737
|
|
@@ -771,7 +769,7 @@ class CycleAnalyzer:
|
|
771
769
|
|
772
770
|
return alerts
|
773
771
|
|
774
|
-
def _calculate_convergence_stability(self, values:
|
772
|
+
def _calculate_convergence_stability(self, values: list[float]) -> float:
|
775
773
|
"""Calculate stability score for convergence values."""
|
776
774
|
if len(values) < 2:
|
777
775
|
return 1.0
|
@@ -788,7 +786,7 @@ class CycleAnalyzer:
|
|
788
786
|
# Lower CV means more stable
|
789
787
|
return max(0.0, 1.0 - min(1.0, cv))
|
790
788
|
|
791
|
-
def _calculate_skewness(self, data:
|
789
|
+
def _calculate_skewness(self, data: list[float]) -> float:
|
792
790
|
"""Calculate skewness of data distribution."""
|
793
791
|
if len(data) < 3:
|
794
792
|
return 0.0
|
@@ -805,7 +803,7 @@ class CycleAnalyzer:
|
|
805
803
|
skewness = sum((x - mean_val) ** 3 for x in data) / (n * std_dev**3)
|
806
804
|
return skewness
|
807
805
|
|
808
|
-
def _analyze_performance_trend(self, iteration_times:
|
806
|
+
def _analyze_performance_trend(self, iteration_times: list[float]) -> str:
|
809
807
|
"""Analyze performance trend over iterations."""
|
810
808
|
if len(iteration_times) < 3:
|
811
809
|
return "insufficient_data"
|
@@ -830,7 +828,7 @@ class CycleAnalyzer:
|
|
830
828
|
|
831
829
|
def _analyze_resource_efficiency(
|
832
830
|
self, trace: CycleExecutionTrace
|
833
|
-
) ->
|
831
|
+
) -> dict[str, Any]:
|
834
832
|
"""Analyze resource usage efficiency."""
|
835
833
|
memory_values = [
|
836
834
|
iter.memory_usage_mb for iter in trace.iterations if iter.memory_usage_mb
|
@@ -867,7 +865,7 @@ class CycleAnalyzer:
|
|
867
865
|
|
868
866
|
return efficiency
|
869
867
|
|
870
|
-
def _export_cycle_report(self, report:
|
868
|
+
def _export_cycle_report(self, report: dict[str, Any], cycle_id: str):
|
871
869
|
"""Export cycle report to file."""
|
872
870
|
if not self.output_directory:
|
873
871
|
return
|
@@ -882,7 +880,7 @@ class CycleAnalyzer:
|
|
882
880
|
|
883
881
|
logger.debug(f"Exported cycle report to {filepath}")
|
884
882
|
|
885
|
-
def _export_session_report(self, report:
|
883
|
+
def _export_session_report(self, report: dict[str, Any], session_id: str):
|
886
884
|
"""Export session report to file."""
|
887
885
|
if not self.output_directory:
|
888
886
|
return
|
@@ -40,7 +40,7 @@ Examples:
|
|
40
40
|
"""
|
41
41
|
|
42
42
|
import logging
|
43
|
-
from typing import TYPE_CHECKING
|
43
|
+
from typing import TYPE_CHECKING
|
44
44
|
|
45
45
|
from kailash.sdk_exceptions import WorkflowValidationError
|
46
46
|
from kailash.workflow.cycle_exceptions import (
|
@@ -75,7 +75,7 @@ class CycleBuilder:
|
|
75
75
|
... .build()
|
76
76
|
"""
|
77
77
|
|
78
|
-
def __init__(self, workflow: "Workflow", cycle_id:
|
78
|
+
def __init__(self, workflow: "Workflow", cycle_id: str | None = None):
|
79
79
|
"""
|
80
80
|
Initialize a new CycleBuilder.
|
81
81
|
|
@@ -87,23 +87,23 @@ class CycleBuilder:
|
|
87
87
|
self._cycle_id = cycle_id
|
88
88
|
|
89
89
|
# Connection parameters
|
90
|
-
self._source_node:
|
91
|
-
self._target_node:
|
92
|
-
self._mapping:
|
90
|
+
self._source_node: str | None = None
|
91
|
+
self._target_node: str | None = None
|
92
|
+
self._mapping: dict[str, str] | None = None
|
93
93
|
|
94
94
|
# Cycle parameters
|
95
|
-
self._max_iterations:
|
96
|
-
self._convergence_check:
|
97
|
-
self._timeout:
|
98
|
-
self._memory_limit:
|
99
|
-
self._condition:
|
100
|
-
self._parent_cycle:
|
95
|
+
self._max_iterations: int | None = None
|
96
|
+
self._convergence_check: str | None = None
|
97
|
+
self._timeout: float | None = None
|
98
|
+
self._memory_limit: int | None = None
|
99
|
+
self._condition: str | None = None
|
100
|
+
self._parent_cycle: str | None = None
|
101
101
|
|
102
102
|
def connect(
|
103
103
|
self,
|
104
104
|
source_node: str,
|
105
105
|
target_node: str,
|
106
|
-
mapping:
|
106
|
+
mapping: dict[str, str] | None = None,
|
107
107
|
) -> "CycleBuilder":
|
108
108
|
"""
|
109
109
|
Configure the source and target nodes for the cycle connection.
|
kailash/workflow/cycle_config.py
CHANGED
@@ -93,8 +93,9 @@ See Also:
|
|
93
93
|
"""
|
94
94
|
|
95
95
|
import logging
|
96
|
+
from collections.abc import Callable
|
96
97
|
from dataclasses import dataclass, field
|
97
|
-
from typing import Any
|
98
|
+
from typing import Any
|
98
99
|
|
99
100
|
from kailash.workflow.cycle_exceptions import CycleConfigurationError
|
100
101
|
|
@@ -150,26 +151,26 @@ class CycleConfig:
|
|
150
151
|
"""
|
151
152
|
|
152
153
|
# Termination conditions (at least one required)
|
153
|
-
max_iterations:
|
154
|
-
convergence_check:
|
155
|
-
timeout:
|
154
|
+
max_iterations: int | None = None
|
155
|
+
convergence_check: str | Callable | None = None
|
156
|
+
timeout: float | None = None
|
156
157
|
|
157
158
|
# Safety and resource limits
|
158
|
-
memory_limit:
|
159
|
+
memory_limit: int | None = None
|
159
160
|
iteration_safety_factor: float = 1.5 # Multiplier for max_iterations safety
|
160
161
|
|
161
162
|
# Cycle metadata and identification
|
162
|
-
cycle_id:
|
163
|
-
parent_cycle:
|
163
|
+
cycle_id: str | None = None
|
164
|
+
parent_cycle: str | None = None
|
164
165
|
description: str = ""
|
165
166
|
|
166
167
|
# Execution control and conditions
|
167
|
-
condition:
|
168
|
+
condition: str | None = None # When to execute the cycle
|
168
169
|
priority: int = 0 # Execution priority for multiple cycles
|
169
170
|
|
170
171
|
# Advanced configuration
|
171
|
-
retry_policy:
|
172
|
-
metadata:
|
172
|
+
retry_policy: dict[str, Any] = field(default_factory=dict)
|
173
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
173
174
|
|
174
175
|
def __post_init__(self):
|
175
176
|
"""
|
@@ -378,7 +379,7 @@ class CycleConfig:
|
|
378
379
|
],
|
379
380
|
)
|
380
381
|
|
381
|
-
def get_effective_max_iterations(self) ->
|
382
|
+
def get_effective_max_iterations(self) -> int | None:
|
382
383
|
"""
|
383
384
|
Get the effective maximum iterations with safety factor applied.
|
384
385
|
|
@@ -401,7 +402,7 @@ class CycleConfig:
|
|
401
402
|
return None
|
402
403
|
return int(self.max_iterations * self.iteration_safety_factor)
|
403
404
|
|
404
|
-
def to_dict(self) ->
|
405
|
+
def to_dict(self) -> dict[str, Any]:
|
405
406
|
"""
|
406
407
|
Convert configuration to dictionary format.
|
407
408
|
|
@@ -433,7 +434,7 @@ class CycleConfig:
|
|
433
434
|
return result
|
434
435
|
|
435
436
|
@classmethod
|
436
|
-
def from_dict(cls, data:
|
437
|
+
def from_dict(cls, data: dict[str, Any]) -> "CycleConfig":
|
437
438
|
"""
|
438
439
|
Create configuration from dictionary data.
|
439
440
|
|
@@ -508,7 +509,7 @@ class CycleConfig:
|
|
508
509
|
|
509
510
|
return CycleConfig(**merged_data)
|
510
511
|
|
511
|
-
def create_template(self, template_name: str) ->
|
512
|
+
def create_template(self, template_name: str) -> dict[str, Any]:
|
512
513
|
"""
|
513
514
|
Create a reusable template from this configuration.
|
514
515
|
|
@@ -600,7 +601,7 @@ class CycleTemplates:
|
|
600
601
|
def optimization_loop(
|
601
602
|
max_iterations: int = 100,
|
602
603
|
convergence_threshold: float = 0.01,
|
603
|
-
timeout:
|
604
|
+
timeout: float | None = None,
|
604
605
|
) -> CycleConfig:
|
605
606
|
"""
|
606
607
|
Create configuration for optimization cycles.
|
@@ -49,7 +49,7 @@ import json
|
|
49
49
|
import logging
|
50
50
|
from dataclasses import dataclass, field
|
51
51
|
from datetime import datetime
|
52
|
-
from typing import Any
|
52
|
+
from typing import Any
|
53
53
|
|
54
54
|
logger = logging.getLogger(__name__)
|
55
55
|
|
@@ -79,18 +79,18 @@ class CycleIteration:
|
|
79
79
|
|
80
80
|
iteration_number: int
|
81
81
|
start_time: datetime
|
82
|
-
end_time:
|
83
|
-
execution_time:
|
84
|
-
input_data:
|
85
|
-
output_data:
|
86
|
-
memory_usage_mb:
|
87
|
-
cpu_usage_percent:
|
88
|
-
convergence_value:
|
89
|
-
error:
|
90
|
-
node_executions:
|
82
|
+
end_time: datetime | None = None
|
83
|
+
execution_time: float | None = None
|
84
|
+
input_data: dict[str, Any] = field(default_factory=dict)
|
85
|
+
output_data: dict[str, Any] | None = None
|
86
|
+
memory_usage_mb: float | None = None
|
87
|
+
cpu_usage_percent: float | None = None
|
88
|
+
convergence_value: float | None = None
|
89
|
+
error: str | None = None
|
90
|
+
node_executions: list[str] = field(default_factory=list)
|
91
91
|
|
92
92
|
def complete(
|
93
|
-
self, output_data:
|
93
|
+
self, output_data: dict[str, Any], convergence_value: float | None = None
|
94
94
|
):
|
95
95
|
"""
|
96
96
|
Mark iteration as complete with output data.
|
@@ -131,7 +131,7 @@ class CycleIteration:
|
|
131
131
|
"""
|
132
132
|
return self.end_time is not None and self.error is None
|
133
133
|
|
134
|
-
def to_dict(self) ->
|
134
|
+
def to_dict(self) -> dict[str, Any]:
|
135
135
|
"""Convert iteration to dictionary for serialization.
|
136
136
|
|
137
137
|
Returns:
|
@@ -179,17 +179,17 @@ class CycleExecutionTrace:
|
|
179
179
|
cycle_id: str
|
180
180
|
workflow_id: str
|
181
181
|
start_time: datetime
|
182
|
-
end_time:
|
183
|
-
total_execution_time:
|
184
|
-
iterations:
|
182
|
+
end_time: datetime | None = None
|
183
|
+
total_execution_time: float | None = None
|
184
|
+
iterations: list[CycleIteration] = field(default_factory=list)
|
185
185
|
converged: bool = False
|
186
|
-
convergence_iteration:
|
186
|
+
convergence_iteration: int | None = None
|
187
187
|
termination_reason: str = "unknown"
|
188
|
-
max_iterations_configured:
|
189
|
-
timeout_configured:
|
190
|
-
convergence_condition:
|
191
|
-
memory_peak_mb:
|
192
|
-
cpu_peak_percent:
|
188
|
+
max_iterations_configured: int | None = None
|
189
|
+
timeout_configured: float | None = None
|
190
|
+
convergence_condition: str | None = None
|
191
|
+
memory_peak_mb: float | None = None
|
192
|
+
cpu_peak_percent: float | None = None
|
193
193
|
|
194
194
|
def add_iteration(self, iteration: CycleIteration):
|
195
195
|
"""
|
@@ -216,7 +216,7 @@ class CycleExecutionTrace:
|
|
216
216
|
self,
|
217
217
|
converged: bool,
|
218
218
|
termination_reason: str,
|
219
|
-
convergence_iteration:
|
219
|
+
convergence_iteration: int | None = None,
|
220
220
|
):
|
221
221
|
"""
|
222
222
|
Mark cycle execution as complete.
|
@@ -232,7 +232,7 @@ class CycleExecutionTrace:
|
|
232
232
|
self.termination_reason = termination_reason
|
233
233
|
self.convergence_iteration = convergence_iteration
|
234
234
|
|
235
|
-
def get_statistics(self) ->
|
235
|
+
def get_statistics(self) -> dict[str, Any]:
|
236
236
|
"""
|
237
237
|
Get comprehensive statistics about the cycle execution.
|
238
238
|
|
@@ -316,7 +316,7 @@ class CycleExecutionTrace:
|
|
316
316
|
|
317
317
|
return stats
|
318
318
|
|
319
|
-
def get_convergence_trend(self) ->
|
319
|
+
def get_convergence_trend(self) -> list[tuple[int, float | None]]:
|
320
320
|
"""
|
321
321
|
Get convergence values over iterations for trend analysis.
|
322
322
|
|
@@ -335,7 +335,7 @@ class CycleExecutionTrace:
|
|
335
335
|
(iter.iteration_number, iter.convergence_value) for iter in self.iterations
|
336
336
|
]
|
337
337
|
|
338
|
-
def to_dict(self) ->
|
338
|
+
def to_dict(self) -> dict[str, Any]:
|
339
339
|
"""Convert trace to dictionary for serialization."""
|
340
340
|
return {
|
341
341
|
"cycle_id": self.cycle_id,
|
@@ -411,7 +411,7 @@ class CycleDebugger:
|
|
411
411
|
"""
|
412
412
|
self.debug_level = debug_level
|
413
413
|
self.enable_profiling = enable_profiling
|
414
|
-
self.active_traces:
|
414
|
+
self.active_traces: dict[str, CycleExecutionTrace] = {}
|
415
415
|
|
416
416
|
# Configure logging based on debug level
|
417
417
|
if debug_level == "verbose":
|
@@ -425,9 +425,9 @@ class CycleDebugger:
|
|
425
425
|
self,
|
426
426
|
cycle_id: str,
|
427
427
|
workflow_id: str,
|
428
|
-
max_iterations:
|
429
|
-
timeout:
|
430
|
-
convergence_condition:
|
428
|
+
max_iterations: int | None = None,
|
429
|
+
timeout: float | None = None,
|
430
|
+
convergence_condition: str | None = None,
|
431
431
|
) -> CycleExecutionTrace:
|
432
432
|
"""
|
433
433
|
Start debugging a new cycle execution.
|
@@ -473,8 +473,8 @@ class CycleDebugger:
|
|
473
473
|
def start_iteration(
|
474
474
|
self,
|
475
475
|
trace: CycleExecutionTrace,
|
476
|
-
input_data:
|
477
|
-
iteration_number:
|
476
|
+
input_data: dict[str, Any],
|
477
|
+
iteration_number: int | None = None,
|
478
478
|
) -> CycleIteration:
|
479
479
|
"""
|
480
480
|
Start debugging a new cycle iteration.
|
@@ -533,9 +533,9 @@ class CycleDebugger:
|
|
533
533
|
self,
|
534
534
|
trace: CycleExecutionTrace,
|
535
535
|
iteration: CycleIteration,
|
536
|
-
output_data:
|
537
|
-
convergence_value:
|
538
|
-
node_executions:
|
536
|
+
output_data: dict[str, Any],
|
537
|
+
convergence_value: float | None = None,
|
538
|
+
node_executions: list[str] | None = None,
|
539
539
|
):
|
540
540
|
"""
|
541
541
|
Complete iteration tracking with output data and metrics.
|
@@ -598,7 +598,7 @@ class CycleDebugger:
|
|
598
598
|
trace: CycleExecutionTrace,
|
599
599
|
converged: bool,
|
600
600
|
termination_reason: str,
|
601
|
-
convergence_iteration:
|
601
|
+
convergence_iteration: int | None = None,
|
602
602
|
):
|
603
603
|
"""
|
604
604
|
Complete cycle tracking with final results and analysis.
|
@@ -632,7 +632,7 @@ class CycleDebugger:
|
|
632
632
|
f"converged={converged}, efficiency={stats['efficiency_score']:.2f}"
|
633
633
|
)
|
634
634
|
|
635
|
-
def generate_report(self, trace: CycleExecutionTrace) ->
|
635
|
+
def generate_report(self, trace: CycleExecutionTrace) -> dict[str, Any]:
|
636
636
|
"""
|
637
637
|
Generate comprehensive debugging report for a cycle execution.
|
638
638
|
|
@@ -691,8 +691,8 @@ class CycleDebugger:
|
|
691
691
|
return report
|
692
692
|
|
693
693
|
def _analyze_convergence(
|
694
|
-
self, convergence_trend:
|
695
|
-
) ->
|
694
|
+
self, convergence_trend: list[tuple[int, float | None]]
|
695
|
+
) -> dict[str, Any]:
|
696
696
|
"""Analyze convergence pattern from trend data."""
|
697
697
|
if not convergence_trend or all(
|
698
698
|
value is None for _, value in convergence_trend
|
@@ -748,8 +748,8 @@ class CycleDebugger:
|
|
748
748
|
}
|
749
749
|
|
750
750
|
def _generate_recommendations(
|
751
|
-
self, trace: CycleExecutionTrace, stats:
|
752
|
-
) ->
|
751
|
+
self, trace: CycleExecutionTrace, stats: dict[str, Any]
|
752
|
+
) -> list[str]:
|
753
753
|
"""Generate optimization recommendations based on execution analysis."""
|
754
754
|
recommendations = []
|
755
755
|
|