From 32ba78273d3a28506364aa66b368b9b2996fa064 Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Sat, 16 May 2026 21:33:03 -0500 Subject: [PATCH 1/3] Port pydantic-ai a2a integration tests + run them in CI Adds `tests/test_pydantic_ai.py` (11 tests) covering the `fasta2a.pydantic_ai` bridge end-to-end: pydantic model outputs with JSON schema, lifespan required-or-runtime-error, text/file/data Part round-trips, error handling, multi-task context sharing, thinking responses, history splicing, and multi-message conversations. Ported verbatim from `tests/test_a2a.py` in `pydantic/pydantic-ai`; snapshots transferred unchanged because the bridge code is identical. CI: - `main.yml` now triggers on `release/**` branches too (not just `main`) - Install step adds `--extra pydantic-ai`; the extra is marker-gated to Python 3.10+, so on 3.9 it resolves to nothing and the test file short-circuits via `pytest.importorskip('pydantic_ai')` Dev deps: - Added `anyio` (explicit), `dirty-equals` (matchers in snapshots) - Added `tests/assets/kiwi.jpg` (copied from pydantic-ai test assets) After this, `pydantic-ai`'s in-tree `tests/test_a2a.py` can be safely dropped in the v2-exec PR since the same coverage now lives upstream. --- .github/workflows/main.yml | 10 +- pyproject.toml | 2 + tests/assets/kiwi.jpg | Bin 0 -> 98572 bytes tests/test_pydantic_ai.py | 1060 ++++++++++++++++++++++++++++++++++++ uv.lock | 13 + 5 files changed, 1082 insertions(+), 3 deletions(-) create mode 100644 tests/assets/kiwi.jpg create mode 100644 tests/test_pydantic_ai.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c1e7580..a6684cc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: ["main"] + branches: ["main", "release/**"] pull_request: - branches: ["main"] + branches: ["main", "release/**"] jobs: test: @@ -21,8 +21,12 @@ jobs: python-version: ${{ matrix.python-version }} enable-cache: true + # `[pydantic-ai]` is the optional extra that pulls `pydantic-ai-slim` for + # the `fasta2a.pydantic_ai` bridge tests. Marker-gated to Python 3.10+, so + # on 3.9 it resolves to nothing and the bridge tests skip themselves via + # `pytest.importorskip('pydantic_ai')` in `tests/test_pydantic_ai.py`. - name: Install dependencies - run: uv sync --frozen + run: uv sync --frozen --extra pydantic-ai - name: Run linters run: scripts/check diff --git a/pyproject.toml b/pyproject.toml index 19ce3c8..c241662 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,8 +56,10 @@ pydantic-ai = ["pydantic-ai-slim>=1.92; python_version >= '3.10'"] [dependency-groups] dev = [ + "anyio", "asgi-lifespan", "coverage", + "dirty-equals", "httpx", "inline-snapshot", "pytest", diff --git a/tests/assets/kiwi.jpg b/tests/assets/kiwi.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c8bd7962fd408b2147e57e5839f617966b6bd7cd GIT binary patch literal 98572 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 K=70d^fdART=gCt5 literal 0 HcmV?d00001 diff --git a/tests/test_pydantic_ai.py b/tests/test_pydantic_ai.py new file mode 100644 index 0000000..29adafa --- /dev/null +++ b/tests/test_pydantic_ai.py @@ -0,0 +1,1060 @@ +"""Integration tests for the Pydantic AI bridge submodule (`fasta2a.pydantic_ai`). + +Ported from `tests/test_a2a.py` in the [pydantic-ai +repo](https://github.com/pydantic/pydantic-ai), where these tests originally exercised +`Agent.to_a2a()`. With the bridge code now hosted upstream here, this file owns the +A2A integration test surface for the Pydantic AI workflow. + +Skipped on Python < 3.10 because `pydantic-ai-slim` requires 3.10+. +""" + +# `fasta2a.pydantic_ai._bridge` raises ImportError when pydantic-ai is missing, so pyright sees an +# Unknown branch on every call from this file. Silencing two Unknown-related rules at the file level +# rather than scattering per-line ignores across 11 test bodies. +# pyright: reportUnknownVariableType=false, reportUnknownArgumentType=false + +from __future__ import annotations as _annotations + +import base64 +import sys +import uuid +from datetime import datetime, timezone +from pathlib import Path +from typing import TYPE_CHECKING, Any + +import anyio +import httpx +import pytest +from asgi_lifespan import LifespanManager +from inline_snapshot import snapshot + +pytest.importorskip('pydantic_ai', reason='pydantic-ai-slim required (Python 3.10+)') + +# `dirty_equals` matchers (`IsStr`, `IsDatetime`, `IsNow`) report `__eq__`-based equivalence but pyright +# can't see they're meant to substitute for `str`/`datetime` in equality contexts. Mirror the stubs trick +# used in `pydantic-ai/tests/conftest.py` to satisfy strict typecheck. +if TYPE_CHECKING: + + def IsStr(*args: Any, **kwargs: Any) -> str: ... + def IsDatetime(*args: Any, **kwargs: Any) -> datetime: ... + def IsNow(*args: Any, **kwargs: Any) -> datetime: ... +else: + from dirty_equals import IsDatetime, IsNow, IsStr + +from pydantic import BaseModel # noqa: E402 +from pydantic_ai import ( # noqa: E402 + Agent, + BinaryContent, + ModelMessage, + ModelRequest, + ModelResponse, + TextPart as PydanticAITextPart, + ThinkingPart, + ToolCallPart, + ToolReturnPart, + UserPromptPart, +) +from pydantic_ai.models.function import AgentInfo, FunctionModel # noqa: E402 +from pydantic_ai.usage import RequestUsage # noqa: E402 + +from fasta2a.applications import FastA2A # noqa: E402 +from fasta2a.client import A2AClient # noqa: E402 +from fasta2a.pydantic_ai import agent_to_a2a # noqa: E402 +from fasta2a.schema import DataPart, FilePart, Message, TextPart # noqa: E402 +from fasta2a.storage import InMemoryStorage # noqa: E402 + +pytestmark = [ + pytest.mark.skipif(sys.version_info < (3, 10), reason='pydantic-ai-slim requires 3.10+'), + pytest.mark.anyio, +] + + +@pytest.fixture(scope='session') +def image_content() -> BinaryContent: + return BinaryContent( + data=(Path(__file__).parent / 'assets' / 'kiwi.jpg').read_bytes(), + media_type='image/jpeg', + ) + + +def return_string(_: list[ModelMessage], info: AgentInfo) -> ModelResponse: + assert info.output_tools is not None + args_json = '{"response": ["foo", "bar"]}' + return ModelResponse(parts=[ToolCallPart(info.output_tools[0].name, args_json)]) + + +model = FunctionModel(return_string) + + +class UserProfile(BaseModel): + name: str + age: int + email: str + + +def return_pydantic_model(_: list[ModelMessage], info: AgentInfo) -> ModelResponse: + assert info.output_tools is not None + args_json = '{"name": "John Doe", "age": 30, "email": "john@example.com"}' + return ModelResponse(parts=[ToolCallPart(info.output_tools[0].name, args_json)]) + + +pydantic_model = FunctionModel(return_pydantic_model) + + +async def test_pydantic_model_output(): + """Pydantic model outputs carry metadata including JSON schema.""" + agent = Agent(model=pydantic_model, output_type=UserProfile) + app: FastA2A = agent_to_a2a(agent) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[TextPart(text='Get user profile', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert 'error' not in response + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + + task_id = result['id'] + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'completed': + result = task['result'] + break + await anyio.sleep(0.1) + + assert 'artifacts' in result + assert len(result['artifacts']) == 1 + artifact = result['artifacts'][0] + + assert artifact['parts'][0]['kind'] == 'data' + assert artifact['parts'][0]['data'] == { + 'result': {'name': 'John Doe', 'age': 30, 'email': 'john@example.com'} + } + + metadata = artifact['parts'][0].get('metadata') + assert metadata is not None + + assert metadata['json_schema'] == snapshot( + { + 'properties': { + 'name': {'title': 'Name', 'type': 'string'}, + 'age': {'title': 'Age', 'type': 'integer'}, + 'email': {'title': 'Email', 'type': 'string'}, + }, + 'required': ['name', 'age', 'email'], + 'title': 'UserProfile', + 'type': 'object', + } + ) + + assert result.get('history') == snapshot( + [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Get user profile'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ] + ) + + +async def test_runtime_error_without_lifespan(): + agent = Agent(model=model, output_type=tuple[str, str]) + app: FastA2A = agent_to_a2a(agent) + + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[TextPart(text='Hello, world!', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + + with pytest.raises(RuntimeError, match='TaskManager was not properly initialized.'): + await a2a_client.send_message(message=message) + + +async def test_simple(): + agent = Agent(model=model, output_type=tuple[str, str]) + app: FastA2A = agent_to_a2a(agent) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[TextPart(text='Hello, world!', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert 'error' not in response + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + assert result == snapshot( + { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'submitted', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + } + ) + + task_id = result['id'] + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'completed': + break + await anyio.sleep(0.1) + + assert task == snapshot( + { + 'jsonrpc': '2.0', + 'id': None, + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'completed', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + 'artifacts': [ + { + 'artifact_id': IsStr(), + 'name': 'result', + 'parts': [ + { + 'metadata': {'json_schema': {'items': {}, 'type': 'array'}}, + 'kind': 'data', + 'data': {'result': ['foo', 'bar']}, + } + ], + } + ], + }, + } + ) + + +async def test_file_message_with_file(): + agent = Agent(model=model, output_type=tuple[str, str]) + app: FastA2A = agent_to_a2a(agent) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[ + FilePart( + kind='file', + file={'uri': 'https://example.com/file.txt', 'mime_type': 'text/plain'}, + ) + ], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert 'error' not in response + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + assert result == snapshot( + { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'submitted', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [ + { + 'kind': 'file', + 'file': {'mime_type': 'text/plain', 'uri': 'https://example.com/file.txt'}, + } + ], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + } + ) + + task_id = result['id'] + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'completed': + break + await anyio.sleep(0.1) + assert task == snapshot( + { + 'jsonrpc': '2.0', + 'id': None, + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'completed', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [ + { + 'kind': 'file', + 'file': {'mime_type': 'text/plain', 'uri': 'https://example.com/file.txt'}, + } + ], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + 'artifacts': [ + { + 'artifact_id': IsStr(), + 'name': 'result', + 'parts': [ + { + 'metadata': {'json_schema': {'items': {}, 'type': 'array'}}, + 'kind': 'data', + 'data': {'result': ['foo', 'bar']}, + } + ], + } + ], + }, + } + ) + + +async def test_file_message_with_file_content(image_content: BinaryContent): + agent = Agent(model=model, output_type=tuple[str, str]) + app: FastA2A = agent_to_a2a(agent) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + base64_image = base64.b64encode(image_content.data).decode('utf-8') + message = Message( + role='user', + parts=[ + FilePart(file={'bytes': base64_image, 'mime_type': image_content.media_type}, kind='file'), + ], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert 'error' not in response + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + assert result == snapshot( + { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'submitted', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [ + {'kind': 'file', 'file': {'bytes': base64_image, 'mime_type': image_content.media_type}} + ], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + } + ) + + task_id = result['id'] + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'completed': + break + await anyio.sleep(0.1) + assert task == snapshot( + { + 'jsonrpc': '2.0', + 'id': None, + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'completed', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [ + { + 'kind': 'file', + 'file': {'bytes': base64_image, 'mime_type': image_content.media_type}, + } + ], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + 'artifacts': [ + { + 'artifact_id': IsStr(), + 'name': 'result', + 'parts': [ + { + 'metadata': {'json_schema': {'items': {}, 'type': 'array'}}, + 'kind': 'data', + 'data': {'result': ['foo', 'bar']}, + } + ], + } + ], + }, + } + ) + + +async def test_file_message_with_data(): + agent = Agent(model=model, output_type=tuple[str, str]) + app: FastA2A = agent_to_a2a(agent) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[DataPart(kind='data', data={'foo': 'bar'})], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert 'error' not in response + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + assert result == snapshot( + { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'submitted', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'data', 'data': {'foo': 'bar'}}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + } + ) + + task_id = result['id'] + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'failed': + break + await anyio.sleep(0.1) + assert task == snapshot( + { + 'jsonrpc': '2.0', + 'id': None, + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'failed', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'data', 'data': {'foo': 'bar'}}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + }, + } + ) + + +async def test_error_handling(): + """Errors during task execution properly update task state to 'failed'.""" + + def raise_error(_: list[ModelMessage], info: AgentInfo) -> ModelResponse: + raise RuntimeError('Test error during agent execution') + + error_model = FunctionModel(raise_error) + agent = Agent(model=error_model, output_type=str) + app: FastA2A = agent_to_a2a(agent) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[TextPart(text='Hello, world!', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert 'error' not in response + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + + task_id = result['id'] + + max_attempts = 50 # 5 seconds total + for _ in range(max_attempts): + task = await a2a_client.get_task(task_id) + if 'result' in task and task['result']['status']['state'] == 'failed': + break + await anyio.sleep(0.1) + else: # pragma: no cover + raise AssertionError(f'Task did not fail within {max_attempts * 0.1} seconds') + + assert 'result' in task + assert task['result']['status']['state'] == 'failed' + + +async def test_multiple_tasks_same_context(): + """Multiple tasks share the same context_id with accumulated history.""" + + messages_received: list[list[ModelMessage]] = [] + + def track_messages(messages: list[ModelMessage], info: AgentInfo) -> ModelResponse: + messages_received.append(messages.copy()) + assert info.output_tools is not None + args_json = '{"response": ["foo", "bar"]}' + return ModelResponse(parts=[ToolCallPart(info.output_tools[0].name, args_json)]) + + tracking_model = FunctionModel(track_messages) + agent = Agent(model=tracking_model, output_type=tuple[str, str]) + app: FastA2A = agent_to_a2a(agent) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message1 = Message( + role='user', + parts=[TextPart(text='First message', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + response1 = await a2a_client.send_message(message=message1) + assert 'error' not in response1 + assert 'result' in response1 + result1 = response1['result'] + assert result1['kind'] == 'task' + + task1_id = result1['id'] + context_id = result1['context_id'] + + while task1 := await a2a_client.get_task(task1_id): # pragma: no branch + if 'result' in task1 and task1['result']['status']['state'] == 'completed': + result1 = task1['result'] + break + await anyio.sleep(0.1) + + assert len(messages_received) == 1 + first_run_history = messages_received[0] + assert first_run_history == snapshot( + [ + ModelRequest( + parts=[UserPromptPart(content='First message', timestamp=IsDatetime())], + timestamp=IsNow(tz=timezone.utc), + run_id=IsStr(), + conversation_id=IsStr(), + ) + ] + ) + + message2 = Message( + role='user', + parts=[TextPart(text='Second message', kind='text')], + kind='message', + context_id=context_id, + message_id=str(uuid.uuid4()), + ) + response2 = await a2a_client.send_message(message=message2) + assert 'error' not in response2 + assert 'result' in response2 + result2 = response2['result'] + assert result2['kind'] == 'task' + + task2_id = result2['id'] + assert task2_id != task1_id + assert result2['context_id'] == context_id + + while task2 := await a2a_client.get_task(task2_id): # pragma: no branch + if 'result' in task2 and task2['result']['status']['state'] == 'completed': + break + await anyio.sleep(0.1) + + assert len(messages_received) == 2 + second_run_history = messages_received[1] + assert second_run_history[0] == first_run_history[0] + + assert second_run_history == snapshot( + [ + ModelRequest( + parts=[UserPromptPart(content='First message', timestamp=IsDatetime())], + timestamp=IsNow(tz=timezone.utc), + run_id=IsStr(), + conversation_id=IsStr(), + ), + ModelResponse( + parts=[ + ToolCallPart( + tool_name='final_result', args='{"response": ["foo", "bar"]}', tool_call_id=IsStr() + ) + ], + usage=RequestUsage(input_tokens=52, output_tokens=7), + model_name='function:track_messages:', + timestamp=IsDatetime(), + run_id=IsStr(), + conversation_id=IsStr(), + ), + ModelRequest( + parts=[ + ToolReturnPart( + tool_name='final_result', + content='Final result processed.', + tool_call_id=IsStr(), + timestamp=IsDatetime(), + ), + UserPromptPart(content='Second message', timestamp=IsDatetime()), + ], + timestamp=IsNow(tz=timezone.utc), + run_id=IsStr(), + conversation_id=IsStr(), + ), + ] + ) + + +async def test_thinking_response(): + """ModelResponse messages with ThinkingPart are properly serialized to A2A.""" + + def return_thinking_response(_: list[ModelMessage], info: AgentInfo) -> ModelResponse: + assert info.output_tools is not None + return ModelResponse( + parts=[ + ThinkingPart(content='Let me think about this...', id='thinking_1'), + PydanticAITextPart(content="Here's my response"), + ] + ) + + thinking_model = FunctionModel(return_thinking_response) + agent = Agent(model=thinking_model, output_type=str) + app: FastA2A = agent_to_a2a(agent) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[TextPart(text='Hello, world!', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert 'error' not in response + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + + task_id = result['id'] + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'completed': + result = task['result'] + break + await anyio.sleep(0.1) + + assert result == snapshot( + { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'completed', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + }, + { + 'role': 'agent', + 'parts': [ + { + 'metadata': {'type': 'thinking', 'thinking_id': 'thinking_1', 'signature': None}, + 'kind': 'text', + 'text': 'Let me think about this...', + }, + {'kind': 'text', 'text': "Here's my response"}, + ], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + }, + ], + 'artifacts': [ + { + 'artifact_id': IsStr(), + 'name': 'result', + 'parts': [{'kind': 'text', 'text': "Here's my response"}], + } + ], + } + ) + + +async def test_multiple_messages(): + agent = Agent(model=model, output_type=tuple[str, str]) + storage = InMemoryStorage() + app: FastA2A = agent_to_a2a(agent, storage=storage) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[TextPart(text='Hello, world!', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert response == snapshot( + { + 'jsonrpc': '2.0', + 'id': IsStr(), + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'submitted', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + }, + } + ) + + # Splice an agent message into history before the worker picks up the task. + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + task_id = result['id'] + task = storage.tasks[task_id] + assert 'history' in task + task['history'].append( + Message( + role='agent', + parts=[TextPart(text='Whats up?', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + ) + + response = await a2a_client.get_task(task_id) + assert response == snapshot( + { + 'jsonrpc': '2.0', + 'id': None, + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'submitted', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + }, + { + 'role': 'agent', + 'parts': [{'kind': 'text', 'text': 'Whats up?'}], + 'kind': 'message', + 'message_id': IsStr(), + }, + ], + }, + } + ) + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'completed': + break + await anyio.sleep(0.1) + + assert task == snapshot( + { + 'jsonrpc': '2.0', + 'id': None, + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'completed', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + }, + { + 'role': 'agent', + 'parts': [{'kind': 'text', 'text': 'Whats up?'}], + 'kind': 'message', + 'message_id': IsStr(), + }, + ], + 'artifacts': [ + { + 'artifact_id': IsStr(), + 'name': 'result', + 'parts': [ + { + 'metadata': {'json_schema': {'items': {}, 'type': 'array'}}, + 'kind': 'data', + 'data': {'result': ['foo', 'bar']}, + } + ], + } + ], + }, + } + ) + + +async def test_multiple_send_task_messages(): + agent = Agent(model=model, output_type=tuple[str, str]) + storage = InMemoryStorage() + app: FastA2A = agent_to_a2a(agent, storage=storage) + + async with LifespanManager(app): + transport = httpx.ASGITransport(app) + async with httpx.AsyncClient(transport=transport) as http_client: + a2a_client = A2AClient(http_client=http_client) + + message = Message( + role='user', + parts=[TextPart(text='Hello, world!', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + ) + response = await a2a_client.send_message(message=message) + assert response == snapshot( + { + 'jsonrpc': '2.0', + 'id': IsStr(), + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'submitted', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + }, + } + ) + assert 'result' in response + result = response['result'] + assert result['kind'] == 'task' + task_id = result['id'] + context_id = result['context_id'] + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'completed': + result = task['result'] + break + await anyio.sleep(0.1) + + assert result == snapshot( + { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'completed', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + 'artifacts': [ + { + 'artifact_id': IsStr(), + 'name': 'result', + 'parts': [ + { + 'metadata': {'json_schema': {'items': {}, 'type': 'array'}}, + 'kind': 'data', + 'data': {'result': ['foo', 'bar']}, + } + ], + } + ], + } + ) + + message = Message( + role='user', + parts=[TextPart(text='Did you get my first message?', kind='text')], + kind='message', + message_id=str(uuid.uuid4()), + context_id=context_id, + ) + response = await a2a_client.send_message(message=message) + assert response == snapshot( + { + 'jsonrpc': '2.0', + 'id': IsStr(), + 'result': { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'submitted', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Did you get my first message?'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + }, + } + ) + + while task := await a2a_client.get_task(task_id): # pragma: no branch + if 'result' in task and task['result']['status']['state'] == 'completed': + result = task['result'] + break + await anyio.sleep(0.1) # pragma: lax no cover + + assert result == snapshot( + { + 'id': IsStr(), + 'context_id': IsStr(), + 'kind': 'task', + 'status': {'state': 'completed', 'timestamp': IsDatetime(iso_string=True)}, + 'history': [ + { + 'role': 'user', + 'parts': [{'kind': 'text', 'text': 'Hello, world!'}], + 'kind': 'message', + 'message_id': IsStr(), + 'context_id': IsStr(), + 'task_id': IsStr(), + } + ], + 'artifacts': [ + { + 'artifact_id': IsStr(), + 'name': 'result', + 'parts': [ + { + 'metadata': {'json_schema': {'items': {}, 'type': 'array'}}, + 'kind': 'data', + 'data': {'result': ['foo', 'bar']}, + } + ], + } + ], + } + ) diff --git a/uv.lock b/uv.lock index 0557720..071eaab 100644 --- a/uv.lock +++ b/uv.lock @@ -402,6 +402,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, ] +[[package]] +name = "dirty-equals" +version = "0.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/1d/c5913ac9d6615515a00f4bdc71356d302437cb74ff2e9aaccd3c14493b78/dirty_equals-0.11.tar.gz", hash = "sha256:f4ac74ee88f2d11e2fa0f65eb30ee4f07105c5f86f4dc92b09eb1138775027c3", size = 128067, upload-time = "2025-11-17T01:51:24.451Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/8d/dbff05239043271dbeace563a7686212a3dd517864a35623fe4d4a64ca19/dirty_equals-0.11-py3-none-any.whl", hash = "sha256:b1d7093273fc2f9be12f443a8ead954ef6daaf6746fd42ef3a5616433ee85286", size = 28051, upload-time = "2025-11-17T01:51:22.849Z" }, +] + [[package]] name = "eval-type-backport" version = "0.2.2" @@ -453,8 +462,10 @@ pydantic-ai = [ [package.dev-dependencies] dev = [ + { name = "anyio" }, { name = "asgi-lifespan" }, { name = "coverage" }, + { name = "dirty-equals" }, { name = "httpx" }, { name = "inline-snapshot" }, { name = "pyright" }, @@ -481,8 +492,10 @@ provides-extras = ["logfire", "pydantic-ai"] [package.metadata.requires-dev] dev = [ + { name = "anyio" }, { name = "asgi-lifespan" }, { name = "coverage" }, + { name = "dirty-equals" }, { name = "httpx" }, { name = "inline-snapshot" }, { name = "pyright" }, From eb5b87c1ec002935a582db205a682ca35252d13d Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Thu, 21 May 2026 13:45:36 -0500 Subject: [PATCH 2/3] Remove unused noqa: E402 directives in test_pydantic_ai.py ruff doesn't raise E402 on imports following the importorskip/TYPE_CHECKING preamble, so RUF100 flagged the suppressions as dead. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/test_pydantic_ai.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_pydantic_ai.py b/tests/test_pydantic_ai.py index 29adafa..d8df329 100644 --- a/tests/test_pydantic_ai.py +++ b/tests/test_pydantic_ai.py @@ -41,8 +41,8 @@ def IsNow(*args: Any, **kwargs: Any) -> datetime: ... else: from dirty_equals import IsDatetime, IsNow, IsStr -from pydantic import BaseModel # noqa: E402 -from pydantic_ai import ( # noqa: E402 +from pydantic import BaseModel +from pydantic_ai import ( Agent, BinaryContent, ModelMessage, @@ -54,14 +54,14 @@ def IsNow(*args: Any, **kwargs: Any) -> datetime: ... ToolReturnPart, UserPromptPart, ) -from pydantic_ai.models.function import AgentInfo, FunctionModel # noqa: E402 -from pydantic_ai.usage import RequestUsage # noqa: E402 - -from fasta2a.applications import FastA2A # noqa: E402 -from fasta2a.client import A2AClient # noqa: E402 -from fasta2a.pydantic_ai import agent_to_a2a # noqa: E402 -from fasta2a.schema import DataPart, FilePart, Message, TextPart # noqa: E402 -from fasta2a.storage import InMemoryStorage # noqa: E402 +from pydantic_ai.models.function import AgentInfo, FunctionModel +from pydantic_ai.usage import RequestUsage + +from fasta2a.applications import FastA2A +from fasta2a.client import A2AClient +from fasta2a.pydantic_ai import agent_to_a2a +from fasta2a.schema import DataPart, FilePart, Message, TextPart +from fasta2a.storage import InMemoryStorage pytestmark = [ pytest.mark.skipif(sys.version_info < (3, 10), reason='pydantic-ai-slim requires 3.10+'), From 4124a4fcf5e278428fdf904ce5bd404f806eac45 Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Thu, 21 May 2026 14:25:52 -0500 Subject: [PATCH 3/3] Split scripts/check into a dedicated lint job scripts/check runs pyright, which must resolve the bridge's pydantic_ai imports. pydantic-ai-slim is marker-gated to Python 3.10+, so running the check across the test matrix failed on the 3.9 row where the extra resolves to nothing. The new lint job pins 3.12; the test matrix now runs only scripts/test. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/main.yml | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a6684cc..7709de4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,6 +7,27 @@ on: branches: ["main", "release/**"] jobs: + # `scripts/check` (ruff, pyright, check-sdist, uv lock) runs once on a fixed + # interpreter. pyright must see `pydantic-ai-slim` to resolve the bridge's + # `pydantic_ai` imports, and that extra is marker-gated to Python 3.10+, so + # this job pins 3.12 — running it across the test matrix would fail on 3.9. + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v4 + with: + python-version: "3.12" + enable-cache: true + + - name: Install dependencies + run: uv sync --frozen --extra pydantic-ai + + - name: Run linters + run: scripts/check + test: runs-on: ubuntu-latest strategy: @@ -28,16 +49,13 @@ jobs: - name: Install dependencies run: uv sync --frozen --extra pydantic-ai - - name: Run linters - run: scripts/check - - name: Run tests run: scripts/test # https://github.com/marketplace/actions/alls-green#why used for branch protection checks check: if: always() - needs: [test] + needs: [lint, test] runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed