kailash 0.9.17__tar.gz → 0.9.19__tar.gz
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-0.9.17/src/kailash.egg-info → kailash-0.9.19}/PKG-INFO +1 -1
- {kailash-0.9.17 → kailash-0.9.19}/pyproject.toml +1 -1
- {kailash-0.9.17 → kailash-0.9.19}/setup.py +1 -1
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/__init__.py +1 -2
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/subscriptions.py +3 -3
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/monitoring/__init__.py +8 -8
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/monitoring/asyncsql_metrics.py +101 -75
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/llm_agent.py +176 -9
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/async_sql.py +93 -26
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/local.py +4 -1
- {kailash-0.9.17 → kailash-0.9.19/src/kailash.egg-info}/PKG-INFO +1 -1
- {kailash-0.9.17 → kailash-0.9.19}/LICENSE +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/MANIFEST.in +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/NOTICE +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/README.md +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/setup.cfg +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/__main__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/access_control/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/access_control/managers.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/access_control/rule_evaluators.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/access_control.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/access_control_abac.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/adapters/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/adapters/mcp_platform_adapter.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/analysis/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/analysis/conditional_branch_analyzer.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/api/auth.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/api/custom_nodes.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/api/custom_nodes_secure.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/api/gateway.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/api/mcp_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/api/studio.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/api/workflow_api.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/channels/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/channels/api_channel.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/channels/base.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/channels/cli_channel.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/channels/event_router.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/channels/mcp_channel.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/channels/session.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/cli/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/cli/commands.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/cli/validate_imports.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/cli/validation_audit.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/client/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/client/enhanced_client.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/config/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/config/database_config.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/actors/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/actors/adaptive_pool_controller.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/actors/connection_actor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/actors/supervisor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/ml/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/ml/query_patterns.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/monitoring/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/monitoring/connection_metrics.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/optimization/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/resilience/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/resilience/bulkhead.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/resilience/circuit_breaker.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/core/resilience/health_monitor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/database/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/database/execution_pipeline.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/compliance.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/consistency.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/coordination/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/coordination/global_ordering.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/coordination/leader_election.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/coordination/partition_detector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/coordination/raft.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/discovery.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/location.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/migration/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/migration/edge_migration_service.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/migration/edge_migrator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/monitoring/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/monitoring/edge_monitor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/prediction/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/prediction/predictive_warmer.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/cloud_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/cost_optimizer.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/docker_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/kubernetes_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/platform_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/predictive_scaler.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/resource_analyzer.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/edge/resource/resource_pools.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/gateway/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/gateway/api.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/gateway/enhanced_gateway.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/gateway/resource_resolver.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/gateway/security.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/integrations/dataflow_edge.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/manifest.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/advanced_features.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/ai_registry_server.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/auth.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/client.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/client_new.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/discovery.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/errors.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/oauth.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/protocol.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/registry_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/server.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/servers/ai_registry.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/transports.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/utils/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/utils/cache.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/utils/config.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/utils/formatters.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/mcp_server/utils/metrics.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/auth/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/auth/access_control.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/auth/auth_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/auth/exceptions.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/auth/jwt_auth.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/auth/models.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/auth/utils.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/communication/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/communication/ai_chat.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/communication/api_gateway.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/communication/events.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/communication/realtime.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/core/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/core/agent_ui.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/core/schema.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/core/workflows.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/database/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/database/base.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/database/base_models.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/database/enums.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/database/migrations.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/database/models.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/database/repositories.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/database/session_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/gateway/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/gateway/checkpoint_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/gateway/deduplicator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/gateway/durable_gateway.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/gateway/durable_request.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/gateway/event_store.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/gateway/storage_backends.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/mcp/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/mcp/client_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/middleware/mcp/enhanced_server.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/cli.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/compatibility_checker.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/configuration_validator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/documentation_generator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/examples/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/examples/complete_migration_example.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/migration_assistant.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/performance_comparator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/regression_detector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/tests/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/tests/test_compatibility_checker.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/tests/test_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/tests/test_migration_assistant.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/migration/tests/test_performance_comparator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/monitoring/alerts.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/monitoring/metrics.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/__init___original.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/audit_log.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/permission_check.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/role_management.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/schema.sql +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/schema_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/security_event.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/tenant_isolation.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/transaction_utils.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/admin/user_management.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/a2a.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/a2a_backup.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/agents.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/ai_providers.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/embedding_generator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/hybrid_search.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/intelligent_agent_orchestrator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/iterative_llm_agent.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/models.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/self_organizing.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/semantic_memory.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/streaming_analytics.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ai/vision_utils.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/alerts/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/alerts/base.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/alerts/discord.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/api/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/api/auth.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/api/graphql.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/api/http.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/api/monitoring.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/api/rate_limiting.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/api/rest.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/api/security.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/auth/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/auth/directory_integration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/auth/enterprise_auth_provider.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/auth/mfa.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/auth/risk_assessment.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/auth/session_management.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/auth/sso.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/base.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/base_async.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/base_cycle_aware.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/base_with_acl.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/cache/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/cache/cache.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/cache/cache_invalidation.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/cache/redis_pool_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/code/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/code/async_python.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/code/python.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/compliance/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/compliance/data_retention.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/compliance/gdpr.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/async_connection.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/async_vector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/bulk_operations.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/directory.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/event_generation.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/file_discovery.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/optimistic_locking.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/query_builder.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/query_cache.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/query_pipeline.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/query_router.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/readers.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/redis.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/retrieval.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/sharepoint_graph.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/sources.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/sql.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/streaming.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/vector_db.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/workflow_connection_pool.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/data/writers.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/base.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/cloud_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/coordination.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/docker_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/edge_data.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/edge_migration_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/edge_monitoring_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/edge_state.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/edge_warming_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/kubernetes_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/platform_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/resource_analyzer_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/resource_optimizer_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/edge/resource_scaler_node.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/enterprise/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/enterprise/audit_logger.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/enterprise/batch_processor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/enterprise/data_lineage.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/enterprise/mcp_executor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/enterprise/service_discovery.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/enterprise/tenant_assignment.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/governance.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/logic/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/logic/async_operations.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/logic/convergence.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/logic/intelligent_merge.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/logic/loop.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/logic/operations.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/logic/workflow.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/mixins/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/mixins/event_emitter.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/mixins/mcp.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/mixins/security.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/mixins.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/connection_dashboard.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/deadlock_detector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/health_check.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/log_processor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/metrics_collector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/performance_anomaly.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/performance_benchmark.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/race_condition_detector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/transaction_metrics.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/monitoring/transaction_monitor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/ports.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/advanced.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/agentic.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/conversational.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/evaluation.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/federated.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/graph.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/multimodal.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/optimized.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/privacy.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/query_processing.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/realtime.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/registry.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/router.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/similarity.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/strategies.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/rag/workflows.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/security/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/security/abac_evaluator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/security/audit_log.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/security/behavior_analysis.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/security/credential_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/security/rotating_credentials.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/security/security_event.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/security/threat_detection.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/system/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/system/command_parser.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/testing/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/testing/credential_testing.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transaction/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transaction/distributed_transaction_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transaction/saga_coordinator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transaction/saga_state_storage.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transaction/saga_step.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transaction/transaction_context.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transaction/two_phase_commit.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transform/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transform/chunkers.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transform/formatters.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/transform/processors.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/validation/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/validation/test_executor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/validation/validation_nodes.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/nodes/validation.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/planning/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/planning/dynamic_execution_planner.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/resources/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/resources/factory.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/resources/health.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/resources/reference.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/resources/registry.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/access_controlled.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/async_local.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/compatibility_reporter.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/docker.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/hierarchical_switch_executor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/monitoring/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/monitoring/runtime_monitor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/parallel.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/parallel_cyclic.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/parameter_injection.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/parameter_injector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/performance_monitor.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/resource_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/runner.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/secret_provider.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/testing.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/validation/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/validation/connection_context.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/validation/enhanced_error_formatter.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/validation/error_categorizer.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/validation/import_validator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/validation/metrics.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/validation/performance.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/runtime/validation/suggestion_engine.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/sdk_exceptions.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/security.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/servers/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/servers/durable_workflow_server.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/servers/enterprise_workflow_server.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/servers/gateway.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/servers/workflow_server.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/testing/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/testing/async_test_case.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/testing/async_utils.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/testing/fixtures.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/testing/mock_registry.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/tracking/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/tracking/manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/tracking/metrics_collector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/tracking/models.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/tracking/storage/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/tracking/storage/base.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/tracking/storage/database.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/tracking/storage/filesystem.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/circular_dependency_detector.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/data_paths.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/data_validation.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/export.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/migrations/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/migrations/generator.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/migrations/models.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/migrations/runner.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/resource_manager.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/secure_logging.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/utils/templates.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/visualization/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/visualization/api.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/visualization/dashboard.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/visualization/performance.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/visualization/reports.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/__init__.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/async_builder.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/async_patterns.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/builder.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/contracts.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/convergence.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/cycle_analyzer.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/cycle_builder.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/cycle_config.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/cycle_debugger.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/cycle_exceptions.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/cycle_profiler.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/cycle_state.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/cyclic_runner.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/edge_infrastructure.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/graph.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/input_handling.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/mermaid_visualizer.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/migration.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/mock_registry.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/resilience.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/runner.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/safety.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/state.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/templates.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/type_inference.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/validation.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash/workflow/visualization.py +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash.egg-info/SOURCES.txt +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash.egg-info/dependency_links.txt +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash.egg-info/entry_points.txt +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash.egg-info/not-zip-safe +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash.egg-info/requires.txt +0 -0
- {kailash-0.9.17 → kailash-0.9.19}/src/kailash.egg-info/top_level.txt +0 -0
@@ -13,7 +13,7 @@ with open(os.path.join(this_directory, "README.md"), encoding="utf-8") as f:
|
|
13
13
|
# Package configuration
|
14
14
|
setup(
|
15
15
|
name="kailash",
|
16
|
-
version="0.9.
|
16
|
+
version="0.9.19",
|
17
17
|
author="Integrum",
|
18
18
|
author_email="info@integrum.com",
|
19
19
|
description="Python SDK for the Kailash container-node architecture",
|
@@ -5,7 +5,6 @@ that align with container-node architecture while allowing rapid prototyping.
|
|
5
5
|
|
6
6
|
New in v0.9.17: AsyncSQL per-pool locking eliminates lock contention bottleneck.
|
7
7
|
Achieves 100% success at 300+ concurrent operations (was 50% failure). 85% performance improvement with per-pool locks.
|
8
|
-
Previous v0.9.14: Code quality improvements and updated dependencies for DataFlow v0.4.6 compatibility.
|
9
8
|
Previous v0.9.13: Fixed WorkflowBuilder parameter validation false positives (Bug 010).
|
10
9
|
Enhanced validation.py to recognize auto_map_from parameters, eliminating spurious warnings.
|
11
10
|
Previous v0.9.12: SQLite Compatibility & Code Quality improvements.
|
@@ -53,7 +52,7 @@ except ImportError:
|
|
53
52
|
# For backward compatibility
|
54
53
|
WorkflowGraph = Workflow
|
55
54
|
|
56
|
-
__version__ = "0.9.
|
55
|
+
__version__ = "0.9.18"
|
57
56
|
|
58
57
|
__all__ = [
|
59
58
|
# Core workflow components
|
@@ -1075,9 +1075,9 @@ class ResourceSubscriptionManager:
|
|
1075
1075
|
This method should be overridden or configured to fetch actual resource data.
|
1076
1076
|
For now, it returns basic resource information from the monitored state.
|
1077
1077
|
"""
|
1078
|
-
async with self.
|
1079
|
-
if uri in self.
|
1080
|
-
state = self.
|
1078
|
+
async with self.resource_monitor._lock:
|
1079
|
+
if uri in self.resource_monitor._resource_states:
|
1080
|
+
state = self.resource_monitor._resource_states[uri]
|
1081
1081
|
return {
|
1082
1082
|
"uri": uri,
|
1083
1083
|
"content": state.get("content", {}),
|
@@ -8,38 +8,38 @@ AsyncSQL lock contention monitoring.
|
|
8
8
|
|
9
9
|
# Original monitoring imports
|
10
10
|
from .alerts import AlertManager, AlertRule, AlertSeverity
|
11
|
-
from .metrics import PerformanceMetrics, SecurityMetrics, ValidationMetrics
|
12
11
|
|
13
12
|
# AsyncSQL lock monitoring imports
|
14
13
|
from .asyncsql_metrics import (
|
14
|
+
PROMETHEUS_AVAILABLE,
|
15
15
|
AsyncSQLMetrics,
|
16
|
-
enable_metrics,
|
17
16
|
disable_metrics,
|
17
|
+
enable_metrics,
|
18
18
|
get_global_metrics,
|
19
|
-
|
19
|
+
integrate_with_async_sql,
|
20
20
|
record_lock_acquisition,
|
21
21
|
record_pool_operation,
|
22
22
|
set_active_locks,
|
23
|
-
|
24
|
-
PROMETHEUS_AVAILABLE
|
23
|
+
set_global_metrics,
|
25
24
|
)
|
25
|
+
from .metrics import PerformanceMetrics, SecurityMetrics, ValidationMetrics
|
26
26
|
|
27
27
|
__all__ = [
|
28
28
|
"ValidationMetrics",
|
29
29
|
"SecurityMetrics",
|
30
|
-
"PerformanceMetrics",
|
30
|
+
"PerformanceMetrics",
|
31
31
|
"AlertManager",
|
32
32
|
"AlertRule",
|
33
33
|
"AlertSeverity",
|
34
34
|
# AsyncSQL monitoring
|
35
35
|
"AsyncSQLMetrics",
|
36
36
|
"enable_metrics",
|
37
|
-
"disable_metrics",
|
37
|
+
"disable_metrics",
|
38
38
|
"get_global_metrics",
|
39
39
|
"set_global_metrics",
|
40
40
|
"record_lock_acquisition",
|
41
41
|
"record_pool_operation",
|
42
42
|
"set_active_locks",
|
43
43
|
"integrate_with_async_sql",
|
44
|
-
"PROMETHEUS_AVAILABLE"
|
44
|
+
"PROMETHEUS_AVAILABLE",
|
45
45
|
]
|
@@ -6,11 +6,12 @@ per-pool locking performance and contention patterns.
|
|
6
6
|
"""
|
7
7
|
|
8
8
|
import time
|
9
|
-
from typing import Optional, Dict, Any
|
10
9
|
from contextlib import asynccontextmanager
|
10
|
+
from typing import Any, Dict, Optional
|
11
11
|
|
12
12
|
try:
|
13
13
|
import prometheus_client
|
14
|
+
|
14
15
|
PROMETHEUS_AVAILABLE = True
|
15
16
|
except ImportError:
|
16
17
|
PROMETHEUS_AVAILABLE = False
|
@@ -18,66 +19,85 @@ except ImportError:
|
|
18
19
|
|
19
20
|
class AsyncSQLMetrics:
|
20
21
|
"""Prometheus metrics collector for AsyncSQL lock contention monitoring."""
|
21
|
-
|
22
|
-
def __init__(
|
22
|
+
|
23
|
+
def __init__(
|
24
|
+
self,
|
25
|
+
enabled: bool = True,
|
26
|
+
registry: Optional[prometheus_client.CollectorRegistry] = None,
|
27
|
+
):
|
23
28
|
"""
|
24
29
|
Initialize AsyncSQL metrics collector.
|
25
|
-
|
30
|
+
|
26
31
|
Args:
|
27
32
|
enabled: Whether to collect metrics (disabled if prometheus_client not available)
|
28
33
|
registry: Custom Prometheus registry (uses default if None)
|
29
34
|
"""
|
30
35
|
self.enabled = enabled and PROMETHEUS_AVAILABLE
|
31
36
|
self.registry = registry or prometheus_client.REGISTRY
|
32
|
-
|
37
|
+
|
33
38
|
if not self.enabled:
|
34
39
|
return
|
35
|
-
|
40
|
+
|
36
41
|
# Lock acquisition counter
|
37
42
|
self.lock_acquisition_counter = prometheus_client.Counter(
|
38
|
-
|
39
|
-
|
40
|
-
[
|
41
|
-
registry=self.registry
|
43
|
+
"asyncsql_lock_acquisitions_total",
|
44
|
+
"Total number of AsyncSQL lock acquisitions",
|
45
|
+
["pool_key", "status"], # status: success, timeout, error
|
46
|
+
registry=self.registry,
|
42
47
|
)
|
43
|
-
|
44
|
-
# Lock wait time histogram
|
48
|
+
|
49
|
+
# Lock wait time histogram
|
45
50
|
self.lock_wait_time_histogram = prometheus_client.Histogram(
|
46
|
-
|
47
|
-
|
48
|
-
[
|
49
|
-
buckets=(
|
50
|
-
|
51
|
+
"asyncsql_lock_wait_seconds",
|
52
|
+
"Time spent waiting for AsyncSQL locks",
|
53
|
+
["pool_key"],
|
54
|
+
buckets=(
|
55
|
+
0.001,
|
56
|
+
0.005,
|
57
|
+
0.01,
|
58
|
+
0.025,
|
59
|
+
0.05,
|
60
|
+
0.1,
|
61
|
+
0.25,
|
62
|
+
0.5,
|
63
|
+
1.0,
|
64
|
+
2.5,
|
65
|
+
5.0,
|
66
|
+
float("inf"),
|
67
|
+
),
|
68
|
+
registry=self.registry,
|
51
69
|
)
|
52
|
-
|
70
|
+
|
53
71
|
# Active locks gauge
|
54
72
|
self.active_locks_gauge = prometheus_client.Gauge(
|
55
|
-
|
56
|
-
|
57
|
-
[
|
58
|
-
registry=self.registry
|
73
|
+
"asyncsql_active_locks",
|
74
|
+
"Number of currently active AsyncSQL locks",
|
75
|
+
["pool_key"],
|
76
|
+
registry=self.registry,
|
59
77
|
)
|
60
|
-
|
78
|
+
|
61
79
|
# Pool operations counter
|
62
80
|
self.pool_operations_counter = prometheus_client.Counter(
|
63
|
-
|
64
|
-
|
65
|
-
[
|
66
|
-
registry=self.registry
|
81
|
+
"asyncsql_pool_operations_total",
|
82
|
+
"Total number of AsyncSQL pool operations",
|
83
|
+
["pool_key", "operation"], # operation: create, cleanup, acquire, release
|
84
|
+
registry=self.registry,
|
67
85
|
)
|
68
|
-
|
86
|
+
|
69
87
|
# Lock contention summary
|
70
88
|
self.lock_contention_summary = prometheus_client.Summary(
|
71
|
-
|
72
|
-
|
73
|
-
[
|
74
|
-
registry=self.registry
|
89
|
+
"asyncsql_lock_contention_seconds",
|
90
|
+
"Summary of AsyncSQL lock contention patterns",
|
91
|
+
["pool_key"],
|
92
|
+
registry=self.registry,
|
75
93
|
)
|
76
|
-
|
77
|
-
def record_lock_acquisition(
|
94
|
+
|
95
|
+
def record_lock_acquisition(
|
96
|
+
self, pool_key: str, status: str, wait_time: float = 0.0
|
97
|
+
):
|
78
98
|
"""
|
79
99
|
Record a lock acquisition event.
|
80
|
-
|
100
|
+
|
81
101
|
Args:
|
82
102
|
pool_key: The pool key for the lock
|
83
103
|
status: 'success', 'timeout', or 'error'
|
@@ -85,44 +105,46 @@ class AsyncSQLMetrics:
|
|
85
105
|
"""
|
86
106
|
if not self.enabled:
|
87
107
|
return
|
88
|
-
|
108
|
+
|
89
109
|
self.lock_acquisition_counter.labels(pool_key=pool_key, status=status).inc()
|
90
|
-
|
110
|
+
|
91
111
|
if wait_time > 0:
|
92
112
|
self.lock_wait_time_histogram.labels(pool_key=pool_key).observe(wait_time)
|
93
113
|
self.lock_contention_summary.labels(pool_key=pool_key).observe(wait_time)
|
94
|
-
|
114
|
+
|
95
115
|
def set_active_locks(self, pool_key: str, count: int):
|
96
116
|
"""
|
97
117
|
Update the count of active locks for a pool.
|
98
|
-
|
118
|
+
|
99
119
|
Args:
|
100
120
|
pool_key: The pool key
|
101
121
|
count: Number of active locks
|
102
122
|
"""
|
103
123
|
if not self.enabled:
|
104
124
|
return
|
105
|
-
|
125
|
+
|
106
126
|
self.active_locks_gauge.labels(pool_key=pool_key).set(count)
|
107
|
-
|
127
|
+
|
108
128
|
def record_pool_operation(self, pool_key: str, operation: str):
|
109
129
|
"""
|
110
130
|
Record a pool operation event.
|
111
|
-
|
131
|
+
|
112
132
|
Args:
|
113
133
|
pool_key: The pool key
|
114
134
|
operation: 'create', 'cleanup', 'acquire', 'release'
|
115
135
|
"""
|
116
136
|
if not self.enabled:
|
117
137
|
return
|
118
|
-
|
119
|
-
self.pool_operations_counter.labels(
|
120
|
-
|
138
|
+
|
139
|
+
self.pool_operations_counter.labels(
|
140
|
+
pool_key=pool_key, operation=operation
|
141
|
+
).inc()
|
142
|
+
|
121
143
|
@asynccontextmanager
|
122
144
|
async def timed_lock_acquisition(self, pool_key: str):
|
123
145
|
"""
|
124
146
|
Context manager to time lock acquisition and automatically record metrics.
|
125
|
-
|
147
|
+
|
126
148
|
Usage:
|
127
149
|
async with metrics.timed_lock_acquisition('my_pool_key'):
|
128
150
|
# Lock acquisition logic here
|
@@ -131,16 +153,16 @@ class AsyncSQLMetrics:
|
|
131
153
|
pass
|
132
154
|
"""
|
133
155
|
start_time = time.time()
|
134
|
-
status =
|
135
|
-
|
156
|
+
status = "error"
|
157
|
+
|
136
158
|
try:
|
137
159
|
yield
|
138
|
-
status =
|
160
|
+
status = "success"
|
139
161
|
except Exception as e:
|
140
|
-
if
|
141
|
-
status =
|
162
|
+
if "timeout" in str(e).lower():
|
163
|
+
status = "timeout"
|
142
164
|
else:
|
143
|
-
status =
|
165
|
+
status = "error"
|
144
166
|
raise
|
145
167
|
finally:
|
146
168
|
wait_time = time.time() - start_time
|
@@ -165,13 +187,15 @@ def set_global_metrics(metrics: Optional[AsyncSQLMetrics]):
|
|
165
187
|
_global_metrics = metrics
|
166
188
|
|
167
189
|
|
168
|
-
def enable_metrics(
|
190
|
+
def enable_metrics(
|
191
|
+
registry: Optional[prometheus_client.CollectorRegistry] = None,
|
192
|
+
) -> AsyncSQLMetrics:
|
169
193
|
"""
|
170
194
|
Enable global AsyncSQL metrics collection.
|
171
|
-
|
195
|
+
|
172
196
|
Args:
|
173
197
|
registry: Custom Prometheus registry (uses default if None)
|
174
|
-
|
198
|
+
|
175
199
|
Returns:
|
176
200
|
The configured metrics instance
|
177
201
|
"""
|
@@ -211,41 +235,41 @@ def set_active_locks(pool_key: str, count: int):
|
|
211
235
|
def integrate_with_async_sql():
|
212
236
|
"""
|
213
237
|
Example of how to integrate metrics with AsyncSQLDatabaseNode.
|
214
|
-
|
238
|
+
|
215
239
|
This would typically be called during AsyncSQL initialization or
|
216
240
|
through a configuration setting.
|
217
241
|
"""
|
218
242
|
if not PROMETHEUS_AVAILABLE:
|
219
243
|
return None
|
220
|
-
|
244
|
+
|
221
245
|
# Enable metrics
|
222
246
|
metrics = enable_metrics()
|
223
|
-
|
247
|
+
|
224
248
|
# Example: monkey-patch AsyncSQL methods to include metrics
|
225
249
|
# (This is just an example - actual integration would be cleaner)
|
226
250
|
from kailash.nodes.data.async_sql import AsyncSQLDatabaseNode
|
227
|
-
|
251
|
+
|
228
252
|
# Store original methods
|
229
253
|
original_get_pool_creation_lock = AsyncSQLDatabaseNode._get_pool_creation_lock
|
230
254
|
original_acquire_lock = AsyncSQLDatabaseNode._acquire_pool_lock_with_timeout
|
231
|
-
|
232
|
-
@classmethod
|
255
|
+
|
256
|
+
@classmethod
|
233
257
|
def instrumented_get_pool_creation_lock(cls, pool_key: str):
|
234
258
|
"""Instrumented version that records pool operations."""
|
235
|
-
record_pool_operation(pool_key,
|
259
|
+
record_pool_operation(pool_key, "acquire")
|
236
260
|
return original_get_pool_creation_lock(pool_key)
|
237
|
-
|
261
|
+
|
238
262
|
@classmethod
|
239
263
|
async def instrumented_acquire_lock(cls, pool_key: str, timeout: float = 5.0):
|
240
264
|
"""Instrumented version that records lock acquisitions."""
|
241
265
|
async with metrics.timed_lock_acquisition(pool_key):
|
242
266
|
async with original_acquire_lock(pool_key, timeout):
|
243
267
|
yield
|
244
|
-
|
268
|
+
|
245
269
|
# Apply instrumentation
|
246
270
|
AsyncSQLDatabaseNode._get_pool_creation_lock = instrumented_get_pool_creation_lock
|
247
271
|
AsyncSQLDatabaseNode._acquire_pool_lock_with_timeout = instrumented_acquire_lock
|
248
|
-
|
272
|
+
|
249
273
|
return metrics
|
250
274
|
|
251
275
|
|
@@ -253,23 +277,25 @@ if __name__ == "__main__":
|
|
253
277
|
# Example usage
|
254
278
|
print("AsyncSQL Metrics Module")
|
255
279
|
print(f"Prometheus available: {PROMETHEUS_AVAILABLE}")
|
256
|
-
|
280
|
+
|
257
281
|
if PROMETHEUS_AVAILABLE:
|
258
282
|
# Enable metrics
|
259
283
|
metrics = enable_metrics()
|
260
|
-
|
284
|
+
|
261
285
|
# Simulate some metrics
|
262
|
-
metrics.record_lock_acquisition(
|
263
|
-
metrics.record_lock_acquisition(
|
264
|
-
metrics.record_lock_acquisition(
|
265
|
-
metrics.set_active_locks(
|
266
|
-
metrics.record_pool_operation(
|
267
|
-
|
286
|
+
metrics.record_lock_acquisition("test_pool_1", "success", 0.005)
|
287
|
+
metrics.record_lock_acquisition("test_pool_1", "success", 0.003)
|
288
|
+
metrics.record_lock_acquisition("test_pool_2", "timeout", 5.0)
|
289
|
+
metrics.set_active_locks("test_pool_1", 2)
|
290
|
+
metrics.record_pool_operation("test_pool_1", "create")
|
291
|
+
|
268
292
|
print("Metrics recorded successfully")
|
269
293
|
print("Access metrics at: http://localhost:8000/metrics")
|
270
294
|
print("(Start prometheus_client HTTP server to view metrics)")
|
271
|
-
|
295
|
+
|
272
296
|
# Start metrics server (for testing)
|
273
297
|
# prometheus_client.start_http_server(8000)
|
274
298
|
else:
|
275
|
-
print(
|
299
|
+
print(
|
300
|
+
"Install prometheus_client to enable metrics: pip install prometheus_client"
|
301
|
+
)
|
@@ -1845,6 +1845,144 @@ class LLMAgentNode(Node):
|
|
1845
1845
|
"efficiency_score": completion_tokens / max(total_tokens, 1),
|
1846
1846
|
}
|
1847
1847
|
|
1848
|
+
def _extract_tool_call_info(self, tool_call) -> dict[str, Any]:
|
1849
|
+
"""Extract tool call information from both Pydantic models and dictionaries.
|
1850
|
+
|
1851
|
+
Handles OpenAI v1.97.1+ Pydantic models and legacy dictionary formats.
|
1852
|
+
|
1853
|
+
Args:
|
1854
|
+
tool_call: Tool call object (either Pydantic model or dict)
|
1855
|
+
|
1856
|
+
Returns:
|
1857
|
+
Dict with normalized tool call information
|
1858
|
+
|
1859
|
+
Raises:
|
1860
|
+
ValueError: If tool_call format is unrecognized or invalid
|
1861
|
+
json.JSONDecodeError: If tool arguments contain invalid JSON
|
1862
|
+
"""
|
1863
|
+
if tool_call is None:
|
1864
|
+
raise ValueError("tool_call cannot be None")
|
1865
|
+
|
1866
|
+
# Try to detect OpenAI Pydantic model first (more specific check)
|
1867
|
+
try:
|
1868
|
+
# Import at runtime to avoid dependency issues
|
1869
|
+
from openai.types.chat import ChatCompletionMessageToolCall
|
1870
|
+
|
1871
|
+
if isinstance(tool_call, ChatCompletionMessageToolCall):
|
1872
|
+
# OpenAI Pydantic model format - validated type
|
1873
|
+
tool_id = tool_call.id
|
1874
|
+
function = tool_call.function
|
1875
|
+
|
1876
|
+
if not function:
|
1877
|
+
raise ValueError(f"Tool call {tool_id} has no function definition")
|
1878
|
+
|
1879
|
+
tool_name = function.name
|
1880
|
+
arguments_str = function.arguments or "{}"
|
1881
|
+
|
1882
|
+
# Validate required fields
|
1883
|
+
if not tool_name:
|
1884
|
+
raise ValueError(f"Tool call {tool_id} has no function name")
|
1885
|
+
|
1886
|
+
# Check for excessively large arguments (10MB limit)
|
1887
|
+
if len(arguments_str) > 10 * 1024 * 1024:
|
1888
|
+
raise ValueError(
|
1889
|
+
f"Tool call {tool_id} arguments too large ({len(arguments_str)} bytes). "
|
1890
|
+
f"Maximum allowed is 10MB."
|
1891
|
+
)
|
1892
|
+
|
1893
|
+
# Parse arguments - let JSONDecodeError propagate if invalid
|
1894
|
+
try:
|
1895
|
+
arguments_dict = json.loads(arguments_str) if arguments_str else {}
|
1896
|
+
except json.JSONDecodeError as e:
|
1897
|
+
# Log the error with context but still raise it
|
1898
|
+
self.logger.error(
|
1899
|
+
f"Invalid JSON in tool arguments for {tool_name} (id: {tool_id}): {arguments_str[:100]}... Error: {e}"
|
1900
|
+
)
|
1901
|
+
raise json.JSONDecodeError(
|
1902
|
+
f"Invalid JSON in tool '{tool_name}' arguments: {e.msg}",
|
1903
|
+
e.doc,
|
1904
|
+
e.pos,
|
1905
|
+
)
|
1906
|
+
|
1907
|
+
self.logger.debug(
|
1908
|
+
f"Extracted Pydantic tool call: {tool_name} (id: {tool_id})"
|
1909
|
+
)
|
1910
|
+
|
1911
|
+
return {
|
1912
|
+
"id": tool_id,
|
1913
|
+
"name": tool_name,
|
1914
|
+
"arguments": arguments_str,
|
1915
|
+
"arguments_dict": arguments_dict,
|
1916
|
+
}
|
1917
|
+
|
1918
|
+
except ImportError:
|
1919
|
+
# OpenAI not installed or old version - fall through to dict handling
|
1920
|
+
pass
|
1921
|
+
except TypeError:
|
1922
|
+
# Not a Pydantic model - fall through to dict handling
|
1923
|
+
pass
|
1924
|
+
|
1925
|
+
# Check if it's a dictionary format
|
1926
|
+
if isinstance(tool_call, dict):
|
1927
|
+
# Legacy dictionary format
|
1928
|
+
tool_id = tool_call.get("id")
|
1929
|
+
function = tool_call.get("function", {})
|
1930
|
+
|
1931
|
+
if not tool_id:
|
1932
|
+
raise ValueError("Tool call dictionary missing required 'id' field")
|
1933
|
+
|
1934
|
+
if not isinstance(function, dict):
|
1935
|
+
raise ValueError(
|
1936
|
+
f"Tool call {tool_id} 'function' field must be a dictionary"
|
1937
|
+
)
|
1938
|
+
|
1939
|
+
tool_name = function.get("name")
|
1940
|
+
arguments_str = function.get("arguments", "{}")
|
1941
|
+
|
1942
|
+
if not tool_name:
|
1943
|
+
raise ValueError(
|
1944
|
+
f"Tool call {tool_id} missing required 'function.name' field"
|
1945
|
+
)
|
1946
|
+
|
1947
|
+
# Check for excessively large arguments (10MB limit)
|
1948
|
+
if len(arguments_str) > 10 * 1024 * 1024:
|
1949
|
+
raise ValueError(
|
1950
|
+
f"Tool call {tool_id} arguments too large ({len(arguments_str)} bytes). "
|
1951
|
+
f"Maximum allowed is 10MB."
|
1952
|
+
)
|
1953
|
+
|
1954
|
+
# Parse arguments - let JSONDecodeError propagate if invalid
|
1955
|
+
try:
|
1956
|
+
arguments_dict = json.loads(arguments_str) if arguments_str else {}
|
1957
|
+
except json.JSONDecodeError as e:
|
1958
|
+
# Log the error with context but still raise it
|
1959
|
+
self.logger.error(
|
1960
|
+
f"Invalid JSON in tool arguments for {tool_name} (id: {tool_id}): {arguments_str[:100]}... Error: {e}"
|
1961
|
+
)
|
1962
|
+
raise json.JSONDecodeError(
|
1963
|
+
f"Invalid JSON in tool '{tool_name}' arguments: {e.msg}",
|
1964
|
+
e.doc,
|
1965
|
+
e.pos,
|
1966
|
+
)
|
1967
|
+
|
1968
|
+
self.logger.debug(
|
1969
|
+
f"Extracted dictionary tool call: {tool_name} (id: {tool_id})"
|
1970
|
+
)
|
1971
|
+
|
1972
|
+
return {
|
1973
|
+
"id": tool_id,
|
1974
|
+
"name": tool_name,
|
1975
|
+
"arguments": arguments_str,
|
1976
|
+
"arguments_dict": arguments_dict,
|
1977
|
+
}
|
1978
|
+
|
1979
|
+
# Unknown format - raise informative error
|
1980
|
+
raise ValueError(
|
1981
|
+
f"Unrecognized tool_call format: {type(tool_call)}. "
|
1982
|
+
f"Expected OpenAI ChatCompletionMessageToolCall or dict with 'id' and 'function' fields. "
|
1983
|
+
f"Got: {repr(tool_call)[:200]}..."
|
1984
|
+
)
|
1985
|
+
|
1848
1986
|
async def _execute_mcp_tool_call(
|
1849
1987
|
self, tool_call: dict, mcp_tools: list[dict]
|
1850
1988
|
) -> dict[str, Any]:
|
@@ -1857,8 +1995,10 @@ class LLMAgentNode(Node):
|
|
1857
1995
|
Returns:
|
1858
1996
|
Tool execution result
|
1859
1997
|
"""
|
1860
|
-
|
1861
|
-
|
1998
|
+
# Handle both OpenAI Pydantic models and dictionary formats
|
1999
|
+
tool_info = self._extract_tool_call_info(tool_call)
|
2000
|
+
tool_name = tool_info["name"]
|
2001
|
+
tool_args = tool_info["arguments_dict"]
|
1862
2002
|
|
1863
2003
|
# Find the MCP tool definition
|
1864
2004
|
mcp_tool = None
|
@@ -1922,8 +2062,10 @@ class LLMAgentNode(Node):
|
|
1922
2062
|
|
1923
2063
|
for tool_call in tool_calls:
|
1924
2064
|
try:
|
1925
|
-
|
1926
|
-
|
2065
|
+
# Handle both OpenAI Pydantic models and dictionary formats
|
2066
|
+
tool_info = self._extract_tool_call_info(tool_call)
|
2067
|
+
tool_name = tool_info["name"]
|
2068
|
+
tool_id = tool_info["id"]
|
1927
2069
|
|
1928
2070
|
# Check if this is an MCP tool
|
1929
2071
|
if tool_name in mcp_tool_names:
|
@@ -1947,13 +2089,36 @@ class LLMAgentNode(Node):
|
|
1947
2089
|
}
|
1948
2090
|
)
|
1949
2091
|
|
2092
|
+
except (ValueError, json.JSONDecodeError) as e:
|
2093
|
+
# Handle extraction errors specifically
|
2094
|
+
self.logger.error(f"Tool call extraction failed: {e}")
|
2095
|
+
# Try to get minimal info for error reporting
|
2096
|
+
if isinstance(tool_call, dict):
|
2097
|
+
tool_id = tool_call.get("id", "unknown")
|
2098
|
+
tool_name = tool_call.get("function", {}).get("name", "unknown")
|
2099
|
+
else:
|
2100
|
+
tool_id = getattr(tool_call, "id", "unknown")
|
2101
|
+
tool_name = "unknown"
|
2102
|
+
|
2103
|
+
tool_results.append(
|
2104
|
+
{
|
2105
|
+
"tool_call_id": tool_id,
|
2106
|
+
"content": json.dumps(
|
2107
|
+
{
|
2108
|
+
"error": f"Invalid tool call format: {str(e)}",
|
2109
|
+
"tool": tool_name,
|
2110
|
+
"status": "failed",
|
2111
|
+
}
|
2112
|
+
),
|
2113
|
+
}
|
2114
|
+
)
|
1950
2115
|
except Exception as e:
|
1951
|
-
#
|
1952
|
-
|
2116
|
+
# Handle other execution errors
|
2117
|
+
# Tool info was already extracted successfully if we got here
|
1953
2118
|
self.logger.error(f"Tool execution failed for {tool_name}: {e}")
|
1954
2119
|
tool_results.append(
|
1955
2120
|
{
|
1956
|
-
"tool_call_id":
|
2121
|
+
"tool_call_id": tool_id,
|
1957
2122
|
"content": json.dumps(
|
1958
2123
|
{"error": str(e), "tool": tool_name, "status": "failed"}
|
1959
2124
|
),
|
@@ -1974,8 +2139,10 @@ class LLMAgentNode(Node):
|
|
1974
2139
|
Returns:
|
1975
2140
|
Tool execution result
|
1976
2141
|
"""
|
1977
|
-
|
1978
|
-
|
2142
|
+
# Handle both OpenAI Pydantic models and dictionary formats
|
2143
|
+
tool_info = self._extract_tool_call_info(tool_call)
|
2144
|
+
tool_name = tool_info["name"]
|
2145
|
+
tool_args = tool_info["arguments_dict"]
|
1979
2146
|
|
1980
2147
|
# For now, return a mock result
|
1981
2148
|
# In future, this could execute actual Python functions
|