agentex-sdk 0.1.0a6__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.
Files changed (289) hide show
  1. agentex/__init__.py +103 -0
  2. agentex/_base_client.py +1992 -0
  3. agentex/_client.py +506 -0
  4. agentex/_compat.py +219 -0
  5. agentex/_constants.py +14 -0
  6. agentex/_exceptions.py +108 -0
  7. agentex/_files.py +123 -0
  8. agentex/_models.py +829 -0
  9. agentex/_qs.py +150 -0
  10. agentex/_resource.py +43 -0
  11. agentex/_response.py +830 -0
  12. agentex/_streaming.py +333 -0
  13. agentex/_types.py +219 -0
  14. agentex/_utils/__init__.py +57 -0
  15. agentex/_utils/_logs.py +25 -0
  16. agentex/_utils/_proxy.py +65 -0
  17. agentex/_utils/_reflection.py +42 -0
  18. agentex/_utils/_resources_proxy.py +24 -0
  19. agentex/_utils/_streams.py +12 -0
  20. agentex/_utils/_sync.py +86 -0
  21. agentex/_utils/_transform.py +447 -0
  22. agentex/_utils/_typing.py +151 -0
  23. agentex/_utils/_utils.py +422 -0
  24. agentex/_version.py +4 -0
  25. agentex/lib/.keep +4 -0
  26. agentex/lib/__init__.py +0 -0
  27. agentex/lib/adk/__init__.py +41 -0
  28. agentex/lib/adk/_modules/__init__.py +0 -0
  29. agentex/lib/adk/_modules/acp.py +247 -0
  30. agentex/lib/adk/_modules/agent_task_tracker.py +176 -0
  31. agentex/lib/adk/_modules/agents.py +77 -0
  32. agentex/lib/adk/_modules/events.py +141 -0
  33. agentex/lib/adk/_modules/messages.py +285 -0
  34. agentex/lib/adk/_modules/state.py +291 -0
  35. agentex/lib/adk/_modules/streaming.py +75 -0
  36. agentex/lib/adk/_modules/tasks.py +124 -0
  37. agentex/lib/adk/_modules/tracing.py +194 -0
  38. agentex/lib/adk/providers/__init__.py +9 -0
  39. agentex/lib/adk/providers/_modules/__init__.py +0 -0
  40. agentex/lib/adk/providers/_modules/litellm.py +232 -0
  41. agentex/lib/adk/providers/_modules/openai.py +416 -0
  42. agentex/lib/adk/providers/_modules/sgp.py +85 -0
  43. agentex/lib/adk/utils/__init__.py +5 -0
  44. agentex/lib/adk/utils/_modules/__init__.py +0 -0
  45. agentex/lib/adk/utils/_modules/templating.py +94 -0
  46. agentex/lib/cli/__init__.py +0 -0
  47. agentex/lib/cli/commands/__init__.py +0 -0
  48. agentex/lib/cli/commands/agents.py +328 -0
  49. agentex/lib/cli/commands/init.py +227 -0
  50. agentex/lib/cli/commands/main.py +33 -0
  51. agentex/lib/cli/commands/secrets.py +169 -0
  52. agentex/lib/cli/commands/tasks.py +118 -0
  53. agentex/lib/cli/commands/uv.py +133 -0
  54. agentex/lib/cli/handlers/__init__.py +0 -0
  55. agentex/lib/cli/handlers/agent_handlers.py +160 -0
  56. agentex/lib/cli/handlers/cleanup_handlers.py +186 -0
  57. agentex/lib/cli/handlers/deploy_handlers.py +351 -0
  58. agentex/lib/cli/handlers/run_handlers.py +452 -0
  59. agentex/lib/cli/handlers/secret_handlers.py +670 -0
  60. agentex/lib/cli/templates/default/.dockerignore.j2 +43 -0
  61. agentex/lib/cli/templates/default/Dockerfile-uv.j2 +42 -0
  62. agentex/lib/cli/templates/default/Dockerfile.j2 +42 -0
  63. agentex/lib/cli/templates/default/README.md.j2 +193 -0
  64. agentex/lib/cli/templates/default/deploy/example.yaml.j2 +55 -0
  65. agentex/lib/cli/templates/default/manifest.yaml.j2 +116 -0
  66. agentex/lib/cli/templates/default/project/acp.py.j2 +29 -0
  67. agentex/lib/cli/templates/default/pyproject.toml.j2 +33 -0
  68. agentex/lib/cli/templates/default/requirements.txt.j2 +5 -0
  69. agentex/lib/cli/templates/deploy/Screenshot 2025-03-19 at 10.36.57/342/200/257AM.png +0 -0
  70. agentex/lib/cli/templates/deploy/example.yaml.j2 +55 -0
  71. agentex/lib/cli/templates/sync/.dockerignore.j2 +43 -0
  72. agentex/lib/cli/templates/sync/Dockerfile-uv.j2 +42 -0
  73. agentex/lib/cli/templates/sync/Dockerfile.j2 +42 -0
  74. agentex/lib/cli/templates/sync/README.md.j2 +293 -0
  75. agentex/lib/cli/templates/sync/deploy/example.yaml.j2 +55 -0
  76. agentex/lib/cli/templates/sync/manifest.yaml.j2 +116 -0
  77. agentex/lib/cli/templates/sync/project/acp.py.j2 +26 -0
  78. agentex/lib/cli/templates/sync/pyproject.toml.j2 +33 -0
  79. agentex/lib/cli/templates/sync/requirements.txt.j2 +5 -0
  80. agentex/lib/cli/templates/temporal/.dockerignore.j2 +43 -0
  81. agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 +48 -0
  82. agentex/lib/cli/templates/temporal/Dockerfile.j2 +48 -0
  83. agentex/lib/cli/templates/temporal/README.md.j2 +316 -0
  84. agentex/lib/cli/templates/temporal/deploy/example.yaml.j2 +55 -0
  85. agentex/lib/cli/templates/temporal/manifest.yaml.j2 +137 -0
  86. agentex/lib/cli/templates/temporal/project/acp.py.j2 +30 -0
  87. agentex/lib/cli/templates/temporal/project/run_worker.py.j2 +33 -0
  88. agentex/lib/cli/templates/temporal/project/workflow.py.j2 +66 -0
  89. agentex/lib/cli/templates/temporal/pyproject.toml.j2 +34 -0
  90. agentex/lib/cli/templates/temporal/requirements.txt.j2 +5 -0
  91. agentex/lib/cli/utils/cli_utils.py +14 -0
  92. agentex/lib/cli/utils/credential_utils.py +103 -0
  93. agentex/lib/cli/utils/exceptions.py +6 -0
  94. agentex/lib/cli/utils/kubectl_utils.py +135 -0
  95. agentex/lib/cli/utils/kubernetes_secrets_utils.py +185 -0
  96. agentex/lib/core/__init__.py +0 -0
  97. agentex/lib/core/adapters/__init__.py +0 -0
  98. agentex/lib/core/adapters/llm/__init__.py +1 -0
  99. agentex/lib/core/adapters/llm/adapter_litellm.py +46 -0
  100. agentex/lib/core/adapters/llm/adapter_sgp.py +55 -0
  101. agentex/lib/core/adapters/llm/port.py +24 -0
  102. agentex/lib/core/adapters/streams/adapter_redis.py +128 -0
  103. agentex/lib/core/adapters/streams/port.py +50 -0
  104. agentex/lib/core/clients/__init__.py +1 -0
  105. agentex/lib/core/clients/temporal/__init__.py +0 -0
  106. agentex/lib/core/clients/temporal/temporal_client.py +181 -0
  107. agentex/lib/core/clients/temporal/types.py +47 -0
  108. agentex/lib/core/clients/temporal/utils.py +56 -0
  109. agentex/lib/core/services/__init__.py +0 -0
  110. agentex/lib/core/services/adk/__init__.py +0 -0
  111. agentex/lib/core/services/adk/acp/__init__.py +0 -0
  112. agentex/lib/core/services/adk/acp/acp.py +210 -0
  113. agentex/lib/core/services/adk/agent_task_tracker.py +85 -0
  114. agentex/lib/core/services/adk/agents.py +43 -0
  115. agentex/lib/core/services/adk/events.py +61 -0
  116. agentex/lib/core/services/adk/messages.py +164 -0
  117. agentex/lib/core/services/adk/providers/__init__.py +0 -0
  118. agentex/lib/core/services/adk/providers/litellm.py +256 -0
  119. agentex/lib/core/services/adk/providers/openai.py +723 -0
  120. agentex/lib/core/services/adk/providers/sgp.py +99 -0
  121. agentex/lib/core/services/adk/state.py +120 -0
  122. agentex/lib/core/services/adk/streaming.py +262 -0
  123. agentex/lib/core/services/adk/tasks.py +69 -0
  124. agentex/lib/core/services/adk/tracing.py +36 -0
  125. agentex/lib/core/services/adk/utils/__init__.py +0 -0
  126. agentex/lib/core/services/adk/utils/templating.py +58 -0
  127. agentex/lib/core/temporal/__init__.py +0 -0
  128. agentex/lib/core/temporal/activities/__init__.py +207 -0
  129. agentex/lib/core/temporal/activities/activity_helpers.py +37 -0
  130. agentex/lib/core/temporal/activities/adk/__init__.py +0 -0
  131. agentex/lib/core/temporal/activities/adk/acp/__init__.py +0 -0
  132. agentex/lib/core/temporal/activities/adk/acp/acp_activities.py +86 -0
  133. agentex/lib/core/temporal/activities/adk/agent_task_tracker_activities.py +76 -0
  134. agentex/lib/core/temporal/activities/adk/agents_activities.py +35 -0
  135. agentex/lib/core/temporal/activities/adk/events_activities.py +50 -0
  136. agentex/lib/core/temporal/activities/adk/messages_activities.py +94 -0
  137. agentex/lib/core/temporal/activities/adk/providers/__init__.py +0 -0
  138. agentex/lib/core/temporal/activities/adk/providers/litellm_activities.py +71 -0
  139. agentex/lib/core/temporal/activities/adk/providers/openai_activities.py +210 -0
  140. agentex/lib/core/temporal/activities/adk/providers/sgp_activities.py +42 -0
  141. agentex/lib/core/temporal/activities/adk/state_activities.py +85 -0
  142. agentex/lib/core/temporal/activities/adk/streaming_activities.py +33 -0
  143. agentex/lib/core/temporal/activities/adk/tasks_activities.py +48 -0
  144. agentex/lib/core/temporal/activities/adk/tracing_activities.py +55 -0
  145. agentex/lib/core/temporal/activities/adk/utils/__init__.py +0 -0
  146. agentex/lib/core/temporal/activities/adk/utils/templating_activities.py +41 -0
  147. agentex/lib/core/temporal/services/__init__.py +0 -0
  148. agentex/lib/core/temporal/services/temporal_task_service.py +69 -0
  149. agentex/lib/core/temporal/types/__init__.py +0 -0
  150. agentex/lib/core/temporal/types/workflow.py +5 -0
  151. agentex/lib/core/temporal/workers/__init__.py +0 -0
  152. agentex/lib/core/temporal/workers/worker.py +162 -0
  153. agentex/lib/core/temporal/workflows/workflow.py +26 -0
  154. agentex/lib/core/tracing/__init__.py +5 -0
  155. agentex/lib/core/tracing/processors/agentex_tracing_processor.py +117 -0
  156. agentex/lib/core/tracing/processors/sgp_tracing_processor.py +119 -0
  157. agentex/lib/core/tracing/processors/tracing_processor_interface.py +40 -0
  158. agentex/lib/core/tracing/trace.py +311 -0
  159. agentex/lib/core/tracing/tracer.py +70 -0
  160. agentex/lib/core/tracing/tracing_processor_manager.py +62 -0
  161. agentex/lib/environment_variables.py +87 -0
  162. agentex/lib/py.typed +0 -0
  163. agentex/lib/sdk/__init__.py +0 -0
  164. agentex/lib/sdk/config/__init__.py +0 -0
  165. agentex/lib/sdk/config/agent_config.py +61 -0
  166. agentex/lib/sdk/config/agent_manifest.py +219 -0
  167. agentex/lib/sdk/config/build_config.py +35 -0
  168. agentex/lib/sdk/config/deployment_config.py +117 -0
  169. agentex/lib/sdk/config/local_development_config.py +56 -0
  170. agentex/lib/sdk/config/project_config.py +103 -0
  171. agentex/lib/sdk/fastacp/__init__.py +3 -0
  172. agentex/lib/sdk/fastacp/base/base_acp_server.py +406 -0
  173. agentex/lib/sdk/fastacp/fastacp.py +74 -0
  174. agentex/lib/sdk/fastacp/impl/agentic_base_acp.py +72 -0
  175. agentex/lib/sdk/fastacp/impl/sync_acp.py +109 -0
  176. agentex/lib/sdk/fastacp/impl/temporal_acp.py +97 -0
  177. agentex/lib/sdk/fastacp/tests/README.md +297 -0
  178. agentex/lib/sdk/fastacp/tests/conftest.py +307 -0
  179. agentex/lib/sdk/fastacp/tests/pytest.ini +10 -0
  180. agentex/lib/sdk/fastacp/tests/run_tests.py +227 -0
  181. agentex/lib/sdk/fastacp/tests/test_base_acp_server.py +450 -0
  182. agentex/lib/sdk/fastacp/tests/test_fastacp_factory.py +344 -0
  183. agentex/lib/sdk/fastacp/tests/test_integration.py +477 -0
  184. agentex/lib/sdk/state_machine/__init__.py +6 -0
  185. agentex/lib/sdk/state_machine/noop_workflow.py +21 -0
  186. agentex/lib/sdk/state_machine/state.py +10 -0
  187. agentex/lib/sdk/state_machine/state_machine.py +189 -0
  188. agentex/lib/sdk/state_machine/state_workflow.py +16 -0
  189. agentex/lib/sdk/utils/__init__.py +0 -0
  190. agentex/lib/sdk/utils/messages.py +223 -0
  191. agentex/lib/types/__init__.py +0 -0
  192. agentex/lib/types/acp.py +94 -0
  193. agentex/lib/types/agent_configs.py +79 -0
  194. agentex/lib/types/agent_results.py +29 -0
  195. agentex/lib/types/credentials.py +34 -0
  196. agentex/lib/types/fastacp.py +61 -0
  197. agentex/lib/types/files.py +13 -0
  198. agentex/lib/types/json_rpc.py +49 -0
  199. agentex/lib/types/llm_messages.py +354 -0
  200. agentex/lib/types/task_message_updates.py +171 -0
  201. agentex/lib/types/tracing.py +34 -0
  202. agentex/lib/utils/__init__.py +0 -0
  203. agentex/lib/utils/completions.py +131 -0
  204. agentex/lib/utils/console.py +14 -0
  205. agentex/lib/utils/io.py +29 -0
  206. agentex/lib/utils/iterables.py +14 -0
  207. agentex/lib/utils/json_schema.py +23 -0
  208. agentex/lib/utils/logging.py +31 -0
  209. agentex/lib/utils/mcp.py +17 -0
  210. agentex/lib/utils/model_utils.py +46 -0
  211. agentex/lib/utils/parsing.py +15 -0
  212. agentex/lib/utils/regex.py +6 -0
  213. agentex/lib/utils/temporal.py +13 -0
  214. agentex/py.typed +0 -0
  215. agentex/resources/__init__.py +103 -0
  216. agentex/resources/agents.py +707 -0
  217. agentex/resources/events.py +294 -0
  218. agentex/resources/messages/__init__.py +33 -0
  219. agentex/resources/messages/batch.py +271 -0
  220. agentex/resources/messages/messages.py +492 -0
  221. agentex/resources/spans.py +557 -0
  222. agentex/resources/states.py +544 -0
  223. agentex/resources/tasks.py +615 -0
  224. agentex/resources/tracker.py +384 -0
  225. agentex/types/__init__.py +56 -0
  226. agentex/types/acp_type.py +7 -0
  227. agentex/types/agent.py +29 -0
  228. agentex/types/agent_list_params.py +13 -0
  229. agentex/types/agent_list_response.py +10 -0
  230. agentex/types/agent_rpc_by_name_params.py +21 -0
  231. agentex/types/agent_rpc_params.py +51 -0
  232. agentex/types/agent_rpc_params1.py +21 -0
  233. agentex/types/agent_rpc_response.py +20 -0
  234. agentex/types/agent_rpc_result.py +90 -0
  235. agentex/types/agent_task_tracker.py +34 -0
  236. agentex/types/data_content.py +30 -0
  237. agentex/types/data_content_param.py +31 -0
  238. agentex/types/data_delta.py +14 -0
  239. agentex/types/event.py +29 -0
  240. agentex/types/event_list_params.py +22 -0
  241. agentex/types/event_list_response.py +10 -0
  242. agentex/types/message_author.py +7 -0
  243. agentex/types/message_create_params.py +18 -0
  244. agentex/types/message_list_params.py +14 -0
  245. agentex/types/message_list_response.py +10 -0
  246. agentex/types/message_style.py +7 -0
  247. agentex/types/message_update_params.py +18 -0
  248. agentex/types/messages/__init__.py +8 -0
  249. agentex/types/messages/batch_create_params.py +16 -0
  250. agentex/types/messages/batch_create_response.py +10 -0
  251. agentex/types/messages/batch_update_params.py +16 -0
  252. agentex/types/messages/batch_update_response.py +10 -0
  253. agentex/types/shared/__init__.py +3 -0
  254. agentex/types/shared/task_message_update.py +83 -0
  255. agentex/types/span.py +36 -0
  256. agentex/types/span_create_params.py +40 -0
  257. agentex/types/span_list_params.py +12 -0
  258. agentex/types/span_list_response.py +10 -0
  259. agentex/types/span_update_params.py +37 -0
  260. agentex/types/state.py +25 -0
  261. agentex/types/state_create_params.py +16 -0
  262. agentex/types/state_list_params.py +16 -0
  263. agentex/types/state_list_response.py +10 -0
  264. agentex/types/state_update_params.py +16 -0
  265. agentex/types/task.py +23 -0
  266. agentex/types/task_delete_by_name_response.py +8 -0
  267. agentex/types/task_delete_response.py +8 -0
  268. agentex/types/task_list_response.py +10 -0
  269. agentex/types/task_message.py +33 -0
  270. agentex/types/task_message_content.py +16 -0
  271. agentex/types/task_message_content_param.py +17 -0
  272. agentex/types/task_message_delta.py +16 -0
  273. agentex/types/text_content.py +53 -0
  274. agentex/types/text_content_param.py +54 -0
  275. agentex/types/text_delta.py +14 -0
  276. agentex/types/tool_request_content.py +36 -0
  277. agentex/types/tool_request_content_param.py +37 -0
  278. agentex/types/tool_request_delta.py +18 -0
  279. agentex/types/tool_response_content.py +36 -0
  280. agentex/types/tool_response_content_param.py +36 -0
  281. agentex/types/tool_response_delta.py +18 -0
  282. agentex/types/tracker_list_params.py +16 -0
  283. agentex/types/tracker_list_response.py +10 -0
  284. agentex/types/tracker_update_params.py +19 -0
  285. agentex_sdk-0.1.0a6.dist-info/METADATA +426 -0
  286. agentex_sdk-0.1.0a6.dist-info/RECORD +289 -0
  287. agentex_sdk-0.1.0a6.dist-info/WHEEL +4 -0
  288. agentex_sdk-0.1.0a6.dist-info/entry_points.txt +2 -0
  289. agentex_sdk-0.1.0a6.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,162 @@
1
+ import dataclasses
2
+ import datetime
3
+ import os
4
+ import uuid
5
+ from collections.abc import Callable
6
+ from concurrent.futures import ThreadPoolExecutor
7
+ from typing import Any
8
+
9
+ from aiohttp import web
10
+ from temporalio.client import Client
11
+ from temporalio.converter import (
12
+ AdvancedJSONEncoder,
13
+ CompositePayloadConverter,
14
+ DataConverter,
15
+ DefaultPayloadConverter,
16
+ JSONPlainPayloadConverter,
17
+ JSONTypeConverter,
18
+ _JSONTypeConverterUnhandled,
19
+ )
20
+ from temporalio.runtime import OpenTelemetryConfig, Runtime, TelemetryConfig
21
+ from temporalio.worker import (
22
+ UnsandboxedWorkflowRunner,
23
+ Worker,
24
+ )
25
+
26
+ from agentex.lib.utils.logging import make_logger
27
+
28
+ logger = make_logger(__name__)
29
+
30
+
31
+ class DateTimeJSONEncoder(AdvancedJSONEncoder):
32
+ def default(self, o: Any) -> Any:
33
+ if isinstance(o, datetime.datetime):
34
+ return o.isoformat()
35
+ return super().default(o)
36
+
37
+
38
+ class DateTimeJSONTypeConverter(JSONTypeConverter):
39
+ def to_typed_value(
40
+ self, hint: type, value: Any
41
+ ) -> Any | None | _JSONTypeConverterUnhandled:
42
+ if hint == datetime.datetime:
43
+ return datetime.datetime.fromisoformat(value)
44
+ return JSONTypeConverter.Unhandled
45
+
46
+
47
+ class DateTimePayloadConverter(CompositePayloadConverter):
48
+ def __init__(self) -> None:
49
+ json_converter = JSONPlainPayloadConverter(
50
+ encoder=DateTimeJSONEncoder,
51
+ custom_type_converters=[DateTimeJSONTypeConverter()],
52
+ )
53
+ super().__init__(
54
+ *[
55
+ c if not isinstance(c, JSONPlainPayloadConverter) else json_converter
56
+ for c in DefaultPayloadConverter.default_encoding_payload_converters
57
+ ]
58
+ )
59
+
60
+
61
+ custom_data_converter = dataclasses.replace(
62
+ DataConverter.default,
63
+ payload_converter_class=DateTimePayloadConverter,
64
+ )
65
+
66
+
67
+ async def get_temporal_client(temporal_address: str, metrics_url: str = None) -> Client:
68
+ if not metrics_url:
69
+ client = await Client.connect(
70
+ target_host=temporal_address, data_converter=custom_data_converter
71
+ )
72
+ else:
73
+ runtime = Runtime(
74
+ telemetry=TelemetryConfig(metrics=OpenTelemetryConfig(url=metrics_url))
75
+ )
76
+ client = await Client.connect(
77
+ target_host=temporal_address,
78
+ data_converter=custom_data_converter,
79
+ runtime=runtime,
80
+ )
81
+ return client
82
+
83
+
84
+ class AgentexWorker:
85
+ def __init__(
86
+ self,
87
+ task_queue,
88
+ max_workers: int = 10,
89
+ max_concurrent_activities: int = 10,
90
+ health_check_port: int = 80,
91
+ ):
92
+ self.task_queue = task_queue
93
+ self.activity_handles = []
94
+ self.max_workers = max_workers
95
+ self.max_concurrent_activities = max_concurrent_activities
96
+ self.health_check_server_running = False
97
+ self.healthy = False
98
+ self.health_check_port = health_check_port
99
+
100
+ async def run(
101
+ self,
102
+ activities: list[Callable],
103
+ workflow: type,
104
+ ):
105
+ await self.start_health_check_server()
106
+ temporal_client = await get_temporal_client(
107
+ temporal_address=os.environ.get("TEMPORAL_ADDRESS", "localhost:7233"),
108
+ )
109
+ worker = Worker(
110
+ client=temporal_client,
111
+ task_queue=self.task_queue,
112
+ activity_executor=ThreadPoolExecutor(max_workers=self.max_workers),
113
+ workflows=[workflow],
114
+ activities=activities,
115
+ workflow_runner=UnsandboxedWorkflowRunner(),
116
+ max_concurrent_activities=self.max_concurrent_activities,
117
+ build_id=str(uuid.uuid4()),
118
+ )
119
+
120
+ logger.info(f"Starting workers for task queue: {self.task_queue}")
121
+ # Eagerly set the worker status to healthy
122
+ self.healthy = True
123
+ logger.info(f"Running workers for task queue: {self.task_queue}")
124
+ await worker.run()
125
+
126
+ async def _health_check(self):
127
+ return web.json_response(self.healthy)
128
+
129
+ async def start_health_check_server(self):
130
+ if not self.health_check_server_running:
131
+ app = web.Application()
132
+ app.router.add_get("/readyz", lambda request: self._health_check())
133
+
134
+ # Disable access logging
135
+ runner = web.AppRunner(app, access_log=None)
136
+ await runner.setup()
137
+
138
+ try:
139
+ site = web.TCPSite(runner, "0.0.0.0", self.health_check_port)
140
+ await site.start()
141
+ logger.info(
142
+ f"Health check server running on http://0.0.0.0:{self.health_check_port}/readyz"
143
+ )
144
+ self.health_check_server_running = True
145
+ except OSError as e:
146
+ logger.error(
147
+ f"Failed to start health check server on port {self.health_check_port}: {e}"
148
+ )
149
+ # Try alternative port if default fails
150
+ try:
151
+ alt_port = self.health_check_port + 1
152
+ site = web.TCPSite(runner, "0.0.0.0", alt_port)
153
+ await site.start()
154
+ logger.info(
155
+ f"Health check server running on alternative port http://0.0.0.0:{alt_port}/readyz"
156
+ )
157
+ self.health_check_server_running = True
158
+ except OSError as e:
159
+ logger.error(
160
+ f"Failed to start health check server on alternative port {alt_port}: {e}"
161
+ )
162
+ raise
@@ -0,0 +1,26 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from temporalio import workflow
4
+
5
+ from agentex.lib.core.temporal.types.workflow import SignalName
6
+ from agentex.lib.types.acp import CreateTaskParams, SendEventParams
7
+ from agentex.lib.utils.logging import make_logger
8
+
9
+ logger = make_logger(__name__)
10
+
11
+
12
+ class BaseWorkflow(ABC):
13
+ def __init__(
14
+ self,
15
+ display_name: str,
16
+ ):
17
+ self.display_name = display_name
18
+
19
+ @abstractmethod
20
+ @workflow.signal(name=SignalName.RECEIVE_EVENT)
21
+ async def on_task_event_send(self, params: SendEventParams) -> None:
22
+ raise NotImplementedError
23
+
24
+ @abstractmethod
25
+ async def on_task_create(self, params: CreateTaskParams) -> None:
26
+ raise NotImplementedError
@@ -0,0 +1,5 @@
1
+ from agentex.lib.core.tracing.trace import AsyncTrace, Trace
2
+ from agentex.lib.core.tracing.tracer import AsyncTracer, Tracer
3
+ from agentex.types.span import Span
4
+
5
+ __all__ = ["Trace", "AsyncTrace", "Span", "Tracer", "AsyncTracer"]
@@ -0,0 +1,117 @@
1
+ from typing import Any, Dict, override
2
+
3
+ from agentex import Agentex, AsyncAgentex
4
+ from agentex.lib.core.tracing.processors.tracing_processor_interface import (
5
+ AsyncTracingProcessor,
6
+ SyncTracingProcessor,
7
+ )
8
+ from agentex.types.span import Span
9
+ from agentex.lib.types.tracing import AgentexTracingProcessorConfig
10
+
11
+
12
+ class AgentexSyncTracingProcessor(SyncTracingProcessor):
13
+ def __init__(self, config: AgentexTracingProcessorConfig):
14
+ self.client = Agentex()
15
+
16
+ @override
17
+ def on_span_start(self, span: Span) -> None:
18
+ self.client.spans.create(
19
+ name=span.name,
20
+ start_time=span.start_time,
21
+ end_time=span.end_time,
22
+ trace_id=span.trace_id,
23
+ id=span.id,
24
+ data=span.data,
25
+ input=span.input,
26
+ output=span.output,
27
+ parent_id=span.parent_id,
28
+ )
29
+
30
+ @override
31
+ def on_span_end(self, span: Span) -> None:
32
+ update: Dict[str, Any] = {}
33
+ if span.trace_id:
34
+ update["trace_id"] = span.trace_id
35
+ if span.name:
36
+ update["name"] = span.name
37
+ if span.parent_id:
38
+ update["parent_id"] = span.parent_id
39
+ if span.start_time:
40
+ update["start_time"] = span.start_time.isoformat()
41
+ if span.end_time is not None:
42
+ update["end_time"] = span.end_time.isoformat()
43
+ if span.input is not None:
44
+ update["input"] = span.input
45
+ if span.output is not None:
46
+ update["output"] = span.output
47
+ if span.data is not None:
48
+ update["data"] = span.data
49
+
50
+ self.client.spans.update(
51
+ span.id,
52
+ **span.model_dump(
53
+ mode="json",
54
+ exclude={"id"},
55
+ exclude_defaults=True,
56
+ exclude_none=True,
57
+ exclude_unset=True,
58
+ ),
59
+ )
60
+
61
+ @override
62
+ def shutdown(self) -> None:
63
+ pass
64
+
65
+
66
+ class AgentexAsyncTracingProcessor(AsyncTracingProcessor):
67
+ def __init__(self, config: AgentexTracingProcessorConfig):
68
+ self.client = AsyncAgentex()
69
+
70
+ @override
71
+ async def on_span_start(self, span: Span) -> None:
72
+ await self.client.spans.create(
73
+ name=span.name,
74
+ start_time=span.start_time,
75
+ end_time=span.end_time,
76
+ id=span.id,
77
+ trace_id=span.trace_id,
78
+ parent_id=span.parent_id,
79
+ input=span.input,
80
+ output=span.output,
81
+ data=span.data,
82
+ )
83
+
84
+ @override
85
+ async def on_span_end(self, span: Span) -> None:
86
+ update: Dict[str, Any] = {}
87
+ if span.trace_id:
88
+ update["trace_id"] = span.trace_id
89
+ if span.name:
90
+ update["name"] = span.name
91
+ if span.parent_id:
92
+ update["parent_id"] = span.parent_id
93
+ if span.start_time:
94
+ update["start_time"] = span.start_time.isoformat()
95
+ if span.end_time:
96
+ update["end_time"] = span.end_time.isoformat()
97
+ if span.input:
98
+ update["input"] = span.input
99
+ if span.output:
100
+ update["output"] = span.output
101
+ if span.data:
102
+ update["data"] = span.data
103
+
104
+ await self.client.spans.update(
105
+ span.id,
106
+ **span.model_dump(
107
+ mode="json",
108
+ exclude={"id"},
109
+ exclude_defaults=True,
110
+ exclude_none=True,
111
+ exclude_unset=True,
112
+ ),
113
+ )
114
+
115
+ @override
116
+ async def shutdown(self) -> None:
117
+ pass
@@ -0,0 +1,119 @@
1
+ from typing import override
2
+
3
+ import scale_gp_beta.lib.tracing as tracing
4
+ from scale_gp_beta import AsyncSGPClient, SGPClient
5
+ from scale_gp_beta.lib.tracing import create_span, flush_queue
6
+ from scale_gp_beta.lib.tracing.span import Span as SGPSpan
7
+
8
+ from agentex.lib.core.tracing.processors.tracing_processor_interface import (
9
+ AsyncTracingProcessor,
10
+ SyncTracingProcessor,
11
+ )
12
+ from agentex.types.span import Span
13
+ from agentex.lib.types.tracing import SGPTracingProcessorConfig
14
+ from agentex.lib.utils.logging import make_logger
15
+
16
+ logger = make_logger(__name__)
17
+
18
+
19
+ class SGPSyncTracingProcessor(SyncTracingProcessor):
20
+ def __init__(self, config: SGPTracingProcessorConfig):
21
+ disabled = config.sgp_api_key == "" or config.sgp_account_id == ""
22
+ tracing.init(
23
+ SGPClient(api_key=config.sgp_api_key, account_id=config.sgp_account_id),
24
+ disabled=disabled,
25
+ )
26
+ self._spans: dict[str, SGPSpan] = {}
27
+
28
+ @override
29
+ def on_span_start(self, span: Span) -> None:
30
+ sgp_span = create_span(
31
+ name=span.name,
32
+ span_id=span.id,
33
+ parent_id=span.parent_id,
34
+ trace_id=span.trace_id,
35
+ input=span.input,
36
+ output=span.output,
37
+ metadata=span.data,
38
+ )
39
+ sgp_span.start_time = span.start_time.isoformat()
40
+ sgp_span.flush(blocking=False)
41
+
42
+ self._spans[span.id] = sgp_span
43
+
44
+ @override
45
+ def on_span_end(self, span: Span) -> None:
46
+ sgp_span = self._spans.get(span.id)
47
+ if sgp_span is None:
48
+ logger.warning(
49
+ f"Span {span.id} not found in stored spans, skipping span end"
50
+ )
51
+ return
52
+
53
+ sgp_span.output = span.output
54
+ sgp_span.metadata = span.data
55
+ sgp_span.end_time = span.end_time.isoformat()
56
+ sgp_span.flush(blocking=False)
57
+
58
+ @override
59
+ def shutdown(self) -> None:
60
+ self._spans.clear()
61
+ flush_queue()
62
+
63
+
64
+ class SGPAsyncTracingProcessor(AsyncTracingProcessor):
65
+ def __init__(self, config: SGPTracingProcessorConfig):
66
+ self.disabled = config.sgp_api_key == "" or config.sgp_account_id == ""
67
+ self._spans: dict[str, SGPSpan] = {}
68
+ self.sgp_async_client = (
69
+ AsyncSGPClient(api_key=config.sgp_api_key, account_id=config.sgp_account_id)
70
+ if not self.disabled
71
+ else None
72
+ )
73
+
74
+ @override
75
+ async def on_span_start(self, span: Span) -> None:
76
+ sgp_span = create_span(
77
+ name=span.name,
78
+ span_id=span.id,
79
+ parent_id=span.parent_id,
80
+ trace_id=span.trace_id,
81
+ input=span.input,
82
+ output=span.output,
83
+ metadata=span.data,
84
+ )
85
+ sgp_span.start_time = span.start_time.isoformat()
86
+
87
+ if self.disabled:
88
+ return
89
+ await self.sgp_async_client.spans.upsert_batch(
90
+ items=[sgp_span.to_request_params()]
91
+ )
92
+
93
+ self._spans[span.id] = sgp_span
94
+
95
+ @override
96
+ async def on_span_end(self, span: Span) -> None:
97
+ sgp_span = self._spans.get(span.id)
98
+ if sgp_span is None:
99
+ logger.warning(
100
+ f"Span {span.id} not found in stored spans, skipping span end"
101
+ )
102
+ return
103
+
104
+ sgp_span.output = span.output
105
+ sgp_span.metadata = span.data
106
+ sgp_span.end_time = span.end_time.isoformat()
107
+
108
+ if self.disabled:
109
+ return
110
+ await self.sgp_async_client.spans.upsert_batch(
111
+ items=[sgp_span.to_request_params()]
112
+ )
113
+
114
+ @override
115
+ async def shutdown(self) -> None:
116
+ await self.sgp_async_client.spans.upsert_batch(
117
+ items=[sgp_span.to_request_params() for sgp_span in self._spans.values()]
118
+ )
119
+ self._spans.clear()
@@ -0,0 +1,40 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from agentex.lib.types.tracing import TracingProcessorConfig
4
+ from agentex.types.span import Span
5
+
6
+
7
+ class SyncTracingProcessor(ABC):
8
+ @abstractmethod
9
+ def __init__(self, config: TracingProcessorConfig):
10
+ pass
11
+
12
+ @abstractmethod
13
+ def on_span_start(self, span: Span) -> None:
14
+ pass
15
+
16
+ @abstractmethod
17
+ def on_span_end(self, span: Span) -> None:
18
+ pass
19
+
20
+ @abstractmethod
21
+ def shutdown(self) -> None:
22
+ pass
23
+
24
+
25
+ class AsyncTracingProcessor(ABC):
26
+ @abstractmethod
27
+ def __init__(self, config: TracingProcessorConfig):
28
+ pass
29
+
30
+ @abstractmethod
31
+ async def on_span_start(self, span: Span) -> None:
32
+ pass
33
+
34
+ @abstractmethod
35
+ async def on_span_end(self, span: Span) -> None:
36
+ pass
37
+
38
+ @abstractmethod
39
+ async def shutdown(self) -> None:
40
+ pass