kubiya-control-plane-api 0.9.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- control_plane_api/LICENSE +676 -0
- control_plane_api/README.md +350 -0
- control_plane_api/__init__.py +4 -0
- control_plane_api/__version__.py +8 -0
- control_plane_api/alembic/README +1 -0
- control_plane_api/alembic/env.py +121 -0
- control_plane_api/alembic/script.py.mako +28 -0
- control_plane_api/alembic/versions/2613c65c3dbe_initial_database_setup.py +32 -0
- control_plane_api/alembic/versions/2df520d4927d_merge_heads.py +28 -0
- control_plane_api/alembic/versions/43abf98d6a01_add_paused_status_to_executions.py +73 -0
- control_plane_api/alembic/versions/6289854264cb_merge_multiple_heads.py +28 -0
- control_plane_api/alembic/versions/6a4d4dc3d8dc_generate_execution_transitions.py +50 -0
- control_plane_api/alembic/versions/87d11cf0a783_add_disconnected_status_to_worker_.py +44 -0
- control_plane_api/alembic/versions/add_ephemeral_queue_support.py +85 -0
- control_plane_api/alembic/versions/add_model_type_to_llm_models.py +31 -0
- control_plane_api/alembic/versions/add_plan_executions_table.py +114 -0
- control_plane_api/alembic/versions/add_trace_span_tables.py +154 -0
- control_plane_api/alembic/versions/add_user_info_to_traces.py +36 -0
- control_plane_api/alembic/versions/adjusting_foreign_keys.py +32 -0
- control_plane_api/alembic/versions/b4983d976db2_initial_tables.py +1128 -0
- control_plane_api/alembic/versions/d181a3b40e71_rename_custom_metadata_to_metadata_in_.py +50 -0
- control_plane_api/alembic/versions/df9117888e82_add_missing_columns.py +82 -0
- control_plane_api/alembic/versions/f25de6ad895a_missing_migrations.py +34 -0
- control_plane_api/alembic/versions/f71305fb69b9_fix_ephemeral_queue_deletion_foreign_key.py +54 -0
- control_plane_api/alembic/versions/mark_local_exec_queues_as_ephemeral.py +68 -0
- control_plane_api/alembic.ini +148 -0
- control_plane_api/api/index.py +12 -0
- control_plane_api/app/__init__.py +11 -0
- control_plane_api/app/activities/__init__.py +20 -0
- control_plane_api/app/activities/agent_activities.py +384 -0
- control_plane_api/app/activities/plan_generation_activities.py +499 -0
- control_plane_api/app/activities/team_activities.py +424 -0
- control_plane_api/app/activities/temporal_cloud_activities.py +588 -0
- control_plane_api/app/config/__init__.py +35 -0
- control_plane_api/app/config/api_config.py +469 -0
- control_plane_api/app/config/config_loader.py +224 -0
- control_plane_api/app/config/model_pricing.py +323 -0
- control_plane_api/app/config/storage_config.py +159 -0
- control_plane_api/app/config.py +115 -0
- control_plane_api/app/controllers/__init__.py +0 -0
- control_plane_api/app/controllers/execution_environment_controller.py +1315 -0
- control_plane_api/app/database.py +135 -0
- control_plane_api/app/exceptions.py +408 -0
- control_plane_api/app/lib/__init__.py +11 -0
- control_plane_api/app/lib/environment.py +65 -0
- control_plane_api/app/lib/event_bus/__init__.py +17 -0
- control_plane_api/app/lib/event_bus/base.py +136 -0
- control_plane_api/app/lib/event_bus/manager.py +335 -0
- control_plane_api/app/lib/event_bus/providers/__init__.py +6 -0
- control_plane_api/app/lib/event_bus/providers/http_provider.py +166 -0
- control_plane_api/app/lib/event_bus/providers/nats_provider.py +324 -0
- control_plane_api/app/lib/event_bus/providers/redis_provider.py +233 -0
- control_plane_api/app/lib/event_bus/providers/websocket_provider.py +497 -0
- control_plane_api/app/lib/job_executor.py +330 -0
- control_plane_api/app/lib/kubiya_client.py +293 -0
- control_plane_api/app/lib/litellm_pricing.py +166 -0
- control_plane_api/app/lib/mcp_validation.py +163 -0
- control_plane_api/app/lib/nats/__init__.py +13 -0
- control_plane_api/app/lib/nats/credentials_manager.py +288 -0
- control_plane_api/app/lib/nats/listener.py +374 -0
- control_plane_api/app/lib/planning_prompt_builder.py +153 -0
- control_plane_api/app/lib/planning_tools/__init__.py +41 -0
- control_plane_api/app/lib/planning_tools/agents.py +409 -0
- control_plane_api/app/lib/planning_tools/agno_toolkit.py +836 -0
- control_plane_api/app/lib/planning_tools/base.py +119 -0
- control_plane_api/app/lib/planning_tools/cognitive_memory_tools.py +403 -0
- control_plane_api/app/lib/planning_tools/context_graph_tools.py +545 -0
- control_plane_api/app/lib/planning_tools/environments.py +218 -0
- control_plane_api/app/lib/planning_tools/knowledge.py +204 -0
- control_plane_api/app/lib/planning_tools/models.py +93 -0
- control_plane_api/app/lib/planning_tools/planning_service.py +646 -0
- control_plane_api/app/lib/planning_tools/resources.py +242 -0
- control_plane_api/app/lib/planning_tools/teams.py +334 -0
- control_plane_api/app/lib/policy_enforcer_client.py +1016 -0
- control_plane_api/app/lib/redis_client.py +803 -0
- control_plane_api/app/lib/sqlalchemy_utils.py +486 -0
- control_plane_api/app/lib/state_transition_tools/__init__.py +7 -0
- control_plane_api/app/lib/state_transition_tools/execution_context.py +388 -0
- control_plane_api/app/lib/storage/__init__.py +20 -0
- control_plane_api/app/lib/storage/base_provider.py +274 -0
- control_plane_api/app/lib/storage/provider_factory.py +157 -0
- control_plane_api/app/lib/storage/vercel_blob_provider.py +468 -0
- control_plane_api/app/lib/supabase.py +71 -0
- control_plane_api/app/lib/supabase_utils.py +138 -0
- control_plane_api/app/lib/task_planning/__init__.py +138 -0
- control_plane_api/app/lib/task_planning/agent_factory.py +308 -0
- control_plane_api/app/lib/task_planning/agents.py +389 -0
- control_plane_api/app/lib/task_planning/cache.py +218 -0
- control_plane_api/app/lib/task_planning/entity_resolver.py +273 -0
- control_plane_api/app/lib/task_planning/helpers.py +293 -0
- control_plane_api/app/lib/task_planning/hooks.py +474 -0
- control_plane_api/app/lib/task_planning/models.py +503 -0
- control_plane_api/app/lib/task_planning/plan_validator.py +166 -0
- control_plane_api/app/lib/task_planning/planning_workflow.py +2911 -0
- control_plane_api/app/lib/task_planning/runner.py +656 -0
- control_plane_api/app/lib/task_planning/streaming_hook.py +213 -0
- control_plane_api/app/lib/task_planning/workflow.py +424 -0
- control_plane_api/app/lib/templating/__init__.py +88 -0
- control_plane_api/app/lib/templating/compiler.py +278 -0
- control_plane_api/app/lib/templating/engine.py +178 -0
- control_plane_api/app/lib/templating/parsers/__init__.py +29 -0
- control_plane_api/app/lib/templating/parsers/base.py +96 -0
- control_plane_api/app/lib/templating/parsers/env.py +85 -0
- control_plane_api/app/lib/templating/parsers/graph.py +112 -0
- control_plane_api/app/lib/templating/parsers/secret.py +87 -0
- control_plane_api/app/lib/templating/parsers/simple.py +81 -0
- control_plane_api/app/lib/templating/resolver.py +366 -0
- control_plane_api/app/lib/templating/types.py +214 -0
- control_plane_api/app/lib/templating/validator.py +201 -0
- control_plane_api/app/lib/temporal_client.py +232 -0
- control_plane_api/app/lib/temporal_credentials_cache.py +178 -0
- control_plane_api/app/lib/temporal_credentials_service.py +203 -0
- control_plane_api/app/lib/validation/__init__.py +24 -0
- control_plane_api/app/lib/validation/runtime_validation.py +388 -0
- control_plane_api/app/main.py +531 -0
- control_plane_api/app/middleware/__init__.py +10 -0
- control_plane_api/app/middleware/auth.py +645 -0
- control_plane_api/app/middleware/exception_handler.py +267 -0
- control_plane_api/app/middleware/prometheus_middleware.py +173 -0
- control_plane_api/app/middleware/rate_limiting.py +384 -0
- control_plane_api/app/middleware/request_id.py +202 -0
- control_plane_api/app/models/__init__.py +40 -0
- control_plane_api/app/models/agent.py +90 -0
- control_plane_api/app/models/analytics.py +206 -0
- control_plane_api/app/models/associations.py +107 -0
- control_plane_api/app/models/auth_user.py +73 -0
- control_plane_api/app/models/context.py +161 -0
- control_plane_api/app/models/custom_integration.py +99 -0
- control_plane_api/app/models/environment.py +64 -0
- control_plane_api/app/models/execution.py +125 -0
- control_plane_api/app/models/execution_transition.py +50 -0
- control_plane_api/app/models/job.py +159 -0
- control_plane_api/app/models/llm_model.py +78 -0
- control_plane_api/app/models/orchestration.py +66 -0
- control_plane_api/app/models/plan_execution.py +102 -0
- control_plane_api/app/models/presence.py +49 -0
- control_plane_api/app/models/project.py +61 -0
- control_plane_api/app/models/project_management.py +85 -0
- control_plane_api/app/models/session.py +29 -0
- control_plane_api/app/models/skill.py +155 -0
- control_plane_api/app/models/system_tables.py +43 -0
- control_plane_api/app/models/task_planning.py +372 -0
- control_plane_api/app/models/team.py +86 -0
- control_plane_api/app/models/trace.py +257 -0
- control_plane_api/app/models/user_profile.py +54 -0
- control_plane_api/app/models/worker.py +221 -0
- control_plane_api/app/models/workflow.py +161 -0
- control_plane_api/app/models/workspace.py +50 -0
- control_plane_api/app/observability/__init__.py +177 -0
- control_plane_api/app/observability/context_logging.py +475 -0
- control_plane_api/app/observability/decorators.py +337 -0
- control_plane_api/app/observability/local_span_processor.py +702 -0
- control_plane_api/app/observability/metrics.py +303 -0
- control_plane_api/app/observability/middleware.py +246 -0
- control_plane_api/app/observability/optional.py +115 -0
- control_plane_api/app/observability/tracing.py +382 -0
- control_plane_api/app/policies/README.md +149 -0
- control_plane_api/app/policies/approved_users.rego +62 -0
- control_plane_api/app/policies/business_hours.rego +51 -0
- control_plane_api/app/policies/rate_limiting.rego +100 -0
- control_plane_api/app/policies/tool_enforcement/README.md +336 -0
- control_plane_api/app/policies/tool_enforcement/bash_command_validation.rego +71 -0
- control_plane_api/app/policies/tool_enforcement/business_hours_enforcement.rego +82 -0
- control_plane_api/app/policies/tool_enforcement/mcp_tool_allowlist.rego +58 -0
- control_plane_api/app/policies/tool_enforcement/production_safeguards.rego +80 -0
- control_plane_api/app/policies/tool_enforcement/role_based_tool_access.rego +44 -0
- control_plane_api/app/policies/tool_restrictions.rego +86 -0
- control_plane_api/app/routers/__init__.py +4 -0
- control_plane_api/app/routers/agents.py +382 -0
- control_plane_api/app/routers/agents_v2.py +1598 -0
- control_plane_api/app/routers/analytics.py +1310 -0
- control_plane_api/app/routers/auth.py +59 -0
- control_plane_api/app/routers/client_config.py +57 -0
- control_plane_api/app/routers/context_graph.py +561 -0
- control_plane_api/app/routers/context_manager.py +577 -0
- control_plane_api/app/routers/custom_integrations.py +490 -0
- control_plane_api/app/routers/enforcer.py +132 -0
- control_plane_api/app/routers/environment_context.py +252 -0
- control_plane_api/app/routers/environments.py +761 -0
- control_plane_api/app/routers/execution_environment.py +847 -0
- control_plane_api/app/routers/executions/__init__.py +28 -0
- control_plane_api/app/routers/executions/router.py +286 -0
- control_plane_api/app/routers/executions/services/__init__.py +22 -0
- control_plane_api/app/routers/executions/services/demo_worker_health.py +156 -0
- control_plane_api/app/routers/executions/services/status_service.py +420 -0
- control_plane_api/app/routers/executions/services/test_worker_health.py +480 -0
- control_plane_api/app/routers/executions/services/worker_health.py +514 -0
- control_plane_api/app/routers/executions/streaming/__init__.py +22 -0
- control_plane_api/app/routers/executions/streaming/deduplication.py +352 -0
- control_plane_api/app/routers/executions/streaming/event_buffer.py +353 -0
- control_plane_api/app/routers/executions/streaming/event_formatter.py +964 -0
- control_plane_api/app/routers/executions/streaming/history_loader.py +588 -0
- control_plane_api/app/routers/executions/streaming/live_source.py +693 -0
- control_plane_api/app/routers/executions/streaming/streamer.py +849 -0
- control_plane_api/app/routers/executions.py +4888 -0
- control_plane_api/app/routers/health.py +165 -0
- control_plane_api/app/routers/health_v2.py +394 -0
- control_plane_api/app/routers/integration_templates.py +496 -0
- control_plane_api/app/routers/integrations.py +287 -0
- control_plane_api/app/routers/jobs.py +1809 -0
- control_plane_api/app/routers/metrics.py +517 -0
- control_plane_api/app/routers/models.py +82 -0
- control_plane_api/app/routers/models_v2.py +628 -0
- control_plane_api/app/routers/plan_executions.py +1481 -0
- control_plane_api/app/routers/plan_generation_async.py +304 -0
- control_plane_api/app/routers/policies.py +669 -0
- control_plane_api/app/routers/presence.py +234 -0
- control_plane_api/app/routers/projects.py +987 -0
- control_plane_api/app/routers/runners.py +379 -0
- control_plane_api/app/routers/runtimes.py +172 -0
- control_plane_api/app/routers/secrets.py +171 -0
- control_plane_api/app/routers/skills.py +1010 -0
- control_plane_api/app/routers/skills_definitions.py +140 -0
- control_plane_api/app/routers/storage.py +456 -0
- control_plane_api/app/routers/task_planning.py +611 -0
- control_plane_api/app/routers/task_queues.py +650 -0
- control_plane_api/app/routers/team_context.py +274 -0
- control_plane_api/app/routers/teams.py +1747 -0
- control_plane_api/app/routers/templates.py +248 -0
- control_plane_api/app/routers/traces.py +571 -0
- control_plane_api/app/routers/websocket_client.py +479 -0
- control_plane_api/app/routers/websocket_executions_status.py +437 -0
- control_plane_api/app/routers/websocket_gateway.py +323 -0
- control_plane_api/app/routers/websocket_traces.py +576 -0
- control_plane_api/app/routers/worker_queues.py +2555 -0
- control_plane_api/app/routers/worker_websocket.py +419 -0
- control_plane_api/app/routers/workers.py +1004 -0
- control_plane_api/app/routers/workflows.py +204 -0
- control_plane_api/app/runtimes/__init__.py +6 -0
- control_plane_api/app/runtimes/validation.py +344 -0
- control_plane_api/app/schemas/__init__.py +1 -0
- control_plane_api/app/schemas/job_schemas.py +302 -0
- control_plane_api/app/schemas/mcp_schemas.py +311 -0
- control_plane_api/app/schemas/template_schemas.py +133 -0
- control_plane_api/app/schemas/trace_schemas.py +168 -0
- control_plane_api/app/schemas/worker_queue_observability_schemas.py +165 -0
- control_plane_api/app/services/__init__.py +1 -0
- control_plane_api/app/services/agno_planning_strategy.py +233 -0
- control_plane_api/app/services/agno_service.py +838 -0
- control_plane_api/app/services/claude_code_planning_service.py +203 -0
- control_plane_api/app/services/context_graph_client.py +224 -0
- control_plane_api/app/services/custom_integration_service.py +415 -0
- control_plane_api/app/services/integration_resolution_service.py +345 -0
- control_plane_api/app/services/litellm_service.py +394 -0
- control_plane_api/app/services/plan_generator.py +79 -0
- control_plane_api/app/services/planning_strategy.py +66 -0
- control_plane_api/app/services/planning_strategy_factory.py +118 -0
- control_plane_api/app/services/policy_service.py +615 -0
- control_plane_api/app/services/state_transition_service.py +755 -0
- control_plane_api/app/services/storage_service.py +593 -0
- control_plane_api/app/services/temporal_cloud_provisioning.py +150 -0
- control_plane_api/app/services/toolsets/context_graph_skill.py +432 -0
- control_plane_api/app/services/trace_retention.py +354 -0
- control_plane_api/app/services/worker_queue_metrics_service.py +190 -0
- control_plane_api/app/services/workflow_cancellation_manager.py +135 -0
- control_plane_api/app/services/workflow_operations_service.py +611 -0
- control_plane_api/app/skills/__init__.py +100 -0
- control_plane_api/app/skills/base.py +239 -0
- control_plane_api/app/skills/builtin/__init__.py +37 -0
- control_plane_api/app/skills/builtin/agent_communication/__init__.py +8 -0
- control_plane_api/app/skills/builtin/agent_communication/skill.py +246 -0
- control_plane_api/app/skills/builtin/code_ingestion/__init__.py +4 -0
- control_plane_api/app/skills/builtin/code_ingestion/skill.py +267 -0
- control_plane_api/app/skills/builtin/cognitive_memory/__init__.py +4 -0
- control_plane_api/app/skills/builtin/cognitive_memory/skill.py +174 -0
- control_plane_api/app/skills/builtin/contextual_awareness/__init__.py +4 -0
- control_plane_api/app/skills/builtin/contextual_awareness/skill.py +387 -0
- control_plane_api/app/skills/builtin/data_visualization/__init__.py +4 -0
- control_plane_api/app/skills/builtin/data_visualization/skill.py +154 -0
- control_plane_api/app/skills/builtin/docker/__init__.py +4 -0
- control_plane_api/app/skills/builtin/docker/skill.py +104 -0
- control_plane_api/app/skills/builtin/file_generation/__init__.py +4 -0
- control_plane_api/app/skills/builtin/file_generation/skill.py +94 -0
- control_plane_api/app/skills/builtin/file_system/__init__.py +4 -0
- control_plane_api/app/skills/builtin/file_system/skill.py +110 -0
- control_plane_api/app/skills/builtin/knowledge_api/__init__.py +5 -0
- control_plane_api/app/skills/builtin/knowledge_api/skill.py +124 -0
- control_plane_api/app/skills/builtin/python/__init__.py +4 -0
- control_plane_api/app/skills/builtin/python/skill.py +92 -0
- control_plane_api/app/skills/builtin/remote_filesystem/__init__.py +5 -0
- control_plane_api/app/skills/builtin/remote_filesystem/skill.py +170 -0
- control_plane_api/app/skills/builtin/shell/__init__.py +4 -0
- control_plane_api/app/skills/builtin/shell/skill.py +161 -0
- control_plane_api/app/skills/builtin/slack/__init__.py +3 -0
- control_plane_api/app/skills/builtin/slack/skill.py +302 -0
- control_plane_api/app/skills/builtin/workflow_executor/__init__.py +4 -0
- control_plane_api/app/skills/builtin/workflow_executor/skill.py +469 -0
- control_plane_api/app/skills/business_intelligence.py +189 -0
- control_plane_api/app/skills/config.py +63 -0
- control_plane_api/app/skills/loaders/__init__.py +14 -0
- control_plane_api/app/skills/loaders/base.py +73 -0
- control_plane_api/app/skills/loaders/filesystem_loader.py +199 -0
- control_plane_api/app/skills/registry.py +125 -0
- control_plane_api/app/utils/helpers.py +12 -0
- control_plane_api/app/utils/workflow_executor.py +354 -0
- control_plane_api/app/workflows/__init__.py +11 -0
- control_plane_api/app/workflows/agent_execution.py +520 -0
- control_plane_api/app/workflows/agent_execution_with_skills.py +223 -0
- control_plane_api/app/workflows/namespace_provisioning.py +326 -0
- control_plane_api/app/workflows/plan_generation.py +254 -0
- control_plane_api/app/workflows/team_execution.py +442 -0
- control_plane_api/scripts/seed_models.py +240 -0
- control_plane_api/scripts/validate_existing_tool_names.py +492 -0
- control_plane_api/shared/__init__.py +8 -0
- control_plane_api/shared/version.py +17 -0
- control_plane_api/test_deduplication.py +274 -0
- control_plane_api/test_executor_deduplication_e2e.py +309 -0
- control_plane_api/test_job_execution_e2e.py +283 -0
- control_plane_api/test_real_integration.py +193 -0
- control_plane_api/version.py +38 -0
- control_plane_api/worker/__init__.py +0 -0
- control_plane_api/worker/activities/__init__.py +0 -0
- control_plane_api/worker/activities/agent_activities.py +1585 -0
- control_plane_api/worker/activities/approval_activities.py +234 -0
- control_plane_api/worker/activities/job_activities.py +199 -0
- control_plane_api/worker/activities/runtime_activities.py +1167 -0
- control_plane_api/worker/activities/skill_activities.py +282 -0
- control_plane_api/worker/activities/team_activities.py +479 -0
- control_plane_api/worker/agent_runtime_server.py +370 -0
- control_plane_api/worker/binary_manager.py +333 -0
- control_plane_api/worker/config/__init__.py +31 -0
- control_plane_api/worker/config/worker_config.py +273 -0
- control_plane_api/worker/control_plane_client.py +1491 -0
- control_plane_api/worker/examples/analytics_integration_example.py +362 -0
- control_plane_api/worker/health_monitor.py +159 -0
- control_plane_api/worker/metrics.py +237 -0
- control_plane_api/worker/models/__init__.py +1 -0
- control_plane_api/worker/models/error_events.py +105 -0
- control_plane_api/worker/models/inputs.py +89 -0
- control_plane_api/worker/runtimes/__init__.py +35 -0
- control_plane_api/worker/runtimes/agent_runtime/runtime.py +485 -0
- control_plane_api/worker/runtimes/agno/__init__.py +34 -0
- control_plane_api/worker/runtimes/agno/config.py +248 -0
- control_plane_api/worker/runtimes/agno/hooks.py +385 -0
- control_plane_api/worker/runtimes/agno/mcp_builder.py +195 -0
- control_plane_api/worker/runtimes/agno/runtime.py +1063 -0
- control_plane_api/worker/runtimes/agno/utils.py +163 -0
- control_plane_api/worker/runtimes/base.py +979 -0
- control_plane_api/worker/runtimes/claude_code/__init__.py +38 -0
- control_plane_api/worker/runtimes/claude_code/cleanup.py +184 -0
- control_plane_api/worker/runtimes/claude_code/client_pool.py +529 -0
- control_plane_api/worker/runtimes/claude_code/config.py +829 -0
- control_plane_api/worker/runtimes/claude_code/hooks.py +482 -0
- control_plane_api/worker/runtimes/claude_code/litellm_proxy.py +1702 -0
- control_plane_api/worker/runtimes/claude_code/mcp_builder.py +467 -0
- control_plane_api/worker/runtimes/claude_code/mcp_discovery.py +558 -0
- control_plane_api/worker/runtimes/claude_code/runtime.py +1546 -0
- control_plane_api/worker/runtimes/claude_code/tool_mapper.py +403 -0
- control_plane_api/worker/runtimes/claude_code/utils.py +149 -0
- control_plane_api/worker/runtimes/factory.py +173 -0
- control_plane_api/worker/runtimes/model_utils.py +107 -0
- control_plane_api/worker/runtimes/validation.py +93 -0
- control_plane_api/worker/services/__init__.py +1 -0
- control_plane_api/worker/services/agent_communication_tools.py +908 -0
- control_plane_api/worker/services/agent_executor.py +485 -0
- control_plane_api/worker/services/agent_executor_v2.py +793 -0
- control_plane_api/worker/services/analytics_collector.py +457 -0
- control_plane_api/worker/services/analytics_service.py +464 -0
- control_plane_api/worker/services/approval_tools.py +310 -0
- control_plane_api/worker/services/approval_tools_agno.py +207 -0
- control_plane_api/worker/services/cancellation_manager.py +177 -0
- control_plane_api/worker/services/code_ingestion_tools.py +465 -0
- control_plane_api/worker/services/contextual_awareness_tools.py +405 -0
- control_plane_api/worker/services/data_visualization.py +834 -0
- control_plane_api/worker/services/event_publisher.py +531 -0
- control_plane_api/worker/services/jira_tools.py +257 -0
- control_plane_api/worker/services/remote_filesystem_tools.py +498 -0
- control_plane_api/worker/services/runtime_analytics.py +328 -0
- control_plane_api/worker/services/session_service.py +365 -0
- control_plane_api/worker/services/skill_context_enhancement.py +181 -0
- control_plane_api/worker/services/skill_factory.py +471 -0
- control_plane_api/worker/services/system_prompt_enhancement.py +410 -0
- control_plane_api/worker/services/team_executor.py +715 -0
- control_plane_api/worker/services/team_executor_v2.py +1866 -0
- control_plane_api/worker/services/tool_enforcement.py +254 -0
- control_plane_api/worker/services/workflow_executor/__init__.py +52 -0
- control_plane_api/worker/services/workflow_executor/event_processor.py +287 -0
- control_plane_api/worker/services/workflow_executor/event_publisher.py +210 -0
- control_plane_api/worker/services/workflow_executor/executors/__init__.py +15 -0
- control_plane_api/worker/services/workflow_executor/executors/base.py +270 -0
- control_plane_api/worker/services/workflow_executor/executors/json_executor.py +50 -0
- control_plane_api/worker/services/workflow_executor/executors/python_executor.py +50 -0
- control_plane_api/worker/services/workflow_executor/models.py +142 -0
- control_plane_api/worker/services/workflow_executor_tools.py +1748 -0
- control_plane_api/worker/skills/__init__.py +12 -0
- control_plane_api/worker/skills/builtin/context_graph_search/README.md +213 -0
- control_plane_api/worker/skills/builtin/context_graph_search/__init__.py +5 -0
- control_plane_api/worker/skills/builtin/context_graph_search/agno_impl.py +808 -0
- control_plane_api/worker/skills/builtin/context_graph_search/skill.yaml +67 -0
- control_plane_api/worker/skills/builtin/contextual_awareness/__init__.py +4 -0
- control_plane_api/worker/skills/builtin/contextual_awareness/agno_impl.py +62 -0
- control_plane_api/worker/skills/builtin/data_visualization/agno_impl.py +18 -0
- control_plane_api/worker/skills/builtin/data_visualization/skill.yaml +84 -0
- control_plane_api/worker/skills/builtin/docker/agno_impl.py +65 -0
- control_plane_api/worker/skills/builtin/docker/skill.yaml +60 -0
- control_plane_api/worker/skills/builtin/file_generation/agno_impl.py +47 -0
- control_plane_api/worker/skills/builtin/file_generation/skill.yaml +64 -0
- control_plane_api/worker/skills/builtin/file_system/agno_impl.py +32 -0
- control_plane_api/worker/skills/builtin/file_system/skill.yaml +54 -0
- control_plane_api/worker/skills/builtin/knowledge_api/__init__.py +4 -0
- control_plane_api/worker/skills/builtin/knowledge_api/agno_impl.py +50 -0
- control_plane_api/worker/skills/builtin/knowledge_api/skill.yaml +66 -0
- control_plane_api/worker/skills/builtin/python/agno_impl.py +25 -0
- control_plane_api/worker/skills/builtin/python/skill.yaml +60 -0
- control_plane_api/worker/skills/builtin/schema_fix_mixin.py +260 -0
- control_plane_api/worker/skills/builtin/shell/agno_impl.py +31 -0
- control_plane_api/worker/skills/builtin/shell/skill.yaml +60 -0
- control_plane_api/worker/skills/builtin/slack/__init__.py +3 -0
- control_plane_api/worker/skills/builtin/slack/agno_impl.py +1282 -0
- control_plane_api/worker/skills/builtin/slack/skill.yaml +276 -0
- control_plane_api/worker/skills/builtin/workflow_executor/agno_impl.py +62 -0
- control_plane_api/worker/skills/builtin/workflow_executor/skill.yaml +79 -0
- control_plane_api/worker/skills/loaders/__init__.py +5 -0
- control_plane_api/worker/skills/loaders/base.py +23 -0
- control_plane_api/worker/skills/loaders/filesystem_loader.py +357 -0
- control_plane_api/worker/skills/registry.py +208 -0
- control_plane_api/worker/tests/__init__.py +1 -0
- control_plane_api/worker/tests/conftest.py +12 -0
- control_plane_api/worker/tests/e2e/__init__.py +0 -0
- control_plane_api/worker/tests/e2e/test_context_graph_real_api.py +338 -0
- control_plane_api/worker/tests/e2e/test_context_graph_templates_e2e.py +523 -0
- control_plane_api/worker/tests/e2e/test_enforcement_e2e.py +344 -0
- control_plane_api/worker/tests/e2e/test_execution_flow.py +571 -0
- control_plane_api/worker/tests/e2e/test_single_execution_mode.py +656 -0
- control_plane_api/worker/tests/integration/__init__.py +0 -0
- control_plane_api/worker/tests/integration/test_builtin_skills_fixes.py +245 -0
- control_plane_api/worker/tests/integration/test_context_graph_search_integration.py +365 -0
- control_plane_api/worker/tests/integration/test_control_plane_integration.py +308 -0
- control_plane_api/worker/tests/integration/test_hook_enforcement_integration.py +579 -0
- control_plane_api/worker/tests/integration/test_scheduled_job_workflow.py +237 -0
- control_plane_api/worker/tests/integration/test_system_prompt_enhancement_integration.py +343 -0
- control_plane_api/worker/tests/unit/__init__.py +0 -0
- control_plane_api/worker/tests/unit/test_builtin_skill_autoload.py +396 -0
- control_plane_api/worker/tests/unit/test_context_graph_search.py +450 -0
- control_plane_api/worker/tests/unit/test_context_graph_templates.py +403 -0
- control_plane_api/worker/tests/unit/test_control_plane_client.py +401 -0
- control_plane_api/worker/tests/unit/test_control_plane_client_jobs.py +345 -0
- control_plane_api/worker/tests/unit/test_job_activities.py +353 -0
- control_plane_api/worker/tests/unit/test_skill_context_enhancement.py +321 -0
- control_plane_api/worker/tests/unit/test_system_prompt_enhancement.py +415 -0
- control_plane_api/worker/tests/unit/test_tool_enforcement.py +324 -0
- control_plane_api/worker/utils/__init__.py +1 -0
- control_plane_api/worker/utils/chunk_batcher.py +330 -0
- control_plane_api/worker/utils/environment.py +65 -0
- control_plane_api/worker/utils/error_publisher.py +260 -0
- control_plane_api/worker/utils/event_batcher.py +256 -0
- control_plane_api/worker/utils/logging_config.py +335 -0
- control_plane_api/worker/utils/logging_helper.py +326 -0
- control_plane_api/worker/utils/parameter_validator.py +120 -0
- control_plane_api/worker/utils/retry_utils.py +60 -0
- control_plane_api/worker/utils/streaming_utils.py +665 -0
- control_plane_api/worker/utils/tool_validation.py +332 -0
- control_plane_api/worker/utils/workspace_manager.py +163 -0
- control_plane_api/worker/websocket_client.py +393 -0
- control_plane_api/worker/worker.py +1297 -0
- control_plane_api/worker/workflows/__init__.py +0 -0
- control_plane_api/worker/workflows/agent_execution.py +909 -0
- control_plane_api/worker/workflows/scheduled_job_wrapper.py +332 -0
- control_plane_api/worker/workflows/team_execution.py +611 -0
- kubiya_control_plane_api-0.9.15.dist-info/METADATA +354 -0
- kubiya_control_plane_api-0.9.15.dist-info/RECORD +479 -0
- kubiya_control_plane_api-0.9.15.dist-info/WHEEL +5 -0
- kubiya_control_plane_api-0.9.15.dist-info/entry_points.txt +5 -0
- kubiya_control_plane_api-0.9.15.dist-info/licenses/LICENSE +676 -0
- kubiya_control_plane_api-0.9.15.dist-info/top_level.txt +3 -0
- scripts/__init__.py +1 -0
- scripts/migrations.py +39 -0
- scripts/seed_worker_queues.py +128 -0
- scripts/setup_agent_runtime.py +142 -0
- worker_internal/__init__.py +1 -0
- worker_internal/planner/__init__.py +1 -0
- worker_internal/planner/activities.py +1499 -0
- worker_internal/planner/agent_tools.py +197 -0
- worker_internal/planner/event_models.py +148 -0
- worker_internal/planner/event_publisher.py +67 -0
- worker_internal/planner/models.py +199 -0
- worker_internal/planner/retry_logic.py +134 -0
- worker_internal/planner/worker.py +300 -0
- worker_internal/planner/workflows.py +970 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
"""
|
|
2
|
+
StatusService for cached workflow status queries.
|
|
3
|
+
|
|
4
|
+
This module provides the StatusService class that caches Temporal workflow status
|
|
5
|
+
queries to reduce API load during high-frequency polling operations.
|
|
6
|
+
|
|
7
|
+
Key Features:
|
|
8
|
+
- 1-second TTL cache for status queries
|
|
9
|
+
- Reduces Temporal API load during SSE polling (typically 200ms intervals)
|
|
10
|
+
- Handles Temporal timeouts gracefully (2 second timeout)
|
|
11
|
+
- Thread-safe for concurrent access
|
|
12
|
+
- Per-execution_id cache keys
|
|
13
|
+
- Terminal state detection
|
|
14
|
+
|
|
15
|
+
Cache Strategy:
|
|
16
|
+
- Cache hit: Return cached status if within 1 second TTL
|
|
17
|
+
- Cache miss: Query Temporal, cache result, return status
|
|
18
|
+
- Cache invalidation: Automatic on TTL expiration or manual invalidation
|
|
19
|
+
- Terminal states cached indefinitely (no need to re-query completed workflows)
|
|
20
|
+
|
|
21
|
+
Test Strategy:
|
|
22
|
+
- Test cache hit behavior (query within 1 second returns cached value)
|
|
23
|
+
- Test cache miss behavior (query after TTL returns fresh value)
|
|
24
|
+
- Test TTL expiration (cache becomes invalid after 1 second)
|
|
25
|
+
- Test timeout handling (2 second Temporal timeout)
|
|
26
|
+
- Test terminal state detection (COMPLETED, FAILED, etc.)
|
|
27
|
+
- Test cache invalidation (manual and automatic)
|
|
28
|
+
- Test concurrent access (asyncio lock prevents race conditions)
|
|
29
|
+
- Test workflow_handle None handling
|
|
30
|
+
- Test Temporal unavailable handling
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import asyncio
|
|
34
|
+
import time
|
|
35
|
+
from typing import Optional, Dict, Any
|
|
36
|
+
import structlog
|
|
37
|
+
|
|
38
|
+
logger = structlog.get_logger()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class StatusService:
|
|
42
|
+
"""
|
|
43
|
+
Service for querying and caching Temporal workflow status.
|
|
44
|
+
|
|
45
|
+
This service provides cached workflow status queries to reduce load on
|
|
46
|
+
Temporal API during high-frequency polling operations (e.g., SSE streaming
|
|
47
|
+
at 200ms intervals).
|
|
48
|
+
|
|
49
|
+
The cache uses a 1-second TTL to balance freshness with API load reduction.
|
|
50
|
+
Terminal states (COMPLETED, FAILED, etc.) are cached indefinitely since
|
|
51
|
+
they won't change.
|
|
52
|
+
|
|
53
|
+
Example:
|
|
54
|
+
```python
|
|
55
|
+
status_service = StatusService(
|
|
56
|
+
temporal_client=client,
|
|
57
|
+
execution_id="exec-123",
|
|
58
|
+
organization_id="org-456"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# First call queries Temporal
|
|
62
|
+
status = await status_service.get_status() # "RUNNING"
|
|
63
|
+
|
|
64
|
+
# Second call within 1 second uses cache
|
|
65
|
+
status = await status_service.get_status() # "RUNNING" (cached)
|
|
66
|
+
|
|
67
|
+
# Force refresh ignores cache
|
|
68
|
+
status = await status_service.get_status(force_refresh=True) # "COMPLETED" (fresh)
|
|
69
|
+
|
|
70
|
+
# Check terminal state
|
|
71
|
+
if await status_service.is_terminal():
|
|
72
|
+
print("Workflow completed")
|
|
73
|
+
```
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
# Cache TTL in seconds - balances freshness with API load
|
|
77
|
+
CACHE_TTL = 1.0
|
|
78
|
+
|
|
79
|
+
# Terminal workflow states that won't change (cache indefinitely)
|
|
80
|
+
TERMINAL_STATES = {"COMPLETED", "FAILED", "CANCELLED", "TERMINATED", "TIMED_OUT"}
|
|
81
|
+
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
workflow_handle: Optional[Any],
|
|
85
|
+
execution_id: str,
|
|
86
|
+
organization_id: str,
|
|
87
|
+
):
|
|
88
|
+
"""
|
|
89
|
+
Initialize StatusService.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
workflow_handle: Temporal workflow handle for status queries (can be None)
|
|
93
|
+
execution_id: Execution ID for this workflow
|
|
94
|
+
organization_id: Organization ID for authorization
|
|
95
|
+
"""
|
|
96
|
+
self.workflow_handle = workflow_handle
|
|
97
|
+
self.execution_id = execution_id
|
|
98
|
+
self.organization_id = organization_id
|
|
99
|
+
|
|
100
|
+
# Cache structure: {execution_id: {status, timestamp, workflow_info}}
|
|
101
|
+
self._cache: Dict[str, Dict[str, Any]] = {}
|
|
102
|
+
|
|
103
|
+
# Lock for thread-safe cache access
|
|
104
|
+
self._lock = asyncio.Lock()
|
|
105
|
+
|
|
106
|
+
logger.debug(
|
|
107
|
+
"status_service_initialized",
|
|
108
|
+
execution_id=execution_id[:8] if execution_id else "unknown",
|
|
109
|
+
has_workflow_handle=workflow_handle is not None,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
async def get_status(self, force_refresh: bool = False) -> Optional[str]:
|
|
113
|
+
"""
|
|
114
|
+
Get workflow status with caching.
|
|
115
|
+
|
|
116
|
+
This method checks the cache first and only queries Temporal if:
|
|
117
|
+
1. Cache is empty (first call)
|
|
118
|
+
2. Cache has expired (TTL exceeded)
|
|
119
|
+
3. force_refresh is True
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
force_refresh: Skip cache and query Temporal directly
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Status string (RUNNING, COMPLETED, FAILED, CANCELLED, TERMINATED, TIMED_OUT)
|
|
126
|
+
or None if workflow_handle is None or query fails
|
|
127
|
+
|
|
128
|
+
Example:
|
|
129
|
+
```python
|
|
130
|
+
# Normal cached query
|
|
131
|
+
status = await service.get_status()
|
|
132
|
+
|
|
133
|
+
# Force fresh query
|
|
134
|
+
status = await service.get_status(force_refresh=True)
|
|
135
|
+
```
|
|
136
|
+
"""
|
|
137
|
+
if not self.workflow_handle:
|
|
138
|
+
logger.debug(
|
|
139
|
+
"status_query_skipped_no_workflow_handle",
|
|
140
|
+
execution_id=self.execution_id[:8],
|
|
141
|
+
)
|
|
142
|
+
return None
|
|
143
|
+
|
|
144
|
+
async with self._lock:
|
|
145
|
+
current_time = time.time()
|
|
146
|
+
|
|
147
|
+
# Check cache validity
|
|
148
|
+
if not force_refresh and self._is_cache_valid(self.execution_id):
|
|
149
|
+
cached_entry = self._cache[self.execution_id]
|
|
150
|
+
cached_status = cached_entry["status"]
|
|
151
|
+
cache_age = current_time - cached_entry["timestamp"]
|
|
152
|
+
|
|
153
|
+
logger.debug(
|
|
154
|
+
"status_cache_hit",
|
|
155
|
+
execution_id=self.execution_id[:8],
|
|
156
|
+
status=cached_status,
|
|
157
|
+
cache_age_ms=int(cache_age * 1000),
|
|
158
|
+
)
|
|
159
|
+
return cached_status
|
|
160
|
+
|
|
161
|
+
# Cache miss or expired - query Temporal
|
|
162
|
+
status = await self._query_temporal()
|
|
163
|
+
|
|
164
|
+
if status:
|
|
165
|
+
# Update cache
|
|
166
|
+
self._cache[self.execution_id] = {
|
|
167
|
+
"status": status,
|
|
168
|
+
"timestamp": current_time,
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
cache_status = "refreshed" if force_refresh else "miss"
|
|
172
|
+
logger.debug(
|
|
173
|
+
f"status_cache_{cache_status}",
|
|
174
|
+
execution_id=self.execution_id[:8],
|
|
175
|
+
status=status,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
return status
|
|
179
|
+
|
|
180
|
+
async def is_terminal(self) -> bool:
|
|
181
|
+
"""
|
|
182
|
+
Check if workflow is in terminal state.
|
|
183
|
+
|
|
184
|
+
Terminal states are: COMPLETED, FAILED, CANCELLED, TERMINATED, TIMED_OUT
|
|
185
|
+
These states are final and won't change.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
True if workflow is in terminal state, False otherwise
|
|
189
|
+
|
|
190
|
+
Example:
|
|
191
|
+
```python
|
|
192
|
+
if await service.is_terminal():
|
|
193
|
+
print("Workflow finished")
|
|
194
|
+
# Stop polling
|
|
195
|
+
```
|
|
196
|
+
"""
|
|
197
|
+
status = await self.get_status()
|
|
198
|
+
if not status:
|
|
199
|
+
return False
|
|
200
|
+
|
|
201
|
+
is_terminal = status in self.TERMINAL_STATES
|
|
202
|
+
|
|
203
|
+
logger.debug(
|
|
204
|
+
"terminal_state_check",
|
|
205
|
+
execution_id=self.execution_id[:8],
|
|
206
|
+
status=status,
|
|
207
|
+
is_terminal=is_terminal,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return is_terminal
|
|
211
|
+
|
|
212
|
+
async def is_running(self) -> bool:
|
|
213
|
+
"""
|
|
214
|
+
Check if workflow is currently running.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
True if workflow status is RUNNING, False otherwise
|
|
218
|
+
|
|
219
|
+
Example:
|
|
220
|
+
```python
|
|
221
|
+
if await service.is_running():
|
|
222
|
+
print("Workflow is active")
|
|
223
|
+
# Continue polling
|
|
224
|
+
```
|
|
225
|
+
"""
|
|
226
|
+
status = await self.get_status()
|
|
227
|
+
if not status:
|
|
228
|
+
return False
|
|
229
|
+
|
|
230
|
+
is_running = status == "RUNNING"
|
|
231
|
+
|
|
232
|
+
logger.debug(
|
|
233
|
+
"running_state_check",
|
|
234
|
+
execution_id=self.execution_id[:8],
|
|
235
|
+
status=status,
|
|
236
|
+
is_running=is_running,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
return is_running
|
|
240
|
+
|
|
241
|
+
async def _query_temporal(self) -> Optional[str]:
|
|
242
|
+
"""
|
|
243
|
+
Query Temporal for current workflow status with timeout.
|
|
244
|
+
|
|
245
|
+
This method queries the Temporal workflow handle with a 2-second timeout
|
|
246
|
+
to prevent hanging on slow/unavailable Temporal clusters.
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
Status enum name (e.g., "RUNNING", "COMPLETED") or None on error
|
|
250
|
+
|
|
251
|
+
Handles:
|
|
252
|
+
- Timeout after 2 seconds
|
|
253
|
+
- Temporal unavailable errors
|
|
254
|
+
- Network errors
|
|
255
|
+
- Invalid workflow handle
|
|
256
|
+
"""
|
|
257
|
+
if not self.workflow_handle:
|
|
258
|
+
return None
|
|
259
|
+
|
|
260
|
+
try:
|
|
261
|
+
t0 = time.time()
|
|
262
|
+
|
|
263
|
+
# Query Temporal with 2 second timeout
|
|
264
|
+
description = await asyncio.wait_for(
|
|
265
|
+
self.workflow_handle.describe(),
|
|
266
|
+
timeout=2.0,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
# Extract status enum name (e.g., "RUNNING")
|
|
270
|
+
# Temporal execution status enum values:
|
|
271
|
+
# RUNNING, COMPLETED, FAILED, CANCELLED, TERMINATED, TIMED_OUT, CONTINUED_AS_NEW
|
|
272
|
+
status = description.status.name
|
|
273
|
+
|
|
274
|
+
query_duration = int((time.time() - t0) * 1000)
|
|
275
|
+
|
|
276
|
+
logger.debug(
|
|
277
|
+
"temporal_status_query_success",
|
|
278
|
+
execution_id=self.execution_id[:8],
|
|
279
|
+
status=status,
|
|
280
|
+
duration_ms=query_duration,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
# Log slow queries (>100ms)
|
|
284
|
+
if query_duration > 100:
|
|
285
|
+
logger.warning(
|
|
286
|
+
"slow_temporal_status_query",
|
|
287
|
+
execution_id=self.execution_id[:8],
|
|
288
|
+
duration_ms=query_duration,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
return status
|
|
292
|
+
|
|
293
|
+
except asyncio.TimeoutError:
|
|
294
|
+
logger.warning(
|
|
295
|
+
"temporal_status_query_timeout",
|
|
296
|
+
execution_id=self.execution_id[:8],
|
|
297
|
+
timeout_seconds=2.0,
|
|
298
|
+
)
|
|
299
|
+
return None
|
|
300
|
+
|
|
301
|
+
except Exception as e:
|
|
302
|
+
error_type = type(e).__name__
|
|
303
|
+
error_msg = str(e)
|
|
304
|
+
|
|
305
|
+
logger.error(
|
|
306
|
+
"temporal_status_query_error",
|
|
307
|
+
execution_id=self.execution_id[:8],
|
|
308
|
+
error_type=error_type,
|
|
309
|
+
error=error_msg,
|
|
310
|
+
)
|
|
311
|
+
return None
|
|
312
|
+
|
|
313
|
+
def _is_cache_valid(self, execution_id: str) -> bool:
|
|
314
|
+
"""
|
|
315
|
+
Check if cached status is still valid (within TTL).
|
|
316
|
+
|
|
317
|
+
For terminal states, cache is always valid (infinite TTL).
|
|
318
|
+
For non-terminal states, cache is valid for CACHE_TTL seconds.
|
|
319
|
+
|
|
320
|
+
Args:
|
|
321
|
+
execution_id: Execution ID to check cache for
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
True if cache exists and is valid, False otherwise
|
|
325
|
+
"""
|
|
326
|
+
if execution_id not in self._cache:
|
|
327
|
+
return False
|
|
328
|
+
|
|
329
|
+
cached_entry = self._cache[execution_id]
|
|
330
|
+
cached_status = cached_entry["status"]
|
|
331
|
+
|
|
332
|
+
# Terminal states are cached indefinitely
|
|
333
|
+
if cached_status in self.TERMINAL_STATES:
|
|
334
|
+
logger.debug(
|
|
335
|
+
"cache_valid_terminal_state",
|
|
336
|
+
execution_id=execution_id[:8],
|
|
337
|
+
status=cached_status,
|
|
338
|
+
)
|
|
339
|
+
return True
|
|
340
|
+
|
|
341
|
+
# Non-terminal states use TTL
|
|
342
|
+
current_time = time.time()
|
|
343
|
+
cache_age = current_time - cached_entry["timestamp"]
|
|
344
|
+
is_valid = cache_age < self.CACHE_TTL
|
|
345
|
+
|
|
346
|
+
if not is_valid:
|
|
347
|
+
logger.debug(
|
|
348
|
+
"cache_expired",
|
|
349
|
+
execution_id=execution_id[:8],
|
|
350
|
+
cache_age_ms=int(cache_age * 1000),
|
|
351
|
+
ttl_ms=int(self.CACHE_TTL * 1000),
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
return is_valid
|
|
355
|
+
|
|
356
|
+
def invalidate_cache(self, execution_id: Optional[str] = None):
|
|
357
|
+
"""
|
|
358
|
+
Invalidate cache for specific execution or all executions.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
execution_id: Execution ID to invalidate, or None to invalidate all
|
|
362
|
+
|
|
363
|
+
Example:
|
|
364
|
+
```python
|
|
365
|
+
# Invalidate specific execution
|
|
366
|
+
service.invalidate_cache("exec-123")
|
|
367
|
+
|
|
368
|
+
# Invalidate all
|
|
369
|
+
service.invalidate_cache()
|
|
370
|
+
```
|
|
371
|
+
"""
|
|
372
|
+
if execution_id:
|
|
373
|
+
if execution_id in self._cache:
|
|
374
|
+
del self._cache[execution_id]
|
|
375
|
+
logger.debug(
|
|
376
|
+
"cache_invalidated",
|
|
377
|
+
execution_id=execution_id[:8],
|
|
378
|
+
)
|
|
379
|
+
else:
|
|
380
|
+
# Invalidate all
|
|
381
|
+
cache_size = len(self._cache)
|
|
382
|
+
self._cache.clear()
|
|
383
|
+
logger.debug(
|
|
384
|
+
"cache_cleared_all",
|
|
385
|
+
cleared_entries=cache_size,
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
def get_cache_stats(self) -> Dict[str, Any]:
|
|
389
|
+
"""
|
|
390
|
+
Get cache statistics for monitoring.
|
|
391
|
+
|
|
392
|
+
Returns:
|
|
393
|
+
Dictionary with cache statistics:
|
|
394
|
+
- size: Number of cached entries
|
|
395
|
+
- entries: List of cached execution IDs with status and age
|
|
396
|
+
|
|
397
|
+
Example:
|
|
398
|
+
```python
|
|
399
|
+
stats = service.get_cache_stats()
|
|
400
|
+
print(f"Cache size: {stats['size']}")
|
|
401
|
+
for entry in stats['entries']:
|
|
402
|
+
print(f" {entry['execution_id']}: {entry['status']} ({entry['age_ms']}ms old)")
|
|
403
|
+
```
|
|
404
|
+
"""
|
|
405
|
+
current_time = time.time()
|
|
406
|
+
entries = []
|
|
407
|
+
|
|
408
|
+
for exec_id, cached_entry in self._cache.items():
|
|
409
|
+
cache_age = current_time - cached_entry["timestamp"]
|
|
410
|
+
entries.append({
|
|
411
|
+
"execution_id": exec_id,
|
|
412
|
+
"status": cached_entry["status"],
|
|
413
|
+
"age_ms": int(cache_age * 1000),
|
|
414
|
+
"is_valid": self._is_cache_valid(exec_id),
|
|
415
|
+
})
|
|
416
|
+
|
|
417
|
+
return {
|
|
418
|
+
"size": len(self._cache),
|
|
419
|
+
"entries": entries,
|
|
420
|
+
}
|