agentex-sdk 0.2.4__py3-none-any.whl → 0.2.5__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/_version.py +1 -1
- agentex/lib/cli/commands/agents.py +3 -3
- agentex/lib/cli/handlers/agent_handlers.py +1 -1
- agentex/lib/cli/handlers/cleanup_handlers.py +9 -15
- agentex/lib/cli/handlers/deploy_handlers.py +28 -4
- agentex/lib/cli/handlers/run_handlers.py +19 -93
- agentex/lib/cli/templates/sync/project/acp.py.j2 +15 -64
- agentex/lib/cli/utils/path_utils.py +143 -0
- agentex/lib/types/converters.py +60 -0
- agentex/resources/agents.py +9 -8
- agentex/resources/messages/messages.py +4 -0
- agentex/resources/tasks.py +9 -10
- agentex/types/__init__.py +1 -2
- agentex/types/message_list_params.py +1 -0
- agentex/types/shared/__init__.py +3 -0
- agentex/types/shared/delete_response.py +11 -0
- {agentex_sdk-0.2.4.dist-info → agentex_sdk-0.2.5.dist-info}/METADATA +2 -2
- {agentex_sdk-0.2.4.dist-info → agentex_sdk-0.2.5.dist-info}/RECORD +21 -19
- agentex/types/task_delete_by_name_response.py +0 -8
- agentex/types/task_delete_response.py +0 -8
- {agentex_sdk-0.2.4.dist-info → agentex_sdk-0.2.5.dist-info}/WHEEL +0 -0
- {agentex_sdk-0.2.4.dist-info → agentex_sdk-0.2.5.dist-info}/entry_points.txt +0 -0
- {agentex_sdk-0.2.4.dist-info → agentex_sdk-0.2.5.dist-info}/licenses/LICENSE +0 -0
agentex/_version.py
CHANGED
@@ -141,13 +141,13 @@ def build(
|
|
141
141
|
typer.echo("No registry provided, skipping image build")
|
142
142
|
return
|
143
143
|
|
144
|
-
platform_list = platforms.split(",") if platforms else []
|
144
|
+
platform_list = platforms.split(",") if platforms else ["linux/amd64"]
|
145
145
|
|
146
146
|
try:
|
147
147
|
image_url = build_agent(
|
148
148
|
manifest_path=manifest,
|
149
|
-
registry_url=registry,
|
150
|
-
repository_name=repository_name
|
149
|
+
registry_url=registry,
|
150
|
+
repository_name=repository_name,
|
151
151
|
platforms=platform_list,
|
152
152
|
push=push,
|
153
153
|
secret=secret or "", # Provide default empty string
|
@@ -168,19 +168,13 @@ def cleanup_single_task(client: Agentex, agent_name: str, task_id: str) -> None:
|
|
168
168
|
"""
|
169
169
|
try:
|
170
170
|
# Use the agent RPC method to cancel the task
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
except Exception as e:
|
179
|
-
# If RPC cancel fails, try direct task deletion as fallback
|
180
|
-
logger.warning(f"RPC task/cancel failed for task {task_id}, trying direct deletion: {e}")
|
181
|
-
client.tasks.delete(task_id=task_id)
|
182
|
-
logger.debug(f"Successfully deleted task {task_id} directly")
|
183
|
-
|
171
|
+
client.agents.rpc_by_name(
|
172
|
+
agent_name=agent_name,
|
173
|
+
method="task/cancel",
|
174
|
+
params={"task_id": task_id}
|
175
|
+
)
|
176
|
+
logger.debug(f"Successfully cancelled task {task_id} via agent '{agent_name}'")
|
177
|
+
|
184
178
|
except Exception as e:
|
185
|
-
logger.warning(f"
|
186
|
-
raise
|
179
|
+
logger.warning(f"RPC task/cancel failed for task {task_id}: {e}")
|
180
|
+
raise
|
@@ -11,6 +11,7 @@ from rich.console import Console
|
|
11
11
|
from agentex.lib.cli.utils.auth_utils import _encode_principal_context
|
12
12
|
from agentex.lib.cli.utils.exceptions import DeploymentError, HelmError
|
13
13
|
from agentex.lib.cli.utils.kubectl_utils import check_and_switch_cluster_context
|
14
|
+
from agentex.lib.cli.utils.path_utils import calculate_docker_acp_module, PathResolutionError
|
14
15
|
from agentex.lib.environment_variables import EnvVarKeys
|
15
16
|
from agentex.lib.sdk.config.agent_config import AgentConfig
|
16
17
|
from agentex.lib.sdk.config.agent_manifest import AgentManifest
|
@@ -100,10 +101,24 @@ def convert_env_vars_dict_to_list(env_vars: dict[str, str]) -> list[dict[str, st
|
|
100
101
|
return [{"name": key, "value": value} for key, value in env_vars.items()]
|
101
102
|
|
102
103
|
|
104
|
+
def add_acp_command_to_helm_values(helm_values: dict[str, Any], manifest: AgentManifest, manifest_path: str) -> None:
|
105
|
+
"""Add dynamic ACP command to helm values based on manifest configuration"""
|
106
|
+
try:
|
107
|
+
docker_acp_module = calculate_docker_acp_module(manifest, manifest_path)
|
108
|
+
# Create the uvicorn command with the correct module path
|
109
|
+
helm_values["command"] = ["uvicorn", f"{docker_acp_module}:acp", "--host", "0.0.0.0", "--port", "8000"]
|
110
|
+
logger.info(f"Using dynamic ACP command: uvicorn {docker_acp_module}:acp")
|
111
|
+
except (PathResolutionError, Exception) as e:
|
112
|
+
# Fallback to default command structure
|
113
|
+
logger.warning(f"Could not calculate dynamic ACP module ({e}), using default: project.acp")
|
114
|
+
helm_values["command"] = ["uvicorn", "project.acp:acp", "--host", "0.0.0.0", "--port", "8000"]
|
115
|
+
|
116
|
+
|
103
117
|
def merge_deployment_configs(
|
104
118
|
manifest: AgentManifest,
|
105
119
|
cluster_config: ClusterConfig | None,
|
106
120
|
deploy_overrides: InputDeployOverrides,
|
121
|
+
manifest_path: str,
|
107
122
|
) -> dict[str, Any]:
|
108
123
|
agent_config: AgentConfig = manifest.agent
|
109
124
|
|
@@ -176,9 +191,12 @@ def merge_deployment_configs(
|
|
176
191
|
if TEMPORAL_WORKER_KEY in helm_values:
|
177
192
|
helm_values[TEMPORAL_WORKER_KEY]["env"] = agent_config.env
|
178
193
|
|
179
|
-
|
180
|
-
|
181
|
-
|
194
|
+
# Add auth principal env var if manifest principal is set
|
195
|
+
encoded_principal = _encode_principal_context(manifest)
|
196
|
+
if encoded_principal:
|
197
|
+
if "env" not in helm_values:
|
198
|
+
helm_values["env"] = {}
|
199
|
+
helm_values["env"][EnvVarKeys.AUTH_PRINCIPAL_B64.value] = encoded_principal
|
182
200
|
|
183
201
|
if manifest.deployment and manifest.deployment.imagePullSecrets:
|
184
202
|
pull_secrets = [
|
@@ -228,10 +246,16 @@ def merge_deployment_configs(
|
|
228
246
|
# Convert the env vars to a list of dictionaries
|
229
247
|
if "env" in helm_values:
|
230
248
|
helm_values["env"] = convert_env_vars_dict_to_list(helm_values["env"])
|
249
|
+
|
250
|
+
# Convert the temporal worker env vars to a list of dictionaries
|
231
251
|
if TEMPORAL_WORKER_KEY in helm_values and "env" in helm_values[TEMPORAL_WORKER_KEY]:
|
232
252
|
helm_values[TEMPORAL_WORKER_KEY]["env"] = convert_env_vars_dict_to_list(
|
233
253
|
helm_values[TEMPORAL_WORKER_KEY]["env"]
|
234
254
|
)
|
255
|
+
|
256
|
+
# Add dynamic ACP command based on manifest configuration
|
257
|
+
add_acp_command_to_helm_values(helm_values, manifest, manifest_path)
|
258
|
+
|
235
259
|
print("Deploying with the following helm values: ", helm_values)
|
236
260
|
return helm_values
|
237
261
|
|
@@ -287,7 +311,7 @@ def deploy_agent(
|
|
287
311
|
add_helm_repo()
|
288
312
|
|
289
313
|
# Merge configurations
|
290
|
-
helm_values = merge_deployment_configs(manifest, override_config, deploy_overrides)
|
314
|
+
helm_values = merge_deployment_configs(manifest, override_config, deploy_overrides, manifest_path)
|
291
315
|
|
292
316
|
# Create values file
|
293
317
|
values_file = create_helm_values_file(helm_values)
|
@@ -11,6 +11,11 @@ from agentex.lib.cli.handlers.cleanup_handlers import (
|
|
11
11
|
cleanup_agent_workflows,
|
12
12
|
should_cleanup_on_restart
|
13
13
|
)
|
14
|
+
from agentex.lib.cli.utils.path_utils import (
|
15
|
+
get_file_paths,
|
16
|
+
calculate_uvicorn_target_for_local,
|
17
|
+
)
|
18
|
+
|
14
19
|
from agentex.lib.environment_variables import EnvVarKeys
|
15
20
|
from agentex.lib.sdk.config.agent_manifest import AgentManifest
|
16
21
|
from agentex.lib.utils.logging import make_logger
|
@@ -104,7 +109,10 @@ async def start_temporal_worker_with_reload(
|
|
104
109
|
# PRE-RESTART CLEANUP - NEW!
|
105
110
|
if current_process is not None:
|
106
111
|
# Extract agent name from worker path for cleanup
|
107
|
-
|
112
|
+
|
113
|
+
agent_name = env.get("AGENT_NAME")
|
114
|
+
if agent_name is None:
|
115
|
+
agent_name = worker_path.parent.parent.name
|
108
116
|
|
109
117
|
# Perform cleanup if configured
|
110
118
|
if should_cleanup_on_restart():
|
@@ -180,15 +188,17 @@ async def start_temporal_worker_with_reload(
|
|
180
188
|
|
181
189
|
|
182
190
|
async def start_acp_server(
|
183
|
-
acp_path: Path, port: int, env: dict[str, str]
|
191
|
+
acp_path: Path, port: int, env: dict[str, str], manifest_dir: Path
|
184
192
|
) -> asyncio.subprocess.Process:
|
185
193
|
"""Start the ACP server process"""
|
186
|
-
# Use
|
194
|
+
# Use file path relative to manifest directory if possible
|
195
|
+
uvicorn_target = calculate_uvicorn_target_for_local(acp_path, manifest_dir)
|
196
|
+
|
187
197
|
cmd = [
|
188
198
|
sys.executable,
|
189
199
|
"-m",
|
190
200
|
"uvicorn",
|
191
|
-
f"{
|
201
|
+
f"{uvicorn_target}:acp",
|
192
202
|
"--reload",
|
193
203
|
"--reload-dir",
|
194
204
|
str(acp_path.parent), # Watch the project directory specifically
|
@@ -201,7 +211,7 @@ async def start_acp_server(
|
|
201
211
|
console.print(f"[blue]Starting ACP server from {acp_path} on port {port}...[/blue]")
|
202
212
|
return await asyncio.create_subprocess_exec(
|
203
213
|
*cmd,
|
204
|
-
cwd=
|
214
|
+
cwd=manifest_dir, # Always use manifest directory as CWD for consistency
|
205
215
|
env=env,
|
206
216
|
stdout=asyncio.subprocess.PIPE,
|
207
217
|
stderr=asyncio.subprocess.STDOUT,
|
@@ -218,7 +228,7 @@ async def start_temporal_worker(
|
|
218
228
|
|
219
229
|
return await asyncio.create_subprocess_exec(
|
220
230
|
*cmd,
|
221
|
-
cwd=worker_path.parent,
|
231
|
+
cwd=worker_path.parent, # Use worker directory as CWD for imports to work
|
222
232
|
env=env,
|
223
233
|
stdout=asyncio.subprocess.PIPE,
|
224
234
|
stderr=asyncio.subprocess.STDOUT,
|
@@ -280,8 +290,9 @@ async def run_agent(manifest_path: str):
|
|
280
290
|
)
|
281
291
|
|
282
292
|
# Start ACP server
|
293
|
+
manifest_dir = Path(manifest_path).parent
|
283
294
|
acp_process = await start_acp_server(
|
284
|
-
file_paths["acp"], manifest.local_development.agent.port, agent_env
|
295
|
+
file_paths["acp"], manifest.local_development.agent.port, agent_env, manifest_dir
|
285
296
|
)
|
286
297
|
process_manager.add_process(acp_process)
|
287
298
|
|
@@ -291,7 +302,7 @@ async def run_agent(manifest_path: str):
|
|
291
302
|
tasks = [acp_output_task]
|
292
303
|
|
293
304
|
# Start temporal worker if needed
|
294
|
-
if is_temporal_agent(manifest):
|
305
|
+
if is_temporal_agent(manifest) and file_paths["worker"]:
|
295
306
|
worker_task = await start_temporal_worker_with_reload(file_paths["worker"], agent_env, process_manager)
|
296
307
|
tasks.append(worker_task)
|
297
308
|
|
@@ -323,92 +334,7 @@ async def run_agent(manifest_path: str):
|
|
323
334
|
await process_manager.cleanup_processes()
|
324
335
|
|
325
336
|
|
326
|
-
def resolve_and_validate_path(base_path: Path, configured_path: str, file_type: str) -> Path:
|
327
|
-
"""Resolve and validate a configured path"""
|
328
|
-
path_obj = Path(configured_path)
|
329
|
-
|
330
|
-
if path_obj.is_absolute():
|
331
|
-
# Absolute path - use as-is
|
332
|
-
resolved_path = path_obj
|
333
|
-
else:
|
334
|
-
# Relative path - resolve relative to manifest directory
|
335
|
-
resolved_path = (base_path / configured_path).resolve()
|
336
|
-
|
337
|
-
# Validate the file exists
|
338
|
-
if not resolved_path.exists():
|
339
|
-
raise RunError(
|
340
|
-
f"{file_type} file not found: {resolved_path}\n"
|
341
|
-
f" Configured path: {configured_path}\n"
|
342
|
-
f" Resolved from manifest: {base_path}"
|
343
|
-
)
|
344
|
-
|
345
|
-
# Validate it's actually a file
|
346
|
-
if not resolved_path.is_file():
|
347
|
-
raise RunError(f"{file_type} path is not a file: {resolved_path}")
|
348
|
-
|
349
|
-
return resolved_path
|
350
|
-
|
351
|
-
|
352
|
-
def validate_path_security(resolved_path: Path, manifest_dir: Path) -> None:
|
353
|
-
"""Basic security validation for resolved paths"""
|
354
|
-
try:
|
355
|
-
# Ensure the resolved path is accessible
|
356
|
-
resolved_path.resolve()
|
357
|
-
|
358
|
-
# Optional: Add warnings for paths that go too far up
|
359
|
-
try:
|
360
|
-
# Check if path goes more than 3 levels up from manifest
|
361
|
-
relative_to_manifest = resolved_path.relative_to(manifest_dir.parent.parent.parent)
|
362
|
-
if str(relative_to_manifest).startswith(".."):
|
363
|
-
logger.warning(
|
364
|
-
f"Path goes significantly outside project structure: {resolved_path}"
|
365
|
-
)
|
366
|
-
except ValueError:
|
367
|
-
# Path is outside the tree - that's okay, just log it
|
368
|
-
logger.info(f"Using path outside manifest directory tree: {resolved_path}")
|
369
|
-
|
370
|
-
except Exception as e:
|
371
|
-
raise RunError(f"Path resolution failed: {resolved_path} - {str(e)}") from e
|
372
|
-
|
373
337
|
|
374
|
-
def get_file_paths(manifest: AgentManifest, manifest_path: str) -> dict[str, Path]:
|
375
|
-
"""Get resolved file paths from manifest configuration"""
|
376
|
-
manifest_dir = Path(manifest_path).parent.resolve()
|
377
|
-
|
378
|
-
# Use configured paths or fall back to defaults for backward compatibility
|
379
|
-
if manifest.local_development and manifest.local_development.paths:
|
380
|
-
paths_config = manifest.local_development.paths
|
381
|
-
|
382
|
-
# Resolve ACP path
|
383
|
-
acp_path = resolve_and_validate_path(manifest_dir, paths_config.acp, "ACP server")
|
384
|
-
validate_path_security(acp_path, manifest_dir)
|
385
|
-
|
386
|
-
# Resolve worker path if specified
|
387
|
-
worker_path = None
|
388
|
-
if paths_config.worker:
|
389
|
-
worker_path = resolve_and_validate_path(
|
390
|
-
manifest_dir, paths_config.worker, "Temporal worker"
|
391
|
-
)
|
392
|
-
validate_path_security(worker_path, manifest_dir)
|
393
|
-
else:
|
394
|
-
# Backward compatibility: use old hardcoded structure
|
395
|
-
project_dir = manifest_dir / "project"
|
396
|
-
acp_path = project_dir / "acp.py"
|
397
|
-
worker_path = project_dir / "run_worker.py" if is_temporal_agent(manifest) else None
|
398
|
-
|
399
|
-
# Validate backward compatibility paths
|
400
|
-
if not acp_path.exists():
|
401
|
-
raise RunError(f"ACP file not found: {acp_path}")
|
402
|
-
|
403
|
-
if worker_path and not worker_path.exists():
|
404
|
-
raise RunError(f"Worker file not found: {worker_path}")
|
405
|
-
|
406
|
-
return {
|
407
|
-
"acp": acp_path,
|
408
|
-
"worker": worker_path,
|
409
|
-
"acp_dir": acp_path.parent,
|
410
|
-
"worker_dir": worker_path.parent if worker_path else None,
|
411
|
-
}
|
412
338
|
|
413
339
|
|
414
340
|
def create_agent_environment(manifest: AgentManifest) -> dict[str, str]:
|
@@ -1,75 +1,26 @@
|
|
1
|
-
import
|
2
|
-
from agentex.lib import adk
|
1
|
+
from typing import AsyncGenerator, Union
|
3
2
|
from agentex.lib.sdk.fastacp.fastacp import FastACP
|
4
|
-
from agentex.lib.types.
|
5
|
-
from agentex.lib.types.acp import CancelTaskParams, CreateTaskParams, SendEventParams
|
3
|
+
from agentex.lib.types.acp import SendMessageParams
|
6
4
|
|
5
|
+
from agentex.lib.types.task_message_updates import TaskMessageUpdate
|
6
|
+
from agentex.types.task_message_content import TaskMessageContent
|
7
7
|
from agentex.types.text_content import TextContent
|
8
8
|
from agentex.lib.utils.logging import make_logger
|
9
9
|
|
10
10
|
logger = make_logger(__name__)
|
11
11
|
|
12
12
|
|
13
|
-
# Create an ACP server
|
14
|
-
# This sets up the core server that will handle task creation, events, and cancellation
|
13
|
+
# Create an ACP server
|
15
14
|
acp = FastACP.create(
|
16
|
-
acp_type="
|
17
|
-
config=AgenticACPConfig(
|
18
|
-
type="base",
|
19
|
-
),
|
15
|
+
acp_type="sync",
|
20
16
|
)
|
21
17
|
|
22
|
-
@acp.
|
23
|
-
async def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# Acknowledge that the task has been created.
|
32
|
-
await adk.messages.create(
|
33
|
-
task_id=params.task.id,
|
34
|
-
content=TextContent(
|
35
|
-
author="agent",
|
36
|
-
content=f"Hello! I've received your task. Normally you can do some state initialization here, or just pass and do nothing until you get your first event. For now I'm just acknowledging that I've received a task with the following params:\n\n{json.dumps(params.params, indent=2)}.\n\nYou should only see this message once, when the task is created. All subsequent events will be handled by the `on_task_event_send` handler.",
|
37
|
-
),
|
38
|
-
)
|
39
|
-
|
40
|
-
@acp.on_task_event_send
|
41
|
-
async def handle_event_send(params: SendEventParams):
|
42
|
-
# This handler is called whenever a new event (like a message) is sent to the task
|
43
|
-
|
44
|
-
#########################################################
|
45
|
-
# 2. (👋) Echo back the client's message to show it in the UI.
|
46
|
-
#########################################################
|
47
|
-
|
48
|
-
# This is not done by default so the agent developer has full control over what is shown to the user.
|
49
|
-
if params.event.content:
|
50
|
-
await adk.messages.create(task_id=params.task.id, content=params.event.content)
|
51
|
-
|
52
|
-
#########################################################
|
53
|
-
# 3. (👋) Send a simple response message.
|
54
|
-
#########################################################
|
55
|
-
|
56
|
-
# In future tutorials, this is where we'll add more sophisticated response logic.
|
57
|
-
await adk.messages.create(
|
58
|
-
task_id=params.task.id,
|
59
|
-
content=TextContent(
|
60
|
-
author="agent",
|
61
|
-
content=f"Hello! I've received your message. I can't respond right now, but in future tutorials we'll see how you can get me to intelligently respond to your message.",
|
62
|
-
),
|
63
|
-
)
|
64
|
-
|
65
|
-
@acp.on_task_cancel
|
66
|
-
async def handle_task_cancel(params: CancelTaskParams):
|
67
|
-
# This handler is called when a task is cancelled.
|
68
|
-
# It's useful for cleaning up any resources or state associated with the task.
|
69
|
-
|
70
|
-
#########################################################
|
71
|
-
# 4. (👋) Do task cleanup here.
|
72
|
-
#########################################################
|
73
|
-
|
74
|
-
# This is mostly for durable workflows that are cancellable like Temporal, but we will leave it here for demonstration purposes.
|
75
|
-
logger.info(f"Hello! I've received task cancel for task {params.task.id}: {params.task}. This isn't necessary for this example, but it's good to know that it's available.")
|
18
|
+
@acp.on_message_send
|
19
|
+
async def handle_message_send(
|
20
|
+
params: SendMessageParams
|
21
|
+
) -> TaskMessageContent | list[TaskMessageContent] | AsyncGenerator[TaskMessageUpdate, None]:
|
22
|
+
"""Default message handler with streaming support"""
|
23
|
+
return TextContent(
|
24
|
+
author="agent",
|
25
|
+
content=f"Hello! I've received your message. Here's a generic response, but in future tutorials we'll see how you can get me to intelligently respond to your message. This is what I heard you say: {params.content.content}",
|
26
|
+
)
|
@@ -0,0 +1,143 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from typing import Dict
|
3
|
+
|
4
|
+
from agentex.lib.sdk.config.agent_manifest import AgentManifest
|
5
|
+
from agentex.lib.utils.logging import make_logger
|
6
|
+
|
7
|
+
logger = make_logger(__name__)
|
8
|
+
|
9
|
+
|
10
|
+
class PathResolutionError(Exception):
|
11
|
+
"""An error occurred during path resolution"""
|
12
|
+
|
13
|
+
|
14
|
+
def resolve_and_validate_path(base_path: Path, configured_path: str, file_type: str) -> Path:
|
15
|
+
"""Resolve and validate a configured path"""
|
16
|
+
path_obj = Path(configured_path)
|
17
|
+
|
18
|
+
if path_obj.is_absolute():
|
19
|
+
# Absolute path - resolve to canonical form
|
20
|
+
resolved_path = path_obj.resolve()
|
21
|
+
else:
|
22
|
+
# Relative path - resolve relative to manifest directory
|
23
|
+
resolved_path = (base_path / configured_path).resolve()
|
24
|
+
|
25
|
+
# Validate the file exists
|
26
|
+
if not resolved_path.exists():
|
27
|
+
raise PathResolutionError(
|
28
|
+
f"{file_type} file not found: {resolved_path}\n"
|
29
|
+
f" Configured path: {configured_path}\n"
|
30
|
+
f" Resolved from manifest: {base_path}"
|
31
|
+
)
|
32
|
+
|
33
|
+
# Validate it's actually a file
|
34
|
+
if not resolved_path.is_file():
|
35
|
+
raise PathResolutionError(f"{file_type} path is not a file: {resolved_path}")
|
36
|
+
|
37
|
+
return resolved_path
|
38
|
+
|
39
|
+
|
40
|
+
def validate_path_security(resolved_path: Path, manifest_dir: Path) -> None:
|
41
|
+
"""Basic security validation for resolved paths"""
|
42
|
+
try:
|
43
|
+
# Ensure the resolved path is accessible
|
44
|
+
resolved_path.resolve()
|
45
|
+
|
46
|
+
# Optional: Add warnings for paths that go too far up
|
47
|
+
try:
|
48
|
+
# Check if path goes more than 3 levels up from manifest
|
49
|
+
relative_to_manifest = resolved_path.relative_to(manifest_dir.parent.parent.parent)
|
50
|
+
if str(relative_to_manifest).startswith(".."):
|
51
|
+
logger.warning(
|
52
|
+
f"Path goes significantly outside project structure: {resolved_path}"
|
53
|
+
)
|
54
|
+
except ValueError:
|
55
|
+
# Path is outside the tree - that's okay, just log it
|
56
|
+
logger.info(f"Using path outside manifest directory tree: {resolved_path}")
|
57
|
+
|
58
|
+
except Exception as e:
|
59
|
+
raise PathResolutionError(f"Path resolution failed: {resolved_path} - {str(e)}") from e
|
60
|
+
|
61
|
+
|
62
|
+
def get_file_paths(manifest: AgentManifest, manifest_path: str) -> Dict[str, Path | None]:
|
63
|
+
"""Get resolved file paths from manifest configuration"""
|
64
|
+
manifest_dir = Path(manifest_path).parent.resolve()
|
65
|
+
|
66
|
+
# Use configured paths or fall back to defaults for backward compatibility
|
67
|
+
if manifest.local_development and manifest.local_development.paths:
|
68
|
+
paths_config = manifest.local_development.paths
|
69
|
+
|
70
|
+
# Resolve ACP path
|
71
|
+
acp_path = resolve_and_validate_path(manifest_dir, paths_config.acp, "ACP server")
|
72
|
+
validate_path_security(acp_path, manifest_dir)
|
73
|
+
|
74
|
+
# Resolve worker path if specified
|
75
|
+
worker_path = None
|
76
|
+
if paths_config.worker:
|
77
|
+
worker_path = resolve_and_validate_path(
|
78
|
+
manifest_dir, paths_config.worker, "Temporal worker"
|
79
|
+
)
|
80
|
+
validate_path_security(worker_path, manifest_dir)
|
81
|
+
else:
|
82
|
+
# Backward compatibility: use old hardcoded structure
|
83
|
+
project_dir = manifest_dir / "project"
|
84
|
+
acp_path = (project_dir / "acp.py").resolve()
|
85
|
+
worker_path = (project_dir / "run_worker.py").resolve() if manifest.agent.is_temporal_agent() else None
|
86
|
+
|
87
|
+
# Validate backward compatibility paths
|
88
|
+
if not acp_path.exists():
|
89
|
+
raise PathResolutionError(f"ACP file not found: {acp_path}")
|
90
|
+
|
91
|
+
if worker_path and not worker_path.exists():
|
92
|
+
raise PathResolutionError(f"Worker file not found: {worker_path}")
|
93
|
+
|
94
|
+
return {
|
95
|
+
"acp": acp_path,
|
96
|
+
"worker": worker_path,
|
97
|
+
"acp_dir": acp_path.parent,
|
98
|
+
"worker_dir": worker_path.parent if worker_path else None,
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
def calculate_uvicorn_target_for_local(acp_path: Path, manifest_dir: Path) -> str:
|
103
|
+
"""Calculate the uvicorn target path for local development"""
|
104
|
+
# Ensure both paths are resolved to canonical form for accurate comparison
|
105
|
+
acp_resolved = acp_path.resolve()
|
106
|
+
manifest_resolved = manifest_dir.resolve()
|
107
|
+
|
108
|
+
try:
|
109
|
+
# Try to use path relative to manifest directory
|
110
|
+
acp_relative = acp_resolved.relative_to(manifest_resolved)
|
111
|
+
# Convert to module notation: project/acp.py -> project.acp
|
112
|
+
module_path = str(acp_relative.with_suffix('')) # Remove .py extension
|
113
|
+
module_path = module_path.replace('/', '.') # Convert slashes to dots
|
114
|
+
module_path = module_path.replace('\\', '.') # Handle Windows paths
|
115
|
+
return module_path
|
116
|
+
except ValueError:
|
117
|
+
# Path cannot be made relative - use absolute file path
|
118
|
+
logger.warning(f"ACP file {acp_resolved} cannot be made relative to manifest directory {manifest_resolved}, using absolute file path")
|
119
|
+
return str(acp_resolved)
|
120
|
+
|
121
|
+
|
122
|
+
def calculate_docker_acp_module(manifest: AgentManifest, manifest_path: str) -> str:
|
123
|
+
"""Calculate the Python module path for the ACP file in the Docker container
|
124
|
+
|
125
|
+
This should return the same module notation as local development for consistency.
|
126
|
+
"""
|
127
|
+
# Use the same logic as local development
|
128
|
+
manifest_dir = Path(manifest_path).parent
|
129
|
+
|
130
|
+
# Get the configured ACP path (could be relative or absolute)
|
131
|
+
if manifest.local_development and manifest.local_development.paths:
|
132
|
+
acp_config_path = manifest.local_development.paths.acp
|
133
|
+
else:
|
134
|
+
acp_config_path = "project/acp.py" # Default
|
135
|
+
|
136
|
+
# Resolve to actual file path
|
137
|
+
acp_path = resolve_and_validate_path(manifest_dir, acp_config_path, "ACP")
|
138
|
+
|
139
|
+
# Use the same module calculation as local development
|
140
|
+
return calculate_uvicorn_target_for_local(acp_path, manifest_dir)
|
141
|
+
|
142
|
+
|
143
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
from agentex.types.task_message import TaskMessage
|
2
|
+
from agentex.types.text_content import TextContent
|
3
|
+
from agentex.types.tool_request_content import ToolRequestContent
|
4
|
+
from agentex.types.tool_response_content import ToolResponseContent
|
5
|
+
import json
|
6
|
+
from agents import TResponseInputItem
|
7
|
+
|
8
|
+
|
9
|
+
def convert_task_messages_to_oai_agents_inputs(
|
10
|
+
task_messages: list[TaskMessage],
|
11
|
+
) -> list[TResponseInputItem]:
|
12
|
+
"""
|
13
|
+
Convert a list of TaskMessages to a list of OpenAI Agents SDK inputs (TResponseInputItem).
|
14
|
+
|
15
|
+
Args:
|
16
|
+
task_messages: The list of TaskMessages to convert.
|
17
|
+
|
18
|
+
Returns:
|
19
|
+
A list of OpenAI Agents SDK inputs (TResponseInputItem).
|
20
|
+
"""
|
21
|
+
converted_messages = []
|
22
|
+
for task_message in task_messages:
|
23
|
+
task_message_content = task_message.content
|
24
|
+
if isinstance(task_message_content, TextContent):
|
25
|
+
converted_messages.append(
|
26
|
+
{
|
27
|
+
"role": (
|
28
|
+
"user" if task_message_content.author == "user" else "assistant"
|
29
|
+
),
|
30
|
+
"content": task_message_content.content,
|
31
|
+
}
|
32
|
+
)
|
33
|
+
elif isinstance(task_message_content, ToolRequestContent):
|
34
|
+
converted_messages.append(
|
35
|
+
{
|
36
|
+
"type": "function_call",
|
37
|
+
"call_id": task_message_content.tool_call_id,
|
38
|
+
"name": task_message_content.name,
|
39
|
+
"arguments": json.dumps(task_message_content.arguments),
|
40
|
+
}
|
41
|
+
)
|
42
|
+
elif isinstance(task_message_content, ToolResponseContent):
|
43
|
+
content_str = (
|
44
|
+
task_message_content.content
|
45
|
+
if isinstance(task_message_content.content, str)
|
46
|
+
else json.dumps(task_message_content.content)
|
47
|
+
)
|
48
|
+
converted_messages.append(
|
49
|
+
{
|
50
|
+
"type": "function_call_output",
|
51
|
+
"call_id": task_message_content.tool_call_id,
|
52
|
+
"output": content_str,
|
53
|
+
}
|
54
|
+
)
|
55
|
+
else:
|
56
|
+
raise ValueError(
|
57
|
+
f"Unsupported content type for converting TaskMessage to OpenAI Agents SDK input: {type(task_message.content)}"
|
58
|
+
)
|
59
|
+
|
60
|
+
return converted_messages
|
agentex/resources/agents.py
CHANGED
@@ -23,6 +23,7 @@ from ..types.agent import Agent
|
|
23
23
|
from .._base_client import make_request_options
|
24
24
|
from ..types.agent_rpc_response import AgentRpcResponse, CancelTaskResponse, CreateTaskResponse, SendEventResponse, SendMessageResponse, SendMessageStreamResponse
|
25
25
|
from ..types.agent_list_response import AgentListResponse
|
26
|
+
from ..types.shared.delete_response import DeleteResponse
|
26
27
|
|
27
28
|
__all__ = ["AgentsResource", "AsyncAgentsResource"]
|
28
29
|
|
@@ -127,7 +128,7 @@ class AgentsResource(SyncAPIResource):
|
|
127
128
|
extra_query: Query | None = None,
|
128
129
|
extra_body: Body | None = None,
|
129
130
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
130
|
-
) ->
|
131
|
+
) -> DeleteResponse:
|
131
132
|
"""
|
132
133
|
Delete an agent by its unique ID.
|
133
134
|
|
@@ -147,7 +148,7 @@ class AgentsResource(SyncAPIResource):
|
|
147
148
|
options=make_request_options(
|
148
149
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
149
150
|
),
|
150
|
-
cast_to=
|
151
|
+
cast_to=DeleteResponse,
|
151
152
|
)
|
152
153
|
|
153
154
|
def delete_by_name(
|
@@ -160,7 +161,7 @@ class AgentsResource(SyncAPIResource):
|
|
160
161
|
extra_query: Query | None = None,
|
161
162
|
extra_body: Body | None = None,
|
162
163
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
163
|
-
) ->
|
164
|
+
) -> DeleteResponse:
|
164
165
|
"""
|
165
166
|
Delete an agent by its unique name.
|
166
167
|
|
@@ -180,7 +181,7 @@ class AgentsResource(SyncAPIResource):
|
|
180
181
|
options=make_request_options(
|
181
182
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
182
183
|
),
|
183
|
-
cast_to=
|
184
|
+
cast_to=DeleteResponse,
|
184
185
|
)
|
185
186
|
|
186
187
|
def retrieve_by_name(
|
@@ -667,7 +668,7 @@ class AsyncAgentsResource(AsyncAPIResource):
|
|
667
668
|
extra_query: Query | None = None,
|
668
669
|
extra_body: Body | None = None,
|
669
670
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
670
|
-
) ->
|
671
|
+
) -> DeleteResponse:
|
671
672
|
"""
|
672
673
|
Delete an agent by its unique ID.
|
673
674
|
|
@@ -687,7 +688,7 @@ class AsyncAgentsResource(AsyncAPIResource):
|
|
687
688
|
options=make_request_options(
|
688
689
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
689
690
|
),
|
690
|
-
cast_to=
|
691
|
+
cast_to=DeleteResponse,
|
691
692
|
)
|
692
693
|
|
693
694
|
async def delete_by_name(
|
@@ -700,7 +701,7 @@ class AsyncAgentsResource(AsyncAPIResource):
|
|
700
701
|
extra_query: Query | None = None,
|
701
702
|
extra_body: Body | None = None,
|
702
703
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
703
|
-
) ->
|
704
|
+
) -> DeleteResponse:
|
704
705
|
"""
|
705
706
|
Delete an agent by its unique name.
|
706
707
|
|
@@ -720,7 +721,7 @@ class AsyncAgentsResource(AsyncAPIResource):
|
|
720
721
|
options=make_request_options(
|
721
722
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
722
723
|
),
|
723
|
-
cast_to=
|
724
|
+
cast_to=DeleteResponse,
|
724
725
|
)
|
725
726
|
|
726
727
|
async def retrieve_by_name(
|
@@ -192,6 +192,8 @@ class MessagesResource(SyncAPIResource):
|
|
192
192
|
List Messages
|
193
193
|
|
194
194
|
Args:
|
195
|
+
task_id: The task ID
|
196
|
+
|
195
197
|
extra_headers: Send extra headers
|
196
198
|
|
197
199
|
extra_query: Add additional query parameters to the request
|
@@ -377,6 +379,8 @@ class AsyncMessagesResource(AsyncAPIResource):
|
|
377
379
|
List Messages
|
378
380
|
|
379
381
|
Args:
|
382
|
+
task_id: The task ID
|
383
|
+
|
380
384
|
extra_headers: Send extra headers
|
381
385
|
|
382
386
|
extra_query: Add additional query parameters to the request
|
agentex/resources/tasks.py
CHANGED
@@ -17,8 +17,7 @@ from .._streaming import Stream, AsyncStream
|
|
17
17
|
from ..types.task import Task
|
18
18
|
from .._base_client import make_request_options
|
19
19
|
from ..types.task_list_response import TaskListResponse
|
20
|
-
from ..types.
|
21
|
-
from ..types.task_delete_by_name_response import TaskDeleteByNameResponse
|
20
|
+
from ..types.shared.delete_response import DeleteResponse
|
22
21
|
|
23
22
|
__all__ = ["TasksResource", "AsyncTasksResource"]
|
24
23
|
|
@@ -105,7 +104,7 @@ class TasksResource(SyncAPIResource):
|
|
105
104
|
extra_query: Query | None = None,
|
106
105
|
extra_body: Body | None = None,
|
107
106
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
108
|
-
) ->
|
107
|
+
) -> DeleteResponse:
|
109
108
|
"""
|
110
109
|
Delete a task by its unique ID.
|
111
110
|
|
@@ -125,7 +124,7 @@ class TasksResource(SyncAPIResource):
|
|
125
124
|
options=make_request_options(
|
126
125
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
127
126
|
),
|
128
|
-
cast_to=
|
127
|
+
cast_to=DeleteResponse,
|
129
128
|
)
|
130
129
|
|
131
130
|
def delete_by_name(
|
@@ -138,7 +137,7 @@ class TasksResource(SyncAPIResource):
|
|
138
137
|
extra_query: Query | None = None,
|
139
138
|
extra_body: Body | None = None,
|
140
139
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
141
|
-
) ->
|
140
|
+
) -> DeleteResponse:
|
142
141
|
"""
|
143
142
|
Delete a task by its unique name.
|
144
143
|
|
@@ -158,7 +157,7 @@ class TasksResource(SyncAPIResource):
|
|
158
157
|
options=make_request_options(
|
159
158
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
160
159
|
),
|
161
|
-
cast_to=
|
160
|
+
cast_to=DeleteResponse,
|
162
161
|
)
|
163
162
|
|
164
163
|
def retrieve_by_name(
|
@@ -347,7 +346,7 @@ class AsyncTasksResource(AsyncAPIResource):
|
|
347
346
|
extra_query: Query | None = None,
|
348
347
|
extra_body: Body | None = None,
|
349
348
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
350
|
-
) ->
|
349
|
+
) -> DeleteResponse:
|
351
350
|
"""
|
352
351
|
Delete a task by its unique ID.
|
353
352
|
|
@@ -367,7 +366,7 @@ class AsyncTasksResource(AsyncAPIResource):
|
|
367
366
|
options=make_request_options(
|
368
367
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
369
368
|
),
|
370
|
-
cast_to=
|
369
|
+
cast_to=DeleteResponse,
|
371
370
|
)
|
372
371
|
|
373
372
|
async def delete_by_name(
|
@@ -380,7 +379,7 @@ class AsyncTasksResource(AsyncAPIResource):
|
|
380
379
|
extra_query: Query | None = None,
|
381
380
|
extra_body: Body | None = None,
|
382
381
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
383
|
-
) ->
|
382
|
+
) -> DeleteResponse:
|
384
383
|
"""
|
385
384
|
Delete a task by its unique name.
|
386
385
|
|
@@ -400,7 +399,7 @@ class AsyncTasksResource(AsyncAPIResource):
|
|
400
399
|
options=make_request_options(
|
401
400
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
402
401
|
),
|
403
|
-
cast_to=
|
402
|
+
cast_to=DeleteResponse,
|
404
403
|
)
|
405
404
|
|
406
405
|
async def retrieve_by_name(
|
agentex/types/__init__.py
CHANGED
@@ -7,6 +7,7 @@ from .task import Task as Task
|
|
7
7
|
from .agent import Agent as Agent
|
8
8
|
from .event import Event as Event
|
9
9
|
from .state import State as State
|
10
|
+
from .shared import DeleteResponse as DeleteResponse
|
10
11
|
from .acp_type import AcpType as AcpType
|
11
12
|
from .data_delta import DataDelta as DataDelta
|
12
13
|
from .text_delta import TextDelta as TextDelta
|
@@ -40,7 +41,6 @@ from .state_update_params import StateUpdateParams as StateUpdateParams
|
|
40
41
|
from .task_message_update import TaskMessageUpdate as TaskMessageUpdate
|
41
42
|
from .tool_response_delta import ToolResponseDelta as ToolResponseDelta
|
42
43
|
from .tracker_list_params import TrackerListParams as TrackerListParams
|
43
|
-
from .task_delete_response import TaskDeleteResponse as TaskDeleteResponse
|
44
44
|
from .task_message_content import TaskMessageContent as TaskMessageContent
|
45
45
|
from .tool_request_content import ToolRequestContent as ToolRequestContent
|
46
46
|
from .message_create_params import MessageCreateParams as MessageCreateParams
|
@@ -53,4 +53,3 @@ from .agent_rpc_by_name_params import AgentRpcByNameParams as AgentRpcByNamePara
|
|
53
53
|
from .task_message_content_param import TaskMessageContentParam as TaskMessageContentParam
|
54
54
|
from .tool_request_content_param import ToolRequestContentParam as ToolRequestContentParam
|
55
55
|
from .tool_response_content_param import ToolResponseContentParam as ToolResponseContentParam
|
56
|
-
from .task_delete_by_name_response import TaskDeleteByNameResponse as TaskDeleteByNameResponse
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: agentex-sdk
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.5
|
4
4
|
Summary: The official Python library for the agentex API
|
5
5
|
Project-URL: Homepage, https://github.com/scaleapi/agentex-python
|
6
6
|
Project-URL: Repository, https://github.com/scaleapi/agentex-python
|
@@ -31,7 +31,7 @@ Requires-Dist: jsonschema<5,>=4.23.0
|
|
31
31
|
Requires-Dist: kubernetes<29.0.0,>=25.0.0
|
32
32
|
Requires-Dist: litellm<2,>=1.66.0
|
33
33
|
Requires-Dist: mcp[cli]>=1.4.1
|
34
|
-
Requires-Dist: openai-agents
|
34
|
+
Requires-Dist: openai-agents!=0.2.3,>=0.0.7
|
35
35
|
Requires-Dist: pydantic<3,>=2.0.0
|
36
36
|
Requires-Dist: pytest-asyncio>=1.0.0
|
37
37
|
Requires-Dist: pytest>=8.4.0
|
@@ -11,7 +11,7 @@ agentex/_resource.py,sha256=S1t7wmR5WUvoDIhZjo_x-E7uoTJBynJ3d8tPJMQYdjw,1106
|
|
11
11
|
agentex/_response.py,sha256=Tb9zazsnemO2rTxWtBjAD5WBqlhli5ZaXGbiKgdu5DE,28794
|
12
12
|
agentex/_streaming.py,sha256=FNGJExRCF-vTRUZHFKUfoAWFhDGOB3XbioVCF37Jr7E,10104
|
13
13
|
agentex/_types.py,sha256=KyKYySGIfHPod2hho1fPxssk5NuVn8C4MeMTtA-lg80,6198
|
14
|
-
agentex/_version.py,sha256=
|
14
|
+
agentex/_version.py,sha256=fPT5ffTH4tk3Hr-8_tC-QuVMI2_qSnjmzLboSSdVt3k,159
|
15
15
|
agentex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
16
|
agentex/_utils/__init__.py,sha256=PNZ_QJuzZEgyYXqkO1HVhGkj5IU9bglVUcw7H-Knjzw,2062
|
17
17
|
agentex/_utils/_logs.py,sha256=LUjFPc3fweSChBUmjhQD8uYmwQAmFMNDuVFKfjYBQfM,777
|
@@ -49,17 +49,17 @@ agentex/lib/adk/utils/_modules/client.py,sha256=2XrFTwB2y9fTTpSzmaXz8hzHR7VWf4F6
|
|
49
49
|
agentex/lib/adk/utils/_modules/templating.py,sha256=YPm2bY_iBv9jWf0lncRGUpBZyq_QHBCRlM-XbHjauRc,3502
|
50
50
|
agentex/lib/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
51
|
agentex/lib/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
52
|
-
agentex/lib/cli/commands/agents.py,sha256=
|
52
|
+
agentex/lib/cli/commands/agents.py,sha256=PJVkopMLQEg4lOQf-Dvjb_b0TL6qaWTH2dN6_cxRneo,11417
|
53
53
|
agentex/lib/cli/commands/init.py,sha256=JsfusiLTgPu5IAI0MVDR15qA6wx5R2ZowjUJ728GJyQ,8146
|
54
54
|
agentex/lib/cli/commands/main.py,sha256=aDn9xJIIQQD33v3caET_NX-8eBxoWC3QfZGMUgjeGN8,1093
|
55
55
|
agentex/lib/cli/commands/secrets.py,sha256=cVtsqyGGieBVM4dKkbJROmzR_NJRODFngcEbi1Nc92A,5604
|
56
56
|
agentex/lib/cli/commands/tasks.py,sha256=9ARR0VgM2ZZXSFDlMiA_E9RDL2V7Piipp8Fna_OBrKQ,3652
|
57
57
|
agentex/lib/cli/commands/uv.py,sha256=n6nk2F2gPUXrvWOljSN06Y5bOEnhaZH4rulproAJktA,3553
|
58
58
|
agentex/lib/cli/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
agentex/lib/cli/handlers/agent_handlers.py,sha256=
|
60
|
-
agentex/lib/cli/handlers/cleanup_handlers.py,sha256=
|
61
|
-
agentex/lib/cli/handlers/deploy_handlers.py,sha256=
|
62
|
-
agentex/lib/cli/handlers/run_handlers.py,sha256=
|
59
|
+
agentex/lib/cli/handlers/agent_handlers.py,sha256=ovhnQOa-lAi5g2J3BVutA0vbprsOFe0lt2qw-qIZah4,5470
|
60
|
+
agentex/lib/cli/handlers/cleanup_handlers.py,sha256=V1V0zeErOUGTgCQqjyUl6CWtzGjFW878uzFaLOQJEyQ,7073
|
61
|
+
agentex/lib/cli/handlers/deploy_handlers.py,sha256=Bj2a0zav7YVaaMM55o39k2-x2cl-DgPdISZXjzd7yPQ,14896
|
62
|
+
agentex/lib/cli/handlers/run_handlers.py,sha256=2DkaGN27nHcL5pZeoOVdlhttnft_jtVdmv_POgnRASE,13923
|
63
63
|
agentex/lib/cli/handlers/secret_handlers.py,sha256=VfAdAQovW9tG36Xgk_gGIGwTyFMxR3P6xc7fmAviNA8,24719
|
64
64
|
agentex/lib/cli/templates/default/.dockerignore.j2,sha256=hweGFxw5eDZYsb5EnRHpv27o9M1HF2PEWOxqsfBBcAE,320
|
65
65
|
agentex/lib/cli/templates/default/Dockerfile-uv.j2,sha256=tGJo_C4vwHYikV4QhGFtSiG6K7Nt4UDdJ71Gob_uTho,1109
|
@@ -82,7 +82,7 @@ agentex/lib/cli/templates/sync/manifest.yaml.j2,sha256=V497KXzvA76sHrgIJ5zRJptpI
|
|
82
82
|
agentex/lib/cli/templates/sync/pyproject.toml.j2,sha256=9cpTISM7rOoICWejV5GYMEwPn8RUmB6-E7csM1pmSFo,528
|
83
83
|
agentex/lib/cli/templates/sync/requirements.txt.j2,sha256=iTmO-z8qFkUa1jTctFCs0WYuq7Sqi6VNQAwATakh2fQ,94
|
84
84
|
agentex/lib/cli/templates/sync/deploy/example.yaml.j2,sha256=sHIEuhtruyCfGPgeLQ1ilCCnRH0HpsqhDdQT44UWUaU,1554
|
85
|
-
agentex/lib/cli/templates/sync/project/acp.py.j2,sha256=
|
85
|
+
agentex/lib/cli/templates/sync/project/acp.py.j2,sha256=X5RaE9iR4Dp-kPJL0r1QAe6ohfiOTcYizwtwGW2GzHg,1003
|
86
86
|
agentex/lib/cli/templates/temporal/.dockerignore.j2,sha256=hweGFxw5eDZYsb5EnRHpv27o9M1HF2PEWOxqsfBBcAE,320
|
87
87
|
agentex/lib/cli/templates/temporal/Dockerfile-uv.j2,sha256=bnvx-zba5DFjl7UC-TYt-Zi_UDJucjlNRCdkSqHgBiQ,1450
|
88
88
|
agentex/lib/cli/templates/temporal/Dockerfile.j2,sha256=pcszlprNTqKMpYEtA4XYlc3vWjq1b0IMQDrN1GxF7yI,1461
|
@@ -102,6 +102,7 @@ agentex/lib/cli/utils/credential_utils.py,sha256=EzI_Wdvr2lt9uf9sNML1RTkzqIv6Ljp
|
|
102
102
|
agentex/lib/cli/utils/exceptions.py,sha256=ZhQZzciroj4zeYlL0TWmoQ6oeLBcAowGhCGMP7Ac_lA,161
|
103
103
|
agentex/lib/cli/utils/kubectl_utils.py,sha256=ucI0z-Zn-sFwk84MKfCgfX9CLZxlLSx242W_0MsyYxU,4907
|
104
104
|
agentex/lib/cli/utils/kubernetes_secrets_utils.py,sha256=uKsUvKvHfRGvNxgRgOFW0MJ2RyA9QJJjPQ1QA-qcaZk,6978
|
105
|
+
agentex/lib/cli/utils/path_utils.py,sha256=WN5rZCdb9SIrtN-P6QqIQuaH54HgqQ3fUMUnaIYxT0I,5747
|
105
106
|
agentex/lib/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
106
107
|
agentex/lib/core/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
107
108
|
agentex/lib/core/adapters/llm/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
@@ -199,6 +200,7 @@ agentex/lib/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
199
200
|
agentex/lib/types/acp.py,sha256=lFuWZwlXy1TNUHGvCXmyPLPbt8ME_2lejdWwx8VcodY,2970
|
200
201
|
agentex/lib/types/agent_configs.py,sha256=3wRa2okimSzi2v8sJyMyrqRlcu_4sxes-_4smEK6fq8,2798
|
201
202
|
agentex/lib/types/agent_results.py,sha256=ev6WnPLfZRbhy2HnBmdIrZq1ExVeaweXoLRxYGspyWM,653
|
203
|
+
agentex/lib/types/converters.py,sha256=u6fLb0rBUDA6nF5hdbC8ms6H-Z21IQfLlIvYpau_P5g,2283
|
202
204
|
agentex/lib/types/credentials.py,sha256=xUyh0MiNgy1c-BSBGXqbAMgbFEqnglESK99SRbsCsZA,1442
|
203
205
|
agentex/lib/types/fastacp.py,sha256=nU4rT823Ckix7bFwvVXtPsk6el3U1E4TH-OEvMqIBr4,1304
|
204
206
|
agentex/lib/types/files.py,sha256=sNxiuR_oEo7Z0YMqjQShErvS3txWyobrZzc4QMMM61U,320
|
@@ -221,16 +223,16 @@ agentex/lib/utils/temporal.py,sha256=sXo8OPMMXiyrF7OSBCJBuN_ufyQOD2bLOXgDbVZoyds
|
|
221
223
|
agentex/lib/utils/dev_tools/__init__.py,sha256=oaHxw6ymfhNql-kzXHv3NWVHuqD4fHumasNXJG7kHTU,261
|
222
224
|
agentex/lib/utils/dev_tools/async_messages.py,sha256=-alUK1KFltcRb6xtRtIJIRJW9Sf1FwDRgaNPhOn-luw,18105
|
223
225
|
agentex/resources/__init__.py,sha256=74rMqWBzQ2dSrKQqsrd7-jskPws0O_ogkFltvZO3HoU,3265
|
224
|
-
agentex/resources/agents.py,sha256=
|
226
|
+
agentex/resources/agents.py,sha256=Iwt2jnBUgSynMdfxYjW7KV9o0nZjT7cgiSqS_Zd4jmU,46735
|
225
227
|
agentex/resources/events.py,sha256=Zc9JhUm3bq2VFnBAolC0M7KZernzj1AjZ_vj0ibP4GY,10412
|
226
228
|
agentex/resources/spans.py,sha256=wmcUs4XbXIF5rPeyU_f39c2RTbTLnkuh2LYogZEBD6s,20936
|
227
229
|
agentex/resources/states.py,sha256=O31A8--n7n0rHsng2e1oCUAzLNjQIxDUk7rq0IXfgGM,19262
|
228
|
-
agentex/resources/tasks.py,sha256=
|
230
|
+
agentex/resources/tasks.py,sha256=92jnjwHeGJ6sA7l0SuuKJKptTaIpk7N1pCxdlGr9OVg,23196
|
229
231
|
agentex/resources/tracker.py,sha256=YxSeiloMwIqrS9nY7SlHclauRA7142qrKw34xgwqYbA,14103
|
230
232
|
agentex/resources/messages/__init__.py,sha256=_J1eusFtr_k6zrAntJSuqx6LWEUBSTrV1OZZh7MaDPE,1015
|
231
233
|
agentex/resources/messages/batch.py,sha256=pegCmnjK_J0jek5ChX1pKpq5RmCucTYLbK69H6qGVS4,9629
|
232
|
-
agentex/resources/messages/messages.py,sha256=
|
233
|
-
agentex/types/__init__.py,sha256=
|
234
|
+
agentex/resources/messages/messages.py,sha256=fuFmmGNOjRJVzmYHcfP2trg0yii0n9MPPCpt7F8fDs4,17930
|
235
|
+
agentex/types/__init__.py,sha256=4urMNGYc6igsHctipe7CasICo7HGxq-SGAzqOSP_fdw,3451
|
234
236
|
agentex/types/acp_type.py,sha256=Fj-4SzmM6m95ck_ZXtNbcWggHiD9F49bxBLPbl1fxe4,208
|
235
237
|
agentex/types/agent.py,sha256=WZRc8VZtc-JIeNHw5FsVTSMrxlaJ5A0ABvHv3t_zA4s,792
|
236
238
|
agentex/types/agent_list_params.py,sha256=81IWnRZ2rLfHH7GB6VkXShYjb44DO0guG1znJcV3tuI,316
|
@@ -248,7 +250,7 @@ agentex/types/event_list_params.py,sha256=Rrz0yo2w3gMTNYe3HQS9YCX1VktE_aaktuHezx
|
|
248
250
|
agentex/types/event_list_response.py,sha256=rjUCkwS0pXnfqHEVPEKZdLIGJ14uXOrjatuOfR36s5s,254
|
249
251
|
agentex/types/message_author.py,sha256=_IIVLAcZsLTG_vQWFpjWuxLIaHrc6wkv3q7qu5gam0o,218
|
250
252
|
agentex/types/message_create_params.py,sha256=Vt7Hig0lI8qxWDpJ4JhjfjglSzptI2PjzbrOD1Qkmxk,502
|
251
|
-
agentex/types/message_list_params.py,sha256=
|
253
|
+
agentex/types/message_list_params.py,sha256=MGXLwUUBaaiG-rsGjui5dlJ0sxv1twkSugFoOLXcX0E,360
|
252
254
|
agentex/types/message_list_response.py,sha256=YYDf-57zLS-E1eX3EZxz7c6XCuBcRBws01_q2G7uk4Y,277
|
253
255
|
agentex/types/message_style.py,sha256=nuoXzoDyP3KAQsQeKHaiby1EMxeY-8TJjWr8eMMpQEE,219
|
254
256
|
agentex/types/message_update_params.py,sha256=_KpnJ56FNeoIcwodQmAgsweqH1YAeIgYVT2jo9ahUhY,502
|
@@ -263,8 +265,6 @@ agentex/types/state_list_params.py,sha256=jsBeE98mVvS-pk9iytNTVVSW6pz7OM4Zt-OxC2
|
|
263
265
|
agentex/types/state_list_response.py,sha256=3UyMRzP3zdEKo9hTkJdvBHjmv6II4KnwoZ8GvlzPCSI,254
|
264
266
|
agentex/types/state_update_params.py,sha256=TpCXMrYaT2MWeOPng9-RGvGX9vE61Te9r3CFRQzzIDg,377
|
265
267
|
agentex/types/task.py,sha256=Pgj5HSrThPJgFRKWXPgW3LRT9Jwgn9eR_CCnlbNznzU,543
|
266
|
-
agentex/types/task_delete_by_name_response.py,sha256=3kjX24vq7NkKSZ0uKsU-i2cPUu_05jb0InIaxS0ZmLg,245
|
267
|
-
agentex/types/task_delete_response.py,sha256=Pxq9Bak_NPudBQusbuQnAG6HihNCyA5ltKoqR5w3rPs,233
|
268
268
|
agentex/types/task_list_response.py,sha256=8Q-RIanLmUC9vOuDXoW5gjpZeE-HR6IrBugG7-cUAZQ,249
|
269
269
|
agentex/types/task_message.py,sha256=hoLAkiQJd1Fl7EjLof-vZq6zVnDw9SKmnV6V74Po58A,918
|
270
270
|
agentex/types/task_message_content.py,sha256=57ebp-65y52KOZ7usVJShArIdXqBhFo5eOn8uy4HM_c,575
|
@@ -288,8 +288,10 @@ agentex/types/messages/batch_create_params.py,sha256=trUV75ntEVnxYhd1FIWub6dHBaN
|
|
288
288
|
agentex/types/messages/batch_create_response.py,sha256=yaSLTw2MWWpHF23BGO1Xy9js38_7EIqHAuiLha8VSfc,278
|
289
289
|
agentex/types/messages/batch_update_params.py,sha256=Ug5CThbD49a8j4qucg04OdmVrp_gApgpw0hg6NLsR3g,433
|
290
290
|
agentex/types/messages/batch_update_response.py,sha256=TbSBe6SuPzjXXWSj-nRjT1JHGBooTshHQQDa1AixQA8,278
|
291
|
-
|
292
|
-
|
293
|
-
agentex_sdk-0.2.
|
294
|
-
agentex_sdk-0.2.
|
295
|
-
agentex_sdk-0.2.
|
291
|
+
agentex/types/shared/__init__.py,sha256=IKs-Qn5Yja0kFh1G1kDqYZo43qrOu1hSoxlPdN-85dI,149
|
292
|
+
agentex/types/shared/delete_response.py,sha256=8qH3zvQXaOHYQSHyXi7UQxdR4miTzR7V9K4zXVsiUyk,215
|
293
|
+
agentex_sdk-0.2.5.dist-info/METADATA,sha256=intnD9hPOyqlKmf-KxVVbIwUr2ew2l2WkC4X3sGcPew,14118
|
294
|
+
agentex_sdk-0.2.5.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
295
|
+
agentex_sdk-0.2.5.dist-info/entry_points.txt,sha256=V7vJuMZdF0UlvgX6KiBN7XUvq_cxF5kplcYvc1QlFaQ,62
|
296
|
+
agentex_sdk-0.2.5.dist-info/licenses/LICENSE,sha256=Q1AOx2FtRcMlyMgQJ9eVN2WKPq2mQ33lnB4tvWxabLA,11337
|
297
|
+
agentex_sdk-0.2.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|