kailash 0.2.0__py3-none-any.whl → 0.2.2__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/api/custom_nodes_secure.py +2 -2
- kailash/api/studio_secure.py +1 -1
- kailash/mcp/client_new.py +1 -1
- kailash/mcp/server_new.py +6 -6
- kailash/nodes/ai/a2a.py +1 -1
- kailash/nodes/api/__init__.py +21 -0
- kailash/nodes/code/python.py +6 -0
- kailash/nodes/data/__init__.py +4 -2
- kailash/nodes/data/directory.py +278 -0
- kailash/nodes/data/sql.py +699 -256
- kailash/nodes/transform/processors.py +31 -0
- kailash/runtime/local.py +13 -0
- kailash/workflow/convergence.py +1 -1
- kailash/workflow/cycle_analyzer.py +346 -225
- kailash/workflow/cycle_builder.py +75 -69
- kailash/workflow/cycle_config.py +62 -46
- kailash/workflow/cycle_debugger.py +284 -184
- kailash/workflow/cycle_exceptions.py +111 -97
- kailash/workflow/cycle_profiler.py +272 -202
- kailash/workflow/graph.py +15 -0
- kailash/workflow/migration.py +238 -197
- kailash/workflow/templates.py +124 -105
- kailash/workflow/validation.py +356 -298
- kailash-0.2.2.dist-info/METADATA +121 -0
- {kailash-0.2.0.dist-info → kailash-0.2.2.dist-info}/RECORD +29 -28
- kailash-0.2.0.dist-info/METADATA +0 -1614
- {kailash-0.2.0.dist-info → kailash-0.2.2.dist-info}/WHEEL +0 -0
- {kailash-0.2.0.dist-info → kailash-0.2.2.dist-info}/entry_points.txt +0 -0
- {kailash-0.2.0.dist-info → kailash-0.2.2.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.2.0.dist-info → kailash-0.2.2.dist-info}/top_level.txt +0 -0
kailash/workflow/templates.py
CHANGED
@@ -54,7 +54,7 @@ Downstream Consumers:
|
|
54
54
|
|
55
55
|
Examples:
|
56
56
|
Optimization cycle template:
|
57
|
-
|
57
|
+
|
58
58
|
>>> from kailash.workflow.templates import CycleTemplates
|
59
59
|
>>> workflow = Workflow("optimization", "Quality Optimization")
|
60
60
|
>>> workflow.add_node("processor", ProcessorNode())
|
@@ -66,9 +66,9 @@ Examples:
|
|
66
66
|
... convergence="quality > 0.95",
|
67
67
|
... max_iterations=100
|
68
68
|
... )
|
69
|
-
|
69
|
+
|
70
70
|
Retry cycle with backoff:
|
71
|
-
|
71
|
+
|
72
72
|
>>> cycle_id = CycleTemplates.retry_cycle(
|
73
73
|
... workflow,
|
74
74
|
... target_node="api_call",
|
@@ -76,9 +76,9 @@ Examples:
|
|
76
76
|
... backoff_strategy="exponential",
|
77
77
|
... success_condition="success == True"
|
78
78
|
... )
|
79
|
-
|
79
|
+
|
80
80
|
Direct workflow integration:
|
81
|
-
|
81
|
+
|
82
82
|
>>> # Templates extend Workflow class
|
83
83
|
>>> workflow = Workflow("ml_training", "Model Training")
|
84
84
|
>>> cycle_id = workflow.add_learning_cycle(
|
@@ -87,16 +87,16 @@ Examples:
|
|
87
87
|
... target_accuracy=0.98,
|
88
88
|
... early_stopping_patience=10
|
89
89
|
... )
|
90
|
-
|
90
|
+
|
91
91
|
Custom template configuration:
|
92
|
-
|
92
|
+
|
93
93
|
>>> # Numerical convergence with custom tolerance
|
94
94
|
>>> cycle_id = workflow.add_convergence_cycle(
|
95
95
|
... processor_node="newton_raphson",
|
96
96
|
... tolerance=0.0001,
|
97
97
|
max_iterations=1000
|
98
98
|
)
|
99
|
-
|
99
|
+
|
100
100
|
# Batch processing for large datasets
|
101
101
|
cycle_id = workflow.add_batch_processing_cycle(
|
102
102
|
processor_node="data_processor",
|
@@ -110,10 +110,10 @@ See Also:
|
|
110
110
|
- :doc:`/examples/patterns` for comprehensive pattern examples
|
111
111
|
"""
|
112
112
|
|
113
|
-
from typing import Dict, Any, List, Optional
|
114
|
-
from dataclasses import dataclass
|
115
|
-
import time
|
116
113
|
import math
|
114
|
+
import time
|
115
|
+
from dataclasses import dataclass
|
116
|
+
from typing import Any, Dict, List, Optional
|
117
117
|
|
118
118
|
from ..nodes.code import PythonCodeNode
|
119
119
|
from . import Workflow
|
@@ -122,6 +122,7 @@ from . import Workflow
|
|
122
122
|
@dataclass
|
123
123
|
class CycleTemplate:
|
124
124
|
"""Configuration for a cycle template."""
|
125
|
+
|
125
126
|
name: str
|
126
127
|
description: str
|
127
128
|
nodes: List[str]
|
@@ -133,7 +134,7 @@ class CycleTemplate:
|
|
133
134
|
|
134
135
|
class CycleTemplates:
|
135
136
|
"""Collection of pre-built cycle templates for common patterns."""
|
136
|
-
|
137
|
+
|
137
138
|
@staticmethod
|
138
139
|
def optimization_cycle(
|
139
140
|
workflow: Workflow,
|
@@ -141,14 +142,14 @@ class CycleTemplates:
|
|
141
142
|
evaluator_node: str,
|
142
143
|
convergence: str = "quality > 0.9",
|
143
144
|
max_iterations: int = 50,
|
144
|
-
cycle_id: Optional[str] = None
|
145
|
+
cycle_id: Optional[str] = None,
|
145
146
|
) -> str:
|
146
147
|
"""
|
147
148
|
Add an optimization cycle pattern to workflow.
|
148
|
-
|
149
|
+
|
149
150
|
Creates a cycle where a processor generates solutions and an evaluator
|
150
151
|
assesses quality, continuing until convergence criteria is met.
|
151
|
-
|
152
|
+
|
152
153
|
Args:
|
153
154
|
workflow: Target workflow
|
154
155
|
processor_node: Node that generates/improves solutions
|
@@ -156,10 +157,10 @@ class CycleTemplates:
|
|
156
157
|
convergence: Convergence condition (e.g., "quality > 0.9")
|
157
158
|
max_iterations: Maximum iterations before stopping
|
158
159
|
cycle_id: Optional custom cycle identifier
|
159
|
-
|
160
|
+
|
160
161
|
Returns:
|
161
162
|
str: The cycle identifier for reference
|
162
|
-
|
163
|
+
|
163
164
|
Example:
|
164
165
|
>>> workflow = Workflow("optimization", "Optimization Example")
|
165
166
|
>>> workflow.add_node("processor", PythonCodeNode(), code="...")
|
@@ -171,22 +172,22 @@ class CycleTemplates:
|
|
171
172
|
"""
|
172
173
|
if cycle_id is None:
|
173
174
|
cycle_id = f"optimization_cycle_{int(time.time())}"
|
174
|
-
|
175
|
+
|
175
176
|
# Connect processor to evaluator
|
176
177
|
workflow.connect(processor_node, evaluator_node)
|
177
|
-
|
178
|
+
|
178
179
|
# Close the cycle with convergence condition
|
179
180
|
workflow.connect(
|
180
|
-
evaluator_node,
|
181
|
+
evaluator_node,
|
181
182
|
processor_node,
|
182
183
|
cycle=True,
|
183
184
|
max_iterations=max_iterations,
|
184
185
|
convergence_check=convergence,
|
185
|
-
cycle_id=cycle_id
|
186
|
+
cycle_id=cycle_id,
|
186
187
|
)
|
187
|
-
|
188
|
+
|
188
189
|
return cycle_id
|
189
|
-
|
190
|
+
|
190
191
|
@staticmethod
|
191
192
|
def retry_cycle(
|
192
193
|
workflow: Workflow,
|
@@ -194,14 +195,14 @@ class CycleTemplates:
|
|
194
195
|
max_retries: int = 3,
|
195
196
|
backoff_strategy: str = "exponential",
|
196
197
|
success_condition: str = "success == True",
|
197
|
-
cycle_id: Optional[str] = None
|
198
|
+
cycle_id: Optional[str] = None,
|
198
199
|
) -> str:
|
199
200
|
"""
|
200
201
|
Add a retry cycle pattern to workflow.
|
201
|
-
|
202
|
+
|
202
203
|
Creates a cycle that retries a node operation with configurable
|
203
204
|
backoff strategy until success or max retries reached.
|
204
|
-
|
205
|
+
|
205
206
|
Args:
|
206
207
|
workflow: Target workflow
|
207
208
|
target_node: Node to retry on failure
|
@@ -209,10 +210,10 @@ class CycleTemplates:
|
|
209
210
|
backoff_strategy: Backoff strategy ("linear", "exponential", "fixed")
|
210
211
|
success_condition: Condition that indicates success
|
211
212
|
cycle_id: Optional custom cycle identifier
|
212
|
-
|
213
|
+
|
213
214
|
Returns:
|
214
215
|
str: The cycle identifier for reference
|
215
|
-
|
216
|
+
|
216
217
|
Example:
|
217
218
|
>>> workflow = Workflow("retry", "Retry Example")
|
218
219
|
>>> workflow.add_node("api_call", PythonCodeNode(), code="...")
|
@@ -223,11 +224,11 @@ class CycleTemplates:
|
|
223
224
|
"""
|
224
225
|
if cycle_id is None:
|
225
226
|
cycle_id = f"retry_cycle_{int(time.time())}"
|
226
|
-
|
227
|
+
|
227
228
|
# Create retry controller node
|
228
229
|
retry_controller_id = f"{target_node}_retry_controller"
|
229
|
-
|
230
|
-
retry_code = f
|
230
|
+
|
231
|
+
retry_code = f"""
|
231
232
|
import time
|
232
233
|
import random
|
233
234
|
|
@@ -270,13 +271,16 @@ result = {{
|
|
270
271
|
"backoff_time": backoff_time,
|
271
272
|
"retry_exhausted": attempt > {max_retries}
|
272
273
|
}}
|
273
|
-
|
274
|
-
|
275
|
-
workflow.add_node(
|
276
|
-
|
274
|
+
"""
|
275
|
+
|
276
|
+
workflow.add_node(
|
277
|
+
retry_controller_id,
|
278
|
+
PythonCodeNode(name=retry_controller_id, code=retry_code),
|
279
|
+
)
|
280
|
+
|
277
281
|
# Connect retry controller to target node
|
278
282
|
workflow.connect(retry_controller_id, target_node)
|
279
|
-
|
283
|
+
|
280
284
|
# Close the cycle with retry logic
|
281
285
|
workflow.connect(
|
282
286
|
target_node,
|
@@ -284,11 +288,11 @@ result = {{
|
|
284
288
|
cycle=True,
|
285
289
|
max_iterations=max_retries + 1,
|
286
290
|
convergence_check=f"({success_condition}) or (retry_exhausted == True)",
|
287
|
-
cycle_id=cycle_id
|
291
|
+
cycle_id=cycle_id,
|
288
292
|
)
|
289
|
-
|
293
|
+
|
290
294
|
return cycle_id
|
291
|
-
|
295
|
+
|
292
296
|
@staticmethod
|
293
297
|
def data_quality_cycle(
|
294
298
|
workflow: Workflow,
|
@@ -296,14 +300,14 @@ result = {{
|
|
296
300
|
validator_node: str,
|
297
301
|
quality_threshold: float = 0.95,
|
298
302
|
max_iterations: int = 10,
|
299
|
-
cycle_id: Optional[str] = None
|
303
|
+
cycle_id: Optional[str] = None,
|
300
304
|
) -> str:
|
301
305
|
"""
|
302
306
|
Add a data quality improvement cycle to workflow.
|
303
|
-
|
307
|
+
|
304
308
|
Creates a cycle where data is cleaned and validated iteratively
|
305
309
|
until quality threshold is met.
|
306
|
-
|
310
|
+
|
307
311
|
Args:
|
308
312
|
workflow: Target workflow
|
309
313
|
cleaner_node: Node that cleans/improves data
|
@@ -311,10 +315,10 @@ result = {{
|
|
311
315
|
quality_threshold: Minimum quality score to achieve
|
312
316
|
max_iterations: Maximum cleaning iterations
|
313
317
|
cycle_id: Optional custom cycle identifier
|
314
|
-
|
318
|
+
|
315
319
|
Returns:
|
316
320
|
str: The cycle identifier for reference
|
317
|
-
|
321
|
+
|
318
322
|
Example:
|
319
323
|
>>> workflow = Workflow("data_quality", "Data Quality Example")
|
320
324
|
>>> workflow.add_node("cleaner", PythonCodeNode(), code="...")
|
@@ -325,10 +329,10 @@ result = {{
|
|
325
329
|
"""
|
326
330
|
if cycle_id is None:
|
327
331
|
cycle_id = f"data_quality_cycle_{int(time.time())}"
|
328
|
-
|
332
|
+
|
329
333
|
# Connect cleaner to validator
|
330
334
|
workflow.connect(cleaner_node, validator_node)
|
331
|
-
|
335
|
+
|
332
336
|
# Close the cycle with quality threshold
|
333
337
|
workflow.connect(
|
334
338
|
validator_node,
|
@@ -336,11 +340,11 @@ result = {{
|
|
336
340
|
cycle=True,
|
337
341
|
max_iterations=max_iterations,
|
338
342
|
convergence_check=f"quality_score >= {quality_threshold}",
|
339
|
-
cycle_id=cycle_id
|
343
|
+
cycle_id=cycle_id,
|
340
344
|
)
|
341
|
-
|
345
|
+
|
342
346
|
return cycle_id
|
343
|
-
|
347
|
+
|
344
348
|
@staticmethod
|
345
349
|
def learning_cycle(
|
346
350
|
workflow: Workflow,
|
@@ -349,14 +353,14 @@ result = {{
|
|
349
353
|
target_accuracy: float = 0.95,
|
350
354
|
max_epochs: int = 100,
|
351
355
|
early_stopping_patience: int = 10,
|
352
|
-
cycle_id: Optional[str] = None
|
356
|
+
cycle_id: Optional[str] = None,
|
353
357
|
) -> str:
|
354
358
|
"""
|
355
359
|
Add a machine learning training cycle to workflow.
|
356
|
-
|
360
|
+
|
357
361
|
Creates a cycle for iterative model training with early stopping
|
358
362
|
based on validation performance.
|
359
|
-
|
363
|
+
|
360
364
|
Args:
|
361
365
|
workflow: Target workflow
|
362
366
|
trainer_node: Node that trains the model
|
@@ -365,10 +369,10 @@ result = {{
|
|
365
369
|
max_epochs: Maximum training epochs
|
366
370
|
early_stopping_patience: Epochs to wait without improvement
|
367
371
|
cycle_id: Optional custom cycle identifier
|
368
|
-
|
372
|
+
|
369
373
|
Returns:
|
370
374
|
str: The cycle identifier for reference
|
371
|
-
|
375
|
+
|
372
376
|
Example:
|
373
377
|
>>> workflow = Workflow("ml_training", "ML Training Example")
|
374
378
|
>>> workflow.add_node("trainer", PythonCodeNode(), code="...")
|
@@ -379,11 +383,11 @@ result = {{
|
|
379
383
|
"""
|
380
384
|
if cycle_id is None:
|
381
385
|
cycle_id = f"learning_cycle_{int(time.time())}"
|
382
|
-
|
386
|
+
|
383
387
|
# Create early stopping controller
|
384
388
|
early_stop_controller_id = f"{trainer_node}_early_stop"
|
385
|
-
|
386
|
-
early_stop_code = f
|
389
|
+
|
390
|
+
early_stop_code = f"""
|
387
391
|
# Initialize early stopping state
|
388
392
|
try:
|
389
393
|
best_accuracy = best_accuracy
|
@@ -429,14 +433,17 @@ result = {{
|
|
429
433
|
"early_stopped": early_stop,
|
430
434
|
"training_complete": not should_continue
|
431
435
|
}}
|
432
|
-
|
433
|
-
|
434
|
-
workflow.add_node(
|
435
|
-
|
436
|
+
"""
|
437
|
+
|
438
|
+
workflow.add_node(
|
439
|
+
early_stop_controller_id,
|
440
|
+
PythonCodeNode(name=early_stop_controller_id, code=early_stop_code),
|
441
|
+
)
|
442
|
+
|
436
443
|
# Connect the training cycle
|
437
444
|
workflow.connect(trainer_node, evaluator_node)
|
438
445
|
workflow.connect(evaluator_node, early_stop_controller_id)
|
439
|
-
|
446
|
+
|
440
447
|
# Close the cycle with early stopping logic
|
441
448
|
workflow.connect(
|
442
449
|
early_stop_controller_id,
|
@@ -444,35 +451,35 @@ result = {{
|
|
444
451
|
cycle=True,
|
445
452
|
max_iterations=max_epochs,
|
446
453
|
convergence_check="training_complete == True",
|
447
|
-
cycle_id=cycle_id
|
454
|
+
cycle_id=cycle_id,
|
448
455
|
)
|
449
|
-
|
456
|
+
|
450
457
|
return cycle_id
|
451
|
-
|
458
|
+
|
452
459
|
@staticmethod
|
453
460
|
def convergence_cycle(
|
454
461
|
workflow: Workflow,
|
455
462
|
processor_node: str,
|
456
463
|
tolerance: float = 0.001,
|
457
464
|
max_iterations: int = 1000,
|
458
|
-
cycle_id: Optional[str] = None
|
465
|
+
cycle_id: Optional[str] = None,
|
459
466
|
) -> str:
|
460
467
|
"""
|
461
468
|
Add a numerical convergence cycle to workflow.
|
462
|
-
|
469
|
+
|
463
470
|
Creates a cycle that continues until successive iterations
|
464
471
|
produce values within a specified tolerance.
|
465
|
-
|
472
|
+
|
466
473
|
Args:
|
467
474
|
workflow: Target workflow
|
468
475
|
processor_node: Node that produces values to check for convergence
|
469
476
|
tolerance: Maximum difference between iterations for convergence
|
470
477
|
max_iterations: Maximum iterations before forced termination
|
471
478
|
cycle_id: Optional custom cycle identifier
|
472
|
-
|
479
|
+
|
473
480
|
Returns:
|
474
481
|
str: The cycle identifier for reference
|
475
|
-
|
482
|
+
|
476
483
|
Example:
|
477
484
|
>>> workflow = Workflow("convergence", "Convergence Example")
|
478
485
|
>>> workflow.add_node("processor", PythonCodeNode(), code="...")
|
@@ -482,11 +489,11 @@ result = {{
|
|
482
489
|
"""
|
483
490
|
if cycle_id is None:
|
484
491
|
cycle_id = f"convergence_cycle_{int(time.time())}"
|
485
|
-
|
492
|
+
|
486
493
|
# Create convergence checker node
|
487
494
|
convergence_checker_id = f"{processor_node}_convergence_checker"
|
488
|
-
|
489
|
-
convergence_code = f
|
495
|
+
|
496
|
+
convergence_code = f"""
|
490
497
|
import math
|
491
498
|
|
492
499
|
# Initialize convergence state
|
@@ -526,13 +533,16 @@ result = {{
|
|
526
533
|
|
527
534
|
# Update for next iteration
|
528
535
|
previous_value = current_value
|
529
|
-
|
530
|
-
|
531
|
-
workflow.add_node(
|
532
|
-
|
536
|
+
"""
|
537
|
+
|
538
|
+
workflow.add_node(
|
539
|
+
convergence_checker_id,
|
540
|
+
PythonCodeNode(name=convergence_checker_id, code=convergence_code),
|
541
|
+
)
|
542
|
+
|
533
543
|
# Connect processor to convergence checker
|
534
544
|
workflow.connect(processor_node, convergence_checker_id)
|
535
|
-
|
545
|
+
|
536
546
|
# Close the cycle with convergence condition
|
537
547
|
workflow.connect(
|
538
548
|
convergence_checker_id,
|
@@ -540,35 +550,35 @@ previous_value = current_value
|
|
540
550
|
cycle=True,
|
541
551
|
max_iterations=max_iterations,
|
542
552
|
convergence_check="converged == True",
|
543
|
-
cycle_id=cycle_id
|
553
|
+
cycle_id=cycle_id,
|
544
554
|
)
|
545
|
-
|
555
|
+
|
546
556
|
return cycle_id
|
547
|
-
|
557
|
+
|
548
558
|
@staticmethod
|
549
559
|
def batch_processing_cycle(
|
550
560
|
workflow: Workflow,
|
551
561
|
processor_node: str,
|
552
562
|
batch_size: int = 100,
|
553
563
|
total_items: Optional[int] = None,
|
554
|
-
cycle_id: Optional[str] = None
|
564
|
+
cycle_id: Optional[str] = None,
|
555
565
|
) -> str:
|
556
566
|
"""
|
557
567
|
Add a batch processing cycle to workflow.
|
558
|
-
|
568
|
+
|
559
569
|
Creates a cycle that processes data in batches, continuing
|
560
570
|
until all items are processed.
|
561
|
-
|
571
|
+
|
562
572
|
Args:
|
563
573
|
workflow: Target workflow
|
564
574
|
processor_node: Node that processes batches
|
565
575
|
batch_size: Number of items to process per batch
|
566
576
|
total_items: Total number of items to process (if known)
|
567
577
|
cycle_id: Optional custom cycle identifier
|
568
|
-
|
578
|
+
|
569
579
|
Returns:
|
570
580
|
str: The cycle identifier for reference
|
571
|
-
|
581
|
+
|
572
582
|
Example:
|
573
583
|
>>> workflow = Workflow("batch", "Batch Processing Example")
|
574
584
|
>>> workflow.add_node("processor", PythonCodeNode(), code="...")
|
@@ -578,11 +588,11 @@ previous_value = current_value
|
|
578
588
|
"""
|
579
589
|
if cycle_id is None:
|
580
590
|
cycle_id = f"batch_cycle_{int(time.time())}"
|
581
|
-
|
591
|
+
|
582
592
|
# Create batch controller node
|
583
593
|
batch_controller_id = f"{processor_node}_batch_controller"
|
584
|
-
|
585
|
-
batch_code = f
|
594
|
+
|
595
|
+
batch_code = f"""
|
586
596
|
# Initialize batch state
|
587
597
|
try:
|
588
598
|
batch_number = batch_number
|
@@ -625,19 +635,22 @@ result = {{
|
|
625
635
|
# Update for next iteration
|
626
636
|
start_index = end_index
|
627
637
|
items_processed += actual_batch_size
|
628
|
-
|
629
|
-
|
630
|
-
workflow.add_node(
|
631
|
-
|
638
|
+
"""
|
639
|
+
|
640
|
+
workflow.add_node(
|
641
|
+
batch_controller_id,
|
642
|
+
PythonCodeNode(name=batch_controller_id, code=batch_code),
|
643
|
+
)
|
644
|
+
|
632
645
|
# Connect batch controller to processor
|
633
646
|
workflow.connect(batch_controller_id, processor_node)
|
634
|
-
|
647
|
+
|
635
648
|
# Calculate max iterations based on total items
|
636
649
|
if total_items is not None:
|
637
650
|
max_iterations = math.ceil(total_items / batch_size) + 1
|
638
651
|
else:
|
639
652
|
max_iterations = 1000 # Default upper bound
|
640
|
-
|
653
|
+
|
641
654
|
# Close the cycle with completion condition
|
642
655
|
workflow.connect(
|
643
656
|
processor_node,
|
@@ -645,9 +658,9 @@ items_processed += actual_batch_size
|
|
645
658
|
cycle=True,
|
646
659
|
max_iterations=max_iterations,
|
647
660
|
convergence_check="all_processed == True",
|
648
|
-
cycle_id=cycle_id
|
661
|
+
cycle_id=cycle_id,
|
649
662
|
)
|
650
|
-
|
663
|
+
|
651
664
|
return cycle_id
|
652
665
|
|
653
666
|
|
@@ -658,7 +671,7 @@ def add_optimization_cycle(
|
|
658
671
|
evaluator_node: str,
|
659
672
|
convergence: str = "quality > 0.9",
|
660
673
|
max_iterations: int = 50,
|
661
|
-
cycle_id: Optional[str] = None
|
674
|
+
cycle_id: Optional[str] = None,
|
662
675
|
) -> str:
|
663
676
|
"""Add an optimization cycle pattern to this workflow."""
|
664
677
|
return CycleTemplates.optimization_cycle(
|
@@ -672,7 +685,7 @@ def add_retry_cycle(
|
|
672
685
|
max_retries: int = 3,
|
673
686
|
backoff_strategy: str = "exponential",
|
674
687
|
success_condition: str = "success == True",
|
675
|
-
cycle_id: Optional[str] = None
|
688
|
+
cycle_id: Optional[str] = None,
|
676
689
|
) -> str:
|
677
690
|
"""Add a retry cycle pattern to this workflow."""
|
678
691
|
return CycleTemplates.retry_cycle(
|
@@ -686,7 +699,7 @@ def add_data_quality_cycle(
|
|
686
699
|
validator_node: str,
|
687
700
|
quality_threshold: float = 0.95,
|
688
701
|
max_iterations: int = 10,
|
689
|
-
cycle_id: Optional[str] = None
|
702
|
+
cycle_id: Optional[str] = None,
|
690
703
|
) -> str:
|
691
704
|
"""Add a data quality improvement cycle to this workflow."""
|
692
705
|
return CycleTemplates.data_quality_cycle(
|
@@ -701,11 +714,17 @@ def add_learning_cycle(
|
|
701
714
|
target_accuracy: float = 0.95,
|
702
715
|
max_epochs: int = 100,
|
703
716
|
early_stopping_patience: int = 10,
|
704
|
-
cycle_id: Optional[str] = None
|
717
|
+
cycle_id: Optional[str] = None,
|
705
718
|
) -> str:
|
706
719
|
"""Add a machine learning training cycle to this workflow."""
|
707
720
|
return CycleTemplates.learning_cycle(
|
708
|
-
self,
|
721
|
+
self,
|
722
|
+
trainer_node,
|
723
|
+
evaluator_node,
|
724
|
+
target_accuracy,
|
725
|
+
max_epochs,
|
726
|
+
early_stopping_patience,
|
727
|
+
cycle_id,
|
709
728
|
)
|
710
729
|
|
711
730
|
|
@@ -714,7 +733,7 @@ def add_convergence_cycle(
|
|
714
733
|
processor_node: str,
|
715
734
|
tolerance: float = 0.001,
|
716
735
|
max_iterations: int = 1000,
|
717
|
-
cycle_id: Optional[str] = None
|
736
|
+
cycle_id: Optional[str] = None,
|
718
737
|
) -> str:
|
719
738
|
"""Add a numerical convergence cycle to this workflow."""
|
720
739
|
return CycleTemplates.convergence_cycle(
|
@@ -727,7 +746,7 @@ def add_batch_processing_cycle(
|
|
727
746
|
processor_node: str,
|
728
747
|
batch_size: int = 100,
|
729
748
|
total_items: Optional[int] = None,
|
730
|
-
cycle_id: Optional[str] = None
|
749
|
+
cycle_id: Optional[str] = None,
|
731
750
|
) -> str:
|
732
751
|
"""Add a batch processing cycle to this workflow."""
|
733
752
|
return CycleTemplates.batch_processing_cycle(
|
@@ -741,4 +760,4 @@ Workflow.add_retry_cycle = add_retry_cycle
|
|
741
760
|
Workflow.add_data_quality_cycle = add_data_quality_cycle
|
742
761
|
Workflow.add_learning_cycle = add_learning_cycle
|
743
762
|
Workflow.add_convergence_cycle = add_convergence_cycle
|
744
|
-
Workflow.add_batch_processing_cycle = add_batch_processing_cycle
|
763
|
+
Workflow.add_batch_processing_cycle = add_batch_processing_cycle
|