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.
- agentex/__init__.py +103 -0
- agentex/_base_client.py +1992 -0
- agentex/_client.py +506 -0
- agentex/_compat.py +219 -0
- agentex/_constants.py +14 -0
- agentex/_exceptions.py +108 -0
- agentex/_files.py +123 -0
- agentex/_models.py +829 -0
- agentex/_qs.py +150 -0
- agentex/_resource.py +43 -0
- agentex/_response.py +830 -0
- agentex/_streaming.py +333 -0
- agentex/_types.py +219 -0
- agentex/_utils/__init__.py +57 -0
- agentex/_utils/_logs.py +25 -0
- agentex/_utils/_proxy.py +65 -0
- agentex/_utils/_reflection.py +42 -0
- agentex/_utils/_resources_proxy.py +24 -0
- agentex/_utils/_streams.py +12 -0
- agentex/_utils/_sync.py +86 -0
- agentex/_utils/_transform.py +447 -0
- agentex/_utils/_typing.py +151 -0
- agentex/_utils/_utils.py +422 -0
- agentex/_version.py +4 -0
- agentex/lib/.keep +4 -0
- agentex/lib/__init__.py +0 -0
- agentex/lib/adk/__init__.py +41 -0
- agentex/lib/adk/_modules/__init__.py +0 -0
- agentex/lib/adk/_modules/acp.py +247 -0
- agentex/lib/adk/_modules/agent_task_tracker.py +176 -0
- agentex/lib/adk/_modules/agents.py +77 -0
- agentex/lib/adk/_modules/events.py +141 -0
- agentex/lib/adk/_modules/messages.py +285 -0
- agentex/lib/adk/_modules/state.py +291 -0
- agentex/lib/adk/_modules/streaming.py +75 -0
- agentex/lib/adk/_modules/tasks.py +124 -0
- agentex/lib/adk/_modules/tracing.py +194 -0
- agentex/lib/adk/providers/__init__.py +9 -0
- agentex/lib/adk/providers/_modules/__init__.py +0 -0
- agentex/lib/adk/providers/_modules/litellm.py +232 -0
- agentex/lib/adk/providers/_modules/openai.py +416 -0
- agentex/lib/adk/providers/_modules/sgp.py +85 -0
- agentex/lib/adk/utils/__init__.py +5 -0
- agentex/lib/adk/utils/_modules/__init__.py +0 -0
- agentex/lib/adk/utils/_modules/templating.py +94 -0
- agentex/lib/cli/__init__.py +0 -0
- agentex/lib/cli/commands/__init__.py +0 -0
- agentex/lib/cli/commands/agents.py +328 -0
- agentex/lib/cli/commands/init.py +227 -0
- agentex/lib/cli/commands/main.py +33 -0
- agentex/lib/cli/commands/secrets.py +169 -0
- agentex/lib/cli/commands/tasks.py +118 -0
- agentex/lib/cli/commands/uv.py +133 -0
- agentex/lib/cli/handlers/__init__.py +0 -0
- agentex/lib/cli/handlers/agent_handlers.py +160 -0
- agentex/lib/cli/handlers/cleanup_handlers.py +186 -0
- agentex/lib/cli/handlers/deploy_handlers.py +351 -0
- agentex/lib/cli/handlers/run_handlers.py +452 -0
- agentex/lib/cli/handlers/secret_handlers.py +670 -0
- agentex/lib/cli/templates/default/.dockerignore.j2 +43 -0
- agentex/lib/cli/templates/default/Dockerfile-uv.j2 +42 -0
- agentex/lib/cli/templates/default/Dockerfile.j2 +42 -0
- agentex/lib/cli/templates/default/README.md.j2 +193 -0
- agentex/lib/cli/templates/default/deploy/example.yaml.j2 +55 -0
- agentex/lib/cli/templates/default/manifest.yaml.j2 +116 -0
- agentex/lib/cli/templates/default/project/acp.py.j2 +29 -0
- agentex/lib/cli/templates/default/pyproject.toml.j2 +33 -0
- agentex/lib/cli/templates/default/requirements.txt.j2 +5 -0
- agentex/lib/cli/templates/deploy/Screenshot 2025-03-19 at 10.36.57/342/200/257AM.png +0 -0
- agentex/lib/cli/templates/deploy/example.yaml.j2 +55 -0
- agentex/lib/cli/templates/sync/.dockerignore.j2 +43 -0
- agentex/lib/cli/templates/sync/Dockerfile-uv.j2 +42 -0
- agentex/lib/cli/templates/sync/Dockerfile.j2 +42 -0
- agentex/lib/cli/templates/sync/README.md.j2 +293 -0
- agentex/lib/cli/templates/sync/deploy/example.yaml.j2 +55 -0
- agentex/lib/cli/templates/sync/manifest.yaml.j2 +116 -0
- agentex/lib/cli/templates/sync/project/acp.py.j2 +26 -0
- agentex/lib/cli/templates/sync/pyproject.toml.j2 +33 -0
- agentex/lib/cli/templates/sync/requirements.txt.j2 +5 -0
- agentex/lib/cli/templates/temporal/.dockerignore.j2 +43 -0
- agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 +48 -0
- agentex/lib/cli/templates/temporal/Dockerfile.j2 +48 -0
- agentex/lib/cli/templates/temporal/README.md.j2 +316 -0
- agentex/lib/cli/templates/temporal/deploy/example.yaml.j2 +55 -0
- agentex/lib/cli/templates/temporal/manifest.yaml.j2 +137 -0
- agentex/lib/cli/templates/temporal/project/acp.py.j2 +30 -0
- agentex/lib/cli/templates/temporal/project/run_worker.py.j2 +33 -0
- agentex/lib/cli/templates/temporal/project/workflow.py.j2 +66 -0
- agentex/lib/cli/templates/temporal/pyproject.toml.j2 +34 -0
- agentex/lib/cli/templates/temporal/requirements.txt.j2 +5 -0
- agentex/lib/cli/utils/cli_utils.py +14 -0
- agentex/lib/cli/utils/credential_utils.py +103 -0
- agentex/lib/cli/utils/exceptions.py +6 -0
- agentex/lib/cli/utils/kubectl_utils.py +135 -0
- agentex/lib/cli/utils/kubernetes_secrets_utils.py +185 -0
- agentex/lib/core/__init__.py +0 -0
- agentex/lib/core/adapters/__init__.py +0 -0
- agentex/lib/core/adapters/llm/__init__.py +1 -0
- agentex/lib/core/adapters/llm/adapter_litellm.py +46 -0
- agentex/lib/core/adapters/llm/adapter_sgp.py +55 -0
- agentex/lib/core/adapters/llm/port.py +24 -0
- agentex/lib/core/adapters/streams/adapter_redis.py +128 -0
- agentex/lib/core/adapters/streams/port.py +50 -0
- agentex/lib/core/clients/__init__.py +1 -0
- agentex/lib/core/clients/temporal/__init__.py +0 -0
- agentex/lib/core/clients/temporal/temporal_client.py +181 -0
- agentex/lib/core/clients/temporal/types.py +47 -0
- agentex/lib/core/clients/temporal/utils.py +56 -0
- agentex/lib/core/services/__init__.py +0 -0
- agentex/lib/core/services/adk/__init__.py +0 -0
- agentex/lib/core/services/adk/acp/__init__.py +0 -0
- agentex/lib/core/services/adk/acp/acp.py +210 -0
- agentex/lib/core/services/adk/agent_task_tracker.py +85 -0
- agentex/lib/core/services/adk/agents.py +43 -0
- agentex/lib/core/services/adk/events.py +61 -0
- agentex/lib/core/services/adk/messages.py +164 -0
- agentex/lib/core/services/adk/providers/__init__.py +0 -0
- agentex/lib/core/services/adk/providers/litellm.py +256 -0
- agentex/lib/core/services/adk/providers/openai.py +723 -0
- agentex/lib/core/services/adk/providers/sgp.py +99 -0
- agentex/lib/core/services/adk/state.py +120 -0
- agentex/lib/core/services/adk/streaming.py +262 -0
- agentex/lib/core/services/adk/tasks.py +69 -0
- agentex/lib/core/services/adk/tracing.py +36 -0
- agentex/lib/core/services/adk/utils/__init__.py +0 -0
- agentex/lib/core/services/adk/utils/templating.py +58 -0
- agentex/lib/core/temporal/__init__.py +0 -0
- agentex/lib/core/temporal/activities/__init__.py +207 -0
- agentex/lib/core/temporal/activities/activity_helpers.py +37 -0
- agentex/lib/core/temporal/activities/adk/__init__.py +0 -0
- agentex/lib/core/temporal/activities/adk/acp/__init__.py +0 -0
- agentex/lib/core/temporal/activities/adk/acp/acp_activities.py +86 -0
- agentex/lib/core/temporal/activities/adk/agent_task_tracker_activities.py +76 -0
- agentex/lib/core/temporal/activities/adk/agents_activities.py +35 -0
- agentex/lib/core/temporal/activities/adk/events_activities.py +50 -0
- agentex/lib/core/temporal/activities/adk/messages_activities.py +94 -0
- agentex/lib/core/temporal/activities/adk/providers/__init__.py +0 -0
- agentex/lib/core/temporal/activities/adk/providers/litellm_activities.py +71 -0
- agentex/lib/core/temporal/activities/adk/providers/openai_activities.py +210 -0
- agentex/lib/core/temporal/activities/adk/providers/sgp_activities.py +42 -0
- agentex/lib/core/temporal/activities/adk/state_activities.py +85 -0
- agentex/lib/core/temporal/activities/adk/streaming_activities.py +33 -0
- agentex/lib/core/temporal/activities/adk/tasks_activities.py +48 -0
- agentex/lib/core/temporal/activities/adk/tracing_activities.py +55 -0
- agentex/lib/core/temporal/activities/adk/utils/__init__.py +0 -0
- agentex/lib/core/temporal/activities/adk/utils/templating_activities.py +41 -0
- agentex/lib/core/temporal/services/__init__.py +0 -0
- agentex/lib/core/temporal/services/temporal_task_service.py +69 -0
- agentex/lib/core/temporal/types/__init__.py +0 -0
- agentex/lib/core/temporal/types/workflow.py +5 -0
- agentex/lib/core/temporal/workers/__init__.py +0 -0
- agentex/lib/core/temporal/workers/worker.py +162 -0
- agentex/lib/core/temporal/workflows/workflow.py +26 -0
- agentex/lib/core/tracing/__init__.py +5 -0
- agentex/lib/core/tracing/processors/agentex_tracing_processor.py +117 -0
- agentex/lib/core/tracing/processors/sgp_tracing_processor.py +119 -0
- agentex/lib/core/tracing/processors/tracing_processor_interface.py +40 -0
- agentex/lib/core/tracing/trace.py +311 -0
- agentex/lib/core/tracing/tracer.py +70 -0
- agentex/lib/core/tracing/tracing_processor_manager.py +62 -0
- agentex/lib/environment_variables.py +87 -0
- agentex/lib/py.typed +0 -0
- agentex/lib/sdk/__init__.py +0 -0
- agentex/lib/sdk/config/__init__.py +0 -0
- agentex/lib/sdk/config/agent_config.py +61 -0
- agentex/lib/sdk/config/agent_manifest.py +219 -0
- agentex/lib/sdk/config/build_config.py +35 -0
- agentex/lib/sdk/config/deployment_config.py +117 -0
- agentex/lib/sdk/config/local_development_config.py +56 -0
- agentex/lib/sdk/config/project_config.py +103 -0
- agentex/lib/sdk/fastacp/__init__.py +3 -0
- agentex/lib/sdk/fastacp/base/base_acp_server.py +406 -0
- agentex/lib/sdk/fastacp/fastacp.py +74 -0
- agentex/lib/sdk/fastacp/impl/agentic_base_acp.py +72 -0
- agentex/lib/sdk/fastacp/impl/sync_acp.py +109 -0
- agentex/lib/sdk/fastacp/impl/temporal_acp.py +97 -0
- agentex/lib/sdk/fastacp/tests/README.md +297 -0
- agentex/lib/sdk/fastacp/tests/conftest.py +307 -0
- agentex/lib/sdk/fastacp/tests/pytest.ini +10 -0
- agentex/lib/sdk/fastacp/tests/run_tests.py +227 -0
- agentex/lib/sdk/fastacp/tests/test_base_acp_server.py +450 -0
- agentex/lib/sdk/fastacp/tests/test_fastacp_factory.py +344 -0
- agentex/lib/sdk/fastacp/tests/test_integration.py +477 -0
- agentex/lib/sdk/state_machine/__init__.py +6 -0
- agentex/lib/sdk/state_machine/noop_workflow.py +21 -0
- agentex/lib/sdk/state_machine/state.py +10 -0
- agentex/lib/sdk/state_machine/state_machine.py +189 -0
- agentex/lib/sdk/state_machine/state_workflow.py +16 -0
- agentex/lib/sdk/utils/__init__.py +0 -0
- agentex/lib/sdk/utils/messages.py +223 -0
- agentex/lib/types/__init__.py +0 -0
- agentex/lib/types/acp.py +94 -0
- agentex/lib/types/agent_configs.py +79 -0
- agentex/lib/types/agent_results.py +29 -0
- agentex/lib/types/credentials.py +34 -0
- agentex/lib/types/fastacp.py +61 -0
- agentex/lib/types/files.py +13 -0
- agentex/lib/types/json_rpc.py +49 -0
- agentex/lib/types/llm_messages.py +354 -0
- agentex/lib/types/task_message_updates.py +171 -0
- agentex/lib/types/tracing.py +34 -0
- agentex/lib/utils/__init__.py +0 -0
- agentex/lib/utils/completions.py +131 -0
- agentex/lib/utils/console.py +14 -0
- agentex/lib/utils/io.py +29 -0
- agentex/lib/utils/iterables.py +14 -0
- agentex/lib/utils/json_schema.py +23 -0
- agentex/lib/utils/logging.py +31 -0
- agentex/lib/utils/mcp.py +17 -0
- agentex/lib/utils/model_utils.py +46 -0
- agentex/lib/utils/parsing.py +15 -0
- agentex/lib/utils/regex.py +6 -0
- agentex/lib/utils/temporal.py +13 -0
- agentex/py.typed +0 -0
- agentex/resources/__init__.py +103 -0
- agentex/resources/agents.py +707 -0
- agentex/resources/events.py +294 -0
- agentex/resources/messages/__init__.py +33 -0
- agentex/resources/messages/batch.py +271 -0
- agentex/resources/messages/messages.py +492 -0
- agentex/resources/spans.py +557 -0
- agentex/resources/states.py +544 -0
- agentex/resources/tasks.py +615 -0
- agentex/resources/tracker.py +384 -0
- agentex/types/__init__.py +56 -0
- agentex/types/acp_type.py +7 -0
- agentex/types/agent.py +29 -0
- agentex/types/agent_list_params.py +13 -0
- agentex/types/agent_list_response.py +10 -0
- agentex/types/agent_rpc_by_name_params.py +21 -0
- agentex/types/agent_rpc_params.py +51 -0
- agentex/types/agent_rpc_params1.py +21 -0
- agentex/types/agent_rpc_response.py +20 -0
- agentex/types/agent_rpc_result.py +90 -0
- agentex/types/agent_task_tracker.py +34 -0
- agentex/types/data_content.py +30 -0
- agentex/types/data_content_param.py +31 -0
- agentex/types/data_delta.py +14 -0
- agentex/types/event.py +29 -0
- agentex/types/event_list_params.py +22 -0
- agentex/types/event_list_response.py +10 -0
- agentex/types/message_author.py +7 -0
- agentex/types/message_create_params.py +18 -0
- agentex/types/message_list_params.py +14 -0
- agentex/types/message_list_response.py +10 -0
- agentex/types/message_style.py +7 -0
- agentex/types/message_update_params.py +18 -0
- agentex/types/messages/__init__.py +8 -0
- agentex/types/messages/batch_create_params.py +16 -0
- agentex/types/messages/batch_create_response.py +10 -0
- agentex/types/messages/batch_update_params.py +16 -0
- agentex/types/messages/batch_update_response.py +10 -0
- agentex/types/shared/__init__.py +3 -0
- agentex/types/shared/task_message_update.py +83 -0
- agentex/types/span.py +36 -0
- agentex/types/span_create_params.py +40 -0
- agentex/types/span_list_params.py +12 -0
- agentex/types/span_list_response.py +10 -0
- agentex/types/span_update_params.py +37 -0
- agentex/types/state.py +25 -0
- agentex/types/state_create_params.py +16 -0
- agentex/types/state_list_params.py +16 -0
- agentex/types/state_list_response.py +10 -0
- agentex/types/state_update_params.py +16 -0
- agentex/types/task.py +23 -0
- agentex/types/task_delete_by_name_response.py +8 -0
- agentex/types/task_delete_response.py +8 -0
- agentex/types/task_list_response.py +10 -0
- agentex/types/task_message.py +33 -0
- agentex/types/task_message_content.py +16 -0
- agentex/types/task_message_content_param.py +17 -0
- agentex/types/task_message_delta.py +16 -0
- agentex/types/text_content.py +53 -0
- agentex/types/text_content_param.py +54 -0
- agentex/types/text_delta.py +14 -0
- agentex/types/tool_request_content.py +36 -0
- agentex/types/tool_request_content_param.py +37 -0
- agentex/types/tool_request_delta.py +18 -0
- agentex/types/tool_response_content.py +36 -0
- agentex/types/tool_response_content_param.py +36 -0
- agentex/types/tool_response_delta.py +18 -0
- agentex/types/tracker_list_params.py +16 -0
- agentex/types/tracker_list_response.py +10 -0
- agentex/types/tracker_update_params.py +19 -0
- agentex_sdk-0.1.0a6.dist-info/METADATA +426 -0
- agentex_sdk-0.1.0a6.dist-info/RECORD +289 -0
- agentex_sdk-0.1.0a6.dist-info/WHEEL +4 -0
- agentex_sdk-0.1.0a6.dist-info/entry_points.txt +2 -0
- 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,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
|