kailash 0.6.6__tar.gz → 0.8.0__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.6.6/src/kailash.egg-info → kailash-0.8.0}/PKG-INFO +3 -2
- {kailash-0.6.6 → kailash-0.8.0}/pyproject.toml +3 -2
- {kailash-0.6.6 → kailash-0.8.0}/setup.py +11 -1
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/__init__.py +35 -5
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/access_control.py +64 -46
- kailash-0.8.0/src/kailash/adapters/__init__.py +5 -0
- kailash-0.8.0/src/kailash/adapters/mcp_platform_adapter.py +273 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/api/workflow_api.py +34 -3
- kailash-0.8.0/src/kailash/channels/__init__.py +21 -0
- kailash-0.8.0/src/kailash/channels/api_channel.py +409 -0
- kailash-0.8.0/src/kailash/channels/base.py +271 -0
- kailash-0.8.0/src/kailash/channels/cli_channel.py +661 -0
- kailash-0.8.0/src/kailash/channels/event_router.py +496 -0
- kailash-0.8.0/src/kailash/channels/mcp_channel.py +648 -0
- kailash-0.8.0/src/kailash/channels/session.py +423 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/discovery.py +57 -18
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/communication/api_gateway.py +23 -3
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/communication/realtime.py +83 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/core/agent_ui.py +1 -1
- kailash-0.8.0/src/kailash/middleware/gateway/storage_backends.py +393 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/mcp/enhanced_server.py +22 -16
- kailash-0.8.0/src/kailash/nexus/__init__.py +21 -0
- kailash-0.8.0/src/kailash/nexus/cli/__init__.py +5 -0
- kailash-0.8.0/src/kailash/nexus/cli/__main__.py +6 -0
- kailash-0.8.0/src/kailash/nexus/cli/main.py +176 -0
- kailash-0.8.0/src/kailash/nexus/factory.py +413 -0
- kailash-0.8.0/src/kailash/nexus/gateway.py +545 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/__init__.py +8 -5
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/iterative_llm_agent.py +988 -17
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/llm_agent.py +29 -9
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/api/__init__.py +2 -2
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/api/monitoring.py +1 -1
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/base.py +29 -5
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/base_async.py +54 -14
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/code/async_python.py +1 -1
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/code/python.py +50 -6
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/async_sql.py +90 -0
- kailash-0.8.0/src/kailash/nodes/data/bulk_operations.py +939 -0
- kailash-0.8.0/src/kailash/nodes/data/query_builder.py +373 -0
- kailash-0.8.0/src/kailash/nodes/data/query_cache.py +512 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/monitoring/__init__.py +10 -0
- kailash-0.8.0/src/kailash/nodes/monitoring/deadlock_detector.py +964 -0
- kailash-0.8.0/src/kailash/nodes/monitoring/performance_anomaly.py +1078 -0
- kailash-0.8.0/src/kailash/nodes/monitoring/race_condition_detector.py +1151 -0
- kailash-0.8.0/src/kailash/nodes/monitoring/transaction_metrics.py +790 -0
- kailash-0.8.0/src/kailash/nodes/monitoring/transaction_monitor.py +931 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/security/behavior_analysis.py +414 -0
- kailash-0.8.0/src/kailash/nodes/system/__init__.py +17 -0
- kailash-0.8.0/src/kailash/nodes/system/command_parser.py +820 -0
- kailash-0.8.0/src/kailash/nodes/transaction/__init__.py +48 -0
- kailash-0.8.0/src/kailash/nodes/transaction/distributed_transaction_manager.py +983 -0
- kailash-0.8.0/src/kailash/nodes/transaction/saga_coordinator.py +652 -0
- kailash-0.8.0/src/kailash/nodes/transaction/saga_state_storage.py +411 -0
- kailash-0.8.0/src/kailash/nodes/transaction/saga_step.py +467 -0
- kailash-0.8.0/src/kailash/nodes/transaction/transaction_context.py +756 -0
- kailash-0.8.0/src/kailash/nodes/transaction/two_phase_commit.py +978 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/transform/processors.py +17 -1
- kailash-0.8.0/src/kailash/nodes/validation/__init__.py +21 -0
- kailash-0.8.0/src/kailash/nodes/validation/test_executor.py +532 -0
- kailash-0.8.0/src/kailash/nodes/validation/validation_nodes.py +447 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/resources/factory.py +1 -1
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/access_controlled.py +9 -7
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/async_local.py +84 -21
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/local.py +21 -2
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/parameter_injector.py +187 -31
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/runner.py +6 -4
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/testing.py +1 -1
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/security.py +22 -3
- kailash-0.8.0/src/kailash/servers/__init__.py +32 -0
- kailash-0.8.0/src/kailash/servers/durable_workflow_server.py +430 -0
- kailash-0.8.0/src/kailash/servers/enterprise_workflow_server.py +522 -0
- kailash-0.8.0/src/kailash/servers/gateway.py +183 -0
- kailash-0.8.0/src/kailash/servers/workflow_server.py +293 -0
- kailash-0.8.0/src/kailash/utils/data_validation.py +192 -0
- kailash-0.8.0/src/kailash/workflow/builder.py +822 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/cyclic_runner.py +102 -10
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/validation.py +144 -8
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/visualization.py +99 -27
- {kailash-0.6.6 → kailash-0.8.0/src/kailash.egg-info}/PKG-INFO +3 -2
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash.egg-info/SOURCES.txt +42 -1
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash.egg-info/requires.txt +2 -1
- kailash-0.6.6/src/kailash/workflow/builder.py +0 -455
- kailash-0.6.6/src/kailash/workflow/builder_improvements.py +0 -207
- {kailash-0.6.6 → kailash-0.8.0}/LICENSE +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/MANIFEST.in +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/README.md +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/setup.cfg +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/__main__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/access_control/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/access_control/managers.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/access_control/rule_evaluators.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/access_control_abac.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/api/auth.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/api/custom_nodes.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/api/custom_nodes_secure.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/api/gateway.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/api/mcp_integration.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/api/studio.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/cli/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/cli/commands.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/client/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/client/enhanced_client.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/config/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/config/database_config.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/actors/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/actors/adaptive_pool_controller.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/actors/connection_actor.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/actors/supervisor.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/ml/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/ml/query_patterns.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/monitoring/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/monitoring/connection_metrics.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/optimization/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/resilience/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/resilience/bulkhead.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/resilience/circuit_breaker.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/core/resilience/health_monitor.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/database/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/database/execution_pipeline.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/edge/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/edge/compliance.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/edge/discovery.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/edge/location.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/gateway/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/gateway/api.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/gateway/enhanced_gateway.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/gateway/resource_resolver.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/gateway/security.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/manifest.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/advanced_features.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/ai_registry_server.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/auth.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/client.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/client_new.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/errors.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/oauth.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/protocol.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/registry_integration.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/server.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/servers/ai_registry.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/transports.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/utils/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/utils/cache.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/utils/config.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/utils/formatters.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/mcp_server/utils/metrics.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/auth/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/auth/access_control.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/auth/auth_manager.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/auth/exceptions.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/auth/jwt_auth.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/auth/models.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/auth/utils.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/communication/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/communication/ai_chat.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/communication/events.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/core/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/core/schema.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/core/workflows.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/database/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/database/base.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/database/base_models.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/database/enums.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/database/migrations.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/database/models.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/database/repositories.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/database/session_manager.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/gateway/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/gateway/checkpoint_manager.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/gateway/deduplicator.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/gateway/durable_gateway.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/gateway/durable_request.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/gateway/event_store.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/mcp/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/middleware/mcp/client_integration.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/audit_log.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/permission_check.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/role_management.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/schema.sql +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/schema_manager.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/security_event.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/tenant_isolation.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/transaction_utils.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/admin/user_management.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/a2a.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/agents.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/ai_providers.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/embedding_generator.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/intelligent_agent_orchestrator.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/models.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/self_organizing.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/ai/vision_utils.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/alerts/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/alerts/base.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/alerts/discord.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/api/auth.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/api/graphql.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/api/http.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/api/rate_limiting.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/api/rest.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/api/security.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/auth/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/auth/directory_integration.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/auth/enterprise_auth_provider.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/auth/mfa.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/auth/risk_assessment.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/auth/session_management.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/auth/sso.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/base_cycle_aware.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/base_with_acl.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/cache/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/cache/cache.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/cache/cache_invalidation.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/cache/redis_pool_manager.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/code/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/compliance/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/compliance/data_retention.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/compliance/gdpr.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/async_connection.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/async_vector.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/directory.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/event_generation.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/file_discovery.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/optimistic_locking.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/query_pipeline.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/query_router.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/readers.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/redis.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/retrieval.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/sharepoint_graph.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/sources.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/sql.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/streaming.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/vector_db.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/workflow_connection_pool.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/data/writers.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/enterprise/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/enterprise/audit_logger.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/enterprise/batch_processor.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/enterprise/data_lineage.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/enterprise/mcp_executor.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/enterprise/service_discovery.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/enterprise/tenant_assignment.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/logic/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/logic/async_operations.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/logic/convergence.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/logic/loop.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/logic/operations.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/logic/workflow.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/mixins/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/mixins/event_emitter.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/mixins/mcp.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/mixins/security.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/mixins.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/monitoring/connection_dashboard.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/monitoring/health_check.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/monitoring/log_processor.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/monitoring/metrics_collector.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/monitoring/performance_benchmark.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/advanced.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/agentic.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/conversational.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/evaluation.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/federated.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/graph.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/multimodal.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/optimized.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/privacy.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/query_processing.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/realtime.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/registry.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/router.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/similarity.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/strategies.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/rag/workflows.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/security/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/security/abac_evaluator.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/security/audit_log.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/security/credential_manager.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/security/rotating_credentials.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/security/security_event.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/security/threat_detection.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/testing/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/testing/credential_testing.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/transform/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/transform/chunkers.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/transform/formatters.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/nodes/validation.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/resources/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/resources/health.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/resources/reference.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/resources/registry.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/docker.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/parallel.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/parallel_cyclic.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/runtime/parameter_injection.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/sdk_exceptions.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/testing/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/testing/async_test_case.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/testing/async_utils.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/testing/fixtures.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/testing/mock_registry.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/tracking/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/tracking/manager.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/tracking/metrics_collector.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/tracking/models.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/tracking/storage/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/tracking/storage/base.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/tracking/storage/database.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/tracking/storage/filesystem.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/export.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/migrations/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/migrations/generator.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/migrations/models.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/migrations/runner.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/resource_manager.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/secure_logging.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/utils/templates.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/visualization/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/visualization/api.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/visualization/dashboard.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/visualization/performance.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/visualization/reports.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/__init__.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/async_builder.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/async_patterns.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/convergence.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/cycle_analyzer.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/cycle_builder.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/cycle_config.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/cycle_debugger.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/cycle_exceptions.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/cycle_profiler.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/cycle_state.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/graph.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/input_handling.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/mermaid_visualizer.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/migration.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/mock_registry.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/resilience.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/runner.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/safety.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/state.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash/workflow/templates.py +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash.egg-info/dependency_links.txt +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash.egg-info/entry_points.txt +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash.egg-info/not-zip-safe +0 -0
- {kailash-0.6.6 → kailash-0.8.0}/src/kailash.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: kailash
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.8.0
|
4
4
|
Summary: Python SDK for the Kailash container-node architecture
|
5
5
|
Home-page: https://github.com/integrum/kailash-python-sdk
|
6
6
|
Author: Integrum
|
@@ -21,7 +21,7 @@ Requires-Dist: matplotlib>=3.5
|
|
21
21
|
Requires-Dist: pyyaml>=6.0
|
22
22
|
Requires-Dist: click>=8.0
|
23
23
|
Requires-Dist: pytest>=8.3.5
|
24
|
-
Requires-Dist: mcp[cli]
|
24
|
+
Requires-Dist: mcp[cli]==1.11.0
|
25
25
|
Requires-Dist: pandas>=2.2.3
|
26
26
|
Requires-Dist: numpy>=2.2.5
|
27
27
|
Requires-Dist: scipy>=1.15.3
|
@@ -78,6 +78,7 @@ Requires-Dist: passlib>=1.7.4
|
|
78
78
|
Requires-Dist: pyotp>=2.9.0
|
79
79
|
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.55b1
|
80
80
|
Requires-Dist: seaborn>=0.13.2
|
81
|
+
Requires-Dist: sqlparse>=0.5.3
|
81
82
|
Provides-Extra: dev
|
82
83
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
83
84
|
Requires-Dist: pytest-cov>=3.0; extra == "dev"
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "kailash"
|
7
|
-
version = "0.
|
7
|
+
version = "0.8.0"
|
8
8
|
description = "Python SDK for the Kailash container-node architecture"
|
9
9
|
authors = [
|
10
10
|
{name = "Integrum", email = "info@integrum.com"}
|
@@ -25,7 +25,7 @@ dependencies = [
|
|
25
25
|
"pyyaml>=6.0",
|
26
26
|
"click>=8.0",
|
27
27
|
"pytest>=8.3.5",
|
28
|
-
"mcp[cli]
|
28
|
+
"mcp[cli]==1.11.0",
|
29
29
|
"pandas>=2.2.3",
|
30
30
|
"numpy>=2.2.5",
|
31
31
|
"scipy>=1.15.3",
|
@@ -82,6 +82,7 @@ dependencies = [
|
|
82
82
|
"pyotp>=2.9.0",
|
83
83
|
"opentelemetry-instrumentation-fastapi>=0.55b1",
|
84
84
|
"seaborn>=0.13.2",
|
85
|
+
"sqlparse>=0.5.3",
|
85
86
|
]
|
86
87
|
|
87
88
|
[project.optional-dependencies]
|
@@ -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.
|
16
|
+
version="0.7.0",
|
17
17
|
author="Integrum",
|
18
18
|
author_email="info@integrum.com",
|
19
19
|
description="Python SDK for the Kailash container-node architecture",
|
@@ -50,6 +50,16 @@ setup(
|
|
50
50
|
"viz": [
|
51
51
|
"pygraphviz>=1.9",
|
52
52
|
],
|
53
|
+
"dataflow": [
|
54
|
+
"dataflow>=0.1.0",
|
55
|
+
],
|
56
|
+
"nexus": [
|
57
|
+
"nexus>=1.0.0",
|
58
|
+
],
|
59
|
+
"all": [
|
60
|
+
"dataflow>=0.1.0",
|
61
|
+
"nexus>=1.0.0",
|
62
|
+
],
|
53
63
|
},
|
54
64
|
# Entry points for CLI
|
55
65
|
entry_points={
|
@@ -3,9 +3,10 @@
|
|
3
3
|
The Kailash SDK provides a comprehensive framework for creating nodes and workflows
|
4
4
|
that align with container-node architecture while allowing rapid prototyping.
|
5
5
|
|
6
|
-
New in v0.
|
7
|
-
|
8
|
-
|
6
|
+
New in v0.7.0: Complete DataFlow and Nexus application frameworks, infrastructure hardening
|
7
|
+
with 100% E2E test pass rate, enhanced AsyncNode event loop handling, 8 new monitoring operations,
|
8
|
+
distributed transactions, QueryBuilder/QueryCache with Redis, and real MCP execution by default.
|
9
|
+
Previous v0.6.6: AgentUIMiddleware shared workflow fix, execute() method standardization.
|
9
10
|
"""
|
10
11
|
|
11
12
|
from kailash.nodes.base import Node, NodeMetadata, NodeParameter
|
@@ -23,6 +24,23 @@ try:
|
|
23
24
|
AIChatMiddleware,
|
24
25
|
APIGateway,
|
25
26
|
RealtimeMiddleware,
|
27
|
+
)
|
28
|
+
|
29
|
+
# Import Nexus multi-channel framework (v0.6.7+)
|
30
|
+
from kailash.nexus import NexusGateway, create_nexus
|
31
|
+
|
32
|
+
# Import new server classes (v0.6.7+)
|
33
|
+
from kailash.servers import (
|
34
|
+
DurableWorkflowServer,
|
35
|
+
EnterpriseWorkflowServer,
|
36
|
+
WorkflowServer,
|
37
|
+
)
|
38
|
+
|
39
|
+
# Import updated create_gateway function with enterprise defaults
|
40
|
+
from kailash.servers.gateway import (
|
41
|
+
create_basic_gateway,
|
42
|
+
create_durable_gateway,
|
43
|
+
create_enterprise_gateway,
|
26
44
|
create_gateway,
|
27
45
|
)
|
28
46
|
|
@@ -34,7 +52,7 @@ except ImportError:
|
|
34
52
|
# For backward compatibility
|
35
53
|
WorkflowGraph = Workflow
|
36
54
|
|
37
|
-
__version__ = "0.
|
55
|
+
__version__ = "0.8.0"
|
38
56
|
|
39
57
|
__all__ = [
|
40
58
|
# Core workflow components
|
@@ -50,14 +68,26 @@ __all__ = [
|
|
50
68
|
"LocalRuntime",
|
51
69
|
]
|
52
70
|
|
53
|
-
# Add middleware to exports if available
|
71
|
+
# Add middleware and servers to exports if available
|
54
72
|
if _MIDDLEWARE_AVAILABLE:
|
55
73
|
__all__.extend(
|
56
74
|
[
|
75
|
+
# Legacy middleware
|
57
76
|
"AgentUIMiddleware",
|
58
77
|
"RealtimeMiddleware",
|
59
78
|
"APIGateway",
|
60
79
|
"AIChatMiddleware",
|
80
|
+
# New server classes
|
81
|
+
"WorkflowServer",
|
82
|
+
"DurableWorkflowServer",
|
83
|
+
"EnterpriseWorkflowServer",
|
84
|
+
# Gateway creation functions
|
61
85
|
"create_gateway",
|
86
|
+
"create_enterprise_gateway",
|
87
|
+
"create_durable_gateway",
|
88
|
+
"create_basic_gateway",
|
89
|
+
# Nexus multi-channel framework
|
90
|
+
"NexusGateway",
|
91
|
+
"create_nexus",
|
62
92
|
]
|
63
93
|
)
|
@@ -435,6 +435,17 @@ class AccessControlManager:
|
|
435
435
|
self, user: UserContext, workflow_id: str, permission: WorkflowPermission
|
436
436
|
) -> AccessDecision:
|
437
437
|
"""Check if user has permission on workflow"""
|
438
|
+
# If access control is disabled, allow all access
|
439
|
+
if not self.enabled:
|
440
|
+
return AccessDecision(
|
441
|
+
allowed=True,
|
442
|
+
reason="Access control disabled",
|
443
|
+
applied_rules=[],
|
444
|
+
conditions_met={},
|
445
|
+
masked_fields=[],
|
446
|
+
redirect_node=None,
|
447
|
+
)
|
448
|
+
|
438
449
|
cache_key = f"workflow:{workflow_id}:{user.user_id}:{permission.value}"
|
439
450
|
|
440
451
|
# Check cache
|
@@ -462,6 +473,17 @@ class AccessControlManager:
|
|
462
473
|
runtime_context: dict[str, Any] = None,
|
463
474
|
) -> AccessDecision:
|
464
475
|
"""Check if user has permission on node"""
|
476
|
+
# If access control is disabled, allow all access
|
477
|
+
if not self.enabled:
|
478
|
+
return AccessDecision(
|
479
|
+
allowed=True,
|
480
|
+
reason="Access control disabled",
|
481
|
+
applied_rules=[],
|
482
|
+
conditions_met={},
|
483
|
+
masked_fields=[],
|
484
|
+
redirect_node=None,
|
485
|
+
)
|
486
|
+
|
465
487
|
cache_key = f"node:{node_id}:{user.user_id}:{permission.value}"
|
466
488
|
|
467
489
|
# For runtime-dependent permissions, don't use cache
|
@@ -494,65 +516,56 @@ class AccessControlManager:
|
|
494
516
|
return decision
|
495
517
|
|
496
518
|
def get_accessible_nodes(
|
497
|
-
self, user: UserContext,
|
498
|
-
) ->
|
499
|
-
"""Get all nodes user can access
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
for rule in node_rules:
|
510
|
-
if self._rule_applies_to_user(rule, user):
|
511
|
-
if rule.effect == PermissionEffect.ALLOW:
|
512
|
-
accessible.add(rule.resource_id)
|
513
|
-
elif rule.effect == PermissionEffect.DENY:
|
514
|
-
accessible.discard(rule.resource_id)
|
515
|
-
|
519
|
+
self, user: UserContext, nodes: list[str], permission: NodePermission
|
520
|
+
) -> list[str]:
|
521
|
+
"""Get all nodes user can access from a list of nodes"""
|
522
|
+
# If access control is disabled, allow access to all nodes
|
523
|
+
if not self.enabled:
|
524
|
+
return nodes
|
525
|
+
|
526
|
+
accessible = []
|
527
|
+
for node_id in nodes:
|
528
|
+
decision = self.check_node_access(user, node_id, permission)
|
529
|
+
if decision.allowed:
|
530
|
+
accessible.append(node_id)
|
516
531
|
return accessible
|
517
532
|
|
518
533
|
def get_permission_based_route(
|
519
534
|
self,
|
520
535
|
user: UserContext,
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
) ->
|
525
|
-
"""
|
526
|
-
#
|
527
|
-
|
528
|
-
|
529
|
-
for node_id in true_path_nodes
|
530
|
-
)
|
536
|
+
node_id: str,
|
537
|
+
permission: NodePermission,
|
538
|
+
alternatives: dict[str, str] = None,
|
539
|
+
) -> str | None:
|
540
|
+
"""Get alternative route if user doesn't have access to node"""
|
541
|
+
# If access control is disabled, allow access to requested node
|
542
|
+
if not self.enabled:
|
543
|
+
return None
|
531
544
|
|
532
|
-
|
533
|
-
return true_path_nodes
|
534
|
-
else:
|
535
|
-
# Check false path
|
536
|
-
false_path_accessible = all(
|
537
|
-
self.check_node_access(user, node_id, NodePermission.EXECUTE).allowed
|
538
|
-
for node_id in false_path_nodes
|
539
|
-
)
|
545
|
+
decision = self.check_node_access(user, node_id, permission)
|
540
546
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
547
|
+
if decision.allowed:
|
548
|
+
return None # No alternative needed
|
549
|
+
|
550
|
+
# If access denied and alternatives provided, return alternative
|
551
|
+
if alternatives and node_id in alternatives:
|
552
|
+
return alternatives[node_id]
|
553
|
+
|
554
|
+
return None
|
546
555
|
|
547
556
|
def mask_node_output(
|
548
557
|
self, user: UserContext, node_id: str, output: dict[str, Any]
|
549
558
|
) -> dict[str, Any]:
|
550
559
|
"""Mask sensitive fields in node output"""
|
551
|
-
|
560
|
+
# If access control is disabled, don't mask anything
|
561
|
+
if not self.enabled:
|
562
|
+
return output
|
563
|
+
|
564
|
+
decision = self.check_node_access(user, node_id, NodePermission.MASK_OUTPUT)
|
552
565
|
|
553
566
|
if not decision.allowed:
|
554
|
-
#
|
555
|
-
return
|
567
|
+
# No masking rules found, return original output
|
568
|
+
return output
|
556
569
|
|
557
570
|
if decision.masked_fields:
|
558
571
|
# Mask specific fields
|
@@ -626,7 +639,12 @@ class AccessControlManager:
|
|
626
639
|
break
|
627
640
|
|
628
641
|
allowed = final_effect == PermissionEffect.ALLOW
|
629
|
-
|
642
|
+
|
643
|
+
# Set reason based on rules found
|
644
|
+
if not applicable_rules:
|
645
|
+
reason = f"No matching rules found for {resource_type} {resource_id}"
|
646
|
+
else:
|
647
|
+
reason = f"Permission {permission.value} {'granted' if allowed else 'denied'} for {resource_type} {resource_id}"
|
630
648
|
|
631
649
|
return AccessDecision(
|
632
650
|
allowed=allowed,
|
@@ -0,0 +1,273 @@
|
|
1
|
+
"""Adapter for bridging mcp_platform and core SDK parameter formats."""
|
2
|
+
|
3
|
+
import logging
|
4
|
+
from typing import Any, Dict, List, Optional, Union
|
5
|
+
|
6
|
+
logger = logging.getLogger(__name__)
|
7
|
+
|
8
|
+
|
9
|
+
class MCPPlatformAdapter:
|
10
|
+
"""Adapter to translate between mcp_platform and SDK MCP parameter formats."""
|
11
|
+
|
12
|
+
@staticmethod
|
13
|
+
def translate_server_config(platform_config: Dict[str, Any]) -> Dict[str, Any]:
|
14
|
+
"""Translate mcp_platform server config to SDK format.
|
15
|
+
|
16
|
+
Args:
|
17
|
+
platform_config: Server config from mcp_platform
|
18
|
+
|
19
|
+
Returns:
|
20
|
+
SDK-compatible server config
|
21
|
+
"""
|
22
|
+
if not isinstance(platform_config, dict):
|
23
|
+
logger.error(f"Platform config must be dict, got {type(platform_config)}")
|
24
|
+
return {}
|
25
|
+
|
26
|
+
# Extract mcp_platform format: {"transport": "stdio", "command": "...", "args": [...]}
|
27
|
+
sdk_config = {}
|
28
|
+
|
29
|
+
# Map required fields
|
30
|
+
if "name" not in platform_config:
|
31
|
+
# Generate name from command if not provided
|
32
|
+
command = platform_config.get("command", "unknown")
|
33
|
+
sdk_config["name"] = command.split("/")[-1].split("\\")[-1]
|
34
|
+
else:
|
35
|
+
sdk_config["name"] = platform_config["name"]
|
36
|
+
|
37
|
+
# Transport mapping
|
38
|
+
transport = platform_config.get("transport", "stdio")
|
39
|
+
sdk_config["transport"] = transport
|
40
|
+
|
41
|
+
# Command mapping
|
42
|
+
if "command" in platform_config:
|
43
|
+
sdk_config["command"] = platform_config["command"]
|
44
|
+
|
45
|
+
# Arguments mapping
|
46
|
+
if "args" in platform_config:
|
47
|
+
sdk_config["args"] = platform_config["args"]
|
48
|
+
elif "arguments" in platform_config:
|
49
|
+
sdk_config["args"] = platform_config["arguments"]
|
50
|
+
|
51
|
+
# Environment mapping
|
52
|
+
if "env" in platform_config:
|
53
|
+
sdk_config["env"] = platform_config["env"]
|
54
|
+
elif "environment" in platform_config:
|
55
|
+
sdk_config["env"] = platform_config["environment"]
|
56
|
+
|
57
|
+
# Server-specific settings
|
58
|
+
if "auto_start" in platform_config:
|
59
|
+
sdk_config["auto_start"] = platform_config["auto_start"]
|
60
|
+
|
61
|
+
if "timeout" in platform_config:
|
62
|
+
sdk_config["timeout"] = platform_config["timeout"]
|
63
|
+
|
64
|
+
# Tool list mapping
|
65
|
+
if "tools" in platform_config:
|
66
|
+
sdk_config["tools"] = platform_config["tools"]
|
67
|
+
|
68
|
+
logger.debug(f"Translated platform config to SDK format: {sdk_config}")
|
69
|
+
return sdk_config
|
70
|
+
|
71
|
+
@staticmethod
|
72
|
+
def translate_mcp_servers_list(
|
73
|
+
platform_servers: List[Dict[str, Any]],
|
74
|
+
) -> List[Dict[str, Any]]:
|
75
|
+
"""Translate list of mcp_platform server configs to SDK format.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
platform_servers: List of server configs from mcp_platform
|
79
|
+
|
80
|
+
Returns:
|
81
|
+
List of SDK-compatible server configs
|
82
|
+
"""
|
83
|
+
if not isinstance(platform_servers, list):
|
84
|
+
logger.error(f"Platform servers must be list, got {type(platform_servers)}")
|
85
|
+
return []
|
86
|
+
|
87
|
+
sdk_servers = []
|
88
|
+
for i, platform_config in enumerate(platform_servers):
|
89
|
+
try:
|
90
|
+
sdk_config = MCPPlatformAdapter.translate_server_config(platform_config)
|
91
|
+
if sdk_config:
|
92
|
+
sdk_servers.append(sdk_config)
|
93
|
+
else:
|
94
|
+
logger.warning(
|
95
|
+
f"Failed to translate server config {i}: {platform_config}"
|
96
|
+
)
|
97
|
+
except Exception as e:
|
98
|
+
logger.error(f"Error translating server config {i}: {e}")
|
99
|
+
|
100
|
+
return sdk_servers
|
101
|
+
|
102
|
+
@staticmethod
|
103
|
+
def translate_tool_parameters(
|
104
|
+
platform_params: Dict[str, Any], tool_schema: Optional[Dict[str, Any]] = None
|
105
|
+
) -> Dict[str, Any]:
|
106
|
+
"""Translate mcp_platform tool parameters to SDK format.
|
107
|
+
|
108
|
+
Args:
|
109
|
+
platform_params: Parameters from mcp_platform
|
110
|
+
tool_schema: Optional tool schema for validation
|
111
|
+
|
112
|
+
Returns:
|
113
|
+
SDK-compatible tool parameters
|
114
|
+
"""
|
115
|
+
if not isinstance(platform_params, dict):
|
116
|
+
logger.error(f"Platform params must be dict, got {type(platform_params)}")
|
117
|
+
return {}
|
118
|
+
|
119
|
+
sdk_params = {}
|
120
|
+
|
121
|
+
# Handle nested server configuration
|
122
|
+
if "server_config" in platform_params:
|
123
|
+
server_config = platform_params["server_config"]
|
124
|
+
sdk_params["mcp_server_config"] = (
|
125
|
+
MCPPlatformAdapter.translate_server_config(server_config)
|
126
|
+
)
|
127
|
+
|
128
|
+
# Handle tool-specific parameters
|
129
|
+
for key, value in platform_params.items():
|
130
|
+
if key == "server_config":
|
131
|
+
continue # Already handled above
|
132
|
+
|
133
|
+
# Parameter name mapping
|
134
|
+
if key == "tool_name":
|
135
|
+
sdk_params["name"] = value
|
136
|
+
elif key == "tool_args":
|
137
|
+
sdk_params["arguments"] = value
|
138
|
+
elif key == "tool_params":
|
139
|
+
sdk_params["parameters"] = value
|
140
|
+
else:
|
141
|
+
sdk_params[key] = value
|
142
|
+
|
143
|
+
# Validate against tool schema if provided
|
144
|
+
if tool_schema and "parameters" in tool_schema:
|
145
|
+
required_params = tool_schema["parameters"].get("required", [])
|
146
|
+
missing_params = [p for p in required_params if p not in sdk_params]
|
147
|
+
if missing_params:
|
148
|
+
logger.warning(f"Missing required tool parameters: {missing_params}")
|
149
|
+
|
150
|
+
logger.debug(f"Translated tool parameters: {sdk_params}")
|
151
|
+
return sdk_params
|
152
|
+
|
153
|
+
@staticmethod
|
154
|
+
def translate_llm_agent_config(platform_config: Dict[str, Any]) -> Dict[str, Any]:
|
155
|
+
"""Translate mcp_platform LLM agent config to SDK format.
|
156
|
+
|
157
|
+
Args:
|
158
|
+
platform_config: LLM agent config from mcp_platform
|
159
|
+
|
160
|
+
Returns:
|
161
|
+
SDK-compatible LLM agent config
|
162
|
+
"""
|
163
|
+
if not isinstance(platform_config, dict):
|
164
|
+
logger.error(f"Platform config must be dict, got {type(platform_config)}")
|
165
|
+
return {}
|
166
|
+
|
167
|
+
sdk_config = platform_config.copy()
|
168
|
+
|
169
|
+
# Handle mcp_platform server configuration
|
170
|
+
if "server_config" in platform_config:
|
171
|
+
server_config = platform_config["server_config"]
|
172
|
+
if isinstance(server_config, dict):
|
173
|
+
# Single server config
|
174
|
+
sdk_config["mcp_servers"] = [
|
175
|
+
MCPPlatformAdapter.translate_server_config(server_config)
|
176
|
+
]
|
177
|
+
elif isinstance(server_config, list):
|
178
|
+
# Multiple server configs
|
179
|
+
sdk_config["mcp_servers"] = (
|
180
|
+
MCPPlatformAdapter.translate_mcp_servers_list(server_config)
|
181
|
+
)
|
182
|
+
|
183
|
+
# Remove the old key
|
184
|
+
sdk_config.pop("server_config")
|
185
|
+
|
186
|
+
# Handle server_configs (plural) as well
|
187
|
+
if "server_configs" in platform_config:
|
188
|
+
server_configs = platform_config["server_configs"]
|
189
|
+
sdk_config["mcp_servers"] = MCPPlatformAdapter.translate_mcp_servers_list(
|
190
|
+
server_configs
|
191
|
+
)
|
192
|
+
sdk_config.pop("server_configs")
|
193
|
+
|
194
|
+
# Ensure use_real_mcp is set correctly
|
195
|
+
if "use_real_mcp" not in sdk_config:
|
196
|
+
sdk_config["use_real_mcp"] = True # Default to real MCP execution
|
197
|
+
|
198
|
+
logger.debug(f"Translated LLM agent config: {sdk_config}")
|
199
|
+
return sdk_config
|
200
|
+
|
201
|
+
@staticmethod
|
202
|
+
def validate_integration(
|
203
|
+
platform_data: Dict[str, Any], expected_sdk_format: str
|
204
|
+
) -> bool:
|
205
|
+
"""Validate that platform data can be properly translated to SDK format.
|
206
|
+
|
207
|
+
Args:
|
208
|
+
platform_data: Data from mcp_platform
|
209
|
+
expected_sdk_format: Expected SDK format type ("server_config", "tool_params", "llm_config")
|
210
|
+
|
211
|
+
Returns:
|
212
|
+
True if valid for translation, False otherwise
|
213
|
+
"""
|
214
|
+
if not isinstance(platform_data, dict):
|
215
|
+
logger.error(f"Platform data must be dict for {expected_sdk_format}")
|
216
|
+
return False
|
217
|
+
|
218
|
+
if expected_sdk_format == "server_config":
|
219
|
+
required_fields = ["transport"]
|
220
|
+
optional_fields = ["command", "name", "args"]
|
221
|
+
|
222
|
+
elif expected_sdk_format == "tool_params":
|
223
|
+
required_fields = []
|
224
|
+
optional_fields = ["tool_name", "tool_args", "server_config"]
|
225
|
+
|
226
|
+
elif expected_sdk_format == "llm_config":
|
227
|
+
required_fields = []
|
228
|
+
optional_fields = ["server_config", "server_configs", "mcp_servers"]
|
229
|
+
|
230
|
+
else:
|
231
|
+
logger.error(f"Unknown SDK format: {expected_sdk_format}")
|
232
|
+
return False
|
233
|
+
|
234
|
+
# Check for required fields
|
235
|
+
missing_required = [f for f in required_fields if f not in platform_data]
|
236
|
+
if missing_required:
|
237
|
+
logger.error(
|
238
|
+
f"Missing required fields for {expected_sdk_format}: {missing_required}"
|
239
|
+
)
|
240
|
+
return False
|
241
|
+
|
242
|
+
# Check if we have at least some relevant fields
|
243
|
+
has_relevant_fields = any(
|
244
|
+
f in platform_data for f in required_fields + optional_fields
|
245
|
+
)
|
246
|
+
if not has_relevant_fields:
|
247
|
+
logger.warning(f"No relevant fields found for {expected_sdk_format}")
|
248
|
+
return False
|
249
|
+
|
250
|
+
return True
|
251
|
+
|
252
|
+
@staticmethod
|
253
|
+
def create_error_recovery_config(
|
254
|
+
original_config: Any, error_msg: str
|
255
|
+
) -> Dict[str, Any]:
|
256
|
+
"""Create a recovery configuration when translation fails.
|
257
|
+
|
258
|
+
Args:
|
259
|
+
original_config: The original configuration that failed
|
260
|
+
error_msg: Error message describing the failure
|
261
|
+
|
262
|
+
Returns:
|
263
|
+
Recovery configuration
|
264
|
+
"""
|
265
|
+
return {
|
266
|
+
"name": "error_recovery",
|
267
|
+
"transport": "stdio",
|
268
|
+
"command": "echo",
|
269
|
+
"args": ["Error in MCP configuration"],
|
270
|
+
"original_config": original_config,
|
271
|
+
"error_message": error_msg,
|
272
|
+
"recovery_mode": True,
|
273
|
+
}
|
@@ -11,7 +11,7 @@ from enum import Enum
|
|
11
11
|
from typing import Any
|
12
12
|
|
13
13
|
import uvicorn
|
14
|
-
from fastapi import BackgroundTasks, FastAPI, HTTPException
|
14
|
+
from fastapi import BackgroundTasks, FastAPI, HTTPException, Request
|
15
15
|
from fastapi.responses import StreamingResponse
|
16
16
|
from pydantic import BaseModel, Field
|
17
17
|
|
@@ -31,12 +31,26 @@ class ExecutionMode(str, Enum):
|
|
31
31
|
class WorkflowRequest(BaseModel):
|
32
32
|
"""Base request model for workflow execution."""
|
33
33
|
|
34
|
-
inputs: dict[str, Any] = Field(
|
34
|
+
inputs: dict[str, Any] | None = Field(
|
35
|
+
None, description="Input data for workflow nodes"
|
36
|
+
)
|
37
|
+
parameters: dict[str, Any] | None = Field(
|
38
|
+
None, description="Legacy: parameters for workflow execution"
|
39
|
+
)
|
35
40
|
config: dict[str, Any] | None = Field(
|
36
41
|
None, description="Node configuration overrides"
|
37
42
|
)
|
38
43
|
mode: ExecutionMode = Field(ExecutionMode.SYNC, description="Execution mode")
|
39
44
|
|
45
|
+
def get_inputs(self) -> dict[str, Any]:
|
46
|
+
"""Get inputs, supporting both 'inputs' and 'parameters' format."""
|
47
|
+
if self.inputs is not None:
|
48
|
+
return self.inputs
|
49
|
+
elif self.parameters is not None:
|
50
|
+
return self.parameters
|
51
|
+
else:
|
52
|
+
return {}
|
53
|
+
|
40
54
|
|
41
55
|
class WorkflowResponse(BaseModel):
|
42
56
|
"""Base response model for workflow execution."""
|
@@ -115,6 +129,21 @@ class WorkflowAPI:
|
|
115
129
|
def _setup_routes(self):
|
116
130
|
"""Setup API routes dynamically based on workflow."""
|
117
131
|
|
132
|
+
# Root execution endpoint (convenience for direct workflow execution)
|
133
|
+
@self.app.post("/")
|
134
|
+
async def execute_workflow_root(
|
135
|
+
request: Request, background_tasks: BackgroundTasks
|
136
|
+
):
|
137
|
+
"""Execute the workflow with provided inputs (root endpoint)."""
|
138
|
+
try:
|
139
|
+
# Try to parse JSON body
|
140
|
+
json_data = await request.json()
|
141
|
+
workflow_request = WorkflowRequest(**json_data)
|
142
|
+
except:
|
143
|
+
# If no JSON or invalid JSON, create empty request
|
144
|
+
workflow_request = WorkflowRequest()
|
145
|
+
return await execute_workflow(workflow_request, background_tasks)
|
146
|
+
|
118
147
|
# Main execution endpoint
|
119
148
|
@self.app.post("/execute")
|
120
149
|
async def execute_workflow(
|
@@ -195,7 +224,9 @@ class WorkflowAPI:
|
|
195
224
|
|
196
225
|
# Execute workflow with inputs
|
197
226
|
results = await asyncio.to_thread(
|
198
|
-
self.runtime.execute,
|
227
|
+
self.runtime.execute,
|
228
|
+
self.workflow_graph,
|
229
|
+
parameters=request.get_inputs(),
|
199
230
|
)
|
200
231
|
|
201
232
|
# Handle tuple return from runtime
|
@@ -0,0 +1,21 @@
|
|
1
|
+
"""Channel abstractions for Nexus multi-channel architecture.
|
2
|
+
|
3
|
+
This module provides the core channel abstractions for the Kailash Nexus framework,
|
4
|
+
enabling unified management of API, CLI, and MCP interfaces through a common channel abstraction.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from .api_channel import APIChannel
|
8
|
+
from .base import Channel, ChannelConfig
|
9
|
+
from .cli_channel import CLIChannel
|
10
|
+
from .mcp_channel import MCPChannel
|
11
|
+
from .session import CrossChannelSession, SessionManager
|
12
|
+
|
13
|
+
__all__ = [
|
14
|
+
"Channel",
|
15
|
+
"ChannelConfig",
|
16
|
+
"APIChannel",
|
17
|
+
"CLIChannel",
|
18
|
+
"MCPChannel",
|
19
|
+
"SessionManager",
|
20
|
+
"CrossChannelSession",
|
21
|
+
]
|