agentex-sdk 0.1.1__py3-none-any.whl → 0.2.1__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 (37) hide show
  1. agentex/_version.py +1 -1
  2. agentex/lib/adk/_modules/messages.py +2 -2
  3. agentex/lib/adk/_modules/streaming.py +2 -2
  4. agentex/lib/adk/providers/_modules/litellm.py +2 -2
  5. agentex/lib/adk/providers/_modules/openai.py +2 -2
  6. agentex/lib/cli/commands/init.py +8 -4
  7. agentex/lib/cli/handlers/deploy_handlers.py +20 -0
  8. agentex/lib/cli/handlers/run_handlers.py +7 -0
  9. agentex/lib/cli/templates/default/README.md.j2 +23 -2
  10. agentex/lib/cli/templates/default/dev.ipynb.j2 +127 -0
  11. agentex/lib/cli/templates/sync/README.md.j2 +22 -2
  12. agentex/lib/cli/templates/sync/dev.ipynb.j2 +181 -0
  13. agentex/lib/cli/templates/sync/project/acp.py.j2 +63 -14
  14. agentex/lib/cli/templates/temporal/README.md.j2 +24 -3
  15. agentex/lib/cli/templates/temporal/dev.ipynb.j2 +127 -0
  16. agentex/lib/cli/templates/temporal/project/workflow.py.j2 +1 -1
  17. agentex/lib/cli/utils/__init__.py +0 -0
  18. agentex/lib/cli/utils/auth_utils.py +18 -0
  19. agentex/lib/core/adapters/streams/adapter_redis.py +4 -4
  20. agentex/lib/core/adapters/streams/port.py +1 -1
  21. agentex/lib/core/services/adk/streaming.py +2 -3
  22. agentex/lib/core/temporal/activities/__init__.py +2 -2
  23. agentex/lib/environment_variables.py +4 -1
  24. agentex/lib/sdk/config/agent_manifest.py +2 -1
  25. agentex/lib/sdk/config/deployment_config.py +5 -1
  26. agentex/lib/sdk/fastacp/base/base_acp_server.py +14 -0
  27. agentex/lib/utils/dev_tools/__init__.py +9 -0
  28. agentex/lib/utils/dev_tools/async_messages.py +386 -0
  29. agentex/resources/agents.py +5 -6
  30. agentex/types/agent_rpc_by_name_params.py +55 -5
  31. agentex/types/agent_rpc_params.py +27 -7
  32. {agentex_sdk-0.1.1.dist-info → agentex_sdk-0.2.1.dist-info}/METADATA +1 -1
  33. {agentex_sdk-0.1.1.dist-info → agentex_sdk-0.2.1.dist-info}/RECORD +36 -30
  34. agentex/types/agent_rpc_params1.py +0 -21
  35. {agentex_sdk-0.1.1.dist-info → agentex_sdk-0.2.1.dist-info}/WHEEL +0 -0
  36. {agentex_sdk-0.1.1.dist-info → agentex_sdk-0.2.1.dist-info}/entry_points.txt +0 -0
  37. {agentex_sdk-0.1.1.dist-info → agentex_sdk-0.2.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,386 @@
1
+ """
2
+ Development utility for subscribing to async task messages with streaming support.
3
+
4
+ This module provides utilities to read existing messages from a task and subscribe
5
+ to new streaming messages, handling mid-stream connections gracefully.
6
+ """
7
+
8
+ import json
9
+ from datetime import datetime, timezone
10
+ from typing import List, Optional
11
+
12
+ from yaspin.core import Yaspin
13
+
14
+ from agentex import Agentex
15
+ from agentex.types import Task, TaskMessage, TextContent, ToolRequestContent, ToolResponseContent
16
+ from agentex.types.task_message_update import (
17
+ TaskMessageUpdate,
18
+ StreamTaskMessageStart,
19
+ StreamTaskMessageDelta,
20
+ StreamTaskMessageFull,
21
+ StreamTaskMessageDone
22
+ )
23
+ from agentex.types.text_delta import TextDelta
24
+
25
+ from rich.console import Console
26
+ from rich.panel import Panel
27
+ from rich.markdown import Markdown
28
+ from yaspin import yaspin
29
+
30
+
31
+ def print_task_message(
32
+ message: TaskMessage,
33
+ print_messages: bool = True,
34
+ rich_print: bool = True,
35
+ ) -> None:
36
+ """
37
+ Print a task message in a formatted way.
38
+
39
+ Args:
40
+ message: The task message to print
41
+ print_messages: Whether to actually print the message (for debugging)
42
+ rich_print: Whether to use rich to print the message
43
+ """
44
+ if not print_messages:
45
+ return
46
+
47
+ # Skip empty messages
48
+ if isinstance(message.content, TextContent) and not message.content.content.strip():
49
+ return
50
+
51
+ timestamp = message.created_at.strftime("%m/%d/%Y %H:%M:%S") if message.created_at else "N/A"
52
+
53
+ console = None
54
+ if rich_print:
55
+ console = Console(width=80) # Fit better in Jupyter cells
56
+
57
+ if isinstance(message.content, TextContent):
58
+ content = message.content.content
59
+ content_type = "text"
60
+ elif isinstance(message.content, ToolRequestContent):
61
+ tool_name = message.content.name
62
+ tool_args = message.content.arguments
63
+
64
+ # Format arguments as pretty JSON
65
+ try:
66
+ if isinstance(tool_args, str):
67
+ parsed_args = json.loads(tool_args)
68
+ formatted_args = json.dumps(parsed_args, indent=2)
69
+ else:
70
+ formatted_args = json.dumps(tool_args, indent=2)
71
+ content = f"🔧 **Tool Request: {tool_name}**\n\n**Arguments:**\n```json\n{formatted_args}\n```"
72
+ except (json.JSONDecodeError, TypeError):
73
+ content = f"🔧 **Tool Request: {tool_name}**\n\n**Arguments:**\n```json\n{tool_args}\n```"
74
+
75
+ content_type = "tool_request"
76
+ elif isinstance(message.content, ToolResponseContent):
77
+ tool_name = message.content.name
78
+ tool_response = message.content.content
79
+
80
+ # Try to parse and format JSON response nicely
81
+ try:
82
+ if isinstance(tool_response, str):
83
+ parsed_response = json.loads(tool_response)
84
+ formatted_json = json.dumps(parsed_response, indent=2)
85
+ content = f"✅ **Tool Response: {tool_name}**\n\n**Response:**\n```json\n{formatted_json}\n```"
86
+ else:
87
+ formatted_json = json.dumps(tool_response, indent=2)
88
+ content = f"✅ **Tool Response: {tool_name}**\n\n**Response:**\n```json\n{formatted_json}\n```"
89
+ except (json.JSONDecodeError, TypeError):
90
+ # If it's not valid JSON, display as text
91
+ if isinstance(tool_response, str):
92
+ # Try to extract text content if it's a JSON string with text field
93
+ try:
94
+ parsed = json.loads(tool_response)
95
+ if isinstance(parsed, dict) and "text" in parsed:
96
+ text_content = str(parsed["text"])
97
+ content = f"✅ **Tool Response: {tool_name}**\n\n{text_content}"
98
+ else:
99
+ content = f"✅ **Tool Response: {tool_name}**\n\n{tool_response}"
100
+ except json.JSONDecodeError:
101
+ content = f"✅ **Tool Response: {tool_name}**\n\n{tool_response}"
102
+ else:
103
+ content = f"✅ **Tool Response: {tool_name}**\n\n{tool_response}"
104
+
105
+ content_type = "tool_response"
106
+ else:
107
+ content = f"{type(message.content).__name__}: {message.content}"
108
+ content_type = "other"
109
+
110
+ if rich_print and console:
111
+ author_color = "bright_cyan" if message.content.author == "user" else "green"
112
+ title = f"[bold {author_color}]{message.content.author.upper()}[/bold {author_color}] [{timestamp}]"
113
+
114
+ # Use different border styles for tool messages
115
+ if content_type == "tool_request":
116
+ border_style = "yellow"
117
+ elif content_type == "tool_response":
118
+ border_style = "bright_green"
119
+ else:
120
+ border_style = author_color
121
+
122
+ panel = Panel(Markdown(content), title=title, border_style=border_style, width=80)
123
+ console.print(panel)
124
+ else:
125
+ title = f"{message.content.author.upper()} [{timestamp}]"
126
+ print(f"{title}\n{content}\n")
127
+
128
+
129
+ def print_task_message_update(
130
+ task_message_update: TaskMessageUpdate,
131
+ print_messages: bool = True,
132
+ rich_print: bool = True,
133
+ show_deltas: bool = True,
134
+ ) -> None:
135
+ """
136
+ Print a task message update in a formatted way.
137
+
138
+ This function handles different types of TaskMessageUpdate objects:
139
+ - StreamTaskMessageStart: Shows start indicator
140
+ - StreamTaskMessageDelta: Shows deltas in real-time (if show_deltas=True)
141
+ - StreamTaskMessageFull: Shows complete message content
142
+ - StreamTaskMessageDone: Shows completion indicator
143
+
144
+ Args:
145
+ task_message_update: The TaskMessageUpdate object to print
146
+ print_messages: Whether to actually print the message (for debugging)
147
+ rich_print: Whether to use rich formatting
148
+ show_deltas: Whether to show delta updates in real-time
149
+ """
150
+ if not print_messages:
151
+ return
152
+
153
+ console = None
154
+ if rich_print:
155
+ console = Console(width=80)
156
+
157
+ if isinstance(task_message_update, StreamTaskMessageStart):
158
+ if rich_print and console:
159
+ console.print("🚀 [cyan]Agent started responding...[/cyan]")
160
+ else:
161
+ print("🚀 Agent started responding...")
162
+
163
+ elif isinstance(task_message_update, StreamTaskMessageDelta):
164
+ if show_deltas and task_message_update.delta:
165
+ if isinstance(task_message_update.delta, TextDelta):
166
+ print(task_message_update.delta.text_delta, end="", flush=True)
167
+ elif rich_print and console:
168
+ console.print(f"[yellow]Non-text delta: {type(task_message_update.delta).__name__}[/yellow]")
169
+ else:
170
+ print(f"Non-text delta: {type(task_message_update.delta).__name__}")
171
+
172
+ elif isinstance(task_message_update, StreamTaskMessageFull):
173
+ if isinstance(task_message_update.content, TextContent):
174
+ timestamp = datetime.now().strftime("%m/%d/%Y %H:%M:%S")
175
+
176
+ if rich_print and console:
177
+ author_color = "bright_cyan" if task_message_update.content.author == "user" else "green"
178
+ title = f"[bold {author_color}]{task_message_update.content.author.upper()}[/bold {author_color}] [{timestamp}]"
179
+ panel = Panel(Markdown(task_message_update.content.content), title=title, border_style=author_color, width=80)
180
+ console.print(panel)
181
+ else:
182
+ title = f"{task_message_update.content.author.upper()} [{timestamp}]"
183
+ print(f"\n{title}\n{task_message_update.content.content}\n")
184
+ else:
185
+ content_type = type(task_message_update.content).__name__
186
+ if rich_print and console:
187
+ console.print(f"[yellow]Non-text content: {content_type}[/yellow]")
188
+ else:
189
+ print(f"Non-text content: {content_type}")
190
+
191
+ else: # StreamTaskMessageDone
192
+ if rich_print and console:
193
+ console.print("\n✅ [green]Agent finished responding.[/green]")
194
+ else:
195
+ print("\n✅ Agent finished responding.")
196
+
197
+
198
+ def subscribe_to_async_task_messages(
199
+ client: Agentex,
200
+ task: Task,
201
+ only_after_timestamp: Optional[datetime] = None,
202
+ print_messages: bool = True,
203
+ rich_print: bool = True,
204
+ timeout: int = 10,
205
+ ) -> List[TaskMessage]:
206
+ """
207
+ Subscribe to async task messages and collect completed messages.
208
+
209
+ This function:
210
+ 1. Reads all existing messages from the task
211
+ 2. Optionally filters messages after a timestamp
212
+ 3. Shows a loading message while listening
213
+ 4. Subscribes to task message events
214
+ 5. Fetches and displays complete messages when they finish
215
+ 6. Returns all messages collected during the session
216
+
217
+ Features:
218
+ - Uses Rich library for beautiful formatting in Jupyter notebooks
219
+ - Agent messages are formatted as Markdown
220
+ - User and agent messages are displayed in colored panels with fixed width
221
+ - Optimized for Jupyter notebook display
222
+
223
+ Args:
224
+ client: The Agentex client instance
225
+ task: The task to subscribe to
226
+ print_messages: Whether to print messages as they arrive
227
+ only_after_timestamp: Only include messages created after this timestamp. If None, all messages will be included.
228
+ rich_print: Whether to use rich to print the message
229
+ timeout: The timeout in seconds for the streaming connection. If the connection times out, the function will return with any messages collected so far.
230
+ Returns:
231
+ List of TaskMessage objects collected during the session
232
+
233
+ Raises:
234
+ ValueError: If the task doesn't have a name (required for streaming)
235
+ """
236
+
237
+ messages_to_return: List[TaskMessage] = []
238
+
239
+ # Read existing messages
240
+ messages = []
241
+ try:
242
+ # List all messages for this task - MessageListResponse is just a List[TaskMessage]
243
+ messages = client.messages.list(task_id=task.id)
244
+
245
+ except Exception as e:
246
+ print(f"Error reading existing messages: {e}")
247
+
248
+ # Filter and display existing messages
249
+ for message in messages:
250
+ if only_after_timestamp:
251
+ if message.created_at is not None:
252
+ # Handle timezone comparison - make both datetimes timezone-aware
253
+ message_time = message.created_at
254
+ if message_time.tzinfo is None:
255
+ # If message time is naive, assume it's in UTC
256
+ message_time = message_time.replace(tzinfo=timezone.utc)
257
+
258
+ comparison_time = only_after_timestamp
259
+ if comparison_time.tzinfo is None:
260
+ # If comparison time is naive, assume it's in UTC
261
+ comparison_time = comparison_time.replace(tzinfo=timezone.utc)
262
+
263
+ if message_time < comparison_time:
264
+ continue
265
+ else:
266
+ messages_to_return.append(message)
267
+ print_task_message(message, print_messages, rich_print)
268
+ else:
269
+ messages_to_return.append(message)
270
+ print_task_message(message, print_messages, rich_print)
271
+
272
+ # Subscribe to server-side events using tasks.stream_events_by_name
273
+ # This is the proper way to get agent responses after sending an event in agentic agents
274
+
275
+ # Ensure task has a name
276
+ if not task.name:
277
+ print("Error: Task must have a name to use stream_events_by_name")
278
+ raise ValueError("Task name is required")
279
+
280
+ try:
281
+ # Use stream_events_by_name to subscribe to TaskMessageUpdate events for this task
282
+ # This doesn't require knowing the agent_id, just the task name
283
+
284
+ # Track active streaming spinners per message index
285
+ active_spinners: dict[int, Yaspin] = {} # index -> yaspin spinner object
286
+
287
+ with client.tasks.with_streaming_response.stream_events_by_name(
288
+ task_name=task.name,
289
+ timeout=timeout
290
+ ) as response:
291
+
292
+ try:
293
+ for task_message_update_str in response.iter_text():
294
+ try:
295
+ # Parse SSE format
296
+ if task_message_update_str.strip().startswith('data: '):
297
+ task_message_update_json = task_message_update_str.strip()[6:] # Remove 'data: ' prefix
298
+ task_message_update_data = json.loads(task_message_update_json)
299
+
300
+ # Deserialize the discriminated union TaskMessageUpdate based on the "type" field
301
+ message_type = task_message_update_data.get("type", "unknown")
302
+
303
+ # Handle different message types for streaming progress
304
+ if message_type == "start":
305
+ task_message_update = StreamTaskMessageStart.model_validate(task_message_update_data)
306
+ index = task_message_update.index or 0
307
+
308
+ # Start a yaspin spinner for this message
309
+ if print_messages and index not in active_spinners:
310
+ spinner = yaspin(text="🔄 Agent responding...")
311
+ spinner.start()
312
+ active_spinners[index] = spinner
313
+
314
+ elif message_type == "delta":
315
+ task_message_update = StreamTaskMessageDelta.model_validate(task_message_update_data)
316
+ index = task_message_update.index or 0
317
+
318
+ # Spinner continues running (no update needed for HTML) or if spinner has not been created yet, create it
319
+ if print_messages and index not in active_spinners:
320
+ spinner = yaspin(text="🔄 Agent responding...")
321
+ spinner.start()
322
+ active_spinners[index] = spinner
323
+
324
+ elif message_type == "full":
325
+ task_message_update = StreamTaskMessageFull.model_validate(task_message_update_data)
326
+ index = task_message_update.index or 0
327
+
328
+ # Stop spinner and show message
329
+ if index in active_spinners:
330
+ active_spinners[index].stop()
331
+ del active_spinners[index]
332
+
333
+ if task_message_update.parent_task_message and task_message_update.parent_task_message.id:
334
+ finished_message = client.messages.retrieve(task_message_update.parent_task_message.id)
335
+ messages_to_return.append(finished_message)
336
+ print_task_message(finished_message, print_messages, rich_print)
337
+
338
+ elif message_type == "done":
339
+ task_message_update = StreamTaskMessageDone.model_validate(task_message_update_data)
340
+ index = task_message_update.index or 0
341
+
342
+ # Stop spinner and show message
343
+ if index in active_spinners:
344
+ active_spinners[index].stop()
345
+ del active_spinners[index]
346
+
347
+ if task_message_update.parent_task_message and task_message_update.parent_task_message.id:
348
+ finished_message = client.messages.retrieve(task_message_update.parent_task_message.id)
349
+ messages_to_return.append(finished_message)
350
+ print_task_message(finished_message, print_messages, rich_print)
351
+
352
+ # Ignore "connected" message type
353
+ elif message_type == "connected":
354
+ pass
355
+ else:
356
+ if print_messages:
357
+ print(f"Unknown TaskMessageUpdate type: {message_type}")
358
+
359
+ except json.JSONDecodeError:
360
+ # Skip invalid JSON or SSE metadata lines
361
+ if task_message_update_str.strip() and not task_message_update_str.startswith(':'):
362
+ if print_messages:
363
+ print(f"Skipping non-JSON: {task_message_update_str.strip()}")
364
+ continue
365
+ except Exception as e:
366
+ if print_messages:
367
+ print(f"Error processing TaskMessageUpdate: {e}")
368
+ print(f"Raw data: {task_message_update_str.strip()}")
369
+ continue
370
+ finally:
371
+ # Stop any remaining spinners when we're done
372
+ for spinner in active_spinners.values():
373
+ spinner.stop()
374
+ active_spinners.clear()
375
+
376
+ except Exception as e:
377
+ # Handle timeout gracefully
378
+ if "timeout" in str(e).lower() or "timed out" in str(e).lower():
379
+ if print_messages:
380
+ print(f"Streaming timed out after {timeout} seconds - returning collected messages")
381
+ else:
382
+ if print_messages:
383
+ print(f"Error subscribing to events: {e}")
384
+ print("Make sure your agent is running and the task exists")
385
+
386
+ return messages_to_return
@@ -7,7 +7,7 @@ from typing_extensions import Literal
7
7
 
8
8
  import httpx
9
9
 
10
- from ..types import AgentRpcParams, agent_rpc_params, agent_list_params, agent_rpc_by_name_params
10
+ from ..types import agent_rpc_params, agent_list_params, agent_rpc_by_name_params
11
11
  from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
12
12
  from .._utils import maybe_transform, async_maybe_transform
13
13
  from .._compat import cached_property
@@ -20,7 +20,6 @@ from .._response import (
20
20
  )
21
21
  from ..types.agent import Agent
22
22
  from .._base_client import make_request_options
23
- from ..types.agent_rpc_params import AgentRpcParams
24
23
  from ..types.agent_rpc_response import AgentRpcResponse
25
24
  from ..types.agent_list_response import AgentListResponse
26
25
 
@@ -221,7 +220,7 @@ class AgentsResource(SyncAPIResource):
221
220
  agent_id: str,
222
221
  *,
223
222
  method: Literal["event/send", "task/create", "message/send", "task/cancel"],
224
- params: AgentRpcParams,
223
+ params: agent_rpc_params.Params,
225
224
  id: Union[int, str, None] | NotGiven = NOT_GIVEN,
226
225
  jsonrpc: Literal["2.0"] | NotGiven = NOT_GIVEN,
227
226
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -269,7 +268,7 @@ class AgentsResource(SyncAPIResource):
269
268
  agent_name: str,
270
269
  *,
271
270
  method: Literal["event/send", "task/create", "message/send", "task/cancel"],
272
- params: AgentRpcParams,
271
+ params: agent_rpc_by_name_params.Params,
273
272
  id: Union[int, str, None] | NotGiven = NOT_GIVEN,
274
273
  jsonrpc: Literal["2.0"] | NotGiven = NOT_GIVEN,
275
274
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -507,7 +506,7 @@ class AsyncAgentsResource(AsyncAPIResource):
507
506
  agent_id: str,
508
507
  *,
509
508
  method: Literal["event/send", "task/create", "message/send", "task/cancel"],
510
- params: AgentRpcParams,
509
+ params: agent_rpc_params.Params,
511
510
  id: Union[int, str, None] | NotGiven = NOT_GIVEN,
512
511
  jsonrpc: Literal["2.0"] | NotGiven = NOT_GIVEN,
513
512
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -555,7 +554,7 @@ class AsyncAgentsResource(AsyncAPIResource):
555
554
  agent_name: str,
556
555
  *,
557
556
  method: Literal["event/send", "task/create", "message/send", "task/cancel"],
558
- params: AgentRpcParams,
557
+ params: agent_rpc_by_name_params.Params,
559
558
  id: Union[int, str, None] | NotGiven = NOT_GIVEN,
560
559
  jsonrpc: Literal["2.0"] | NotGiven = NOT_GIVEN,
561
560
  # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -2,20 +2,70 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Union
6
- from typing_extensions import Literal, Required, TypedDict
5
+ from typing import Dict, Union, Optional
6
+ from typing_extensions import Literal, Required, TypeAlias, TypedDict
7
7
 
8
- from .agent_rpc_params import AgentRpcParams
8
+ from .task_message_content_param import TaskMessageContentParam
9
9
 
10
- __all__ = ["AgentRpcByNameParams"]
10
+ __all__ = [
11
+ "AgentRpcByNameParams",
12
+ "Params",
13
+ "ParamsCreateTaskRequest",
14
+ "ParamsCancelTaskRequest",
15
+ "ParamsSendMessageRequest",
16
+ "ParamsSendEventRequest",
17
+ ]
11
18
 
12
19
 
13
20
  class AgentRpcByNameParams(TypedDict, total=False):
14
21
  method: Required[Literal["event/send", "task/create", "message/send", "task/cancel"]]
15
22
 
16
- params: Required[AgentRpcParams]
23
+ params: Required[Params]
17
24
  """The parameters for the agent RPC request"""
18
25
 
19
26
  id: Union[int, str, None]
20
27
 
21
28
  jsonrpc: Literal["2.0"]
29
+
30
+
31
+ class ParamsCreateTaskRequest(TypedDict, total=False):
32
+ name: Optional[str]
33
+ """The name of the task to create"""
34
+
35
+ params: Optional[Dict[str, object]]
36
+ """The parameters for the task"""
37
+
38
+
39
+ class ParamsCancelTaskRequest(TypedDict, total=False):
40
+ task_id: Optional[str]
41
+ """The ID of the task to cancel. Either this or task_name must be provided."""
42
+
43
+ task_name: Optional[str]
44
+ """The name of the task to cancel. Either this or task_id must be provided."""
45
+
46
+
47
+ class ParamsSendMessageRequest(TypedDict, total=False):
48
+ content: Required[TaskMessageContentParam]
49
+ """The message that was sent to the agent"""
50
+
51
+ stream: bool
52
+ """Whether to stream the response message back to the client"""
53
+
54
+ task_id: Optional[str]
55
+ """The ID of the task that the message was sent to"""
56
+
57
+
58
+ class ParamsSendEventRequest(TypedDict, total=False):
59
+ content: Optional[TaskMessageContentParam]
60
+ """The content to send to the event"""
61
+
62
+ task_id: Optional[str]
63
+ """The ID of the task that the event was sent to"""
64
+
65
+ task_name: Optional[str]
66
+ """The name of the task that the event was sent to"""
67
+
68
+
69
+ Params: TypeAlias = Union[
70
+ ParamsCreateTaskRequest, ParamsCancelTaskRequest, ParamsSendMessageRequest, ParamsSendEventRequest
71
+ ]
@@ -3,14 +3,32 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from typing import Dict, Union, Optional
6
- from typing_extensions import Required, TypeAlias, TypedDict
6
+ from typing_extensions import Literal, Required, TypeAlias, TypedDict
7
7
 
8
8
  from .task_message_content_param import TaskMessageContentParam
9
9
 
10
- __all__ = ["AgentRpcParams", "CreateTaskRequest", "CancelTaskRequest", "SendMessageRequest", "SendEventRequest"]
10
+ __all__ = [
11
+ "AgentRpcParams",
12
+ "Params",
13
+ "ParamsCreateTaskRequest",
14
+ "ParamsCancelTaskRequest",
15
+ "ParamsSendMessageRequest",
16
+ "ParamsSendEventRequest",
17
+ ]
11
18
 
12
19
 
13
- class CreateTaskRequest(TypedDict, total=False):
20
+ class AgentRpcParams(TypedDict, total=False):
21
+ method: Required[Literal["event/send", "task/create", "message/send", "task/cancel"]]
22
+
23
+ params: Required[Params]
24
+ """The parameters for the agent RPC request"""
25
+
26
+ id: Union[int, str, None]
27
+
28
+ jsonrpc: Literal["2.0"]
29
+
30
+
31
+ class ParamsCreateTaskRequest(TypedDict, total=False):
14
32
  name: Optional[str]
15
33
  """The name of the task to create"""
16
34
 
@@ -18,7 +36,7 @@ class CreateTaskRequest(TypedDict, total=False):
18
36
  """The parameters for the task"""
19
37
 
20
38
 
21
- class CancelTaskRequest(TypedDict, total=False):
39
+ class ParamsCancelTaskRequest(TypedDict, total=False):
22
40
  task_id: Optional[str]
23
41
  """The ID of the task to cancel. Either this or task_name must be provided."""
24
42
 
@@ -26,7 +44,7 @@ class CancelTaskRequest(TypedDict, total=False):
26
44
  """The name of the task to cancel. Either this or task_id must be provided."""
27
45
 
28
46
 
29
- class SendMessageRequest(TypedDict, total=False):
47
+ class ParamsSendMessageRequest(TypedDict, total=False):
30
48
  content: Required[TaskMessageContentParam]
31
49
  """The message that was sent to the agent"""
32
50
 
@@ -37,7 +55,7 @@ class SendMessageRequest(TypedDict, total=False):
37
55
  """The ID of the task that the message was sent to"""
38
56
 
39
57
 
40
- class SendEventRequest(TypedDict, total=False):
58
+ class ParamsSendEventRequest(TypedDict, total=False):
41
59
  content: Optional[TaskMessageContentParam]
42
60
  """The content to send to the event"""
43
61
 
@@ -48,4 +66,6 @@ class SendEventRequest(TypedDict, total=False):
48
66
  """The name of the task that the event was sent to"""
49
67
 
50
68
 
51
- AgentRpcParams: TypeAlias = Union[CreateTaskRequest, CancelTaskRequest, SendMessageRequest, SendEventRequest]
69
+ Params: TypeAlias = Union[
70
+ ParamsCreateTaskRequest, ParamsCancelTaskRequest, ParamsSendMessageRequest, ParamsSendEventRequest
71
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: agentex-sdk
3
- Version: 0.1.1
3
+ Version: 0.2.1
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