agentenv-framework-protocol 0.1.292__tar.gz → 0.1.294__tar.gz

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 (39) hide show
  1. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/PKG-INFO +6 -1
  2. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/README.md +5 -0
  3. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/pyproject.toml +1 -1
  4. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/a2a_agent/framework.py +5 -5
  5. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_a2a_agent.py +73 -0
  6. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/.gitignore +0 -0
  7. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/LICENSE +0 -0
  8. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/NOTICE +0 -0
  9. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/THIRD_PARTY_NOTICES.md +0 -0
  10. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/examples/__init__.py +0 -0
  11. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/examples/advanced_agent.py +0 -0
  12. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/examples/basic_agent.py +0 -0
  13. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/examples/custom_extensions_agent.py +0 -0
  14. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/examples/multimodal_agent.py +0 -0
  15. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/examples/reference_model.py +0 -0
  16. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/examples/streaming_agent.py +0 -0
  17. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/__init__.py +0 -0
  18. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/a2a_agent/__init__.py +0 -0
  19. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/a2a_agent/_triggers.py +0 -0
  20. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/a2a_agent/extensions.py +0 -0
  21. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/a2a_agent/registry.py +0 -0
  22. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/a2a_agent/staging.py +0 -0
  23. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/a2a_agent/tasks/__init__.py +0 -0
  24. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/a2a_agent/tasks/v1.py +0 -0
  25. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/agent_env_environment.py +0 -0
  26. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/client.py +0 -0
  27. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/manifest.py +0 -0
  28. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/preflight.py +0 -0
  29. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/transfers.py +0 -0
  30. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/src/agentenv_protocol/types.py +0 -0
  31. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_a2a_agent_examples.py +0 -0
  32. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_a2a_object_transfers.py +0 -0
  33. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_a2a_staging.py +0 -0
  34. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_agent_env_environment.py +0 -0
  35. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_client.py +0 -0
  36. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_data_objects.py +0 -0
  37. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_intake.py +0 -0
  38. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_manifest.py +0 -0
  39. {agentenv_framework_protocol-0.1.292 → agentenv_framework_protocol-0.1.294}/tests/test_preflight.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentenv-framework-protocol
3
- Version: 0.1.292
3
+ Version: 0.1.294
4
4
  Summary: Open data-plane protocol and server SDK for agent environments.
5
5
  Project-URL: Homepage, https://www.agentenvframework.com
6
6
  Project-URL: Documentation, https://www.agentenvframework.com/docs
@@ -345,6 +345,11 @@ A successful `TaskResult` must contain at least one text, file, or data part;
345
345
  the framework rejects empty successes rather than emitting an ungradeable task.
346
346
  The SDK does not retry tasks.
347
347
 
348
+ A client that gives up on a task sends `tasks/cancel`. The framework marks the
349
+ task canceled and cancels `run()`, which gets `asyncio.CancelledError` at its
350
+ next `await`. A process `run()` started keeps running unless `run()` stops it,
351
+ so kill it before re-raising.
352
+
348
353
  `enable(..., description="...")` is reserved for declarations carrying
349
354
  configuration or metadata. It preserves the agent-specific extension prose
350
355
  published in the Agent Card. The versioned SDK definition provides a generic
@@ -301,6 +301,11 @@ A successful `TaskResult` must contain at least one text, file, or data part;
301
301
  the framework rejects empty successes rather than emitting an ungradeable task.
302
302
  The SDK does not retry tasks.
303
303
 
304
+ A client that gives up on a task sends `tasks/cancel`. The framework marks the
305
+ task canceled and cancels `run()`, which gets `asyncio.CancelledError` at its
306
+ next `await`. A process `run()` started keeps running unless `run()` stops it,
307
+ so kill it before re-raising.
308
+
304
309
  `enable(..., description="...")` is reserved for declarations carrying
305
310
  configuration or metadata. It preserves the agent-specific extension prose
306
311
  published in the Agent Card. The versioned SDK definition provides a generic
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentenv-framework-protocol"
3
- version = "0.1.292"
3
+ version = "0.1.294"
4
4
  description = "Open data-plane protocol and server SDK for agent environments."
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -1226,12 +1226,12 @@ class _StandardExecutor:
1226
1226
  "streaming TaskStatusUpdateEvent must be non-terminal and final=False"
1227
1227
  )
1228
1228
 
1229
- async def cancel(self, _context: Any, _event_queue: Any) -> None:
1230
- """Satisfy the upstream executor interface without offering cancellation."""
1231
- from a2a.types import UnsupportedOperationError
1232
- from a2a.utils.errors import ServerError
1229
+ async def cancel(self, context: Any, event_queue: Any) -> None:
1230
+ """Mark the task canceled. The SDK then cancels the coroutine running it, so ``agent.run`` gets
1231
+ ``CancelledError`` at its next ``await`` and should stop whatever it started, such as a CLI process."""
1232
+ from a2a.server.tasks import TaskUpdater
1233
1233
 
1234
- raise ServerError(error=UnsupportedOperationError())
1234
+ await TaskUpdater(event_queue, context.task_id, context.context_id).cancel()
1235
1235
 
1236
1236
 
1237
1237
  def _from_a2a_part(part: Any) -> Any:
@@ -2908,3 +2908,76 @@ def test_extension_cannot_shadow_framework_route(
2908
2908
 
2909
2909
  with pytest.raises(ValueError, match=rf"conflicts with {owner} route"):
2910
2910
  Agent().create_app()
2911
+
2912
+
2913
+ def _send_in_context(client: TestClient, text: str, message_id: str) -> str:
2914
+ response = client.post(
2915
+ "/a2a",
2916
+ json={
2917
+ "jsonrpc": "2.0",
2918
+ "id": message_id,
2919
+ "method": "message/send",
2920
+ "params": {
2921
+ "message": {
2922
+ "kind": "message",
2923
+ "messageId": message_id,
2924
+ "role": "user",
2925
+ "contextId": "context-1",
2926
+ "parts": [{"kind": "text", "text": text}],
2927
+ },
2928
+ "configuration": {"blocking": False},
2929
+ },
2930
+ },
2931
+ )
2932
+ return response.json()["result"]["id"]
2933
+
2934
+
2935
+ def _task_rpc(client: TestClient, method: str, task_id: str) -> dict[str, Any]:
2936
+ return client.post(
2937
+ "/a2a",
2938
+ json={"jsonrpc": "2.0", "id": method, "method": method, "params": {"id": task_id}},
2939
+ ).json()
2940
+
2941
+
2942
+ def _within(seconds: float, condition) -> bool:
2943
+ deadline = time.monotonic() + seconds
2944
+ while not condition():
2945
+ if time.monotonic() > deadline:
2946
+ return False
2947
+ time.sleep(0.01)
2948
+ return True
2949
+
2950
+
2951
+ def test_cancel_stops_a_running_task_and_frees_its_context() -> None:
2952
+ ran: list[str] = []
2953
+ cancelled: list[str] = []
2954
+
2955
+ @a2a_agent(identity=AgentIdentity(name="slow", description="test", version="1"))
2956
+ class Agent(AgentEnvAgent):
2957
+ async def run(self, request: TaskRequest) -> TaskResult:
2958
+ text = request.parts[0].text
2959
+ ran.append(text)
2960
+ if text == "hang":
2961
+ try:
2962
+ await asyncio.Event().wait()
2963
+ except asyncio.CancelledError:
2964
+ cancelled.append(text)
2965
+ raise
2966
+ return TaskResult.text(f"did {text}")
2967
+
2968
+ def state(client: TestClient, task_id: str) -> str:
2969
+ return _task_rpc(client, "tasks/get", task_id)["result"]["status"]["state"]
2970
+
2971
+ with TestClient(Agent().create_app()) as client:
2972
+ hung = _send_in_context(client, "hang", "message-1")
2973
+ assert _within(5, lambda: ran == ["hang"])
2974
+
2975
+ canceled = _task_rpc(client, "tasks/cancel", hung)
2976
+ assert canceled["result"]["status"]["state"] == "canceled"
2977
+
2978
+ following = _send_in_context(client, "next", "message-2")
2979
+ assert _within(5, lambda: state(client, following) == "completed")
2980
+ assert state(client, hung) == "canceled"
2981
+
2982
+ assert cancelled == ["hang"]
2983
+ assert ran == ["hang", "next"]