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,362 @@
1
+ """
2
+ Example of integrating analytics collection into agent execution.
3
+
4
+ This shows how to instrument your agent execution to automatically
5
+ track metrics without blocking performance.
6
+ """
7
+
8
+ import asyncio
9
+ import os
10
+ import time
11
+ from typing import Any, Dict
12
+ from datetime import datetime, timezone
13
+
14
+ # Import analytics components
15
+ from control_plane_api.worker.services.analytics_collector import (
16
+ create_analytics_collector,
17
+ ExecutionContext,
18
+ )
19
+
20
+
21
+ async def execute_agent_with_analytics_example():
22
+ """
23
+ Example showing end-to-end analytics integration.
24
+
25
+ This demonstrates:
26
+ 1. Setting up the analytics collector
27
+ 2. Tracking LLM turns with token usage
28
+ 3. Tracking tool calls
29
+ 4. Tracking tasks
30
+ 5. Async submission (non-blocking)
31
+ """
32
+
33
+ # ========================================================================
34
+ # 1. Setup Analytics Collector
35
+ # ========================================================================
36
+
37
+ collector = create_analytics_collector(
38
+ control_plane_url=os.getenv("CONTROL_PLANE_URL", "http://localhost:8000"),
39
+ api_key=os.getenv("KUBIYA_API_KEY"),
40
+ )
41
+
42
+ # Create execution context
43
+ ctx = ExecutionContext(
44
+ execution_id="550e8400-e29b-41d4-a716-446655440000", # From Temporal workflow
45
+ organization_id="org-123", # From execution record
46
+ turn_number=0,
47
+ )
48
+
49
+ print("🚀 Starting agent execution with analytics tracking\n")
50
+
51
+ # ========================================================================
52
+ # 2. Track LLM Turn (Using LiteLLM)
53
+ # ========================================================================
54
+
55
+ print("📊 Turn 1: LLM Call with LiteLLM")
56
+ ctx = collector.start_turn(ctx)
57
+
58
+ # Simulate LiteLLM call
59
+ turn_start = time.time()
60
+
61
+ # In real code, you'd do:
62
+ # response = await litellm.acompletion(
63
+ # model="claude-sonnet-4",
64
+ # messages=[{"role": "user", "content": "Hello"}],
65
+ # )
66
+
67
+ # For this example, create a mock response
68
+ class MockUsage:
69
+ prompt_tokens = 1000
70
+ completion_tokens = 500
71
+ total_tokens = 1500
72
+
73
+ class MockMessage:
74
+ content = "This is the LLM response with detailed information about the task."
75
+
76
+ class MockChoice:
77
+ message = MockMessage()
78
+ finish_reason = "stop"
79
+
80
+ class MockLiteLLMResponse:
81
+ usage = MockUsage()
82
+ choices = [MockChoice()]
83
+
84
+ await asyncio.sleep(0.1) # Simulate API call
85
+ response = MockLiteLLMResponse()
86
+
87
+ # Record the turn (async, non-blocking)
88
+ collector.record_turn_from_litellm(
89
+ ctx=ctx,
90
+ response=response,
91
+ model="claude-sonnet-4",
92
+ finish_reason="stop",
93
+ )
94
+
95
+ print(f" ✓ Turn recorded: {response.usage.total_tokens} tokens")
96
+ print(f" ✓ Duration: {int((time.time() - turn_start) * 1000)}ms\n")
97
+
98
+ # ========================================================================
99
+ # 3. Track Tool Calls
100
+ # ========================================================================
101
+
102
+ print("🔧 Turn 1: Tool Calls")
103
+
104
+ # Tool call 1: Read file
105
+ tool_start = time.time()
106
+ await asyncio.sleep(0.05) # Simulate tool execution
107
+ tool_end = time.time()
108
+
109
+ collector.record_tool_call(
110
+ ctx=ctx,
111
+ tool_name="Read",
112
+ tool_input={"file_path": "/app/main.py"},
113
+ tool_output="def main():\n print('Hello')\n ...",
114
+ start_time=tool_start,
115
+ end_time=tool_end,
116
+ success=True,
117
+ )
118
+
119
+ print(f" ✓ Tool call recorded: Read (successful)")
120
+
121
+ # Tool call 2: Bash command
122
+ tool_start = time.time()
123
+ await asyncio.sleep(0.1) # Simulate tool execution
124
+ tool_end = time.time()
125
+
126
+ collector.record_tool_call(
127
+ ctx=ctx,
128
+ tool_name="Bash",
129
+ tool_input={"command": "ls -la"},
130
+ tool_output="total 48\ndrwxr-xr-x 10 user staff 320 Jan 8 14:00 .\n...",
131
+ start_time=tool_start,
132
+ end_time=tool_end,
133
+ success=True,
134
+ )
135
+
136
+ print(f" ✓ Tool call recorded: Bash (successful)\n")
137
+
138
+ # ========================================================================
139
+ # 4. Track LLM Turn (Using Agno)
140
+ # ========================================================================
141
+
142
+ print("📊 Turn 2: LLM Call with Agno")
143
+ ctx = collector.start_turn(ctx)
144
+
145
+ turn_start = time.time()
146
+
147
+ # In real code, you'd do:
148
+ # result = agent.run(message)
149
+
150
+ # For this example, create a mock Agno result
151
+ class MockMetrics:
152
+ input_tokens = 800
153
+ output_tokens = 600
154
+ total_tokens = 1400
155
+ input_token_details = {
156
+ "cache_read": 200,
157
+ "cache_creation": 100,
158
+ }
159
+
160
+ class MockAgnoResult:
161
+ metrics = MockMetrics()
162
+ content = "Based on the analysis, I recommend the following changes..."
163
+ run_id = "run-456"
164
+
165
+ await asyncio.sleep(0.15) # Simulate API call
166
+ result = MockAgnoResult()
167
+
168
+ # Record the turn (async, non-blocking)
169
+ collector.record_turn_from_agno(
170
+ ctx=ctx,
171
+ result=result,
172
+ model="claude-sonnet-4",
173
+ finish_reason="stop",
174
+ )
175
+
176
+ print(f" ✓ Turn recorded: {result.metrics.total_tokens} tokens (with cache)")
177
+ print(f" ✓ Cache read: {result.metrics.input_token_details['cache_read']} tokens")
178
+ print(f" ✓ Duration: {int((time.time() - turn_start) * 1000)}ms\n")
179
+
180
+ # ========================================================================
181
+ # 5. Track Tasks
182
+ # ========================================================================
183
+
184
+ print("📋 Task Tracking")
185
+
186
+ task_id = collector.record_task(
187
+ ctx=ctx,
188
+ task_number=1,
189
+ task_description="Analyze codebase and identify issues",
190
+ task_type="analysis",
191
+ status="completed",
192
+ started_at=datetime.now(timezone.utc).isoformat(),
193
+ )
194
+
195
+ print(f" ✓ Task recorded: {task_id}\n")
196
+
197
+ # ========================================================================
198
+ # 6. Wait for Analytics Submission
199
+ # ========================================================================
200
+
201
+ print("⏳ Waiting for analytics submission...")
202
+
203
+ # Wait for all analytics to be submitted (with timeout)
204
+ await collector.wait_for_submissions(timeout=5.0)
205
+
206
+ print("✅ All analytics submitted!\n")
207
+
208
+ # ========================================================================
209
+ # 7. Query Analytics
210
+ # ========================================================================
211
+
212
+ print("📈 Analytics Summary:")
213
+ print(f" - Total turns: 2")
214
+ print(f" - Total tokens: 2900")
215
+ print(f" - Total tool calls: 2")
216
+ print(f" - Total tasks: 1")
217
+ print(f" - Estimated cost: $0.0435")
218
+
219
+
220
+ async def execute_agent_with_error_handling_example():
221
+ """
222
+ Example showing error handling in analytics.
223
+
224
+ Demonstrates that analytics failures don't break execution.
225
+ """
226
+
227
+ collector = create_analytics_collector(
228
+ control_plane_url="http://localhost:8000",
229
+ api_key="test-key",
230
+ )
231
+
232
+ ctx = ExecutionContext(
233
+ execution_id="exec-123",
234
+ organization_id="org-456",
235
+ )
236
+
237
+ print("\n🔥 Error Handling Example\n")
238
+
239
+ # Start turn
240
+ ctx = collector.start_turn(ctx)
241
+
242
+ # Even if analytics submission fails, execution continues
243
+ try:
244
+ # Simulate a failed LLM call
245
+ raise Exception("LLM API timeout")
246
+ except Exception as e:
247
+ print(f"❌ LLM call failed: {e}")
248
+
249
+ # Record turn with error (still tracked for analytics)
250
+ class MockErrorResponse:
251
+ usage = None
252
+
253
+ collector.record_turn_from_litellm(
254
+ ctx=ctx,
255
+ response=MockErrorResponse(),
256
+ model="claude-sonnet-4",
257
+ finish_reason="error",
258
+ error_message=str(e),
259
+ )
260
+
261
+ print(" ✓ Error tracked in analytics (execution can continue)")
262
+
263
+ # Tool call that fails
264
+ tool_start = time.time()
265
+ try:
266
+ raise PermissionError("Access denied to file")
267
+ except Exception as e:
268
+ tool_end = time.time()
269
+
270
+ collector.record_tool_call(
271
+ ctx=ctx,
272
+ tool_name="Read",
273
+ tool_input={"file_path": "/restricted/file.txt"},
274
+ tool_output=None,
275
+ start_time=tool_start,
276
+ end_time=tool_end,
277
+ success=False,
278
+ error_message=str(e),
279
+ error_type=type(e).__name__,
280
+ )
281
+
282
+ print(f" ✓ Tool failure tracked: {type(e).__name__}")
283
+
284
+ print("\n✅ Execution continued despite errors (resilient)")
285
+
286
+
287
+ async def performance_test_example():
288
+ """
289
+ Example showing performance characteristics.
290
+
291
+ Analytics should add minimal overhead (<5ms per submission).
292
+ """
293
+
294
+ collector = create_analytics_collector(
295
+ control_plane_url="http://localhost:8000",
296
+ api_key="test-key",
297
+ )
298
+
299
+ ctx = ExecutionContext(
300
+ execution_id="perf-test",
301
+ organization_id="org-perf",
302
+ )
303
+
304
+ print("\n⚡ Performance Test\n")
305
+
306
+ # Test turn recording performance
307
+ turn_count = 10
308
+ start_time = time.time()
309
+
310
+ for i in range(turn_count):
311
+ ctx = collector.start_turn(ctx)
312
+
313
+ class MockResponse:
314
+ class Usage:
315
+ prompt_tokens = 1000
316
+ completion_tokens = 500
317
+ total_tokens = 1500
318
+
319
+ usage = Usage()
320
+
321
+ class Choice:
322
+ class Message:
323
+ content = "Response content"
324
+
325
+ message = Message()
326
+ finish_reason = "stop"
327
+
328
+ choices = [Choice()]
329
+
330
+ collector.record_turn_from_litellm(
331
+ ctx=ctx,
332
+ response=MockResponse(),
333
+ model="claude-sonnet-4",
334
+ )
335
+
336
+ end_time = time.time()
337
+ overhead_per_turn = ((end_time - start_time) / turn_count) * 1000
338
+
339
+ print(f" • Recorded {turn_count} turns")
340
+ print(f" • Overhead per turn: {overhead_per_turn:.2f}ms")
341
+ print(f" • Status: {'✓ Fast' if overhead_per_turn < 5 else '⚠️ Slow'}")
342
+
343
+ # Wait for submissions
344
+ await collector.wait_for_submissions()
345
+
346
+ print("\n✅ Performance test complete")
347
+
348
+
349
+ if __name__ == "__main__":
350
+ """Run all examples"""
351
+ print("=" * 70)
352
+ print("Analytics Integration Examples")
353
+ print("=" * 70)
354
+
355
+ # Run examples
356
+ asyncio.run(execute_agent_with_analytics_example())
357
+ asyncio.run(execute_agent_with_error_handling_example())
358
+ asyncio.run(performance_test_example())
359
+
360
+ print("\n" + "=" * 70)
361
+ print("Examples complete! Check Control Plane for analytics data.")
362
+ print("=" * 70)
@@ -0,0 +1 @@
1
+ """Data models for worker activities"""
@@ -0,0 +1,89 @@
1
+ """Input dataclasses for all Temporal activities"""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Optional, List, Dict, Any
5
+
6
+
7
+ @dataclass
8
+ class AgentExecutionInput:
9
+ """Input for agent execution activity"""
10
+ execution_id: str
11
+ agent_id: str
12
+ organization_id: str
13
+ prompt: str
14
+ system_prompt: Optional[str] = None
15
+ model_id: Optional[str] = None
16
+ model_config: Optional[Dict[str, Any]] = None
17
+ mcp_servers: Optional[Dict[str, Any]] = None
18
+ session_id: Optional[str] = None
19
+ user_id: Optional[str] = None
20
+
21
+ def __post_init__(self):
22
+ if self.model_config is None:
23
+ self.model_config = {}
24
+ if self.mcp_servers is None:
25
+ self.mcp_servers = {}
26
+
27
+
28
+ @dataclass
29
+ class TeamExecutionInput:
30
+ """Input for team execution activity"""
31
+ execution_id: str
32
+ team_id: str
33
+ organization_id: str
34
+ prompt: str
35
+ system_prompt: Optional[str] = None
36
+ model_id: Optional[str] = None
37
+ model_config: Optional[Dict[str, Any]] = None
38
+ mcp_servers: Optional[Dict[str, Any]] = None
39
+ session_id: Optional[str] = None
40
+ user_id: Optional[str] = None
41
+ team_config: Optional[Dict[str, Any]] = None
42
+
43
+ def __post_init__(self):
44
+ if self.model_config is None:
45
+ self.model_config = {}
46
+ if self.mcp_servers is None:
47
+ self.mcp_servers = {}
48
+ if self.team_config is None:
49
+ self.team_config = {}
50
+
51
+
52
+ @dataclass
53
+ class CancelExecutionInput:
54
+ """Input for cancellation activity"""
55
+ execution_id: str
56
+
57
+
58
+ @dataclass
59
+ class UpdateExecutionStatusInput:
60
+ """Input for status update activity"""
61
+ execution_id: str
62
+ status: str
63
+ started_at: Optional[str] = None
64
+ completed_at: Optional[str] = None
65
+ response: Optional[str] = None
66
+ error_message: Optional[str] = None
67
+ usage: Optional[Dict[str, Any]] = None
68
+ execution_metadata: Optional[Dict[str, Any]] = None
69
+
70
+ def __post_init__(self):
71
+ if self.usage is None:
72
+ self.usage = {}
73
+ if self.execution_metadata is None:
74
+ self.execution_metadata = {}
75
+
76
+
77
+ @dataclass
78
+ class UpdateAgentStatusInput:
79
+ """Input for agent status update"""
80
+ agent_id: str
81
+ organization_id: str
82
+ status: str
83
+ last_active_at: str
84
+ error_message: Optional[str] = None
85
+ state: Optional[Dict[str, Any]] = None
86
+
87
+ def __post_init__(self):
88
+ if self.state is None:
89
+ self.state = {}
@@ -0,0 +1,31 @@
1
+ """
2
+ Runtime abstraction layer for agent execution.
3
+
4
+ This package provides a pluggable runtime system that allows agents to be
5
+ powered by different frameworks (Agno, Claude Code SDK, etc.) without changing
6
+ the core workflow and activity logic.
7
+ """
8
+
9
+ from .base import (
10
+ RuntimeType,
11
+ RuntimeExecutionResult,
12
+ RuntimeExecutionContext,
13
+ RuntimeCapabilities,
14
+ BaseRuntime,
15
+ RuntimeRegistry,
16
+ )
17
+ from .factory import RuntimeFactory
18
+ from .default_runtime import DefaultRuntime
19
+ from .claude_code_runtime import ClaudeCodeRuntime
20
+
21
+ __all__ = [
22
+ "RuntimeType",
23
+ "RuntimeExecutionResult",
24
+ "RuntimeExecutionContext",
25
+ "RuntimeCapabilities",
26
+ "BaseRuntime",
27
+ "RuntimeRegistry",
28
+ "RuntimeFactory",
29
+ "DefaultRuntime",
30
+ "ClaudeCodeRuntime",
31
+ ]