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,266 @@
1
+ # Kubiya Control Plane API
2
+
3
+ A multi-tenant AI agent orchestration and management platform built with FastAPI, Temporal, and PostgreSQL.
4
+
5
+ ## Features
6
+
7
+ - **Multi-tenant Architecture**: Manage multiple projects, teams, and agents
8
+ - **Workflow Orchestration**: Temporal-based workflow execution
9
+ - **Flexible Agent Runtime**: Support for multiple agent types and skills
10
+ - **Policy Enforcement**: OPA-based policy engine for agent governance
11
+ - **Scalable Workers**: Distributed worker architecture for agent execution
12
+ - **Context Management**: Environment and team-specific context handling
13
+ - **LLM Integration**: Support for multiple LLM providers via LiteLLM
14
+ - **Comprehensive APIs**: RESTful APIs for all platform features
15
+
16
+ ## Installation
17
+
18
+ ### Using pip
19
+
20
+ ```bash
21
+ pip install kubiya-control_plane_api
22
+ ```
23
+
24
+ ### From source
25
+
26
+ ```bash
27
+ git clone https://github.com/kubiyabot/agent-control-plane.git
28
+ cd agent-control-plane/control_plane_api
29
+ pip install -e .
30
+ ```
31
+
32
+ ### With development dependencies
33
+
34
+ ```bash
35
+ pip install kubiya-control_plane_api[dev]
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ### 1. Set up environment variables
41
+
42
+ Create a `.env` file or set the following environment variables:
43
+
44
+ ```bash
45
+ # Database Configuration
46
+ DATABASE_URL=postgresql://user:password@localhost:5432/control_plane
47
+
48
+ # Supabase (for serverless deployments)
49
+ SUPABASE_URL=your-supabase-url
50
+ SUPABASE_KEY=your-supabase-key
51
+
52
+ # Temporal Configuration
53
+ TEMPORAL_HOST=localhost:7233
54
+ TEMPORAL_NAMESPACE=default
55
+
56
+ # API Configuration
57
+ API_TITLE="Agent Control Plane"
58
+ API_VERSION="1.0.0"
59
+ ENVIRONMENT=development
60
+ LOG_LEVEL=info
61
+
62
+ # Security
63
+ SECRET_KEY=your-secret-key-here
64
+
65
+ # Optional: Kubiya Integration
66
+ KUBIYA_API_KEY=your-kubiya-api-key
67
+ KUBIYA_API_URL=https://api.kubiya.ai
68
+ ```
69
+
70
+ ### 2. Run database migrations
71
+
72
+ ```bash
73
+ alembic upgrade head
74
+ ```
75
+
76
+ ### 3. Start the API server
77
+
78
+ ```bash
79
+ uvicorn app.main:app --host 0.0.0.0 --port 7777 --reload
80
+ ```
81
+
82
+ The API will be available at `http://localhost:7777`
83
+
84
+ ### 4. Access the API documentation
85
+
86
+ Open your browser and navigate to:
87
+ - Swagger UI: `http://localhost:7777/api/docs`
88
+ - ReDoc: `http://localhost:7777/api/redoc`
89
+
90
+ ### 5. Start a worker (optional)
91
+
92
+ To process agent execution workflows:
93
+
94
+ ```bash
95
+ python worker.py
96
+ ```
97
+
98
+ ## Package Structure
99
+
100
+ ```
101
+ app/
102
+ ├── activities/ # Temporal activities
103
+ ├── lib/ # Client libraries (Kubiya, Redis, Temporal, etc.)
104
+ ├── middleware/ # FastAPI middleware (auth, etc.)
105
+ ├── models/ # SQLAlchemy models
106
+ ├── policies/ # OPA policy files (.rego)
107
+ ├── routers/ # FastAPI route handlers
108
+ ├── services/ # Business logic services
109
+ ├── skills/ # Agent skills
110
+ ├── workflows/ # Temporal workflows
111
+ ├── config.py # Configuration management
112
+ ├── database.py # Database connection
113
+ └── main.py # FastAPI application entry point
114
+ ```
115
+
116
+ ## API Endpoints
117
+
118
+ ### Core Resources
119
+
120
+ - **Projects**: `/api/v1/projects` - Multi-project management
121
+ - **Environments**: `/api/v1/environments` - Environment configuration
122
+ - **Agents**: `/api/v1/agents` - Agent management
123
+ - **Teams**: `/api/v1/teams` - Team management
124
+ - **Workflows**: `/api/v1/workflows` - Workflow definitions
125
+ - **Executions**: `/api/v1/executions` - Execution tracking
126
+ - **Workers**: `/api/v1/workers` - Worker registration and management
127
+
128
+ ### Skills and Policies
129
+
130
+ - **Skills**: `/api/v1/skills` - Tool sets and definitions
131
+ - **Policies**: `/api/v1/policies` - Policy management and enforcement
132
+
133
+ ### Integration
134
+
135
+ - **Secrets**: `/api/v1/secrets` - Secrets management (proxies to Kubiya)
136
+ - **Integrations**: `/api/v1/integrations` - Third-party integrations
137
+ - **Models**: `/api/v1/models` - LLM model configuration
138
+
139
+ ### Utilities
140
+
141
+ - **Health**: `/api/health` - Health check endpoint
142
+ - **Task Planning**: `/api/v1/task-planning` - AI-powered task planning
143
+
144
+ ## Configuration
145
+
146
+ The application uses Pydantic Settings for configuration management. All settings can be configured via environment variables or a `.env` file.
147
+
148
+ ### Key Configuration Options
149
+
150
+ - `DATABASE_URL`: PostgreSQL connection string
151
+ - `SUPABASE_URL`, `SUPABASE_KEY`: Supabase configuration for serverless
152
+ - `TEMPORAL_HOST`: Temporal server address
153
+ - `KUBIYA_API_KEY`: Kubiya platform API key
154
+ - `SECRET_KEY`: Secret key for JWT token signing
155
+ - `LOG_LEVEL`: Logging level (debug, info, warning, error)
156
+ - `ENVIRONMENT`: Deployment environment (development, staging, production)
157
+
158
+ ## Development
159
+
160
+ ### Install development dependencies
161
+
162
+ ```bash
163
+ pip install -e ".[dev]"
164
+ ```
165
+
166
+ ### Run tests
167
+
168
+ ```bash
169
+ # All tests
170
+ pytest
171
+
172
+ # Unit tests only
173
+ pytest -m unit
174
+
175
+ # Integration tests
176
+ pytest -m integration
177
+
178
+ # With coverage
179
+ pytest --cov=app --cov-report=html
180
+ ```
181
+
182
+ ### Code formatting
183
+
184
+ ```bash
185
+ # Format code with black
186
+ black .
187
+
188
+ # Lint with ruff
189
+ ruff check .
190
+ ```
191
+
192
+ ### Database migrations
193
+
194
+ ```bash
195
+ # Create a new migration
196
+ alembic revision --autogenerate -m "Description of changes"
197
+
198
+ # Apply migrations
199
+ alembic upgrade head
200
+
201
+ # Rollback migration
202
+ alembic downgrade -1
203
+ ```
204
+
205
+ ## Deployment
206
+
207
+ ### Docker
208
+
209
+ ```bash
210
+ docker build -t control_plane_api .
211
+ docker run -p 7777:7777 --env-file .env control_plane_api
212
+ ```
213
+
214
+ ### Vercel (Serverless)
215
+
216
+ The API is configured for Vercel deployment with `vercel.json` and the Mangum adapter.
217
+
218
+ ```bash
219
+ vercel deploy
220
+ ```
221
+
222
+ ## Architecture
223
+
224
+ ### Workflow Orchestration
225
+
226
+ The platform uses Temporal for reliable workflow execution:
227
+ - Durable execution with automatic retries
228
+ - Activity-based task decomposition
229
+ - Support for long-running workflows
230
+ - Built-in observability and monitoring
231
+
232
+ ### Multi-tenancy
233
+
234
+ - **Projects**: Top-level isolation boundary
235
+ - **Environments**: Isolated execution contexts within projects
236
+ - **Teams**: Collaborative agent groups
237
+ - **Agents**: Individual agent instances
238
+
239
+ ### Worker Architecture
240
+
241
+ Workers pull tasks from environment-specific queues and execute agent workflows using Temporal.
242
+
243
+ ## Contributing
244
+
245
+ 1. Fork the repository
246
+ 2. Create a feature branch
247
+ 3. Make your changes
248
+ 4. Run tests and linting
249
+ 5. Submit a pull request
250
+
251
+ ## License
252
+
253
+ MIT License - see LICENSE file for details
254
+
255
+ ## Support
256
+
257
+ For issues and questions:
258
+ - GitHub Issues: https://github.com/kubiyabot/agent-control-plane/issues
259
+ - Email: support@kubiya.ai
260
+
261
+ ## Links
262
+
263
+ - [Documentation](https://github.com/kubiyabot/agent-control-plane/blob/main/README.md)
264
+ - [GitHub Repository](https://github.com/kubiyabot/agent-control-plane)
265
+ - [Kubiya Platform](https://kubiya.ai)
266
+
File without changes
@@ -0,0 +1 @@
1
+ __version__ = "0.3.4"
@@ -0,0 +1 @@
1
+ Generic single-database configuration.
@@ -0,0 +1,98 @@
1
+ from logging.config import fileConfig
2
+
3
+ from sqlalchemy import engine_from_config
4
+ from sqlalchemy import pool
5
+
6
+ from alembic import context
7
+
8
+ # Import application settings and models
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ # Add parent directory to path so control_plane_api is importable
13
+ # env.py location: /app/control_plane_api/alembic/env.py
14
+ # We need: /app (which is parent.parent.parent)
15
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))
16
+
17
+ from control_plane_api.app.config import settings
18
+ from control_plane_api.app.database import Base
19
+ from control_plane_api.app.models import (
20
+ Project, Agent, Team, Workflow, Session,
21
+ Execution, UserPresence, Environment, AgentEnvironment, TeamEnvironment
22
+ )
23
+
24
+ # this is the Alembic Config object, which provides
25
+ # access to the values within the .ini file in use.
26
+ config = context.config
27
+
28
+ # Override sqlalchemy.url with our DATABASE_URL from settings
29
+ if settings.database_url:
30
+ # Escape % characters for ConfigParser (% -> %%)
31
+ escaped_url = settings.database_url.replace("%", "%%")
32
+ config.set_main_option("sqlalchemy.url", escaped_url)
33
+
34
+ # Interpret the config file for Python logging.
35
+ # This line sets up loggers basically.
36
+ if config.config_file_name is not None:
37
+ fileConfig(config.config_file_name)
38
+
39
+ # add your model's MetaData object here
40
+ # for 'autogenerate' support
41
+ target_metadata = Base.metadata
42
+
43
+ # other values from the config, defined by the needs of env.py,
44
+ # can be acquired:
45
+ # my_important_option = config.get_main_option("my_important_option")
46
+ # ... etc.
47
+
48
+
49
+ def run_migrations_offline() -> None:
50
+ """Run migrations in 'offline' mode.
51
+
52
+ This configures the context with just a URL
53
+ and not an Engine, though an Engine is acceptable
54
+ here as well. By skipping the Engine creation
55
+ we don't even need a DBAPI to be available.
56
+
57
+ Calls to context.execute() here emit the given string to the
58
+ script output.
59
+
60
+ """
61
+ url = config.get_main_option("sqlalchemy.url")
62
+ context.configure(
63
+ url=url,
64
+ target_metadata=target_metadata,
65
+ literal_binds=True,
66
+ dialect_opts={"paramstyle": "named"},
67
+ )
68
+
69
+ with context.begin_transaction():
70
+ context.run_migrations()
71
+
72
+
73
+ def run_migrations_online() -> None:
74
+ """Run migrations in 'online' mode.
75
+
76
+ In this scenario we need to create an Engine
77
+ and associate a connection with the context.
78
+
79
+ """
80
+ connectable = engine_from_config(
81
+ config.get_section(config.config_ini_section, {}),
82
+ prefix="sqlalchemy.",
83
+ poolclass=pool.NullPool,
84
+ )
85
+
86
+ with connectable.connect() as connection:
87
+ context.configure(
88
+ connection=connection, target_metadata=target_metadata
89
+ )
90
+
91
+ with context.begin_transaction():
92
+ context.run_migrations()
93
+
94
+
95
+ if context.is_offline_mode():
96
+ run_migrations_offline()
97
+ else:
98
+ run_migrations_online()
@@ -0,0 +1,28 @@
1
+ """${message}
2
+
3
+ Revision ID: ${up_revision}
4
+ Revises: ${down_revision | comma,n}
5
+ Create Date: ${create_date}
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ ${imports if imports else ""}
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = ${repr(up_revision)}
16
+ down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
17
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ ${upgrades if upgrades else "pass"}
24
+
25
+
26
+ def downgrade() -> None:
27
+ """Downgrade schema."""
28
+ ${downgrades if downgrades else "pass"}
@@ -0,0 +1,251 @@
1
+ """Initial migration with all models
2
+
3
+ Revision ID: 1382bec74309
4
+ Revises:
5
+ Create Date: 2025-10-28 17:21:33.097680
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = '1382bec74309'
16
+ down_revision: Union[str, Sequence[str], None] = None
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table('environments',
25
+ sa.Column('id', sa.String(), nullable=False),
26
+ sa.Column('organization_id', sa.String(), nullable=False),
27
+ sa.Column('name', sa.String(), nullable=False),
28
+ sa.Column('display_name', sa.String(), nullable=True),
29
+ sa.Column('description', sa.String(), nullable=True),
30
+ sa.Column('tags', sa.JSON(), nullable=False),
31
+ sa.Column('settings', sa.JSON(), nullable=False),
32
+ sa.Column('status', sa.Enum('PENDING', 'PROVISIONING', 'ACTIVE', 'INACTIVE', 'ERROR', name='environmentstatus'), nullable=False),
33
+ sa.Column('worker_token', sa.String(), nullable=True),
34
+ sa.Column('provisioning_workflow_id', sa.String(), nullable=True),
35
+ sa.Column('provisioned_at', sa.DateTime(), nullable=True),
36
+ sa.Column('error_message', sa.String(), nullable=True),
37
+ sa.Column('temporal_namespace_id', sa.String(), nullable=True),
38
+ sa.Column('execution_environment', sa.JSON(), nullable=False),
39
+ sa.Column('created_at', sa.DateTime(), nullable=False),
40
+ sa.Column('updated_at', sa.DateTime(), nullable=False),
41
+ sa.Column('created_by', sa.String(), nullable=True),
42
+ sa.Column('updated_by', sa.String(), nullable=True),
43
+ sa.PrimaryKeyConstraint('id')
44
+ )
45
+ op.create_index(op.f('ix_environments_name'), 'environments', ['name'], unique=False)
46
+ op.create_index(op.f('ix_environments_organization_id'), 'environments', ['organization_id'], unique=False)
47
+ op.create_index(op.f('ix_environments_status'), 'environments', ['status'], unique=False)
48
+ op.create_table('executions',
49
+ sa.Column('id', sa.String(), nullable=False),
50
+ sa.Column('organization_id', sa.String(), nullable=False),
51
+ sa.Column('execution_type', sa.Enum('agent', 'team', 'workflow', name='executiontype'), nullable=False),
52
+ sa.Column('entity_id', sa.String(), nullable=False),
53
+ sa.Column('entity_name', sa.String(), nullable=True),
54
+ sa.Column('runner_name', sa.String(), nullable=True),
55
+ sa.Column('user_id', sa.String(), nullable=True),
56
+ sa.Column('user_email', sa.String(), nullable=True),
57
+ sa.Column('user_name', sa.String(), nullable=True),
58
+ sa.Column('user_avatar', sa.String(), nullable=True),
59
+ sa.Column('prompt', sa.Text(), nullable=False),
60
+ sa.Column('system_prompt', sa.Text(), nullable=True),
61
+ sa.Column('config', sa.JSON(), nullable=True),
62
+ sa.Column('status', sa.Enum('pending', 'running', 'waiting_for_input', 'completed', 'failed', 'cancelled', name='executionstatus'), nullable=False),
63
+ sa.Column('response', sa.Text(), nullable=True),
64
+ sa.Column('error_message', sa.Text(), nullable=True),
65
+ sa.Column('usage', sa.JSON(), nullable=True),
66
+ sa.Column('execution_metadata', sa.JSON(), nullable=True),
67
+ sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
68
+ sa.Column('started_at', sa.DateTime(timezone=True), nullable=True),
69
+ sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
70
+ sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
71
+ sa.PrimaryKeyConstraint('id')
72
+ )
73
+ op.create_index(op.f('ix_executions_organization_id'), 'executions', ['organization_id'], unique=False)
74
+ op.create_index(op.f('ix_executions_user_id'), 'executions', ['user_id'], unique=False)
75
+ op.create_table('projects',
76
+ sa.Column('id', sa.String(), nullable=False),
77
+ sa.Column('organization_id', sa.String(), nullable=False),
78
+ sa.Column('name', sa.String(), nullable=False),
79
+ sa.Column('description', sa.Text(), nullable=True),
80
+ sa.Column('goals', sa.Text(), nullable=True),
81
+ sa.Column('status', sa.Enum('active', 'archived', 'paused', name='projectstatus'), nullable=False),
82
+ sa.Column('restrict_to_environment', sa.Boolean(), nullable=False),
83
+ sa.Column('default_model', sa.String(), nullable=True),
84
+ sa.Column('default_settings', sa.JSON(), nullable=False),
85
+ sa.Column('is_default', sa.Boolean(), nullable=False),
86
+ sa.Column('created_at', sa.DateTime(), nullable=False),
87
+ sa.Column('updated_at', sa.DateTime(), nullable=False),
88
+ sa.PrimaryKeyConstraint('id')
89
+ )
90
+ op.create_index(op.f('ix_projects_name'), 'projects', ['name'], unique=False)
91
+ op.create_index(op.f('ix_projects_organization_id'), 'projects', ['organization_id'], unique=False)
92
+ op.create_table('teams',
93
+ sa.Column('id', sa.String(), nullable=False),
94
+ sa.Column('organization_id', sa.String(), nullable=False),
95
+ sa.Column('name', sa.String(), nullable=False),
96
+ sa.Column('description', sa.Text(), nullable=True),
97
+ sa.Column('status', sa.Enum('active', 'inactive', 'archived', name='teamstatus'), nullable=False),
98
+ sa.Column('configuration', sa.JSON(), nullable=False),
99
+ sa.Column('skill_ids', sa.ARRAY(sa.UUID(as_uuid=False)), nullable=False),
100
+ sa.Column('execution_environment', sa.JSON(), nullable=False),
101
+ sa.Column('created_at', sa.DateTime(), nullable=False),
102
+ sa.Column('updated_at', sa.DateTime(), nullable=False),
103
+ sa.PrimaryKeyConstraint('id'),
104
+ sa.UniqueConstraint('organization_id', 'name', name='uq_team_org_name')
105
+ )
106
+ op.create_index(op.f('ix_teams_name'), 'teams', ['name'], unique=False)
107
+ op.create_index(op.f('ix_teams_organization_id'), 'teams', ['organization_id'], unique=False)
108
+ op.create_table('user_presence',
109
+ sa.Column('id', sa.String(), nullable=False),
110
+ sa.Column('user_id', sa.String(), nullable=False),
111
+ sa.Column('user_email', sa.String(), nullable=True),
112
+ sa.Column('user_name', sa.String(), nullable=True),
113
+ sa.Column('user_avatar', sa.String(), nullable=True),
114
+ sa.Column('agent_id', sa.String(), nullable=True),
115
+ sa.Column('session_id', sa.String(), nullable=True),
116
+ sa.Column('execution_id', sa.String(), nullable=True),
117
+ sa.Column('is_active', sa.Boolean(), nullable=False),
118
+ sa.Column('is_typing', sa.Boolean(), nullable=False),
119
+ sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
120
+ sa.Column('last_active_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
121
+ sa.PrimaryKeyConstraint('id')
122
+ )
123
+ op.create_index('idx_presence_lookup', 'user_presence', ['agent_id', 'is_active', 'last_active_at'], unique=False)
124
+ op.create_index('idx_presence_user', 'user_presence', ['user_id', 'is_active'], unique=False)
125
+ op.create_index(op.f('ix_user_presence_agent_id'), 'user_presence', ['agent_id'], unique=False)
126
+ op.create_index(op.f('ix_user_presence_execution_id'), 'user_presence', ['execution_id'], unique=False)
127
+ op.create_index(op.f('ix_user_presence_session_id'), 'user_presence', ['session_id'], unique=False)
128
+ op.create_index(op.f('ix_user_presence_user_id'), 'user_presence', ['user_id'], unique=False)
129
+ op.create_table('agents',
130
+ sa.Column('id', sa.String(), nullable=False),
131
+ sa.Column('name', sa.String(), nullable=False),
132
+ sa.Column('description', sa.Text(), nullable=True),
133
+ sa.Column('status', sa.Enum('idle', 'running', 'paused', 'completed', 'failed', 'stopped', name='agentstatus'), nullable=False),
134
+ sa.Column('capabilities', sa.JSON(), nullable=False),
135
+ sa.Column('configuration', sa.JSON(), nullable=False),
136
+ sa.Column('model_id', sa.String(), nullable=True),
137
+ sa.Column('model_config', sa.JSON(), nullable=False),
138
+ sa.Column('runtime', sa.Enum('default', 'claude_code', name='runtimetype'), server_default='default', nullable=False),
139
+ sa.Column('organization_id', sa.String(), nullable=False),
140
+ sa.Column('team_id', sa.String(), nullable=True),
141
+ sa.Column('created_at', sa.DateTime(), nullable=False),
142
+ sa.Column('updated_at', sa.DateTime(), nullable=False),
143
+ sa.Column('last_active_at', sa.DateTime(), nullable=True),
144
+ sa.Column('state', sa.JSON(), nullable=False),
145
+ sa.Column('error_message', sa.Text(), nullable=True),
146
+ sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ),
147
+ sa.PrimaryKeyConstraint('id')
148
+ )
149
+ op.create_index(op.f('ix_agents_name'), 'agents', ['name'], unique=False)
150
+ op.create_index(op.f('ix_agents_organization_id'), 'agents', ['organization_id'], unique=False)
151
+ op.create_index(op.f('ix_agents_runtime'), 'agents', ['runtime'], unique=False)
152
+ op.create_table('team_environments',
153
+ sa.Column('id', sa.String(), nullable=False),
154
+ sa.Column('team_id', sa.String(), nullable=False),
155
+ sa.Column('environment_id', sa.String(), nullable=False),
156
+ sa.Column('organization_id', sa.String(), nullable=False),
157
+ sa.Column('assigned_at', sa.DateTime(), nullable=False),
158
+ sa.Column('assigned_by', sa.String(), nullable=True),
159
+ sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='CASCADE'),
160
+ sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ondelete='CASCADE'),
161
+ sa.PrimaryKeyConstraint('id')
162
+ )
163
+ op.create_index(op.f('ix_team_environments_organization_id'), 'team_environments', ['organization_id'], unique=False)
164
+ op.create_table('workflows',
165
+ sa.Column('id', sa.String(), nullable=False),
166
+ sa.Column('name', sa.String(), nullable=False),
167
+ sa.Column('description', sa.Text(), nullable=True),
168
+ sa.Column('status', sa.Enum('pending', 'running', 'paused', 'completed', 'failed', 'cancelled', name='workflowstatus'), nullable=False),
169
+ sa.Column('steps', sa.JSON(), nullable=False),
170
+ sa.Column('current_step', sa.String(), nullable=True),
171
+ sa.Column('configuration', sa.JSON(), nullable=False),
172
+ sa.Column('team_id', sa.String(), nullable=True),
173
+ sa.Column('created_at', sa.DateTime(), nullable=False),
174
+ sa.Column('updated_at', sa.DateTime(), nullable=False),
175
+ sa.Column('started_at', sa.DateTime(), nullable=True),
176
+ sa.Column('completed_at', sa.DateTime(), nullable=True),
177
+ sa.Column('state', sa.JSON(), nullable=False),
178
+ sa.Column('error_message', sa.Text(), nullable=True),
179
+ sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ),
180
+ sa.PrimaryKeyConstraint('id')
181
+ )
182
+ op.create_index(op.f('ix_workflows_name'), 'workflows', ['name'], unique=False)
183
+ op.create_table('agent_environments',
184
+ sa.Column('id', sa.String(), nullable=False),
185
+ sa.Column('agent_id', sa.String(), nullable=False),
186
+ sa.Column('environment_id', sa.String(), nullable=False),
187
+ sa.Column('organization_id', sa.String(), nullable=False),
188
+ sa.Column('assigned_at', sa.DateTime(), nullable=False),
189
+ sa.Column('assigned_by', sa.String(), nullable=True),
190
+ sa.ForeignKeyConstraint(['agent_id'], ['agents.id'], ondelete='CASCADE'),
191
+ sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='CASCADE'),
192
+ sa.PrimaryKeyConstraint('id')
193
+ )
194
+ op.create_index(op.f('ix_agent_environments_organization_id'), 'agent_environments', ['organization_id'], unique=False)
195
+ op.create_table('sessions',
196
+ sa.Column('id', sa.String(), nullable=False),
197
+ sa.Column('agent_id', sa.String(), nullable=False),
198
+ sa.Column('user_id', sa.String(), nullable=True),
199
+ sa.Column('user_email', sa.String(), nullable=True),
200
+ sa.Column('user_name', sa.String(), nullable=True),
201
+ sa.Column('user_avatar', sa.String(), nullable=True),
202
+ sa.Column('messages', sa.JSON(), nullable=False),
203
+ sa.Column('context', sa.JSON(), nullable=False),
204
+ sa.Column('session_metadata', sa.JSON(), nullable=False),
205
+ sa.Column('created_at', sa.DateTime(), nullable=False),
206
+ sa.Column('updated_at', sa.DateTime(), nullable=False),
207
+ sa.Column('expires_at', sa.DateTime(), nullable=True),
208
+ sa.Column('last_active_at', sa.DateTime(), nullable=False),
209
+ sa.ForeignKeyConstraint(['agent_id'], ['agents.id'], ),
210
+ sa.PrimaryKeyConstraint('id')
211
+ )
212
+ op.create_index(op.f('ix_sessions_user_id'), 'sessions', ['user_id'], unique=False)
213
+ # ### end Alembic commands ###
214
+
215
+
216
+ def downgrade() -> None:
217
+ """Downgrade schema."""
218
+ # ### commands auto generated by Alembic - please adjust! ###
219
+ op.drop_index(op.f('ix_sessions_user_id'), table_name='sessions')
220
+ op.drop_table('sessions')
221
+ op.drop_index(op.f('ix_agent_environments_organization_id'), table_name='agent_environments')
222
+ op.drop_table('agent_environments')
223
+ op.drop_index(op.f('ix_workflows_name'), table_name='workflows')
224
+ op.drop_table('workflows')
225
+ op.drop_index(op.f('ix_team_environments_organization_id'), table_name='team_environments')
226
+ op.drop_table('team_environments')
227
+ op.drop_index(op.f('ix_agents_runtime'), table_name='agents')
228
+ op.drop_index(op.f('ix_agents_organization_id'), table_name='agents')
229
+ op.drop_index(op.f('ix_agents_name'), table_name='agents')
230
+ op.drop_table('agents')
231
+ op.drop_index(op.f('ix_user_presence_user_id'), table_name='user_presence')
232
+ op.drop_index(op.f('ix_user_presence_session_id'), table_name='user_presence')
233
+ op.drop_index(op.f('ix_user_presence_execution_id'), table_name='user_presence')
234
+ op.drop_index(op.f('ix_user_presence_agent_id'), table_name='user_presence')
235
+ op.drop_index('idx_presence_user', table_name='user_presence')
236
+ op.drop_index('idx_presence_lookup', table_name='user_presence')
237
+ op.drop_table('user_presence')
238
+ op.drop_index(op.f('ix_teams_organization_id'), table_name='teams')
239
+ op.drop_index(op.f('ix_teams_name'), table_name='teams')
240
+ op.drop_table('teams')
241
+ op.drop_index(op.f('ix_projects_organization_id'), table_name='projects')
242
+ op.drop_index(op.f('ix_projects_name'), table_name='projects')
243
+ op.drop_table('projects')
244
+ op.drop_index(op.f('ix_executions_user_id'), table_name='executions')
245
+ op.drop_index(op.f('ix_executions_organization_id'), table_name='executions')
246
+ op.drop_table('executions')
247
+ op.drop_index(op.f('ix_environments_status'), table_name='environments')
248
+ op.drop_index(op.f('ix_environments_organization_id'), table_name='environments')
249
+ op.drop_index(op.f('ix_environments_name'), table_name='environments')
250
+ op.drop_table('environments')
251
+ # ### end Alembic commands ###