kailash 0.2.0__py3-none-any.whl → 0.2.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/mcp/server_new.py +6 -6
- kailash/nodes/data/__init__.py +1 -2
- kailash/nodes/data/sql.py +699 -256
- 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/migration.py +238 -197
- kailash/workflow/templates.py +124 -105
- kailash/workflow/validation.py +356 -298
- {kailash-0.2.0.dist-info → kailash-0.2.1.dist-info}/METADATA +4 -1
- {kailash-0.2.0.dist-info → kailash-0.2.1.dist-info}/RECORD +18 -18
- {kailash-0.2.0.dist-info → kailash-0.2.1.dist-info}/WHEEL +0 -0
- {kailash-0.2.0.dist-info → kailash-0.2.1.dist-info}/entry_points.txt +0 -0
- {kailash-0.2.0.dist-info → kailash-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.2.0.dist-info → kailash-0.2.1.dist-info}/top_level.txt +0 -0
@@ -57,7 +57,7 @@ class CycleException(WorkflowException):
|
|
57
57
|
error_code: str = "CYCLE_ERROR",
|
58
58
|
context: Optional[Dict[str, Any]] = None,
|
59
59
|
suggestions: Optional[List[str]] = None,
|
60
|
-
documentation_url: Optional[str] = None
|
60
|
+
documentation_url: Optional[str] = None,
|
61
61
|
):
|
62
62
|
"""
|
63
63
|
Initialize cycle exception with enhanced error information.
|
@@ -77,7 +77,7 @@ class CycleException(WorkflowException):
|
|
77
77
|
self.context = context or {}
|
78
78
|
self.suggestions = suggestions or []
|
79
79
|
self.documentation_url = documentation_url
|
80
|
-
|
80
|
+
|
81
81
|
# Log error for debugging
|
82
82
|
logger.debug(f"CycleException raised: {error_code} - {message}")
|
83
83
|
|
@@ -99,22 +99,22 @@ class CycleException(WorkflowException):
|
|
99
99
|
Documentation: https://docs.kailash.ai/cycles/configuration'
|
100
100
|
"""
|
101
101
|
message_parts = [f"Error: {self.args[0]}"]
|
102
|
-
|
102
|
+
|
103
103
|
if self.error_code != "CYCLE_ERROR":
|
104
104
|
message_parts.append(f"Code: {self.error_code}")
|
105
|
-
|
105
|
+
|
106
106
|
if self.context:
|
107
107
|
context_str = ", ".join(f"{k}={v}" for k, v in self.context.items())
|
108
108
|
message_parts.append(f"Context: {context_str}")
|
109
|
-
|
109
|
+
|
110
110
|
if self.suggestions:
|
111
111
|
message_parts.append("Suggestions:")
|
112
112
|
for suggestion in self.suggestions:
|
113
113
|
message_parts.append(f"• {suggestion}")
|
114
|
-
|
114
|
+
|
115
115
|
if self.documentation_url:
|
116
116
|
message_parts.append(f"Documentation: {self.documentation_url}")
|
117
|
-
|
117
|
+
|
118
118
|
return "\n".join(message_parts)
|
119
119
|
|
120
120
|
def __str__(self) -> str:
|
@@ -150,7 +150,7 @@ class CycleConfigurationError(CycleException):
|
|
150
150
|
message: str,
|
151
151
|
cycle_id: Optional[str] = None,
|
152
152
|
invalid_params: Optional[Dict[str, Any]] = None,
|
153
|
-
**kwargs
|
153
|
+
**kwargs,
|
154
154
|
):
|
155
155
|
"""
|
156
156
|
Initialize cycle configuration error.
|
@@ -164,30 +164,30 @@ class CycleConfigurationError(CycleException):
|
|
164
164
|
Side Effects:
|
165
165
|
Automatically generates context and suggestions based on parameters
|
166
166
|
"""
|
167
|
-
context = kwargs.get(
|
168
|
-
suggestions = kwargs.get(
|
169
|
-
|
167
|
+
context = kwargs.get("context", {})
|
168
|
+
suggestions = kwargs.get("suggestions", [])
|
169
|
+
|
170
170
|
# Add cycle-specific context
|
171
171
|
if cycle_id:
|
172
|
-
context[
|
172
|
+
context["cycle_id"] = cycle_id
|
173
173
|
if invalid_params:
|
174
174
|
context.update(invalid_params)
|
175
|
-
|
175
|
+
|
176
176
|
# Add common suggestions if none provided
|
177
177
|
if not suggestions:
|
178
178
|
suggestions = [
|
179
179
|
"Ensure at least one termination condition (max_iterations, convergence_check, or timeout)",
|
180
180
|
"Use positive values for numeric parameters",
|
181
181
|
"Avoid unsafe operations in convergence expressions",
|
182
|
-
"Check the CycleConfig documentation for valid parameter ranges"
|
182
|
+
"Check the CycleConfig documentation for valid parameter ranges",
|
183
183
|
]
|
184
|
-
|
184
|
+
|
185
185
|
super().__init__(
|
186
186
|
message,
|
187
|
-
error_code=kwargs.get(
|
187
|
+
error_code=kwargs.get("error_code", "CYCLE_CONFIG_001"),
|
188
188
|
context=context,
|
189
189
|
suggestions=suggestions,
|
190
|
-
documentation_url="https://docs.kailash.ai/cycles/configuration"
|
190
|
+
documentation_url="https://docs.kailash.ai/cycles/configuration",
|
191
191
|
)
|
192
192
|
|
193
193
|
|
@@ -220,7 +220,7 @@ class CycleConnectionError(CycleException):
|
|
220
220
|
target_node: Optional[str] = None,
|
221
221
|
available_nodes: Optional[List[str]] = None,
|
222
222
|
mapping_errors: Optional[Dict[str, str]] = None,
|
223
|
-
**kwargs
|
223
|
+
**kwargs,
|
224
224
|
):
|
225
225
|
"""
|
226
226
|
Initialize cycle connection error.
|
@@ -233,36 +233,40 @@ class CycleConnectionError(CycleException):
|
|
233
233
|
mapping_errors (Dict[str, str], optional): Parameter mapping errors
|
234
234
|
**kwargs: Additional arguments for base exception
|
235
235
|
"""
|
236
|
-
context = kwargs.get(
|
237
|
-
suggestions = kwargs.get(
|
238
|
-
|
236
|
+
context = kwargs.get("context", {})
|
237
|
+
suggestions = kwargs.get("suggestions", [])
|
238
|
+
|
239
239
|
# Add connection-specific context
|
240
240
|
if source_node:
|
241
|
-
context[
|
241
|
+
context["source_node"] = source_node
|
242
242
|
if target_node:
|
243
|
-
context[
|
243
|
+
context["target_node"] = target_node
|
244
244
|
if available_nodes:
|
245
|
-
context[
|
245
|
+
context["available_nodes"] = available_nodes
|
246
246
|
if mapping_errors:
|
247
|
-
context[
|
248
|
-
|
247
|
+
context["mapping_errors"] = mapping_errors
|
248
|
+
|
249
249
|
# Generate specific suggestions
|
250
250
|
if not suggestions:
|
251
251
|
suggestions = []
|
252
252
|
if available_nodes:
|
253
253
|
suggestions.append(f"Available nodes: {', '.join(available_nodes)}")
|
254
254
|
if source_node and available_nodes and source_node not in available_nodes:
|
255
|
-
suggestions.append(
|
255
|
+
suggestions.append(
|
256
|
+
f"Add node '{source_node}' to workflow before connecting"
|
257
|
+
)
|
256
258
|
if mapping_errors:
|
257
|
-
suggestions.append(
|
259
|
+
suggestions.append(
|
260
|
+
"Check parameter mappings for typos and type compatibility"
|
261
|
+
)
|
258
262
|
suggestions.append("Verify node IDs match exactly (case-sensitive)")
|
259
|
-
|
263
|
+
|
260
264
|
super().__init__(
|
261
265
|
message,
|
262
|
-
error_code=kwargs.get(
|
266
|
+
error_code=kwargs.get("error_code", "CYCLE_CONN_001"),
|
263
267
|
context=context,
|
264
268
|
suggestions=suggestions,
|
265
|
-
documentation_url="https://docs.kailash.ai/cycles/connections"
|
269
|
+
documentation_url="https://docs.kailash.ai/cycles/connections",
|
266
270
|
)
|
267
271
|
|
268
272
|
|
@@ -293,7 +297,7 @@ class CycleValidationError(CycleException):
|
|
293
297
|
cycle_group: Optional[str] = None,
|
294
298
|
validation_failures: Optional[List[str]] = None,
|
295
299
|
conflicting_values: Optional[List[Any]] = None,
|
296
|
-
**kwargs
|
300
|
+
**kwargs,
|
297
301
|
):
|
298
302
|
"""
|
299
303
|
Initialize cycle validation error.
|
@@ -305,34 +309,34 @@ class CycleValidationError(CycleException):
|
|
305
309
|
conflicting_values (List[Any], optional): Conflicting parameter values
|
306
310
|
**kwargs: Additional arguments for base exception
|
307
311
|
"""
|
308
|
-
context = kwargs.get(
|
309
|
-
suggestions = kwargs.get(
|
310
|
-
|
312
|
+
context = kwargs.get("context", {})
|
313
|
+
suggestions = kwargs.get("suggestions", [])
|
314
|
+
|
311
315
|
# Add validation-specific context
|
312
316
|
if cycle_group:
|
313
|
-
context[
|
317
|
+
context["cycle_group"] = cycle_group
|
314
318
|
if validation_failures:
|
315
|
-
context[
|
319
|
+
context["validation_failures"] = validation_failures
|
316
320
|
if conflicting_values:
|
317
|
-
context[
|
318
|
-
|
321
|
+
context["conflicting_values"] = conflicting_values
|
322
|
+
|
319
323
|
# Generate validation-specific suggestions
|
320
324
|
if not suggestions:
|
321
325
|
suggestions = [
|
322
326
|
"Review cycle configuration for consistency",
|
323
327
|
"Ensure all cycle edges use the same parameters",
|
324
328
|
"Check for proper cycle marking (cycle=True)",
|
325
|
-
"Validate nested cycle relationships"
|
329
|
+
"Validate nested cycle relationships",
|
326
330
|
]
|
327
331
|
if conflicting_values:
|
328
332
|
suggestions.append("Use consistent parameter values across cycle group")
|
329
|
-
|
333
|
+
|
330
334
|
super().__init__(
|
331
335
|
message,
|
332
|
-
error_code=kwargs.get(
|
336
|
+
error_code=kwargs.get("error_code", "CYCLE_VALID_001"),
|
333
337
|
context=context,
|
334
338
|
suggestions=suggestions,
|
335
|
-
documentation_url="https://docs.kailash.ai/cycles/validation"
|
339
|
+
documentation_url="https://docs.kailash.ai/cycles/validation",
|
336
340
|
)
|
337
341
|
|
338
342
|
|
@@ -366,7 +370,7 @@ class CycleExecutionError(CycleException):
|
|
366
370
|
max_iterations: Optional[int] = None,
|
367
371
|
timeout_seconds: Optional[float] = None,
|
368
372
|
memory_usage_mb: Optional[int] = None,
|
369
|
-
**kwargs
|
373
|
+
**kwargs,
|
370
374
|
):
|
371
375
|
"""
|
372
376
|
Initialize cycle execution error.
|
@@ -380,49 +384,59 @@ class CycleExecutionError(CycleException):
|
|
380
384
|
memory_usage_mb (int, optional): Current memory usage
|
381
385
|
**kwargs: Additional arguments for base exception
|
382
386
|
"""
|
383
|
-
context = kwargs.get(
|
384
|
-
suggestions = kwargs.get(
|
385
|
-
|
387
|
+
context = kwargs.get("context", {})
|
388
|
+
suggestions = kwargs.get("suggestions", [])
|
389
|
+
|
386
390
|
# Add execution-specific context
|
387
391
|
if cycle_id:
|
388
|
-
context[
|
392
|
+
context["cycle_id"] = cycle_id
|
389
393
|
if current_iteration is not None:
|
390
|
-
context[
|
394
|
+
context["current_iteration"] = current_iteration
|
391
395
|
if max_iterations is not None:
|
392
|
-
context[
|
396
|
+
context["max_iterations"] = max_iterations
|
393
397
|
if timeout_seconds is not None:
|
394
|
-
context[
|
398
|
+
context["timeout_seconds"] = timeout_seconds
|
395
399
|
if memory_usage_mb is not None:
|
396
|
-
context[
|
397
|
-
|
400
|
+
context["memory_usage_mb"] = memory_usage_mb
|
401
|
+
|
398
402
|
# Generate execution-specific suggestions
|
399
403
|
if not suggestions:
|
400
404
|
suggestions = []
|
401
|
-
if
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
405
|
+
if (
|
406
|
+
current_iteration
|
407
|
+
and max_iterations
|
408
|
+
and current_iteration >= max_iterations
|
409
|
+
):
|
410
|
+
suggestions.extend(
|
411
|
+
[
|
412
|
+
"Increase max_iterations if more iterations are needed",
|
413
|
+
"Add or improve convergence_check for early termination",
|
414
|
+
"Review cycle logic for efficiency improvements",
|
415
|
+
]
|
416
|
+
)
|
407
417
|
if timeout_seconds:
|
408
|
-
suggestions.extend(
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
418
|
+
suggestions.extend(
|
419
|
+
[
|
420
|
+
"Increase timeout limit if legitimate long execution is expected",
|
421
|
+
"Optimize node processing for faster execution",
|
422
|
+
"Consider breaking into smaller cycles",
|
423
|
+
]
|
424
|
+
)
|
413
425
|
if memory_usage_mb:
|
414
|
-
suggestions.extend(
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
426
|
+
suggestions.extend(
|
427
|
+
[
|
428
|
+
"Increase memory_limit if more memory is needed",
|
429
|
+
"Optimize data handling to reduce memory usage",
|
430
|
+
"Consider streaming or chunked processing",
|
431
|
+
]
|
432
|
+
)
|
433
|
+
|
420
434
|
super().__init__(
|
421
435
|
message,
|
422
|
-
error_code=kwargs.get(
|
436
|
+
error_code=kwargs.get("error_code", "CYCLE_EXEC_001"),
|
423
437
|
context=context,
|
424
438
|
suggestions=suggestions,
|
425
|
-
documentation_url="https://docs.kailash.ai/cycles/execution"
|
439
|
+
documentation_url="https://docs.kailash.ai/cycles/execution",
|
426
440
|
)
|
427
441
|
|
428
442
|
|
@@ -455,7 +469,7 @@ class CycleConvergenceError(CycleException):
|
|
455
469
|
evaluation_error: Optional[str] = None,
|
456
470
|
available_variables: Optional[List[str]] = None,
|
457
471
|
cycle_data: Optional[Dict[str, Any]] = None,
|
458
|
-
**kwargs
|
472
|
+
**kwargs,
|
459
473
|
):
|
460
474
|
"""
|
461
475
|
Initialize cycle convergence error.
|
@@ -468,46 +482,48 @@ class CycleConvergenceError(CycleException):
|
|
468
482
|
cycle_data (Dict[str, Any], optional): Current cycle data
|
469
483
|
**kwargs: Additional arguments for base exception
|
470
484
|
"""
|
471
|
-
context = kwargs.get(
|
472
|
-
suggestions = kwargs.get(
|
473
|
-
|
485
|
+
context = kwargs.get("context", {})
|
486
|
+
suggestions = kwargs.get("suggestions", [])
|
487
|
+
|
474
488
|
# Add convergence-specific context
|
475
489
|
if convergence_expression:
|
476
|
-
context[
|
490
|
+
context["convergence_expression"] = convergence_expression
|
477
491
|
if evaluation_error:
|
478
|
-
context[
|
492
|
+
context["evaluation_error"] = evaluation_error
|
479
493
|
if available_variables:
|
480
|
-
context[
|
494
|
+
context["available_variables"] = available_variables
|
481
495
|
if cycle_data:
|
482
|
-
context[
|
483
|
-
|
496
|
+
context["cycle_data"] = {
|
497
|
+
k: str(v)[:100] for k, v in cycle_data.items()
|
498
|
+
} # Truncate for readability
|
499
|
+
|
484
500
|
# Generate convergence-specific suggestions
|
485
501
|
if not suggestions:
|
486
502
|
suggestions = [
|
487
503
|
"Check convergence expression syntax for typos",
|
488
504
|
"Ensure all referenced variables exist in cycle output",
|
489
505
|
"Use simple comparison operators (>, <, ==, >=, <=)",
|
490
|
-
"Avoid complex logic or function calls in expressions"
|
506
|
+
"Avoid complex logic or function calls in expressions",
|
491
507
|
]
|
492
508
|
if available_variables:
|
493
|
-
suggestions.append(
|
509
|
+
suggestions.append(
|
510
|
+
f"Available variables: {', '.join(available_variables)}"
|
511
|
+
)
|
494
512
|
if convergence_expression and evaluation_error:
|
495
513
|
suggestions.append("Test convergence expression with sample data")
|
496
|
-
|
514
|
+
|
497
515
|
super().__init__(
|
498
516
|
message,
|
499
|
-
error_code=kwargs.get(
|
517
|
+
error_code=kwargs.get("error_code", "CYCLE_CONV_001"),
|
500
518
|
context=context,
|
501
519
|
suggestions=suggestions,
|
502
|
-
documentation_url="https://docs.kailash.ai/cycles/convergence"
|
520
|
+
documentation_url="https://docs.kailash.ai/cycles/convergence",
|
503
521
|
)
|
504
522
|
|
505
523
|
|
506
524
|
# Utility functions for enhanced error reporting
|
507
525
|
def create_configuration_error(
|
508
|
-
issue: str,
|
509
|
-
cycle_id: Optional[str] = None,
|
510
|
-
**invalid_params
|
526
|
+
issue: str, cycle_id: Optional[str] = None, **invalid_params
|
511
527
|
) -> CycleConfigurationError:
|
512
528
|
"""
|
513
529
|
Create a standardized configuration error with common suggestions.
|
@@ -528,9 +544,7 @@ def create_configuration_error(
|
|
528
544
|
... )
|
529
545
|
"""
|
530
546
|
return CycleConfigurationError(
|
531
|
-
message=issue,
|
532
|
-
cycle_id=cycle_id,
|
533
|
-
invalid_params=invalid_params
|
547
|
+
message=issue, cycle_id=cycle_id, invalid_params=invalid_params
|
534
548
|
)
|
535
549
|
|
536
550
|
|
@@ -538,7 +552,7 @@ def create_connection_error(
|
|
538
552
|
issue: str,
|
539
553
|
source_node: Optional[str] = None,
|
540
554
|
target_node: Optional[str] = None,
|
541
|
-
available_nodes: Optional[List[str]] = None
|
555
|
+
available_nodes: Optional[List[str]] = None,
|
542
556
|
) -> CycleConnectionError:
|
543
557
|
"""
|
544
558
|
Create a standardized connection error with node context.
|
@@ -563,7 +577,7 @@ def create_connection_error(
|
|
563
577
|
message=issue,
|
564
578
|
source_node=source_node,
|
565
579
|
target_node=target_node,
|
566
|
-
available_nodes=available_nodes
|
580
|
+
available_nodes=available_nodes,
|
567
581
|
)
|
568
582
|
|
569
583
|
|
@@ -571,7 +585,7 @@ def create_execution_error(
|
|
571
585
|
issue: str,
|
572
586
|
cycle_id: Optional[str] = None,
|
573
587
|
current_iteration: Optional[int] = None,
|
574
|
-
max_iterations: Optional[int] = None
|
588
|
+
max_iterations: Optional[int] = None,
|
575
589
|
) -> CycleExecutionError:
|
576
590
|
"""
|
577
591
|
Create a standardized execution error with runtime context.
|
@@ -597,5 +611,5 @@ def create_execution_error(
|
|
597
611
|
message=issue,
|
598
612
|
cycle_id=cycle_id,
|
599
613
|
current_iteration=current_iteration,
|
600
|
-
max_iterations=max_iterations
|
601
|
-
)
|
614
|
+
max_iterations=max_iterations,
|
615
|
+
)
|