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,138 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Supabase utility functions with defensive error handling.
|
|
3
|
+
|
|
4
|
+
Provides wrappers around Supabase queries to handle common errors like:
|
|
5
|
+
- Code 556: JSON could not be generated (invalid JSONB data)
|
|
6
|
+
- Network timeouts
|
|
7
|
+
- Connection errors
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import structlog
|
|
11
|
+
from typing import Any, Optional, Callable
|
|
12
|
+
from supabase import Client
|
|
13
|
+
|
|
14
|
+
logger = structlog.get_logger()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def safe_execute_query(
|
|
18
|
+
client: Client,
|
|
19
|
+
query_builder: Callable,
|
|
20
|
+
operation_name: str,
|
|
21
|
+
fallback_query_builder: Optional[Callable] = None,
|
|
22
|
+
**context
|
|
23
|
+
) -> Any:
|
|
24
|
+
"""
|
|
25
|
+
Execute a Supabase query with defensive error handling.
|
|
26
|
+
|
|
27
|
+
This wrapper handles common Supabase/PostgREST errors gracefully,
|
|
28
|
+
including code 556 (JSON could not be generated) which occurs when
|
|
29
|
+
JSONB columns contain invalid data.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
client: Supabase client
|
|
33
|
+
query_builder: Function that returns the query to execute
|
|
34
|
+
operation_name: Name of the operation for logging
|
|
35
|
+
fallback_query_builder: Optional fallback query if primary fails
|
|
36
|
+
**context: Additional context for logging
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Query result or None if both queries fail
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
```python
|
|
43
|
+
result = safe_execute_query(
|
|
44
|
+
client=get_supabase(),
|
|
45
|
+
query_builder=lambda: client.table("executions")
|
|
46
|
+
.select("*, execution_participants(*)")
|
|
47
|
+
.eq("organization_id", org_id),
|
|
48
|
+
fallback_query_builder=lambda: client.table("executions")
|
|
49
|
+
.select("*")
|
|
50
|
+
.eq("organization_id", org_id),
|
|
51
|
+
operation_name="list_executions",
|
|
52
|
+
org_id=org_id,
|
|
53
|
+
)
|
|
54
|
+
```
|
|
55
|
+
"""
|
|
56
|
+
try:
|
|
57
|
+
# Try primary query
|
|
58
|
+
query = query_builder()
|
|
59
|
+
result = query.execute()
|
|
60
|
+
return result
|
|
61
|
+
|
|
62
|
+
except Exception as primary_error:
|
|
63
|
+
error_str = str(primary_error)
|
|
64
|
+
|
|
65
|
+
# Check if it's a JSON serialization error (code 556)
|
|
66
|
+
is_json_error = (
|
|
67
|
+
"JSON could not be generated" in error_str or
|
|
68
|
+
"'code': 556" in error_str or
|
|
69
|
+
"code\": 556" in error_str
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
if is_json_error:
|
|
73
|
+
logger.warning(
|
|
74
|
+
f"{operation_name}_json_error_using_fallback",
|
|
75
|
+
error=error_str[:200], # Truncate long errors
|
|
76
|
+
**context
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Try fallback query if provided
|
|
80
|
+
if fallback_query_builder:
|
|
81
|
+
try:
|
|
82
|
+
fallback_query = fallback_query_builder()
|
|
83
|
+
result = fallback_query.execute()
|
|
84
|
+
logger.debug(
|
|
85
|
+
f"{operation_name}_fallback_succeeded",
|
|
86
|
+
**context
|
|
87
|
+
)
|
|
88
|
+
return result
|
|
89
|
+
|
|
90
|
+
except Exception as fallback_error:
|
|
91
|
+
logger.error(
|
|
92
|
+
f"{operation_name}_fallback_query_failed",
|
|
93
|
+
error=str(fallback_error),
|
|
94
|
+
**context
|
|
95
|
+
)
|
|
96
|
+
raise fallback_error
|
|
97
|
+
else:
|
|
98
|
+
# No fallback provided, re-raise original error
|
|
99
|
+
raise primary_error
|
|
100
|
+
else:
|
|
101
|
+
# Different error type - re-raise
|
|
102
|
+
logger.error(
|
|
103
|
+
f"{operation_name}_query_failed",
|
|
104
|
+
error=error_str,
|
|
105
|
+
error_type=type(primary_error).__name__,
|
|
106
|
+
**context
|
|
107
|
+
)
|
|
108
|
+
raise primary_error
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def sanitize_jsonb_field(value: Any, field_name: str, default: dict = None) -> dict:
|
|
112
|
+
"""
|
|
113
|
+
Sanitize a JSONB field value to ensure it's a valid dict.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
value: The value to sanitize
|
|
117
|
+
field_name: Name of the field for logging
|
|
118
|
+
default: Default value if sanitization fails
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Valid dict or default
|
|
122
|
+
"""
|
|
123
|
+
if default is None:
|
|
124
|
+
default = {}
|
|
125
|
+
|
|
126
|
+
if value is None:
|
|
127
|
+
return default
|
|
128
|
+
|
|
129
|
+
if isinstance(value, dict):
|
|
130
|
+
return value
|
|
131
|
+
|
|
132
|
+
logger.debug(
|
|
133
|
+
"invalid_jsonb_field_sanitized",
|
|
134
|
+
field_name=field_name,
|
|
135
|
+
type=type(value).__name__
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
return default
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task Planning Library
|
|
3
|
+
|
|
4
|
+
This package provides utilities for AI-powered task planning including:
|
|
5
|
+
- Modular workflow components (agents, hooks, cache, runner)
|
|
6
|
+
- Helper functions for resource discovery and preparation
|
|
7
|
+
- Agent factory for creating planning agents
|
|
8
|
+
- SSE message formatting for streaming responses
|
|
9
|
+
|
|
10
|
+
Architecture:
|
|
11
|
+
- models.py: Pydantic schemas for step outputs
|
|
12
|
+
- cache.py: Pre-fetch caching with TTL
|
|
13
|
+
- agents.py: Agent factory functions
|
|
14
|
+
- hooks.py: Pre/post validation hooks
|
|
15
|
+
- workflow.py: Workflow factory
|
|
16
|
+
- runner.py: Workflow execution with streaming
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from .helpers import (
|
|
20
|
+
make_json_serializable,
|
|
21
|
+
save_planning_prompt_debug,
|
|
22
|
+
format_sse_message,
|
|
23
|
+
)
|
|
24
|
+
from .agent_factory import create_planning_agent
|
|
25
|
+
|
|
26
|
+
# New modular API
|
|
27
|
+
from .cache import (
|
|
28
|
+
get_cached_prefetch,
|
|
29
|
+
set_cached_prefetch,
|
|
30
|
+
invalidate_prefetch_cache,
|
|
31
|
+
clear_prefetch_cache,
|
|
32
|
+
get_prefetch_cache,
|
|
33
|
+
PrefetchCache,
|
|
34
|
+
)
|
|
35
|
+
from .models import (
|
|
36
|
+
TaskAnalysisOutput,
|
|
37
|
+
ResourceDiscoveryOutput,
|
|
38
|
+
FastSelectionOutput,
|
|
39
|
+
CostEstimationOutput,
|
|
40
|
+
validate_resource_discovery,
|
|
41
|
+
)
|
|
42
|
+
from .agents import (
|
|
43
|
+
create_analysis_and_selection_agent,
|
|
44
|
+
create_plan_generation_agent,
|
|
45
|
+
create_fast_selection_agent,
|
|
46
|
+
create_task_analysis_agent,
|
|
47
|
+
create_cost_estimation_agent,
|
|
48
|
+
build_prefetch_tools,
|
|
49
|
+
build_search_tools,
|
|
50
|
+
)
|
|
51
|
+
from .hooks import (
|
|
52
|
+
validate_task_input,
|
|
53
|
+
validate_prefetch_context,
|
|
54
|
+
validate_step1_output,
|
|
55
|
+
validate_step2_output,
|
|
56
|
+
InputValidationError,
|
|
57
|
+
OutputValidationError,
|
|
58
|
+
EntityNotFoundError,
|
|
59
|
+
HallucinatedIdError,
|
|
60
|
+
)
|
|
61
|
+
from .workflow import (
|
|
62
|
+
create_planning_workflow,
|
|
63
|
+
create_fast_planning_workflow,
|
|
64
|
+
create_workflow_with_config,
|
|
65
|
+
WorkflowConfig,
|
|
66
|
+
get_litellm_config,
|
|
67
|
+
create_model,
|
|
68
|
+
prefetch_resources,
|
|
69
|
+
)
|
|
70
|
+
from .runner import (
|
|
71
|
+
run_workflow_stream,
|
|
72
|
+
run_fast_workflow_stream,
|
|
73
|
+
execute_step,
|
|
74
|
+
extract_json_from_content,
|
|
75
|
+
STEP_DESCRIPTIONS,
|
|
76
|
+
STEP_STAGE_NAMES,
|
|
77
|
+
STEP_PROGRESS_MAP,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
__all__ = [
|
|
81
|
+
# Legacy helpers
|
|
82
|
+
"make_json_serializable",
|
|
83
|
+
"save_planning_prompt_debug",
|
|
84
|
+
"format_sse_message",
|
|
85
|
+
"create_planning_agent",
|
|
86
|
+
|
|
87
|
+
# Cache
|
|
88
|
+
"get_cached_prefetch",
|
|
89
|
+
"set_cached_prefetch",
|
|
90
|
+
"invalidate_prefetch_cache",
|
|
91
|
+
"clear_prefetch_cache",
|
|
92
|
+
"get_prefetch_cache",
|
|
93
|
+
"PrefetchCache",
|
|
94
|
+
|
|
95
|
+
# Models
|
|
96
|
+
"TaskAnalysisOutput",
|
|
97
|
+
"ResourceDiscoveryOutput",
|
|
98
|
+
"FastSelectionOutput",
|
|
99
|
+
"CostEstimationOutput",
|
|
100
|
+
"validate_resource_discovery",
|
|
101
|
+
|
|
102
|
+
# Agents
|
|
103
|
+
"create_analysis_and_selection_agent",
|
|
104
|
+
"create_plan_generation_agent",
|
|
105
|
+
"create_fast_selection_agent",
|
|
106
|
+
"create_task_analysis_agent",
|
|
107
|
+
"create_cost_estimation_agent",
|
|
108
|
+
"build_prefetch_tools",
|
|
109
|
+
"build_search_tools",
|
|
110
|
+
|
|
111
|
+
# Hooks
|
|
112
|
+
"validate_task_input",
|
|
113
|
+
"validate_prefetch_context",
|
|
114
|
+
"validate_step1_output",
|
|
115
|
+
"validate_step2_output",
|
|
116
|
+
"InputValidationError",
|
|
117
|
+
"OutputValidationError",
|
|
118
|
+
"EntityNotFoundError",
|
|
119
|
+
"HallucinatedIdError",
|
|
120
|
+
|
|
121
|
+
# Workflow
|
|
122
|
+
"create_planning_workflow",
|
|
123
|
+
"create_fast_planning_workflow",
|
|
124
|
+
"create_workflow_with_config",
|
|
125
|
+
"WorkflowConfig",
|
|
126
|
+
"get_litellm_config",
|
|
127
|
+
"create_model",
|
|
128
|
+
"prefetch_resources",
|
|
129
|
+
|
|
130
|
+
# Runner
|
|
131
|
+
"run_workflow_stream",
|
|
132
|
+
"run_fast_workflow_stream",
|
|
133
|
+
"execute_step",
|
|
134
|
+
"extract_json_from_content",
|
|
135
|
+
"STEP_DESCRIPTIONS",
|
|
136
|
+
"STEP_STAGE_NAMES",
|
|
137
|
+
"STEP_PROGRESS_MAP",
|
|
138
|
+
]
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task Planning Agent Factory
|
|
3
|
+
"""
|
|
4
|
+
from typing import Optional, Callable
|
|
5
|
+
from sqlalchemy.orm import Session
|
|
6
|
+
import structlog
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
from agno.agent import Agent
|
|
10
|
+
from agno.models.litellm import LiteLLM
|
|
11
|
+
from control_plane_api.app.models.task_planning import TaskPlanResponse
|
|
12
|
+
from control_plane_api.app.lib.planning_tools import (
|
|
13
|
+
AgentsContextTools,
|
|
14
|
+
TeamsContextTools,
|
|
15
|
+
EnvironmentsContextTools,
|
|
16
|
+
ResourcesContextTools,
|
|
17
|
+
KnowledgeContextTools,
|
|
18
|
+
)
|
|
19
|
+
from control_plane_api.app.lib.planning_tools.context_graph_tools import ContextGraphPlanningTools
|
|
20
|
+
|
|
21
|
+
logger = structlog.get_logger()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def create_planning_agent(
|
|
25
|
+
organization_id: Optional[str] = None,
|
|
26
|
+
db: Optional[Session] = None,
|
|
27
|
+
api_token: str = None,
|
|
28
|
+
tool_hook: Optional[Callable] = None,
|
|
29
|
+
quick_mode: bool = False
|
|
30
|
+
) -> Agent:
|
|
31
|
+
"""
|
|
32
|
+
Create an Agno agent for task planning using LiteLLM with context tools
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
organization_id: Optional organization ID for filtering resources
|
|
36
|
+
db: Database session to pass to tools
|
|
37
|
+
api_token: API token for accessing organizational knowledge (required)
|
|
38
|
+
tool_hook: Optional hook to capture tool executions for streaming
|
|
39
|
+
quick_mode: If True, use faster, cheaper model for quick planning (Haiku instead of Sonnet)
|
|
40
|
+
"""
|
|
41
|
+
# Get LiteLLM configuration
|
|
42
|
+
litellm_api_url = (
|
|
43
|
+
os.getenv("LITELLM_API_URL") or
|
|
44
|
+
os.getenv("LITELLM_API_BASE") or
|
|
45
|
+
"https://llm-proxy.kubiya.ai"
|
|
46
|
+
).strip()
|
|
47
|
+
|
|
48
|
+
litellm_api_key = os.getenv("LITELLM_API_KEY", "").strip()
|
|
49
|
+
|
|
50
|
+
if not litellm_api_key:
|
|
51
|
+
raise ValueError("LITELLM_API_KEY environment variable not set")
|
|
52
|
+
|
|
53
|
+
# Use same model for both modes (Sonnet 4)
|
|
54
|
+
# Note: quick_mode parameter kept for future use if needed
|
|
55
|
+
model = os.getenv("LITELLM_DEFAULT_MODEL", "kubiya/claude-sonnet-4").strip()
|
|
56
|
+
logger.info("creating_planning_agent", model=model, quick_mode=quick_mode)
|
|
57
|
+
|
|
58
|
+
logger.info(
|
|
59
|
+
"creating_agno_planning_agent_with_tools",
|
|
60
|
+
litellm_api_url=litellm_api_url,
|
|
61
|
+
model=model,
|
|
62
|
+
has_api_key=bool(litellm_api_key),
|
|
63
|
+
organization_id=organization_id,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Initialize context tools with database session
|
|
67
|
+
# NOTE: Keep agents_tools and teams_tools for backward compatibility,
|
|
68
|
+
# but planning agent should primarily use context_graph_tools for intelligent discovery
|
|
69
|
+
agents_tools = AgentsContextTools(db=db, organization_id=organization_id)
|
|
70
|
+
teams_tools = TeamsContextTools(db=db, organization_id=organization_id)
|
|
71
|
+
environments_tools = EnvironmentsContextTools(db=db, organization_id=organization_id)
|
|
72
|
+
resources_tools = ResourcesContextTools(db=db, organization_id=organization_id)
|
|
73
|
+
knowledge_tools = KnowledgeContextTools(db=db, organization_id=organization_id, api_token=api_token)
|
|
74
|
+
|
|
75
|
+
# NEW: Add context graph tools for intelligent resource discovery
|
|
76
|
+
context_graph_tools = ContextGraphPlanningTools(
|
|
77
|
+
db=db,
|
|
78
|
+
organization_id=organization_id,
|
|
79
|
+
api_token=api_token
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Build tools list with context graph tools FIRST (higher priority for tool-based discovery)
|
|
83
|
+
tools_list = [
|
|
84
|
+
context_graph_tools, # Primary discovery method via context graph
|
|
85
|
+
agents_tools, # Fallback for direct agent queries
|
|
86
|
+
teams_tools, # Fallback for direct team queries
|
|
87
|
+
environments_tools,
|
|
88
|
+
resources_tools,
|
|
89
|
+
knowledge_tools, # Include knowledge tools for comprehensive planning
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
logger.info("planning_agent_tools_initialized",
|
|
93
|
+
tools_count=len(tools_list),
|
|
94
|
+
has_context_graph=True,
|
|
95
|
+
has_knowledge=True,
|
|
96
|
+
has_api_token=bool(api_token))
|
|
97
|
+
|
|
98
|
+
# Create fast planning agent optimized for speed
|
|
99
|
+
planning_agent = Agent(
|
|
100
|
+
name="Task Planning Agent",
|
|
101
|
+
role="Expert project manager and task planner",
|
|
102
|
+
model=LiteLLM(
|
|
103
|
+
id=f"openai/{model}",
|
|
104
|
+
api_base=litellm_api_url,
|
|
105
|
+
api_key=litellm_api_key,
|
|
106
|
+
request_params={
|
|
107
|
+
"timeout": 120, # 2 minute timeout for LiteLLM requests
|
|
108
|
+
},
|
|
109
|
+
),
|
|
110
|
+
# NOTE: output_schema blocks reasoning streams! Removed to enable real-time streaming.
|
|
111
|
+
# We'll parse the JSON response manually after streaming completes.
|
|
112
|
+
# output_schema=TaskPlanResponse,
|
|
113
|
+
tools=tools_list,
|
|
114
|
+
tool_hooks=[tool_hook] if tool_hook else None, # FIX: Agno expects tool_hooks (plural) as a list
|
|
115
|
+
instructions=[
|
|
116
|
+
"You are a CONCISE task planning analyst producing KEY INSIGHTS for structured output conversion.",
|
|
117
|
+
"",
|
|
118
|
+
"**CRITICAL - Be CONCISE:**",
|
|
119
|
+
"- You are Agent 1 in a two-agent workflow - provide KEY POINTS ONLY",
|
|
120
|
+
"- Agent 2 will convert your analysis to JSON - keep it SHORT and FOCUSED",
|
|
121
|
+
"- DO NOT produce verbose reasoning - focus on ESSENTIAL insights",
|
|
122
|
+
"- DO NOT return JSON - return brief analysis that answers: WHO, WHAT, HOW, WHEN",
|
|
123
|
+
"",
|
|
124
|
+
"**Required Analysis (Keep Each Section Brief):**",
|
|
125
|
+
"",
|
|
126
|
+
"1. **Task Summary** (2-3 sentences):",
|
|
127
|
+
" - What needs to be done and why",
|
|
128
|
+
"",
|
|
129
|
+
"2. **Recommended Agent/Team** (1-2 sentences):",
|
|
130
|
+
" - Which agent/team should handle this",
|
|
131
|
+
" - Key reason: relevant skills + available secrets/env_vars",
|
|
132
|
+
"",
|
|
133
|
+
"3. **Complexity Assessment** (1 sentence):",
|
|
134
|
+
" - Story points (1-20) and justification",
|
|
135
|
+
"",
|
|
136
|
+
"4. **Task Breakdown** (List format):",
|
|
137
|
+
" - Task 1: [title] - [what to do] - [which skills/secrets to use]",
|
|
138
|
+
" - Task 2: [title] - [what to do] - [dependencies: task 1]",
|
|
139
|
+
" - Keep each task description to 1-2 sentences max",
|
|
140
|
+
"",
|
|
141
|
+
"5. **Prerequisites** (bullet list if any):",
|
|
142
|
+
" - Required setup or dependencies",
|
|
143
|
+
"",
|
|
144
|
+
"6. **Risks** (bullet list if any):",
|
|
145
|
+
" - Key risks to be aware of",
|
|
146
|
+
"",
|
|
147
|
+
"**Available Tools** (use sparingly):",
|
|
148
|
+
"- list_agents() - Get available agents",
|
|
149
|
+
"- get_agent_details(id) - Get specific agent info",
|
|
150
|
+
"- query_knowledge(q) - Search knowledge base",
|
|
151
|
+
"",
|
|
152
|
+
"**Agent Context Format:**",
|
|
153
|
+
"- Agent skills: agent['skills'] array",
|
|
154
|
+
"- Secrets: agent['execution_environment']['secrets'] keys",
|
|
155
|
+
"- Env vars: agent['execution_environment']['env_vars'] keys",
|
|
156
|
+
"",
|
|
157
|
+
"**Example Output Format:**",
|
|
158
|
+
"```",
|
|
159
|
+
"Task: Deploy auth service to production",
|
|
160
|
+
"",
|
|
161
|
+
"Recommended: DevOps Agent",
|
|
162
|
+
"Reason: Has aws_ec2 skill and AWS_ACCESS_KEY_ID secret",
|
|
163
|
+
"",
|
|
164
|
+
"Complexity: 8 story points (multi-step deployment)",
|
|
165
|
+
"",
|
|
166
|
+
"Tasks:",
|
|
167
|
+
"1. Validate deployment config - check YAML syntax - uses kubectl skill",
|
|
168
|
+
"2. Deploy to staging - run kubectl apply - uses KUBECONFIG env var - depends on task 1",
|
|
169
|
+
"3. Run smoke tests - verify endpoints - uses curl",
|
|
170
|
+
"4. Promote to prod - kubectl apply to prod namespace - depends on tasks 2,3",
|
|
171
|
+
"",
|
|
172
|
+
"Prerequisites:",
|
|
173
|
+
"- Valid kubeconfig for target cluster",
|
|
174
|
+
"",
|
|
175
|
+
"Risks:",
|
|
176
|
+
"- Downtime during deployment",
|
|
177
|
+
"```",
|
|
178
|
+
"",
|
|
179
|
+
"REMEMBER: Keep it SHORT. Agent 2 handles JSON structuring.",
|
|
180
|
+
],
|
|
181
|
+
description="Fast task planner for AI agent teams",
|
|
182
|
+
markdown=False,
|
|
183
|
+
add_history_to_context=False, # Disable for speed
|
|
184
|
+
retries=3, # Increased retries for reliability
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
return planning_agent
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def create_structuring_agent() -> Agent:
|
|
191
|
+
"""
|
|
192
|
+
Create a fast structuring agent that converts reasoning output to structured JSON.
|
|
193
|
+
|
|
194
|
+
This is Agent 2 in the two-agent workflow:
|
|
195
|
+
1. Agent 1 (planning_agent) streams reasoning/thinking
|
|
196
|
+
2. Agent 2 (structuring_agent) converts reasoning to TaskPlanResponse
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
Agent configured with output_schema for structured JSON output
|
|
200
|
+
"""
|
|
201
|
+
# Get LiteLLM configuration
|
|
202
|
+
litellm_api_url = (
|
|
203
|
+
os.getenv("LITELLM_API_URL") or
|
|
204
|
+
os.getenv("LITELLM_API_BASE") or
|
|
205
|
+
"https://llm-proxy.kubiya.ai"
|
|
206
|
+
).strip()
|
|
207
|
+
|
|
208
|
+
litellm_api_key = os.getenv("LITELLM_API_KEY", "").strip()
|
|
209
|
+
|
|
210
|
+
if not litellm_api_key:
|
|
211
|
+
raise ValueError("LITELLM_API_KEY environment variable not set")
|
|
212
|
+
|
|
213
|
+
# Use same model as Agent 1 for structuring (Sonnet 4)
|
|
214
|
+
# Can be overridden with LITELLM_STRUCTURING_MODEL env var if Haiku is available
|
|
215
|
+
model = os.getenv("LITELLM_STRUCTURING_MODEL", os.getenv("LITELLM_DEFAULT_MODEL", "kubiya/claude-sonnet-4")).strip()
|
|
216
|
+
logger.info("creating_structuring_agent", model=model)
|
|
217
|
+
|
|
218
|
+
structuring_agent = Agent(
|
|
219
|
+
name="Task Structuring Agent",
|
|
220
|
+
role="Expert at converting task planning analysis into structured JSON",
|
|
221
|
+
model=LiteLLM(
|
|
222
|
+
id=f"openai/{model}",
|
|
223
|
+
api_base=litellm_api_url,
|
|
224
|
+
api_key=litellm_api_key,
|
|
225
|
+
request_params={
|
|
226
|
+
"timeout": 60, # 1 minute timeout for structuring
|
|
227
|
+
},
|
|
228
|
+
),
|
|
229
|
+
output_schema=TaskPlanResponse, # IMPORTANT: This enforces structured output
|
|
230
|
+
tools=[], # No tools needed for structuring
|
|
231
|
+
instructions=[
|
|
232
|
+
"You are a task structuring agent that converts planning analysis into structured JSON.",
|
|
233
|
+
"",
|
|
234
|
+
"**Your Job:**",
|
|
235
|
+
"- You will receive detailed planning analysis and reasoning from another agent",
|
|
236
|
+
"- Extract all the key information from that analysis",
|
|
237
|
+
"- Convert it into a properly structured TaskPlanResponse JSON object",
|
|
238
|
+
"",
|
|
239
|
+
"**CRITICAL Requirements:**",
|
|
240
|
+
"- You MUST return valid JSON matching the TaskPlanResponse schema",
|
|
241
|
+
"- DO NOT add any reasoning, explanations, or markdown",
|
|
242
|
+
"- ONLY return the structured JSON object",
|
|
243
|
+
"- Ensure all required fields are populated with data from the analysis",
|
|
244
|
+
"",
|
|
245
|
+
"**Task Breakdown Fields:**",
|
|
246
|
+
"- Extract tasks with: id, title, description, details, test_strategy, priority, dependencies",
|
|
247
|
+
"- Extract skills_to_use, env_vars_to_use, secrets_to_use, knowledge_references from the analysis",
|
|
248
|
+
"- Ensure task IDs are sequential integers starting from 1",
|
|
249
|
+
"- Set dependencies as arrays of task IDs ([] if no dependencies)",
|
|
250
|
+
"",
|
|
251
|
+
"**If Information is Missing:**",
|
|
252
|
+
"- Use reasonable defaults based on the task description",
|
|
253
|
+
"- Set array fields to [] if not specified (never null)",
|
|
254
|
+
"- Provide basic but complete task breakdowns even if analysis is sparse",
|
|
255
|
+
],
|
|
256
|
+
description="Fast structuring agent for converting analysis to JSON",
|
|
257
|
+
markdown=False,
|
|
258
|
+
add_history_to_context=False,
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
logger.info("structuring_agent_created", model=model)
|
|
262
|
+
return structuring_agent
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def create_planning_workflow(
|
|
266
|
+
organization_id: Optional[str] = None,
|
|
267
|
+
db: Optional[Session] = None,
|
|
268
|
+
api_token: str = None,
|
|
269
|
+
tool_hook: Optional[Callable] = None,
|
|
270
|
+
) -> "Workflow":
|
|
271
|
+
"""
|
|
272
|
+
Create an Agno Workflow that chains the reasoning agent → structuring agent.
|
|
273
|
+
|
|
274
|
+
This implements the proper two-agent workflow:
|
|
275
|
+
1. Agent 1 (reasoning): Analyzes task, uses tools, streams thinking
|
|
276
|
+
2. Agent 2 (structuring): Converts analysis to TaskPlanResponse JSON
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
organization_id: Optional organization ID for filtering resources
|
|
280
|
+
db: Database session to pass to tools
|
|
281
|
+
api_token: API token for accessing organizational knowledge
|
|
282
|
+
tool_hook: Optional hook to capture tool executions for streaming
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
Workflow with two steps: reasoning → structuring
|
|
286
|
+
"""
|
|
287
|
+
from agno.workflow import Workflow
|
|
288
|
+
|
|
289
|
+
# Create Agent 1 (reasoning with tools)
|
|
290
|
+
reasoning_agent = create_planning_agent(
|
|
291
|
+
organization_id=organization_id,
|
|
292
|
+
db=db,
|
|
293
|
+
api_token=api_token,
|
|
294
|
+
tool_hook=tool_hook
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
# Create Agent 2 (structuring without tools)
|
|
298
|
+
structuring_agent = create_structuring_agent()
|
|
299
|
+
|
|
300
|
+
# Chain them in a workflow
|
|
301
|
+
workflow = Workflow(
|
|
302
|
+
name="Task Planning Workflow",
|
|
303
|
+
steps=[reasoning_agent, structuring_agent],
|
|
304
|
+
description="Two-step workflow: analyze task → structure output"
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
logger.info("planning_workflow_created", steps=2)
|
|
308
|
+
return workflow
|