kubiya-control-plane-api 0.1.0__py3-none-any.whl → 0.3.4__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.

Potentially problematic release.


This version of kubiya-control-plane-api might be problematic. Click here for more details.

Files changed (185) hide show
  1. control_plane_api/README.md +266 -0
  2. control_plane_api/__init__.py +0 -0
  3. control_plane_api/__version__.py +1 -0
  4. control_plane_api/alembic/README +1 -0
  5. control_plane_api/alembic/env.py +98 -0
  6. control_plane_api/alembic/script.py.mako +28 -0
  7. control_plane_api/alembic/versions/1382bec74309_initial_migration_with_all_models.py +251 -0
  8. control_plane_api/alembic/versions/1f54bc2a37e3_add_analytics_tables.py +162 -0
  9. control_plane_api/alembic/versions/2e4cb136dc10_rename_toolset_ids_to_skill_ids_in_teams.py +30 -0
  10. control_plane_api/alembic/versions/31cd69a644ce_add_skill_templates_table.py +28 -0
  11. control_plane_api/alembic/versions/89e127caa47d_add_jobs_and_job_executions_tables.py +161 -0
  12. control_plane_api/alembic/versions/add_llm_models_table.py +51 -0
  13. control_plane_api/alembic/versions/b0e10697f212_add_runtime_column_to_teams_simple.py +42 -0
  14. control_plane_api/alembic/versions/ce43b24b63bf_add_execution_trigger_source_and_fix_.py +155 -0
  15. control_plane_api/alembic/versions/d4eaf16e3f8d_rename_toolsets_to_skills.py +84 -0
  16. control_plane_api/alembic/versions/efa2dc427da1_rename_metadata_to_custom_metadata.py +32 -0
  17. control_plane_api/alembic/versions/f973b431d1ce_add_workflow_executor_to_skill_types.py +44 -0
  18. control_plane_api/alembic.ini +148 -0
  19. control_plane_api/api/index.py +12 -0
  20. control_plane_api/app/__init__.py +11 -0
  21. control_plane_api/app/activities/__init__.py +20 -0
  22. control_plane_api/app/activities/agent_activities.py +379 -0
  23. control_plane_api/app/activities/team_activities.py +410 -0
  24. control_plane_api/app/activities/temporal_cloud_activities.py +577 -0
  25. control_plane_api/app/config/__init__.py +35 -0
  26. control_plane_api/app/config/api_config.py +354 -0
  27. control_plane_api/app/config/model_pricing.py +318 -0
  28. control_plane_api/app/config.py +95 -0
  29. control_plane_api/app/database.py +135 -0
  30. control_plane_api/app/exceptions.py +408 -0
  31. control_plane_api/app/lib/__init__.py +11 -0
  32. control_plane_api/app/lib/job_executor.py +312 -0
  33. control_plane_api/app/lib/kubiya_client.py +235 -0
  34. control_plane_api/app/lib/litellm_pricing.py +166 -0
  35. control_plane_api/app/lib/planning_tools/__init__.py +22 -0
  36. control_plane_api/app/lib/planning_tools/agents.py +155 -0
  37. control_plane_api/app/lib/planning_tools/base.py +189 -0
  38. control_plane_api/app/lib/planning_tools/environments.py +214 -0
  39. control_plane_api/app/lib/planning_tools/resources.py +240 -0
  40. control_plane_api/app/lib/planning_tools/teams.py +198 -0
  41. control_plane_api/app/lib/policy_enforcer_client.py +939 -0
  42. control_plane_api/app/lib/redis_client.py +436 -0
  43. control_plane_api/app/lib/supabase.py +71 -0
  44. control_plane_api/app/lib/temporal_client.py +138 -0
  45. control_plane_api/app/lib/validation/__init__.py +20 -0
  46. control_plane_api/app/lib/validation/runtime_validation.py +287 -0
  47. control_plane_api/app/main.py +128 -0
  48. control_plane_api/app/middleware/__init__.py +8 -0
  49. control_plane_api/app/middleware/auth.py +513 -0
  50. control_plane_api/app/middleware/exception_handler.py +267 -0
  51. control_plane_api/app/middleware/rate_limiting.py +384 -0
  52. control_plane_api/app/middleware/request_id.py +202 -0
  53. control_plane_api/app/models/__init__.py +27 -0
  54. control_plane_api/app/models/agent.py +79 -0
  55. control_plane_api/app/models/analytics.py +206 -0
  56. control_plane_api/app/models/associations.py +81 -0
  57. control_plane_api/app/models/environment.py +63 -0
  58. control_plane_api/app/models/execution.py +93 -0
  59. control_plane_api/app/models/job.py +179 -0
  60. control_plane_api/app/models/llm_model.py +75 -0
  61. control_plane_api/app/models/presence.py +49 -0
  62. control_plane_api/app/models/project.py +47 -0
  63. control_plane_api/app/models/session.py +38 -0
  64. control_plane_api/app/models/team.py +66 -0
  65. control_plane_api/app/models/workflow.py +55 -0
  66. control_plane_api/app/policies/README.md +121 -0
  67. control_plane_api/app/policies/approved_users.rego +62 -0
  68. control_plane_api/app/policies/business_hours.rego +51 -0
  69. control_plane_api/app/policies/rate_limiting.rego +100 -0
  70. control_plane_api/app/policies/tool_restrictions.rego +86 -0
  71. control_plane_api/app/routers/__init__.py +4 -0
  72. control_plane_api/app/routers/agents.py +364 -0
  73. control_plane_api/app/routers/agents_v2.py +1260 -0
  74. control_plane_api/app/routers/analytics.py +1014 -0
  75. control_plane_api/app/routers/context_manager.py +562 -0
  76. control_plane_api/app/routers/environment_context.py +270 -0
  77. control_plane_api/app/routers/environments.py +715 -0
  78. control_plane_api/app/routers/execution_environment.py +517 -0
  79. control_plane_api/app/routers/executions.py +1911 -0
  80. control_plane_api/app/routers/health.py +92 -0
  81. control_plane_api/app/routers/health_v2.py +326 -0
  82. control_plane_api/app/routers/integrations.py +274 -0
  83. control_plane_api/app/routers/jobs.py +1344 -0
  84. control_plane_api/app/routers/models.py +82 -0
  85. control_plane_api/app/routers/models_v2.py +361 -0
  86. control_plane_api/app/routers/policies.py +639 -0
  87. control_plane_api/app/routers/presence.py +234 -0
  88. control_plane_api/app/routers/projects.py +902 -0
  89. control_plane_api/app/routers/runners.py +379 -0
  90. control_plane_api/app/routers/runtimes.py +172 -0
  91. control_plane_api/app/routers/secrets.py +155 -0
  92. control_plane_api/app/routers/skills.py +1001 -0
  93. control_plane_api/app/routers/skills_definitions.py +140 -0
  94. control_plane_api/app/routers/task_planning.py +1256 -0
  95. control_plane_api/app/routers/task_queues.py +654 -0
  96. control_plane_api/app/routers/team_context.py +270 -0
  97. control_plane_api/app/routers/teams.py +1400 -0
  98. control_plane_api/app/routers/worker_queues.py +1545 -0
  99. control_plane_api/app/routers/workers.py +935 -0
  100. control_plane_api/app/routers/workflows.py +204 -0
  101. control_plane_api/app/runtimes/__init__.py +6 -0
  102. control_plane_api/app/runtimes/validation.py +344 -0
  103. control_plane_api/app/schemas/job_schemas.py +295 -0
  104. control_plane_api/app/services/__init__.py +1 -0
  105. control_plane_api/app/services/agno_service.py +619 -0
  106. control_plane_api/app/services/litellm_service.py +190 -0
  107. control_plane_api/app/services/policy_service.py +525 -0
  108. control_plane_api/app/services/temporal_cloud_provisioning.py +150 -0
  109. control_plane_api/app/skills/__init__.py +44 -0
  110. control_plane_api/app/skills/base.py +229 -0
  111. control_plane_api/app/skills/business_intelligence.py +189 -0
  112. control_plane_api/app/skills/data_visualization.py +154 -0
  113. control_plane_api/app/skills/docker.py +104 -0
  114. control_plane_api/app/skills/file_generation.py +94 -0
  115. control_plane_api/app/skills/file_system.py +110 -0
  116. control_plane_api/app/skills/python.py +92 -0
  117. control_plane_api/app/skills/registry.py +65 -0
  118. control_plane_api/app/skills/shell.py +102 -0
  119. control_plane_api/app/skills/workflow_executor.py +469 -0
  120. control_plane_api/app/utils/workflow_executor.py +354 -0
  121. control_plane_api/app/workflows/__init__.py +11 -0
  122. control_plane_api/app/workflows/agent_execution.py +507 -0
  123. control_plane_api/app/workflows/agent_execution_with_skills.py +222 -0
  124. control_plane_api/app/workflows/namespace_provisioning.py +326 -0
  125. control_plane_api/app/workflows/team_execution.py +399 -0
  126. control_plane_api/scripts/seed_models.py +239 -0
  127. control_plane_api/worker/__init__.py +0 -0
  128. control_plane_api/worker/activities/__init__.py +0 -0
  129. control_plane_api/worker/activities/agent_activities.py +1241 -0
  130. control_plane_api/worker/activities/approval_activities.py +234 -0
  131. control_plane_api/worker/activities/runtime_activities.py +388 -0
  132. control_plane_api/worker/activities/skill_activities.py +267 -0
  133. control_plane_api/worker/activities/team_activities.py +1217 -0
  134. control_plane_api/worker/config/__init__.py +31 -0
  135. control_plane_api/worker/config/worker_config.py +275 -0
  136. control_plane_api/worker/control_plane_client.py +529 -0
  137. control_plane_api/worker/examples/analytics_integration_example.py +362 -0
  138. control_plane_api/worker/models/__init__.py +1 -0
  139. control_plane_api/worker/models/inputs.py +89 -0
  140. control_plane_api/worker/runtimes/__init__.py +31 -0
  141. control_plane_api/worker/runtimes/base.py +789 -0
  142. control_plane_api/worker/runtimes/claude_code_runtime.py +1443 -0
  143. control_plane_api/worker/runtimes/default_runtime.py +617 -0
  144. control_plane_api/worker/runtimes/factory.py +173 -0
  145. control_plane_api/worker/runtimes/validation.py +93 -0
  146. control_plane_api/worker/services/__init__.py +1 -0
  147. control_plane_api/worker/services/agent_executor.py +422 -0
  148. control_plane_api/worker/services/agent_executor_v2.py +383 -0
  149. control_plane_api/worker/services/analytics_collector.py +457 -0
  150. control_plane_api/worker/services/analytics_service.py +464 -0
  151. control_plane_api/worker/services/approval_tools.py +310 -0
  152. control_plane_api/worker/services/approval_tools_agno.py +207 -0
  153. control_plane_api/worker/services/cancellation_manager.py +177 -0
  154. control_plane_api/worker/services/data_visualization.py +827 -0
  155. control_plane_api/worker/services/jira_tools.py +257 -0
  156. control_plane_api/worker/services/runtime_analytics.py +328 -0
  157. control_plane_api/worker/services/session_service.py +194 -0
  158. control_plane_api/worker/services/skill_factory.py +175 -0
  159. control_plane_api/worker/services/team_executor.py +574 -0
  160. control_plane_api/worker/services/team_executor_v2.py +465 -0
  161. control_plane_api/worker/services/workflow_executor_tools.py +1418 -0
  162. control_plane_api/worker/tests/__init__.py +1 -0
  163. control_plane_api/worker/tests/e2e/__init__.py +0 -0
  164. control_plane_api/worker/tests/e2e/test_execution_flow.py +571 -0
  165. control_plane_api/worker/tests/integration/__init__.py +0 -0
  166. control_plane_api/worker/tests/integration/test_control_plane_integration.py +308 -0
  167. control_plane_api/worker/tests/unit/__init__.py +0 -0
  168. control_plane_api/worker/tests/unit/test_control_plane_client.py +401 -0
  169. control_plane_api/worker/utils/__init__.py +1 -0
  170. control_plane_api/worker/utils/chunk_batcher.py +305 -0
  171. control_plane_api/worker/utils/retry_utils.py +60 -0
  172. control_plane_api/worker/utils/streaming_utils.py +373 -0
  173. control_plane_api/worker/worker.py +753 -0
  174. control_plane_api/worker/workflows/__init__.py +0 -0
  175. control_plane_api/worker/workflows/agent_execution.py +589 -0
  176. control_plane_api/worker/workflows/team_execution.py +429 -0
  177. kubiya_control_plane_api-0.3.4.dist-info/METADATA +229 -0
  178. kubiya_control_plane_api-0.3.4.dist-info/RECORD +182 -0
  179. kubiya_control_plane_api-0.3.4.dist-info/entry_points.txt +2 -0
  180. kubiya_control_plane_api-0.3.4.dist-info/top_level.txt +1 -0
  181. kubiya_control_plane_api-0.1.0.dist-info/METADATA +0 -66
  182. kubiya_control_plane_api-0.1.0.dist-info/RECORD +0 -5
  183. kubiya_control_plane_api-0.1.0.dist-info/top_level.txt +0 -1
  184. {kubiya_control_plane_api-0.1.0.dist-info/licenses → control_plane_api}/LICENSE +0 -0
  185. {kubiya_control_plane_api-0.1.0.dist-info → kubiya_control_plane_api-0.3.4.dist-info}/WHEEL +0 -0
@@ -0,0 +1,150 @@
1
+ """
2
+ Temporal Cloud Provisioning Service
3
+
4
+ This service handles provisioning Temporal Cloud namespaces via the
5
+ Vercel serverless function (api/provision-namespace.go).
6
+ """
7
+
8
+ import os
9
+ import httpx
10
+ import structlog
11
+ from typing import Dict, Any
12
+
13
+ logger = structlog.get_logger()
14
+
15
+
16
+ class TemporalCloudProvisioningService:
17
+ """Service for provisioning Temporal Cloud namespaces"""
18
+
19
+ def __init__(self):
20
+ # Get the Vercel function URL from environment
21
+ self.proxy_url = os.getenv("TEMPORAL_CLOUD_PROXY_URL")
22
+ if not self.proxy_url:
23
+ # If not set, use the Vercel production URL
24
+ self.proxy_url = "https://temporal-cloud-proxy.vercel.app/api/provision-namespace"
25
+
26
+ # Get the admin token for authorization (will be checked when actually used)
27
+ self.admin_token = os.getenv("TEMPORAL_CLOUD_ADMIN_TOKEN")
28
+
29
+ async def provision_namespace_for_organization(
30
+ self,
31
+ organization_id: str,
32
+ organization_name: str,
33
+ region: str = "aws-us-east-1",
34
+ retention_days: int = 7,
35
+ ) -> Dict[str, Any]:
36
+ """
37
+ Provision a Temporal Cloud namespace for an organization.
38
+
39
+ Args:
40
+ organization_id: The organization ID
41
+ organization_name: The organization name
42
+ region: The Temporal Cloud region (default: aws-us-east-1)
43
+ retention_days: Number of days to retain workflow history (default: 7)
44
+
45
+ Returns:
46
+ Dictionary with:
47
+ - success: Boolean indicating if provisioning succeeded
48
+ - namespace_name: The provisioned namespace name
49
+ - namespace: Dictionary with namespace details
50
+ - already_exists: Boolean indicating if namespace already existed
51
+ - error: Error message if failed
52
+ - timeout: Boolean indicating if operation timed out
53
+ """
54
+ logger.info(
55
+ "provisioning_temporal_namespace",
56
+ organization_id=organization_id,
57
+ organization_name=organization_name,
58
+ region=region,
59
+ )
60
+
61
+ # Check if token is available
62
+ if not self.admin_token:
63
+ error_msg = "TEMPORAL_CLOUD_ADMIN_TOKEN environment variable is required but not set"
64
+ logger.error("temporal_cloud_token_missing", organization_id=organization_id)
65
+ return {
66
+ "success": False,
67
+ "error": error_msg,
68
+ "timeout": False,
69
+ }
70
+
71
+ try:
72
+ # Prepare the request
73
+ payload = {
74
+ "organization_id": organization_id,
75
+ "organization_name": organization_name,
76
+ "region": region,
77
+ "retention_days": retention_days,
78
+ }
79
+
80
+ headers = {
81
+ "Authorization": f"Bearer {self.admin_token}",
82
+ "Content-Type": "application/json",
83
+ }
84
+
85
+ # Call the Vercel function
86
+ async with httpx.AsyncClient(timeout=60.0) as client:
87
+ response = await client.post(
88
+ self.proxy_url,
89
+ json=payload,
90
+ headers=headers,
91
+ )
92
+
93
+ # Check response status
94
+ if response.status_code == 200:
95
+ result = response.json()
96
+ logger.info(
97
+ "namespace_provisioned_successfully",
98
+ organization_id=organization_id,
99
+ namespace_name=result.get("namespace_name"),
100
+ already_exists=result.get("already_exists", False),
101
+ )
102
+ return result
103
+ else:
104
+ error_msg = response.text
105
+ logger.error(
106
+ "namespace_provisioning_failed",
107
+ organization_id=organization_id,
108
+ status_code=response.status_code,
109
+ error=error_msg,
110
+ )
111
+ return {
112
+ "success": False,
113
+ "error": f"HTTP {response.status_code}: {error_msg}",
114
+ "timeout": False,
115
+ }
116
+
117
+ except httpx.TimeoutException as e:
118
+ logger.warning(
119
+ "namespace_provisioning_timeout",
120
+ organization_id=organization_id,
121
+ error=str(e),
122
+ )
123
+ return {
124
+ "success": False,
125
+ "error": "Provisioning timed out",
126
+ "timeout": True,
127
+ }
128
+ except Exception as e:
129
+ logger.error(
130
+ "namespace_provisioning_exception",
131
+ organization_id=organization_id,
132
+ error=str(e),
133
+ )
134
+ return {
135
+ "success": False,
136
+ "error": str(e),
137
+ "timeout": False,
138
+ }
139
+
140
+
141
+ # Global instance
142
+ _provisioning_service = None
143
+
144
+
145
+ def get_provisioning_service() -> TemporalCloudProvisioningService:
146
+ """Get the provisioning service singleton"""
147
+ global _provisioning_service
148
+ if _provisioning_service is None:
149
+ _provisioning_service = TemporalCloudProvisioningService()
150
+ return _provisioning_service
@@ -0,0 +1,44 @@
1
+ """
2
+ Skills Module
3
+
4
+ This module manages all available skills (OS-level capabilities) that can be
5
+ assigned to agents and teams. Each skill corresponds to a capability that agents
6
+ can use during execution (file system, shell, Docker, Python, etc.).
7
+
8
+ Skills are defined as Python classes that provide:
9
+ - Metadata (name, description, icon)
10
+ - Default configuration
11
+ - Validation logic
12
+ - Instantiation logic for the underlying framework
13
+ """
14
+
15
+ from .base import SkillDefinition, SkillType, SkillCategory, SkillRequirements, SkillVariant
16
+ from .registry import skill_registry, get_skill, get_all_skills, register_skill
17
+
18
+ # Import all skill definitions to auto-register them
19
+ from .file_system import FileSystemSkill
20
+ from .shell import ShellSkill
21
+ from .docker import DockerSkill
22
+ from .python import PythonSkill
23
+ from .file_generation import FileGenerationSkill
24
+ from .data_visualization import DataVisualizationSkill
25
+ from .workflow_executor import WorkflowExecutorSkill
26
+
27
+ __all__ = [
28
+ "SkillDefinition",
29
+ "SkillType",
30
+ "SkillCategory",
31
+ "SkillRequirements",
32
+ "SkillVariant",
33
+ "skill_registry",
34
+ "get_skill",
35
+ "get_all_skills",
36
+ "register_skill",
37
+ "FileSystemSkill",
38
+ "ShellSkill",
39
+ "DockerSkill",
40
+ "PythonSkill",
41
+ "FileGenerationSkill",
42
+ "DataVisualizationSkill",
43
+ "WorkflowExecutorSkill",
44
+ ]
@@ -0,0 +1,229 @@
1
+ """
2
+ Base classes for skill definitions
3
+ """
4
+ from typing import Dict, Any, List, Optional, Set
5
+ from enum import Enum
6
+ from pydantic import BaseModel, Field
7
+ from abc import ABC, abstractmethod
8
+ import platform
9
+
10
+
11
+ class SkillType(str, Enum):
12
+ """Supported skill types"""
13
+ FILE_SYSTEM = "file_system"
14
+ SHELL = "shell"
15
+ DOCKER = "docker"
16
+ PYTHON = "python"
17
+ FILE_GENERATION = "file_generation"
18
+ DATA_VISUALIZATION = "data_visualization"
19
+ SLEEP = "sleep"
20
+ WORKFLOW_EXECUTOR = "workflow_executor"
21
+ CUSTOM = "custom"
22
+
23
+
24
+ class SkillCategory(str, Enum):
25
+ """Skill categories for organization"""
26
+ COMMON = "common" # Frequently used, safe defaults
27
+ ADVANCED = "advanced" # Advanced features, require more privileges
28
+ SECURITY = "security" # Security-focused, restricted access
29
+ CUSTOM = "custom" # User-defined custom skills
30
+
31
+
32
+ class SkillRequirements(BaseModel):
33
+ """Runtime requirements for a skill"""
34
+ # Python packages required (will be checked/installed by worker)
35
+ python_packages: List[str] = Field(default_factory=list)
36
+
37
+ # System packages required (informational, worker should validate)
38
+ system_packages: List[str] = Field(default_factory=list)
39
+
40
+ # Supported operating systems (e.g., ["linux", "darwin", "windows"])
41
+ supported_os: Optional[List[str]] = None
42
+
43
+ # Minimum Python version (e.g., "3.10")
44
+ min_python_version: Optional[str] = None
45
+
46
+ # Environment variables required
47
+ required_env_vars: List[str] = Field(default_factory=list)
48
+
49
+ # External services/APIs required (informational)
50
+ external_dependencies: List[str] = Field(default_factory=list)
51
+
52
+ # Additional notes about requirements
53
+ notes: Optional[str] = None
54
+
55
+
56
+ class SkillVariant(BaseModel):
57
+ """A specific variant/preset of a skill"""
58
+ id: str
59
+ name: str
60
+ description: str
61
+ category: SkillCategory
62
+ configuration: Dict[str, Any]
63
+ badge: Optional[str] = None # e.g., "Safe", "Recommended", "Advanced"
64
+ icon: Optional[str] = None
65
+ is_default: bool = False
66
+
67
+
68
+ class SkillDefinition(ABC):
69
+ """
70
+ Base class for all skill definitions.
71
+
72
+ Each skill type should subclass this and implement the required methods.
73
+ This provides a clean interface for defining new skills.
74
+ """
75
+
76
+ @property
77
+ @abstractmethod
78
+ def type(self) -> SkillType:
79
+ """The type identifier for this skill"""
80
+ pass
81
+
82
+ @property
83
+ @abstractmethod
84
+ def name(self) -> str:
85
+ """Human-readable name"""
86
+ pass
87
+
88
+ @property
89
+ @abstractmethod
90
+ def description(self) -> str:
91
+ """Description of what this skill does"""
92
+ pass
93
+
94
+ @property
95
+ @abstractmethod
96
+ def icon(self) -> str:
97
+ """Icon name (Lucide or React Icons)"""
98
+ pass
99
+
100
+ @property
101
+ def icon_type(self) -> str:
102
+ """Icon type: 'lucide' or 'react-icon'"""
103
+ return "lucide"
104
+
105
+ @abstractmethod
106
+ def get_variants(self) -> List[SkillVariant]:
107
+ """
108
+ Get all predefined variants/presets for this skill.
109
+
110
+ Returns a list of variants with different configurations
111
+ (e.g., "Read Only", "Full Access", "Sandboxed")
112
+ """
113
+ pass
114
+
115
+ @abstractmethod
116
+ def validate_configuration(self, config: Dict[str, Any]) -> Dict[str, Any]:
117
+ """
118
+ Validate and normalize configuration.
119
+
120
+ Args:
121
+ config: Raw configuration dict
122
+
123
+ Returns:
124
+ Validated and normalized configuration
125
+
126
+ Raises:
127
+ ValueError: If configuration is invalid
128
+ """
129
+ pass
130
+
131
+ @abstractmethod
132
+ def get_default_configuration(self) -> Dict[str, Any]:
133
+ """Get the default configuration for this skill"""
134
+ pass
135
+
136
+ def get_framework_class_name(self) -> str:
137
+ """
138
+ Get the underlying framework tool class name.
139
+ This is used for instantiation during agent execution.
140
+
141
+ Returns:
142
+ Class name (e.g., "FileTools", "ShellTools")
143
+ """
144
+ # Default mapping based on type
145
+ mapping = {
146
+ SkillType.FILE_SYSTEM: "FileTools",
147
+ SkillType.SHELL: "ShellTools",
148
+ SkillType.DOCKER: "DockerTools",
149
+ SkillType.PYTHON: "PythonTools",
150
+ SkillType.FILE_GENERATION: "FileGenerationTools",
151
+ SkillType.DATA_VISUALIZATION: "DataVisualizationTools",
152
+ SkillType.SLEEP: "SleepTools",
153
+ }
154
+ return mapping.get(self.type, "BaseTool")
155
+
156
+ def get_requirements(self) -> SkillRequirements:
157
+ """
158
+ Get runtime requirements for this skill.
159
+
160
+ Override this method to specify requirements like:
161
+ - Python packages
162
+ - System packages
163
+ - OS requirements
164
+ - Environment variables
165
+
166
+ Returns:
167
+ SkillRequirements instance
168
+ """
169
+ # Default: no special requirements
170
+ return SkillRequirements()
171
+
172
+ def check_requirements(self) -> tuple[bool, List[str]]:
173
+ """
174
+ Check if requirements are met in current environment.
175
+
176
+ Returns:
177
+ Tuple of (is_satisfied, missing_requirements)
178
+ """
179
+ requirements = self.get_requirements()
180
+ missing = []
181
+
182
+ # Check OS
183
+ if requirements.supported_os:
184
+ current_os = platform.system().lower()
185
+ if current_os not in requirements.supported_os:
186
+ missing.append(f"OS '{current_os}' not supported (requires: {', '.join(requirements.supported_os)})")
187
+
188
+ # Check Python version
189
+ if requirements.min_python_version:
190
+ import sys
191
+ from packaging import version
192
+ current_version = f"{sys.version_info.major}.{sys.version_info.minor}"
193
+ if version.parse(current_version) < version.parse(requirements.min_python_version):
194
+ missing.append(f"Python {requirements.min_python_version}+ required (current: {current_version})")
195
+
196
+ # Check environment variables
197
+ import os
198
+ for env_var in requirements.required_env_vars:
199
+ if not os.getenv(env_var):
200
+ missing.append(f"Environment variable '{env_var}' not set")
201
+
202
+ # Check Python packages (basic import check)
203
+ for package in requirements.python_packages:
204
+ package_name = package.split('[')[0].split('>=')[0].split('==')[0].strip()
205
+ try:
206
+ __import__(package_name)
207
+ except ImportError:
208
+ missing.append(f"Python package '{package}' not installed")
209
+
210
+ return len(missing) == 0, missing
211
+
212
+ def to_dict(self) -> Dict[str, Any]:
213
+ """Convert to dictionary representation"""
214
+ requirements = self.get_requirements()
215
+ is_satisfied, missing = self.check_requirements()
216
+
217
+ return {
218
+ "type": self.type.value,
219
+ "name": self.name,
220
+ "description": self.description,
221
+ "icon": self.icon,
222
+ "icon_type": self.icon_type,
223
+ "default_configuration": self.get_default_configuration(),
224
+ "variants": [v.model_dump() for v in self.get_variants()],
225
+ "framework_class": self.get_framework_class_name(),
226
+ "requirements": requirements.model_dump(),
227
+ "requirements_satisfied": is_satisfied,
228
+ "missing_requirements": missing,
229
+ }
@@ -0,0 +1,189 @@
1
+ """
2
+ Business Intelligence Skill
3
+
4
+ Provides comprehensive BI capabilities including database querying, analytics,
5
+ visualization generation, and multi-agent analysis. Supports PostgreSQL, MySQL,
6
+ MongoDB, and file-based data sources (CSV, JSON, Parquet, Excel).
7
+ """
8
+ from typing import Dict, Any, List
9
+ from .base import SkillDefinition, SkillType, SkillCategory, SkillVariant
10
+ from .registry import register_skill
11
+
12
+
13
+ class BusinessIntelligenceSkill(SkillDefinition):
14
+ """Business Intelligence and Analytics skill"""
15
+
16
+ @property
17
+ def type(self) -> SkillType:
18
+ return SkillType.BUSINESS_INTELLIGENCE
19
+
20
+ @property
21
+ def name(self) -> str:
22
+ return "Business Intelligence"
23
+
24
+ @property
25
+ def description(self) -> str:
26
+ return "Advanced BI and analytics with multi-agent analysis, database querying, and interactive visualizations"
27
+
28
+ @property
29
+ def icon(self) -> str:
30
+ return "BarChart"
31
+
32
+ def get_variants(self) -> List[SkillVariant]:
33
+ return [
34
+ SkillVariant(
35
+ id="bi_full",
36
+ name="Full BI Suite",
37
+ description="Complete BI capabilities with all data sources and analytics features",
38
+ category=SkillCategory.ADVANCED,
39
+ badge="Recommended",
40
+ icon="BarChart",
41
+ configuration={
42
+ "data_sources": [
43
+ {
44
+ "id": "default_postgres",
45
+ "name": "PostgreSQL Database",
46
+ "type": "postgresql",
47
+ "connection": {
48
+ "host": "${POSTGRES_HOST}",
49
+ "port": "${POSTGRES_PORT:5432}",
50
+ "database": "${POSTGRES_DB}",
51
+ "username": "${POSTGRES_USER}",
52
+ "password": "${POSTGRES_PASSWORD}",
53
+ "ssl": True,
54
+ "pool_size": 5
55
+ },
56
+ "query_limits": {
57
+ "max_rows": 10000,
58
+ "timeout_seconds": 30
59
+ }
60
+ }
61
+ ],
62
+ "security": {
63
+ "allowed_sql_commands": ["SELECT"],
64
+ "deny_patterns": ["DROP", "DELETE", "TRUNCATE", "ALTER", "INSERT", "UPDATE"]
65
+ },
66
+ "features": {
67
+ "enable_multi_agent": True,
68
+ "enable_visualizations": True,
69
+ "enable_schema_introspection": True,
70
+ "enable_query_validation": True
71
+ }
72
+ },
73
+ is_default=True,
74
+ ),
75
+ SkillVariant(
76
+ id="bi_read_only",
77
+ name="Read-Only BI",
78
+ description="Safe, read-only analytics with SELECT-only permissions",
79
+ category=SkillCategory.COMMON,
80
+ badge="Safe",
81
+ icon="Eye",
82
+ configuration={
83
+ "data_sources": [], # Configured per agent
84
+ "security": {
85
+ "allowed_sql_commands": ["SELECT"],
86
+ "deny_patterns": ["DROP", "DELETE", "TRUNCATE", "ALTER", "INSERT", "UPDATE", "CREATE"]
87
+ },
88
+ "features": {
89
+ "enable_multi_agent": True,
90
+ "enable_visualizations": True,
91
+ "enable_schema_introspection": True,
92
+ "enable_query_validation": True
93
+ }
94
+ },
95
+ is_default=False,
96
+ ),
97
+ SkillVariant(
98
+ id="bi_file_analysis",
99
+ name="File Analysis",
100
+ description="Analyze CSV, JSON, Parquet, and Excel files without database access",
101
+ category=SkillCategory.COMMON,
102
+ badge="Simple",
103
+ icon="FileSpreadsheet",
104
+ configuration={
105
+ "data_sources": [],
106
+ "security": {
107
+ "allowed_sql_commands": ["SELECT"],
108
+ "deny_patterns": []
109
+ },
110
+ "features": {
111
+ "enable_multi_agent": True,
112
+ "enable_visualizations": True,
113
+ "enable_schema_introspection": True,
114
+ "enable_query_validation": False,
115
+ "supported_formats": ["csv", "json", "parquet", "excel"]
116
+ }
117
+ },
118
+ is_default=False,
119
+ ),
120
+ SkillVariant(
121
+ id="bi_custom",
122
+ name="Custom BI Configuration",
123
+ description="Fully customizable BI setup with user-defined data sources and security policies",
124
+ category=SkillCategory.ADVANCED,
125
+ badge="Flexible",
126
+ icon="Settings",
127
+ configuration={
128
+ "data_sources": [],
129
+ "security": {
130
+ "allowed_sql_commands": ["SELECT"],
131
+ "deny_patterns": []
132
+ },
133
+ "features": {
134
+ "enable_multi_agent": True,
135
+ "enable_visualizations": True,
136
+ "enable_schema_introspection": True,
137
+ "enable_query_validation": True
138
+ }
139
+ },
140
+ is_default=False,
141
+ ),
142
+ ]
143
+
144
+ def validate_configuration(self, config: Dict[str, Any]) -> bool:
145
+ """Validate BI skill configuration"""
146
+ required_keys = ["data_sources", "security", "features"]
147
+
148
+ # Check required top-level keys
149
+ for key in required_keys:
150
+ if key not in config:
151
+ return False
152
+
153
+ # Validate security config
154
+ if "security" in config:
155
+ security = config["security"]
156
+ if "allowed_sql_commands" not in security:
157
+ return False
158
+ if not isinstance(security["allowed_sql_commands"], list):
159
+ return False
160
+
161
+ # Validate data sources
162
+ if "data_sources" in config:
163
+ for ds in config["data_sources"]:
164
+ if "id" not in ds or "type" not in ds:
165
+ return False
166
+ if "connection" not in ds:
167
+ return False
168
+
169
+ return True
170
+
171
+ def get_default_configuration(self) -> Dict[str, Any]:
172
+ """Get default configuration for BI skill"""
173
+ return {
174
+ "data_sources": [],
175
+ "security": {
176
+ "allowed_sql_commands": ["SELECT"],
177
+ "deny_patterns": ["DROP", "DELETE", "TRUNCATE", "ALTER", "INSERT", "UPDATE"]
178
+ },
179
+ "features": {
180
+ "enable_multi_agent": True,
181
+ "enable_visualizations": True,
182
+ "enable_schema_introspection": True,
183
+ "enable_query_validation": True
184
+ }
185
+ }
186
+
187
+
188
+ # Register the skill
189
+ register_skill(BusinessIntelligenceToolSet())