diff --git a/pyproject.toml b/pyproject.toml index a55f2074..57dbc3ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,10 +44,10 @@ sql = ["sqlalchemy[asyncio,postgresql-asyncpg,aiomysql,aiosqlite]>=2.0.0"] encryption = ["cryptography>=43.0.0"] [project.urls] -homepage = "https://a2a-protocol.org/" +homepage = "https://a2aproject.github.io/A2A/" repository = "https://github.com/a2aproject/a2a-python" changelog = "https://github.com/a2aproject/a2a-python/blob/main/CHANGELOG.md" -documentation = "https://a2a-protocol.org/latest/sdk/python/" +documentation = "https://a2aproject.github.io/A2A/sdk/python/" [tool.hatch.build.targets.wheel] packages = ["src/a2a"] diff --git a/scripts/generate_types.sh b/scripts/generate_types.sh index 64889c28..6842e62e 100644 --- a/scripts/generate_types.sh +++ b/scripts/generate_types.sh @@ -33,7 +33,9 @@ uv run datamodel-codegen \ --class-name A2A \ --use-standard-collections \ --use-subclass-enum \ - --base-class a2a._base.A2ABaseModel + --base-class a2a._base.A2ABaseModel \ + --snake-case-field \ + --no-alias echo "Formatting generated file with ruff..." uv run ruff format "$GENERATED_FILE" diff --git a/src/a2a/_base.py b/src/a2a/_base.py index e74cf185..a8e95a93 100644 --- a/src/a2a/_base.py +++ b/src/a2a/_base.py @@ -1,4 +1,5 @@ from pydantic import BaseModel, ConfigDict +from pydantic.alias_generators import to_camel class A2ABaseModel(BaseModel): @@ -12,4 +13,6 @@ class A2ABaseModel(BaseModel): # SEE: https://docs.pydantic.dev/latest/api/config/#pydantic.config.ConfigDict.populate_by_name validate_by_name=True, validate_by_alias=True, + serialize_by_alias=True, + alias_generator=to_camel, ) diff --git a/src/a2a/client/auth/interceptor.py b/src/a2a/client/auth/interceptor.py index a164f135..60559484 100644 --- a/src/a2a/client/auth/interceptor.py +++ b/src/a2a/client/auth/interceptor.py @@ -36,7 +36,7 @@ async def intercept( if ( agent_card is None or agent_card.security is None - or agent_card.securitySchemes is None + or agent_card.security_schemes is None ): return request_payload, http_kwargs @@ -45,8 +45,8 @@ async def intercept( credential = await self._credential_service.get_credentials( scheme_name, context ) - if credential and scheme_name in agent_card.securitySchemes: - scheme_def_union = agent_card.securitySchemes.get( + if credential and scheme_name in agent_card.security_schemes: + scheme_def_union = agent_card.security_schemes.get( scheme_name ) if not scheme_def_union: diff --git a/src/a2a/client/helpers.py b/src/a2a/client/helpers.py index 4eedadb8..930c71e6 100644 --- a/src/a2a/client/helpers.py +++ b/src/a2a/client/helpers.py @@ -15,8 +15,8 @@ def create_text_message_object( content: The text content of the message. Defaults to an empty string. Returns: - A `Message` object with a new UUID messageId. + A `Message` object with a new UUID message_id. """ return Message( - role=role, parts=[Part(TextPart(text=content))], messageId=str(uuid4()) + role=role, parts=[Part(TextPart(text=content))], message_id=str(uuid4()) ) diff --git a/src/a2a/server/agent_execution/context.py b/src/a2a/server/agent_execution/context.py index 782d488b..c992ba8e 100644 --- a/src/a2a/server/agent_execution/context.py +++ b/src/a2a/server/agent_execution/context.py @@ -53,14 +53,14 @@ def __init__( # noqa: PLR0913 # match the request. Otherwise, create them if self._params: if task_id: - self._params.message.taskId = task_id + self._params.message.task_id = task_id if task and task.id != task_id: raise ServerError(InvalidParamsError(message='bad task id')) else: self._check_or_generate_task_id() if context_id: - self._params.message.contextId = context_id - if task and task.contextId != context_id: + self._params.message.context_id = context_id + if task and task.context_id != context_id: raise ServerError( InvalidParamsError(message='bad context id') ) @@ -148,17 +148,17 @@ def _check_or_generate_task_id(self) -> None: if not self._params: return - if not self._task_id and not self._params.message.taskId: - self._params.message.taskId = str(uuid.uuid4()) - if self._params.message.taskId: - self._task_id = self._params.message.taskId + if not self._task_id and not self._params.message.task_id: + self._params.message.task_id = str(uuid.uuid4()) + if self._params.message.task_id: + self._task_id = self._params.message.task_id def _check_or_generate_context_id(self) -> None: """Ensures a context ID is present, generating one if necessary.""" if not self._params: return - if not self._context_id and not self._params.message.contextId: - self._params.message.contextId = str(uuid.uuid4()) - if self._params.message.contextId: - self._context_id = self._params.message.contextId + if not self._context_id and not self._params.message.context_id: + self._params.message.context_id = str(uuid.uuid4()) + if self._params.message.context_id: + self._context_id = self._params.message.context_id diff --git a/src/a2a/server/agent_execution/simple_request_context_builder.py b/src/a2a/server/agent_execution/simple_request_context_builder.py index 80518eae..3eca4435 100644 --- a/src/a2a/server/agent_execution/simple_request_context_builder.py +++ b/src/a2a/server/agent_execution/simple_request_context_builder.py @@ -18,7 +18,7 @@ def __init__( Args: should_populate_referred_tasks: If True, the builder will fetch tasks - referenced in `params.message.referenceTaskIds` and populate the + referenced in `params.message.reference_task_ids` and populate the `related_tasks` field in the RequestContext. Defaults to False. task_store: The TaskStore instance to use for fetching referred tasks. Required if `should_populate_referred_tasks` is True. @@ -38,7 +38,7 @@ async def build( This method assembles the RequestContext object. If the builder was initialized with `should_populate_referred_tasks=True`, it fetches all tasks - referenced in `params.message.referenceTaskIds` from the `task_store`. + referenced in `params.message.reference_task_ids` from the `task_store`. Args: params: The parameters of the incoming message send request. @@ -57,12 +57,12 @@ async def build( self._task_store and self._should_populate_referred_tasks and params - and params.message.referenceTaskIds + and params.message.reference_task_ids ): tasks = await asyncio.gather( *[ self._task_store.get(task_id) - for task_id in params.message.referenceTaskIds + for task_id in params.message.reference_task_ids ] ) related_tasks = [x for x in tasks if x is not None] diff --git a/src/a2a/server/apps/jsonrpc/fastapi_app.py b/src/a2a/server/apps/jsonrpc/fastapi_app.py index 74060688..421c3784 100644 --- a/src/a2a/server/apps/jsonrpc/fastapi_app.py +++ b/src/a2a/server/apps/jsonrpc/fastapi_app.py @@ -89,7 +89,7 @@ def add_routes_to_app( )(self._handle_requests) app.get(agent_card_url)(self._handle_get_agent_card) - if self.agent_card.supportsAuthenticatedExtendedCard: + if self.agent_card.supports_authenticated_extended_card: app.get(extended_agent_card_url)( self._handle_get_authenticated_extended_agent_card ) diff --git a/src/a2a/server/apps/jsonrpc/jsonrpc_app.py b/src/a2a/server/apps/jsonrpc/jsonrpc_app.py index 2591bb00..08e6b53f 100644 --- a/src/a2a/server/apps/jsonrpc/jsonrpc_app.py +++ b/src/a2a/server/apps/jsonrpc/jsonrpc_app.py @@ -135,11 +135,11 @@ def __init__( agent_card=agent_card, request_handler=http_handler ) if ( - self.agent_card.supportsAuthenticatedExtendedCard + self.agent_card.supports_authenticated_extended_card and self.extended_agent_card is None ): logger.error( - 'AgentCard.supportsAuthenticatedExtendedCard is True, but no extended_agent_card was provided. The /agent/authenticatedExtendedCard endpoint will return 404.' + 'AgentCard.supports_authenticated_extended_card is True, but no extended_agent_card was provided. The /agent/authenticatedExtendedCard endpoint will return 404.' ) self._context_builder = context_builder or DefaultCallContextBuilder() @@ -421,7 +421,7 @@ async def _handle_get_authenticated_extended_agent_card( self, request: Request ) -> JSONResponse: """Handles GET requests for the authenticated extended agent card.""" - if not self.agent_card.supportsAuthenticatedExtendedCard: + if not self.agent_card.supports_authenticated_extended_card: return JSONResponse( {'error': 'Extended agent card not supported or not enabled.'}, status_code=404, @@ -435,7 +435,7 @@ async def _handle_get_authenticated_extended_agent_card( by_alias=True, ) ) - # If supportsAuthenticatedExtendedCard is true, but no specific + # If supports_authenticated_extended_card is true, but no specific # extended_agent_card was provided during server initialization, # return a 404 return JSONResponse( diff --git a/src/a2a/server/apps/jsonrpc/starlette_app.py b/src/a2a/server/apps/jsonrpc/starlette_app.py index 70758739..fb03d99b 100644 --- a/src/a2a/server/apps/jsonrpc/starlette_app.py +++ b/src/a2a/server/apps/jsonrpc/starlette_app.py @@ -86,7 +86,7 @@ def routes( ), ] - if self.agent_card.supportsAuthenticatedExtendedCard: + if self.agent_card.supports_authenticated_extended_card: app_routes.append( Route( extended_agent_card_url, diff --git a/src/a2a/server/models.py b/src/a2a/server/models.py index 09db5641..38b0f700 100644 --- a/src/a2a/server/models.py +++ b/src/a2a/server/models.py @@ -123,7 +123,7 @@ class TaskMixin: """Mixin providing standard task columns with proper type handling.""" id: Mapped[str] = mapped_column(String(36), primary_key=True, index=True) - contextId: Mapped[str] = mapped_column(String(36), nullable=False) # noqa: N815 + context_id: Mapped[str] = mapped_column(String(36), nullable=False) kind: Mapped[str] = mapped_column( String(16), nullable=False, default='task' ) @@ -148,12 +148,12 @@ def task_metadata(cls) -> Mapped[dict[str, Any] | None]: def __repr__(self) -> str: """Return a string representation of the task.""" repr_template = ( - '<{CLS}(id="{ID}", contextId="{CTX_ID}", status="{STATUS}")>' + '<{CLS}(id="{ID}", context_id="{CTX_ID}", status="{STATUS}")>' ) return repr_template.format( CLS=self.__class__.__name__, ID=self.id, - CTX_ID=self.contextId, + CTX_ID=self.context_id, STATUS=self.status, ) @@ -188,11 +188,11 @@ class TaskModel(TaskMixin, base): @override def __repr__(self) -> str: """Return a string representation of the task.""" - repr_template = '' + repr_template = '' return repr_template.format( TABLE=table_name, ID=self.id, - CTX_ID=self.contextId, + CTX_ID=self.context_id, STATUS=self.status, ) diff --git a/src/a2a/server/request_handlers/default_request_handler.py b/src/a2a/server/request_handlers/default_request_handler.py index a1b8d565..513355fe 100644 --- a/src/a2a/server/request_handlers/default_request_handler.py +++ b/src/a2a/server/request_handlers/default_request_handler.py @@ -126,7 +126,7 @@ async def on_cancel_task( task_manager = TaskManager( task_id=task.id, - context_id=task.contextId, + context_id=task.context_id, task_store=self.task_store, initial_message=None, ) @@ -140,7 +140,7 @@ async def on_cancel_task( RequestContext( None, task_id=task.id, - context_id=task.contextId, + context_id=task.context_id, task=task, ), queue, @@ -184,8 +184,8 @@ async def _setup_message_execution( """ # Create task manager and validate existing task task_manager = TaskManager( - task_id=params.message.taskId, - context_id=params.message.contextId, + task_id=params.message.task_id, + context_id=params.message.context_id, task_store=self.task_store, initial_message=params.message, ) @@ -205,7 +205,7 @@ async def _setup_message_execution( request_context = await self._request_context_builder.build( params=params, task_id=task.id if task else None, - context_id=params.message.contextId, + context_id=params.message.context_id, task=task, context=context, ) @@ -218,10 +218,10 @@ async def _setup_message_execution( if ( self._push_config_store and params.configuration - and params.configuration.pushNotificationConfig + and params.configuration.push_notification_config ): await self._push_config_store.set_info( - task_id, params.configuration.pushNotificationConfig + task_id, params.configuration.push_notification_config ) queue = await self._queue_manager.create_or_tap(task_id) @@ -366,13 +366,13 @@ async def on_set_task_push_notification_config( if not self._push_config_store: raise ServerError(error=UnsupportedOperationError()) - task: Task | None = await self.task_store.get(params.taskId) + task: Task | None = await self.task_store.get(params.task_id) if not task: raise ServerError(error=TaskNotFoundError()) await self._push_config_store.set_info( - params.taskId, - params.pushNotificationConfig, + params.task_id, + params.push_notification_config, ) return params @@ -404,7 +404,8 @@ async def on_get_task_push_notification_config( ) return TaskPushNotificationConfig( - taskId=params.id, pushNotificationConfig=push_notification_config[0] + task_id=params.id, + pushNotificationConfig=push_notification_config[0], ) async def on_resubscribe_to_task( @@ -430,7 +431,7 @@ async def on_resubscribe_to_task( task_manager = TaskManager( task_id=task.id, - context_id=task.contextId, + context_id=task.context_id, task_store=self.task_store, initial_message=None, ) @@ -470,7 +471,7 @@ async def on_list_task_push_notification_config( for config in push_notification_config_list: task_push_notification_config.append( TaskPushNotificationConfig( - taskId=params.id, pushNotificationConfig=config + task_id=params.id, pushNotificationConfig=config ) ) @@ -493,5 +494,5 @@ async def on_delete_task_push_notification_config( raise ServerError(error=TaskNotFoundError()) await self._push_config_store.delete_info( - params.id, params.pushNotificationConfigId + params.id, params.push_notification_config_id ) diff --git a/src/a2a/server/request_handlers/grpc_handler.py b/src/a2a/server/request_handlers/grpc_handler.py index d2323115..48b7ef9b 100644 --- a/src/a2a/server/request_handlers/grpc_handler.py +++ b/src/a2a/server/request_handlers/grpc_handler.py @@ -224,7 +224,7 @@ async def GetTaskPushNotificationConfig( return a2a_pb2.TaskPushNotificationConfig() @validate( - lambda self: self.agent_card.capabilities.pushNotifications, + lambda self: self.agent_card.capabilities.push_notifications, 'Push notifications are not supported by the agent', ) async def CreateTaskPushNotificationConfig( diff --git a/src/a2a/server/request_handlers/jsonrpc_handler.py b/src/a2a/server/request_handlers/jsonrpc_handler.py index 5de7dae9..88a169fe 100644 --- a/src/a2a/server/request_handlers/jsonrpc_handler.py +++ b/src/a2a/server/request_handlers/jsonrpc_handler.py @@ -255,7 +255,7 @@ async def get_push_notification_config( ) @validate( - lambda self: self.agent_card.capabilities.pushNotifications, + lambda self: self.agent_card.capabilities.push_notifications, 'Push notifications are not supported by the agent', ) async def set_push_notification_config( diff --git a/src/a2a/server/tasks/database_task_store.py b/src/a2a/server/tasks/database_task_store.py index 70b02e10..cff94c1e 100644 --- a/src/a2a/server/tasks/database_task_store.py +++ b/src/a2a/server/tasks/database_task_store.py @@ -95,7 +95,7 @@ def _to_orm(self, task: Task) -> TaskModel: """Maps a Pydantic Task to a SQLAlchemy TaskModel instance.""" return self.task_model( id=task.id, - contextId=task.contextId, + context_id=task.context_id, kind=task.kind, status=task.status, artifacts=task.artifacts, @@ -108,7 +108,7 @@ def _from_orm(self, task_model: TaskModel) -> Task: # Map database columns to Pydantic model fields task_data_from_db = { 'id': task_model.id, - 'contextId': task_model.contextId, + 'context_id': task_model.context_id, 'kind': task_model.kind, 'status': task_model.status, 'artifacts': task_model.artifacts, diff --git a/src/a2a/server/tasks/task_manager.py b/src/a2a/server/tasks/task_manager.py index cf763396..334d9992 100644 --- a/src/a2a/server/tasks/task_manager.py +++ b/src/a2a/server/tasks/task_manager.py @@ -99,7 +99,7 @@ async def save_task_event( when the TaskManager's ID is already set. """ task_id_from_event = ( - event.id if isinstance(event, Task) else event.taskId + event.id if isinstance(event, Task) else event.task_id ) # If task id is known, make sure it is matched if self.task_id and self.task_id != task_id_from_event: @@ -110,14 +110,14 @@ async def save_task_event( ) if not self.task_id: self.task_id = task_id_from_event - if self.context_id and self.context_id != event.contextId: + if self.context_id and self.context_id != event.context_id: raise ServerError( error=InvalidParamsError( - message=f"Context in event doesn't match TaskManager {self.context_id} : {event.contextId}" + message=f"Context in event doesn't match TaskManager {self.context_id} : {event.context_id}" ) ) if not self.context_id: - self.context_id = event.contextId + self.context_id = event.context_id logger.debug( 'Processing save of task event of type %s for task_id: %s', @@ -172,12 +172,12 @@ async def ensure_task( if not task: logger.info( 'Task not found or task_id not set. Creating new task for event (task_id: %s, context_id: %s).', - event.taskId, - event.contextId, + event.task_id, + event.context_id, ) # streaming agent did not previously stream task object. # Create a task object with the available information and persist the event - task = self._init_task_obj(event.taskId, event.contextId) + task = self._init_task_obj(event.task_id, event.context_id) await self._save_task(task) return task @@ -219,7 +219,7 @@ def _init_task_obj(self, task_id: str, context_id: str) -> Task: history = [self._initial_message] if self._initial_message else [] return Task( id=task_id, - contextId=context_id, + context_id=context_id, status=TaskStatus(state=TaskState.submitted), history=history, ) @@ -236,7 +236,7 @@ async def _save_task(self, task: Task) -> None: if not self.task_id: logger.info('New task created with id: %s', task.id) self.task_id = task.id - self.context_id = task.contextId + self.context_id = task.context_id def update_with_message(self, message: Message, task: Task) -> Task: """Updates a task object in memory by adding a new message to its history. diff --git a/src/a2a/server/tasks/task_updater.py b/src/a2a/server/tasks/task_updater.py index 11157456..529cc4fd 100644 --- a/src/a2a/server/tasks/task_updater.py +++ b/src/a2a/server/tasks/task_updater.py @@ -74,8 +74,8 @@ async def update_status( ) await self.event_queue.enqueue_event( TaskStatusUpdateEvent( - taskId=self.task_id, - contextId=self.context_id, + task_id=self.task_id, + context_id=self.context_id, final=final, status=TaskStatus( state=state, @@ -109,16 +109,16 @@ async def add_artifact( # noqa: PLR0913 await self.event_queue.enqueue_event( TaskArtifactUpdateEvent( - taskId=self.task_id, - contextId=self.context_id, + task_id=self.task_id, + context_id=self.context_id, artifact=Artifact( - artifactId=artifact_id, + artifact_id=artifact_id, name=name, parts=parts, metadata=metadata, ), append=append, - lastChunk=last_chunk, + last_chunk=last_chunk, ) ) @@ -197,9 +197,9 @@ def new_agent_message( """ return Message( role=Role.agent, - taskId=self.task_id, - contextId=self.context_id, - messageId=str(uuid.uuid4()), + task_id=self.task_id, + context_id=self.context_id, + message_id=str(uuid.uuid4()), metadata=metadata, parts=parts, ) diff --git a/src/a2a/types.py b/src/a2a/types.py index f4e2880d..edc5ca23 100644 --- a/src/a2a/types.py +++ b/src/a2a/types.py @@ -34,7 +34,7 @@ class APIKeySecurityScheme(A2ABaseModel): """ Description of this security scheme. """ - in_: In = Field(..., alias='in') + in_: In """ The location of the API key. Valid values are "query", "header", or "cookie". """ @@ -119,7 +119,7 @@ class AgentSkill(A2ABaseModel): """ Unique identifier for the agent's skill. """ - inputModes: list[str] | None = None + input_modes: list[str] | None = None """ The set of interaction modes that the skill supports (if different than the default). @@ -129,7 +129,7 @@ class AgentSkill(A2ABaseModel): """ Human readable name of the skill. """ - outputModes: list[str] | None = None + output_modes: list[str] | None = None """ Supported media types for output. """ @@ -146,12 +146,12 @@ class AuthorizationCodeOAuthFlow(A2ABaseModel): Configuration details for a supported OAuth Flow """ - authorizationUrl: str + authorization_url: str """ The authorization URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS """ - refreshUrl: str | None = None + refresh_url: str | None = None """ The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. @@ -161,7 +161,7 @@ class AuthorizationCodeOAuthFlow(A2ABaseModel): The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. The map MAY be empty. """ - tokenUrl: str + token_url: str """ The token URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. @@ -173,7 +173,7 @@ class ClientCredentialsOAuthFlow(A2ABaseModel): Configuration details for a supported OAuth Flow """ - refreshUrl: str | None = None + refresh_url: str | None = None """ The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. @@ -183,7 +183,7 @@ class ClientCredentialsOAuthFlow(A2ABaseModel): The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. The map MAY be empty. """ - tokenUrl: str + token_url: str """ The token URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. @@ -239,7 +239,7 @@ class DeleteTaskPushNotificationConfigParams(A2ABaseModel): Task id. """ metadata: dict[str, Any] | None = None - pushNotificationConfigId: str + push_notification_config_id: str class DeleteTaskPushNotificationConfigRequest(A2ABaseModel): @@ -293,7 +293,7 @@ class FileBase(A2ABaseModel): Represents the base entity for FileParts """ - mimeType: str | None = None + mime_type: str | None = None """ Optional mimeType for the file """ @@ -312,7 +312,7 @@ class FileWithBytes(A2ABaseModel): """ base64 encoded content of the file """ - mimeType: str | None = None + mime_type: str | None = None """ Optional mimeType for the file """ @@ -327,7 +327,7 @@ class FileWithUri(A2ABaseModel): Define the variant where 'uri' is present and 'bytes' is absent """ - mimeType: str | None = None + mime_type: str | None = None """ Optional mimeType for the file """ @@ -351,7 +351,7 @@ class GetTaskPushNotificationConfigParams(A2ABaseModel): Task id. """ metadata: dict[str, Any] | None = None - pushNotificationConfigId: str | None = None + push_notification_config_id: str | None = None class HTTPAuthSecurityScheme(A2ABaseModel): @@ -359,7 +359,7 @@ class HTTPAuthSecurityScheme(A2ABaseModel): HTTP Authentication security scheme. """ - bearerFormat: str | None = None + bearer_format: str | None = None """ A hint to the client to identify how the bearer token is formatted. Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation @@ -383,12 +383,12 @@ class ImplicitOAuthFlow(A2ABaseModel): Configuration details for a supported OAuth Flow """ - authorizationUrl: str + authorization_url: str """ The authorization URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS """ - refreshUrl: str | None = None + refresh_url: str | None = None """ The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. @@ -657,7 +657,7 @@ class OpenIdConnectSecurityScheme(A2ABaseModel): """ Description of this security scheme. """ - openIdConnectUrl: str + open_id_connect_url: str """ Well-known URL to discover the [[OpenID-Connect-Discovery]] provider metadata. """ @@ -680,7 +680,7 @@ class PasswordOAuthFlow(A2ABaseModel): Configuration details for a supported OAuth Flow """ - refreshUrl: str | None = None + refresh_url: str | None = None """ The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. @@ -690,7 +690,7 @@ class PasswordOAuthFlow(A2ABaseModel): The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. The map MAY be empty. """ - tokenUrl: str + token_url: str """ The token URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. @@ -820,11 +820,11 @@ class TaskPushNotificationConfig(A2ABaseModel): Parameters for setting or getting push notification configuration for a task """ - pushNotificationConfig: PushNotificationConfig + push_notification_config: PushNotificationConfig """ Push notification configuration. """ - taskId: str + task_id: str """ Task id. """ @@ -835,7 +835,7 @@ class TaskQueryParams(A2ABaseModel): Parameters for querying a task, including optional history length. """ - historyLength: int | None = None + history_length: int | None = None """ Number of recent messages to be retrieved. """ @@ -964,11 +964,11 @@ class AgentCapabilities(A2ABaseModel): """ extensions supported by this agent. """ - pushNotifications: bool | None = None + push_notifications: bool | None = None """ true if the agent can notify updates to client. """ - stateTransitionHistory: bool | None = None + state_transition_history: bool | None = None """ true if the agent exposes status change history for tasks. """ @@ -1147,7 +1147,7 @@ class MessageSendConfiguration(A2ABaseModel): Configuration for the send message request. """ - acceptedOutputModes: list[str] | None = None + accepted_output_modes: list[str] | None = None """ Accepted output modalities by the client. """ @@ -1155,11 +1155,11 @@ class MessageSendConfiguration(A2ABaseModel): """ If the server should treat the client as a blocking request. """ - historyLength: int | None = None + history_length: int | None = None """ Number of recent messages to be retrieved. """ - pushNotificationConfig: PushNotificationConfig | None = None + push_notification_config: PushNotificationConfig | None = None """ Where the server should send notifications when disconnected. """ @@ -1170,11 +1170,11 @@ class OAuthFlows(A2ABaseModel): Allows configuration of the supported OAuth Flows """ - authorizationCode: AuthorizationCodeOAuthFlow | None = None + authorization_code: AuthorizationCodeOAuthFlow | None = None """ Configuration for the OAuth Authorization Code flow. Previously called accessCode in OpenAPI 2.0. """ - clientCredentials: ClientCredentialsOAuthFlow | None = None + client_credentials: ClientCredentialsOAuthFlow | None = None """ Configuration for the OAuth Client Credentials flow. Previously called application in OpenAPI 2.0 """ @@ -1246,7 +1246,7 @@ class Artifact(A2ABaseModel): Represents an artifact generated for a task. """ - artifactId: str + artifact_id: str """ Unique identifier for the artifact. """ @@ -1310,7 +1310,7 @@ class Message(A2ABaseModel): Represents a single message exchanged between user and agent. """ - contextId: str | None = None + context_id: str | None = None """ The context the message is associated with """ @@ -1322,7 +1322,7 @@ class Message(A2ABaseModel): """ Event type """ - messageId: str + message_id: str """ Identifier created by the message creator """ @@ -1334,7 +1334,7 @@ class Message(A2ABaseModel): """ Message content """ - referenceTaskIds: list[str] | None = None + reference_task_ids: list[str] | None = None """ List of tasks referenced as context by this message. """ @@ -1342,7 +1342,7 @@ class Message(A2ABaseModel): """ Message sender's role """ - taskId: str | None = None + task_id: str | None = None """ Identifier of task the message is related to """ @@ -1475,7 +1475,7 @@ class TaskArtifactUpdateEvent(A2ABaseModel): """ Generated artifact """ - contextId: str + context_id: str """ The context the task is associated with """ @@ -1483,7 +1483,7 @@ class TaskArtifactUpdateEvent(A2ABaseModel): """ Event type """ - lastChunk: bool | None = None + last_chunk: bool | None = None """ Indicates if this is the last chunk of the artifact """ @@ -1491,7 +1491,7 @@ class TaskArtifactUpdateEvent(A2ABaseModel): """ Extension metadata. """ - taskId: str + task_id: str """ Task id """ @@ -1520,7 +1520,7 @@ class TaskStatusUpdateEvent(A2ABaseModel): Sent by server during sendStream or subscribe requests """ - contextId: str + context_id: str """ The context the task is associated with """ @@ -1540,7 +1540,7 @@ class TaskStatusUpdateEvent(A2ABaseModel): """ Current status of the task """ - taskId: str + task_id: str """ Task id """ @@ -1584,7 +1584,7 @@ class AgentCard(A2ABaseModel): - Authentication requirements """ - additionalInterfaces: list[AgentInterface] | None = None + additional_interfaces: list[AgentInterface] | None = None """ Announcement of additional supported transports. Client can use any of the supported transports. @@ -1593,12 +1593,12 @@ class AgentCard(A2ABaseModel): """ Optional capabilities supported by the agent. """ - defaultInputModes: list[str] + default_input_modes: list[str] """ The set of interaction modes that the agent supports across all skills. This can be overridden per-skill. Supported media types for input. """ - defaultOutputModes: list[str] + default_output_modes: list[str] """ Supported media types for output. """ @@ -1609,11 +1609,11 @@ class AgentCard(A2ABaseModel): A human-readable description of the agent. Used to assist users and other agents in understanding what the agent can do. """ - documentationUrl: str | None = None + documentation_url: str | None = None """ A URL to documentation for the agent. """ - iconUrl: str | None = None + icon_url: str | None = None """ A URL to an icon for the agent. """ @@ -1621,11 +1621,11 @@ class AgentCard(A2ABaseModel): """ Human readable name of the agent. """ - preferredTransport: str | None = None + preferred_transport: str | None = None """ The transport of the preferred endpoint. If empty, defaults to JSONRPC. """ - protocolVersion: str | None = '0.2.5' + protocol_version: str | None = '0.2.5' """ The version of the A2A protocol this agent supports. """ @@ -1637,7 +1637,7 @@ class AgentCard(A2ABaseModel): """ Security requirements for contacting the agent. """ - securitySchemes: dict[str, SecurityScheme] | None = None + security_schemes: dict[str, SecurityScheme] | None = None """ Security scheme details used for authenticating with this agent. """ @@ -1645,7 +1645,7 @@ class AgentCard(A2ABaseModel): """ Skills are a unit of capability that an agent can perform. """ - supportsAuthenticatedExtendedCard: bool | None = None + supports_authenticated_extended_card: bool | None = None """ true if the agent supports providing an extended agent card when the user is authenticated. Defaults to false if not specified. @@ -1666,7 +1666,7 @@ class Task(A2ABaseModel): """ Collection of artifacts created by the agent. """ - contextId: str + context_id: str """ Server-generated id for contextual alignment across interactions """ diff --git a/src/a2a/utils/artifact.py b/src/a2a/utils/artifact.py index ee91a891..1cf0a89a 100644 --- a/src/a2a/utils/artifact.py +++ b/src/a2a/utils/artifact.py @@ -18,10 +18,10 @@ def new_artifact( description: An optional description of the artifact. Returns: - A new `Artifact` object with a generated artifactId. + A new `Artifact` object with a generated artifact_id. """ return Artifact( - artifactId=str(uuid.uuid4()), + artifact_id=str(uuid.uuid4()), parts=parts, name=name, description=description, @@ -41,7 +41,7 @@ def new_text_artifact( description: An optional description of the artifact. Returns: - A new `Artifact` object with a generated artifactId. + A new `Artifact` object with a generated artifact_id. """ return new_artifact( [Part(root=TextPart(text=text))], @@ -63,7 +63,7 @@ def new_data_artifact( description: An optional description of the artifact. Returns: - A new `Artifact` object with a generated artifactId. + A new `Artifact` object with a generated artifact_id. """ return new_artifact( [Part(root=DataPart(data=data))], diff --git a/src/a2a/utils/helpers.py b/src/a2a/utils/helpers.py index a1cc43ec..091268ba 100644 --- a/src/a2a/utils/helpers.py +++ b/src/a2a/utils/helpers.py @@ -36,12 +36,12 @@ def create_task_obj(message_send_params: MessageSendParams) -> Task: Returns: A new `Task` object initialized with 'submitted' status and the input message in history. """ - if not message_send_params.message.contextId: - message_send_params.message.contextId = str(uuid4()) + if not message_send_params.message.context_id: + message_send_params.message.context_id = str(uuid4()) return Task( id=str(uuid4()), - contextId=message_send_params.message.contextId, + context_id=message_send_params.message.context_id, status=TaskStatus(state=TaskState.submitted), history=[message_send_params.message], ) @@ -62,7 +62,7 @@ def append_artifact_to_task(task: Task, event: TaskArtifactUpdateEvent) -> None: task.artifacts = [] new_artifact_data: Artifact = event.artifact - artifact_id: str = new_artifact_data.artifactId + artifact_id: str = new_artifact_data.artifact_id append_parts: bool = event.append or False existing_artifact: Artifact | None = None @@ -70,7 +70,7 @@ def append_artifact_to_task(task: Task, event: TaskArtifactUpdateEvent) -> None: # Find existing artifact by its id for i, art in enumerate(task.artifacts): - if art.artifactId == artifact_id: + if art.artifact_id == artifact_id: existing_artifact = art existing_artifact_list_index = i break @@ -115,7 +115,7 @@ def build_text_artifact(text: str, artifact_id: str) -> Artifact: """ text_part = TextPart(text=text) part = Part(root=text_part) - return Artifact(parts=[part], artifactId=artifact_id) + return Artifact(parts=[part], artifact_id=artifact_id) def validate( diff --git a/src/a2a/utils/message.py b/src/a2a/utils/message.py index 708d85c2..4d78cd46 100644 --- a/src/a2a/utils/message.py +++ b/src/a2a/utils/message.py @@ -34,9 +34,9 @@ def new_agent_text_message( return Message( role=Role.agent, parts=[Part(root=TextPart(text=text))], - messageId=str(uuid.uuid4()), - taskId=task_id, - contextId=context_id, + message_id=str(uuid.uuid4()), + task_id=task_id, + context_id=context_id, ) @@ -58,9 +58,9 @@ def new_agent_parts_message( return Message( role=Role.agent, parts=parts, - messageId=str(uuid.uuid4()), - taskId=task_id, - contextId=context_id, + message_id=str(uuid.uuid4()), + task_id=task_id, + context_id=context_id, ) diff --git a/src/a2a/utils/proto_utils.py b/src/a2a/utils/proto_utils.py index 0871f05c..bb3f139a 100644 --- a/src/a2a/utils/proto_utils.py +++ b/src/a2a/utils/proto_utils.py @@ -26,10 +26,10 @@ def message(cls, message: types.Message | None) -> a2a_pb2.Message | None: if message is None: return None return a2a_pb2.Message( - message_id=message.messageId, + message_id=message.message_id, content=[ToProto.part(p) for p in message.parts], - context_id=message.contextId, - task_id=message.taskId, + context_id=message.context_id, + task_id=message.task_id, role=cls.role(message.role), metadata=ToProto.metadata(message.metadata), ) @@ -81,7 +81,7 @@ def file( def task(cls, task: types.Task) -> a2a_pb2.Task: return a2a_pb2.Task( id=task.id, - context_id=task.contextId, + context_id=task.context_id, status=ToProto.task_status(task.status), artifacts=( [ToProto.artifact(a) for a in task.artifacts] @@ -123,7 +123,7 @@ def task_state(cls, state: types.TaskState) -> a2a_pb2.TaskState: @classmethod def artifact(cls, artifact: types.Artifact) -> a2a_pb2.Artifact: return a2a_pb2.Artifact( - artifact_id=artifact.artifactId, + artifact_id=artifact.artifact_id, description=artifact.description, metadata=ToProto.metadata(artifact.metadata), name=artifact.name, @@ -160,12 +160,12 @@ def task_artifact_update_event( cls, event: types.TaskArtifactUpdateEvent ) -> a2a_pb2.TaskArtifactUpdateEvent: return a2a_pb2.TaskArtifactUpdateEvent( - task_id=event.taskId, - context_id=event.contextId, + task_id=event.task_id, + context_id=event.context_id, artifact=ToProto.artifact(event.artifact), metadata=ToProto.metadata(event.metadata), append=event.append or False, - last_chunk=event.lastChunk or False, + last_chunk=event.last_chunk or False, ) @classmethod @@ -173,8 +173,8 @@ def task_status_update_event( cls, event: types.TaskStatusUpdateEvent ) -> a2a_pb2.TaskStatusUpdateEvent: return a2a_pb2.TaskStatusUpdateEvent( - task_id=event.taskId, - context_id=event.contextId, + task_id=event.task_id, + context_id=event.context_id, status=ToProto.task_status(event.status), metadata=ToProto.metadata(event.metadata), final=event.final, @@ -187,13 +187,13 @@ def message_send_configuration( if not config: return a2a_pb2.SendMessageConfiguration() return a2a_pb2.SendMessageConfiguration( - accepted_output_modes=config.acceptedOutputModes, + accepted_output_modes=config.accepted_output_modes, push_notification=ToProto.push_notification_config( - config.pushNotificationConfig + config.push_notification_config ) - if config.pushNotificationConfig + if config.push_notification_config else None, - history_length=config.historyLength, + history_length=config.history_length, blocking=config.blocking or False, ) @@ -259,9 +259,9 @@ def task_push_notification_config( cls, config: types.TaskPushNotificationConfig ) -> a2a_pb2.TaskPushNotificationConfig: return a2a_pb2.TaskPushNotificationConfig( - name=f'tasks/{config.taskId}/pushNotificationConfigs/{config.taskId}', + name=f'tasks/{config.task_id}/pushNotificationConfigs/{config.task_id}', push_notification_config=cls.push_notification_config( - config.pushNotificationConfig, + config.push_notification_config, ), ) @@ -272,19 +272,19 @@ def agent_card( ) -> a2a_pb2.AgentCard: return a2a_pb2.AgentCard( capabilities=cls.capabilities(card.capabilities), - default_input_modes=list(card.defaultInputModes), - default_output_modes=list(card.defaultOutputModes), + default_input_modes=list(card.default_input_modes), + default_output_modes=list(card.default_output_modes), description=card.description, - documentation_url=card.documentationUrl, + documentation_url=card.documentation_url, name=card.name, provider=cls.provider(card.provider), security=cls.security(card.security), - security_schemes=cls.security_schemes(card.securitySchemes), + security_schemes=cls.security_schemes(card.security_schemes), skills=[cls.skill(x) for x in card.skills] if card.skills else [], url=card.url, version=card.version, supports_authenticated_extended_card=bool( - card.supportsAuthenticatedExtendedCard + card.supports_authenticated_extended_card ), ) @@ -294,7 +294,7 @@ def capabilities( ) -> a2a_pb2.AgentCapabilities: return a2a_pb2.AgentCapabilities( streaming=bool(capabilities.streaming), - push_notifications=bool(capabilities.pushNotifications), + push_notifications=bool(capabilities.push_notifications), ) @classmethod @@ -353,7 +353,7 @@ def security_scheme( http_auth_security_scheme=a2a_pb2.HTTPAuthSecurityScheme( description=scheme.root.description, scheme=scheme.root.scheme, - bearer_format=scheme.root.bearerFormat, + bearer_format=scheme.root.bearer_format, ) ) if isinstance(scheme.root, types.OAuth2SecurityScheme): @@ -366,43 +366,43 @@ def security_scheme( return a2a_pb2.SecurityScheme( open_id_connect_security_scheme=a2a_pb2.OpenIdConnectSecurityScheme( description=scheme.root.description, - open_id_connect_url=scheme.root.openIdConnectUrl, + open_id_connect_url=scheme.root.open_id_connect_url, ) ) @classmethod def oauth2_flows(cls, flows: types.OAuthFlows) -> a2a_pb2.OAuthFlows: - if flows.authorizationCode: + if flows.authorization_code: return a2a_pb2.OAuthFlows( authorization_code=a2a_pb2.AuthorizationCodeOAuthFlow( - authorization_url=flows.authorizationCode.authorizationUrl, - refresh_url=flows.authorizationCode.refreshUrl, - scopes=dict(flows.authorizationCode.scopes.items()), - token_url=flows.authorizationCode.tokenUrl, + authorization_url=flows.authorization_code.authorization_url, + refresh_url=flows.authorization_code.refresh_url, + scopes=dict(flows.authorization_code.scopes.items()), + token_url=flows.authorization_code.token_url, ), ) - if flows.clientCredentials: + if flows.client_credentials: return a2a_pb2.OAuthFlows( client_credentials=a2a_pb2.ClientCredentialsOAuthFlow( - refresh_url=flows.clientCredentials.refreshUrl, - scopes=dict(flows.clientCredentials.scopes.items()), - token_url=flows.clientCredentials.tokenUrl, + refresh_url=flows.client_credentials.refresh_url, + scopes=dict(flows.client_credentials.scopes.items()), + token_url=flows.client_credentials.token_url, ), ) if flows.implicit: return a2a_pb2.OAuthFlows( implicit=a2a_pb2.ImplicitOAuthFlow( - authorization_url=flows.implicit.authorizationUrl, - refresh_url=flows.implicit.refreshUrl, + authorization_url=flows.implicit.authorization_url, + refresh_url=flows.implicit.refresh_url, scopes=dict(flows.implicit.scopes.items()), ), ) if flows.password: return a2a_pb2.OAuthFlows( password=a2a_pb2.PasswordOAuthFlow( - refresh_url=flows.password.refreshUrl, + refresh_url=flows.password.refresh_url, scopes=dict(flows.password.scopes.items()), - token_url=flows.password.tokenUrl, + token_url=flows.password.token_url, ), ) raise ValueError('Unknown oauth flow definition') @@ -415,8 +415,8 @@ def skill(cls, skill: types.AgentSkill) -> a2a_pb2.AgentSkill: description=skill.description, tags=skill.tags, examples=skill.examples, - input_modes=skill.inputModes, - output_modes=skill.outputModes, + input_modes=skill.input_modes, + output_modes=skill.output_modes, ) @classmethod @@ -436,10 +436,10 @@ class FromProto: @classmethod def message(cls, message: a2a_pb2.Message) -> types.Message: return types.Message( - messageId=message.message_id, + message_id=message.message_id, parts=[FromProto.part(p) for p in message.content], - contextId=message.context_id, - taskId=message.task_id, + context_id=message.context_id, + task_id=message.task_id, role=FromProto.role(message.role), metadata=FromProto.metadata(message.metadata), ) @@ -483,7 +483,7 @@ def file( def task(cls, task: a2a_pb2.Task) -> types.Task: return types.Task( id=task.id, - contextId=task.context_id, + context_id=task.context_id, status=FromProto.task_status(task.status), artifacts=[FromProto.artifact(a) for a in task.artifacts], history=[FromProto.message(h) for h in task.history], @@ -517,7 +517,7 @@ def task_state(cls, state: a2a_pb2.TaskState) -> types.TaskState: @classmethod def artifact(cls, artifact: a2a_pb2.Artifact) -> types.Artifact: return types.Artifact( - artifactId=artifact.artifact_id, + artifact_id=artifact.artifact_id, description=artifact.description, metadata=FromProto.metadata(artifact.metadata), name=artifact.name, @@ -529,12 +529,12 @@ def task_artifact_update_event( cls, event: a2a_pb2.TaskArtifactUpdateEvent ) -> types.TaskArtifactUpdateEvent: return types.TaskArtifactUpdateEvent( - taskId=event.task_id, - contextId=event.context_id, + task_id=event.task_id, + context_id=event.context_id, artifact=FromProto.artifact(event.artifact), metadata=FromProto.metadata(event.metadata), append=event.append, - lastChunk=event.last_chunk, + last_chunk=event.last_chunk, ) @classmethod @@ -542,8 +542,8 @@ def task_status_update_event( cls, event: a2a_pb2.TaskStatusUpdateEvent ) -> types.TaskStatusUpdateEvent: return types.TaskStatusUpdateEvent( - taskId=event.task_id, - contextId=event.context_id, + task_id=event.task_id, + context_id=event.context_id, status=FromProto.task_status(event.status), metadata=FromProto.metadata(event.metadata), final=event.final, @@ -576,13 +576,13 @@ def message_send_configuration( cls, config: a2a_pb2.SendMessageConfiguration ) -> types.MessageSendConfiguration: return types.MessageSendConfiguration( - acceptedOutputModes=list(config.accepted_output_modes), - pushNotificationConfig=FromProto.push_notification_config( + accepted_output_modes=list(config.accepted_output_modes), + push_notification_config=FromProto.push_notification_config( config.push_notification ) if config.HasField('push_notification') else None, - historyLength=config.history_length, + history_length=config.history_length, blocking=config.blocking, ) @@ -638,10 +638,10 @@ def task_push_notification_config( ) ) return types.TaskPushNotificationConfig( - pushNotificationConfig=cls.push_notification_config( + push_notification_config=cls.push_notification_config( request.config.push_notification_config, ), - taskId=m.group(1), + task_id=m.group(1), ) @classmethod @@ -651,18 +651,18 @@ def agent_card( ) -> types.AgentCard: return types.AgentCard( capabilities=cls.capabilities(card.capabilities), - defaultInputModes=list(card.default_input_modes), - defaultOutputModes=list(card.default_output_modes), + default_input_modes=list(card.default_input_modes), + default_output_modes=list(card.default_output_modes), description=card.description, - documentationUrl=card.documentation_url, + documentation_url=card.documentation_url, name=card.name, provider=cls.provider(card.provider), security=cls.security(list(card.security)), - securitySchemes=cls.security_schemes(dict(card.security_schemes)), + security_schemes=cls.security_schemes(dict(card.security_schemes)), skills=[cls.skill(x) for x in card.skills] if card.skills else [], url=card.url, version=card.version, - supportsAuthenticatedExtendedCard=card.supports_authenticated_extended_card, + supports_authenticated_extended_card=card.supports_authenticated_extended_card, ) @classmethod @@ -678,7 +678,7 @@ def task_query_params( ) ) return types.TaskQueryParams( - historyLength=request.history_length + history_length=request.history_length if request.history_length else None, id=m.group(1), @@ -691,7 +691,7 @@ def capabilities( ) -> types.AgentCapabilities: return types.AgentCapabilities( streaming=capabilities.streaming, - pushNotifications=capabilities.push_notifications, + push_notifications=capabilities.push_notifications, ) @classmethod @@ -741,7 +741,7 @@ def security_scheme( root=types.HTTPAuthSecurityScheme( description=scheme.http_auth_security_scheme.description, scheme=scheme.http_auth_security_scheme.scheme, - bearerFormat=scheme.http_auth_security_scheme.bearer_format, + bearer_format=scheme.http_auth_security_scheme.bearer_format, ) ) if scheme.HasField('oauth2_security_scheme'): @@ -754,7 +754,7 @@ def security_scheme( return types.SecurityScheme( root=types.OpenIdConnectSecurityScheme( description=scheme.open_id_connect_security_scheme.description, - openIdConnectUrl=scheme.open_id_connect_security_scheme.open_id_connect_url, + open_id_connect_url=scheme.open_id_connect_security_scheme.open_id_connect_url, ) ) @@ -762,34 +762,34 @@ def security_scheme( def oauth2_flows(cls, flows: a2a_pb2.OAuthFlows) -> types.OAuthFlows: if flows.HasField('authorization_code'): return types.OAuthFlows( - authorizationCode=types.AuthorizationCodeOAuthFlow( - authorizationUrl=flows.authorization_code.authorization_url, - refreshUrl=flows.authorization_code.refresh_url, + authorization_code=types.AuthorizationCodeOAuthFlow( + authorization_url=flows.authorization_code.authorization_url, + refresh_url=flows.authorization_code.refresh_url, scopes=dict(flows.authorization_code.scopes.items()), - tokenUrl=flows.authorization_code.token_url, + token_url=flows.authorization_code.token_url, ), ) if flows.HasField('client_credentials'): return types.OAuthFlows( - clientCredentials=types.ClientCredentialsOAuthFlow( - refreshUrl=flows.client_credentials.refresh_url, + client_credentials=types.ClientCredentialsOAuthFlow( + refresh_url=flows.client_credentials.refresh_url, scopes=dict(flows.client_credentials.scopes.items()), - tokenUrl=flows.client_credentials.token_url, + token_url=flows.client_credentials.token_url, ), ) if flows.HasField('implicit'): return types.OAuthFlows( implicit=types.ImplicitOAuthFlow( - authorizationUrl=flows.implicit.authorization_url, - refreshUrl=flows.implicit.refresh_url, + authorization_url=flows.implicit.authorization_url, + refresh_url=flows.implicit.refresh_url, scopes=dict(flows.implicit.scopes.items()), ), ) return types.OAuthFlows( password=types.PasswordOAuthFlow( - refreshUrl=flows.password.refresh_url, + refresh_url=flows.password.refresh_url, scopes=dict(flows.password.scopes.items()), - tokenUrl=flows.password.token_url, + token_url=flows.password.token_url, ), ) @@ -801,8 +801,8 @@ def skill(cls, skill: a2a_pb2.AgentSkill) -> types.AgentSkill: description=skill.description, tags=list(skill.tags), examples=list(skill.examples), - inputModes=list(skill.input_modes), - outputModes=list(skill.output_modes), + input_modes=list(skill.input_modes), + output_modes=list(skill.output_modes), ) @classmethod diff --git a/src/a2a/utils/task.py b/src/a2a/utils/task.py index 9b8c82a9..2b3ec710 100644 --- a/src/a2a/utils/task.py +++ b/src/a2a/utils/task.py @@ -27,9 +27,9 @@ def new_task(request: Message) -> Task: return Task( status=TaskStatus(state=TaskState.submitted), - id=(request.taskId if request.taskId else str(uuid.uuid4())), - contextId=( - request.contextId if request.contextId else str(uuid.uuid4()) + id=(request.task_id if request.task_id else str(uuid.uuid4())), + context_id=( + request.context_id if request.context_id else str(uuid.uuid4()) ), history=[request], ) @@ -65,7 +65,7 @@ def completed_task( return Task( status=TaskStatus(state=TaskState.completed), id=task_id, - contextId=context_id, + context_id=context_id, artifacts=artifacts, history=history, ) diff --git a/tests/client/test_auth_middleware.py b/tests/client/test_auth_middleware.py index 34db5b95..ec89d1e2 100644 --- a/tests/client/test_auth_middleware.py +++ b/tests/client/test_auth_middleware.py @@ -55,7 +55,7 @@ def build_success_response() -> dict: jsonrpc='2.0', result=Message( kind='message', - messageId='message-id', + message_id='message-id', role=Role.agent, parts=[], ), @@ -68,7 +68,7 @@ def build_send_message_request() -> SendMessageRequest: id='1', params=MessageSendParams( message=Message( - messageId='msg1', + message_id='msg1', role=Role.user, parts=[], ) @@ -223,9 +223,9 @@ class AuthTestCase: security_scheme=OAuth2SecurityScheme( type='oauth2', flows=OAuthFlows( - authorizationCode=AuthorizationCodeOAuthFlow( - authorizationUrl='http://provider.com/auth', - tokenUrl='http://provider.com/token', + authorization_code=AuthorizationCodeOAuthFlow( + authorization_url='http://provider.com/auth', + token_url='http://provider.com/token', scopes={'read': 'Read scope'}, ) ), @@ -242,7 +242,7 @@ class AuthTestCase: credential='secret-oidc-id-token', security_scheme=OpenIdConnectSecurityScheme( type='openIdConnect', - openIdConnectUrl='http://provider.com/.well-known/openid-configuration', + open_id_connect_url='http://provider.com/.well-known/openid-configuration', ), expected_header_key='Authorization', expected_header_value_func=lambda c: f'Bearer {c}', @@ -282,12 +282,12 @@ async def test_auth_interceptor_variants(test_case, store): name=f'{test_case.scheme_name}bot', description=f'A bot that uses {test_case.scheme_name}', version='1.0', - defaultInputModes=[], - defaultOutputModes=[], + default_input_modes=[], + default_output_modes=[], skills=[], capabilities=AgentCapabilities(), security=[{test_case.scheme_name: []}], - securitySchemes={ + security_schemes={ test_case.scheme_name: SecurityScheme( root=test_case.security_scheme ) @@ -314,7 +314,7 @@ async def test_auth_interceptor_skips_when_scheme_not_in_security_schemes( ): """ Tests that AuthInterceptor skips a scheme if it's listed in security requirements - but not defined in securitySchemes. + but not defined in security_schemes. """ scheme_name = 'missing' session_id = 'session-id' @@ -328,12 +328,12 @@ async def test_auth_interceptor_skips_when_scheme_not_in_security_schemes( name='missingbot', description='A bot that uses missing scheme definition', version='1.0', - defaultInputModes=[], - defaultOutputModes=[], + default_input_modes=[], + default_output_modes=[], skills=[], capabilities=AgentCapabilities(), security=[{scheme_name: []}], - securitySchemes={}, + security_schemes={}, ) new_payload, new_kwargs = await auth_interceptor.intercept( diff --git a/tests/client/test_client.py b/tests/client/test_client.py index 00ab8796..f12906c9 100644 --- a/tests/client/test_client.py +++ b/tests/client/test_client.py @@ -55,8 +55,8 @@ description='Just a hello world agent', url='http://localhost:9999/', version='1.0.0', - defaultInputModes=['text'], - defaultOutputModes=['text'], + default_input_modes=['text'], + default_output_modes=['text'], capabilities=AgentCapabilities(), skills=[ AgentSkill( @@ -87,7 +87,7 @@ ) AGENT_CARD_SUPPORTS_EXTENDED = AGENT_CARD.model_copy( - update={'supportsAuthenticatedExtendedCard': True} + update={'supports_authenticated_extended_card': True} ) AGENT_CARD_NO_URL_SUPPORTS_EXTENDED = AGENT_CARD_SUPPORTS_EXTENDED.model_copy( update={'url': ''} @@ -838,7 +838,7 @@ async def test_set_task_callback_success( ) # Correctly create the TaskPushNotificationConfig (outer model) params_model = TaskPushNotificationConfig( - taskId=task_id_val, pushNotificationConfig=push_config_payload + task_id=task_id_val, push_notification_config=push_config_payload ) # request.id will be generated by the client method if not provided @@ -903,7 +903,7 @@ async def test_set_task_callback_error_response( req_id = 'set_cb_err_req' push_config_payload = PushNotificationConfig(url='https://errors.com') params_model = TaskPushNotificationConfig( - taskId='task_err_cb', pushNotificationConfig=push_config_payload + task_id='task_err_cb', push_notification_config=push_config_payload ) request = SetTaskPushNotificationConfigRequest( id=req_id, params=params_model @@ -938,7 +938,8 @@ async def test_set_task_callback_http_kwargs_passed( ) push_config_payload = PushNotificationConfig(url='https://kwargs.com') params_model = TaskPushNotificationConfig( - taskId='task_cb_kwargs', pushNotificationConfig=push_config_payload + task_id='task_cb_kwargs', + push_notification_config=push_config_payload, ) request = SetTaskPushNotificationConfigRequest( id='cb_kwargs_req', params=params_model @@ -987,7 +988,7 @@ async def test_get_task_callback_success( url='https://callback.example.com/taskupdate' ) expected_callback_config = TaskPushNotificationConfig( - taskId=task_id_val, pushNotificationConfig=push_config_payload + task_id=task_id_val, push_notification_config=push_config_payload ) rpc_response_payload: dict[str, Any] = { 'id': ANY, @@ -1089,8 +1090,8 @@ async def test_get_task_callback_http_kwargs_passed( url='https://getkwargs.com' ) expected_callback_config = TaskPushNotificationConfig( - taskId='task_get_cb_kwargs', - pushNotificationConfig=push_config_payload_for_expected, + task_id='task_get_cb_kwargs', + push_notification_config=push_config_payload_for_expected, ) rpc_response_payload: dict[str, Any] = { 'id': 'get_cb_kwargs_req', diff --git a/tests/client/test_grpc_client.py b/tests/client/test_grpc_client.py index ff823342..26967d73 100644 --- a/tests/client/test_grpc_client.py +++ b/tests/client/test_grpc_client.py @@ -43,9 +43,9 @@ def sample_agent_card() -> AgentCard: description='Agent for testing gRPC client', url='grpc://localhost:50051', version='1.0', - capabilities=AgentCapabilities(streaming=True, pushNotifications=True), - defaultInputModes=['text/plain'], - defaultOutputModes=['text/plain'], + capabilities=AgentCapabilities(streaming=True, push_notifications=True), + default_input_modes=['text/plain'], + default_output_modes=['text/plain'], skills=[], ) @@ -64,7 +64,7 @@ def sample_message_send_params() -> MessageSendParams: return MessageSendParams( message=Message( role=Role.user, - messageId='msg-1', + message_id='msg-1', parts=[Part(root=TextPart(text='Hello'))], ) ) @@ -75,7 +75,7 @@ def sample_task() -> Task: """Provides a sample Task object.""" return Task( id='task-1', - contextId='ctx-1', + context_id='ctx-1', status=TaskStatus(state=TaskState.completed), ) @@ -85,7 +85,7 @@ def sample_message() -> Message: """Provides a sample Message object.""" return Message( role=Role.agent, - messageId='msg-response', + message_id='msg-response', parts=[Part(root=TextPart(text='Hi there'))], ) diff --git a/tests/server/agent_execution/test_context.py b/tests/server/agent_execution/test_context.py index aa72b5a6..7b9651b0 100644 --- a/tests/server/agent_execution/test_context.py +++ b/tests/server/agent_execution/test_context.py @@ -19,7 +19,7 @@ class TestRequestContext: @pytest.fixture def mock_message(self): """Fixture for a mock Message.""" - return Mock(spec=Message, taskId=None, contextId=None) + return Mock(spec=Message, task_id=None, context_id=None) @pytest.fixture def mock_params(self, mock_message): @@ -29,7 +29,7 @@ def mock_params(self, mock_message): @pytest.fixture def mock_task(self): """Fixture for a mock Task.""" - return Mock(spec=Task, id='task-123', contextId='context-456') + return Mock(spec=Task, id='task-123', context_id='context-456') def test_init_without_params(self): """Test initialization without parameters.""" @@ -54,11 +54,12 @@ def test_init_with_params_no_ids(self, mock_params): assert context.message == mock_params.message assert context.task_id == '00000000-0000-0000-0000-000000000001' assert ( - mock_params.message.taskId == '00000000-0000-0000-0000-000000000001' + mock_params.message.task_id + == '00000000-0000-0000-0000-000000000001' ) assert context.context_id == '00000000-0000-0000-0000-000000000002' assert ( - mock_params.message.contextId + mock_params.message.context_id == '00000000-0000-0000-0000-000000000002' ) @@ -68,7 +69,7 @@ def test_init_with_task_id(self, mock_params): context = RequestContext(request=mock_params, task_id=task_id) assert context.task_id == task_id - assert mock_params.message.taskId == task_id + assert mock_params.message.task_id == task_id def test_init_with_context_id(self, mock_params): """Test initialization with context ID provided.""" @@ -76,7 +77,7 @@ def test_init_with_context_id(self, mock_params): context = RequestContext(request=mock_params, context_id=context_id) assert context.context_id == context_id - assert mock_params.message.contextId == context_id + assert mock_params.message.context_id == context_id def test_init_with_both_ids(self, mock_params): """Test initialization with both task and context IDs provided.""" @@ -87,9 +88,9 @@ def test_init_with_both_ids(self, mock_params): ) assert context.task_id == task_id - assert mock_params.message.taskId == task_id + assert mock_params.message.task_id == task_id assert context.context_id == context_id - assert mock_params.message.contextId == context_id + assert mock_params.message.context_id == context_id def test_init_with_task(self, mock_params, mock_task): """Test initialization with a task object.""" @@ -139,13 +140,13 @@ def test_check_or_generate_task_id_no_params(self): def test_check_or_generate_task_id_with_existing_task_id(self, mock_params): """Test _check_or_generate_task_id with existing task ID.""" existing_id = 'existing-task-id' - mock_params.message.taskId = existing_id + mock_params.message.task_id = existing_id context = RequestContext(request=mock_params) # The method is called during initialization assert context.task_id == existing_id - assert mock_params.message.taskId == existing_id + assert mock_params.message.task_id == existing_id def test_check_or_generate_context_id_no_params(self): """Test _check_or_generate_context_id with no params does nothing.""" @@ -158,13 +159,13 @@ def test_check_or_generate_context_id_with_existing_context_id( ): """Test _check_or_generate_context_id with existing context ID.""" existing_id = 'existing-context-id' - mock_params.message.contextId = existing_id + mock_params.message.context_id = existing_id context = RequestContext(request=mock_params) # The method is called during initialization assert context.context_id == existing_id - assert mock_params.message.contextId == existing_id + assert mock_params.message.context_id == existing_id def test_init_raises_error_on_task_id_mismatch( self, mock_params, mock_task @@ -179,9 +180,9 @@ def test_init_raises_error_on_task_id_mismatch( def test_init_raises_error_on_context_id_mismatch( self, mock_params, mock_task ): - """Test that an error is raised if provided context_id mismatches task.contextId.""" + """Test that an error is raised if provided context_id mismatches task.context_id.""" # Set a valid task_id to avoid that error - mock_params.message.taskId = mock_task.id + mock_params.message.task_id = mock_task.id with pytest.raises(ServerError) as exc_info: RequestContext( @@ -224,8 +225,8 @@ def test_metadata_property_with_content(self, mock_params): def test_init_with_existing_ids_in_message(self, mock_message, mock_params): """Test initialization with existing IDs in the message.""" - mock_message.taskId = 'existing-task-id' - mock_message.contextId = 'existing-context-id' + mock_message.task_id = 'existing-task-id' + mock_message.context_id = 'existing-context-id' context = RequestContext(request=mock_params) @@ -237,7 +238,7 @@ def test_init_with_task_id_and_existing_task_id_match( self, mock_params, mock_task ): """Test initialization succeeds when task_id matches task.id.""" - mock_params.message.taskId = mock_task.id + mock_params.message.task_id = mock_task.id context = RequestContext( request=mock_params, task_id=mock_task.id, task=mock_task @@ -249,16 +250,16 @@ def test_init_with_task_id_and_existing_task_id_match( def test_init_with_context_id_and_existing_context_id_match( self, mock_params, mock_task ): - """Test initialization succeeds when context_id matches task.contextId.""" - mock_params.message.taskId = mock_task.id # Set matching task ID - mock_params.message.contextId = mock_task.contextId + """Test initialization succeeds when context_id matches task.context_id.""" + mock_params.message.task_id = mock_task.id # Set matching task ID + mock_params.message.context_id = mock_task.context_id context = RequestContext( request=mock_params, task_id=mock_task.id, - context_id=mock_task.contextId, + context_id=mock_task.context_id, task=mock_task, ) - assert context.context_id == mock_task.contextId + assert context.context_id == mock_task.context_id assert context.current_task == mock_task diff --git a/tests/server/agent_execution/test_simple_request_context_builder.py b/tests/server/agent_execution/test_simple_request_context_builder.py index 714996bf..116f4011 100644 --- a/tests/server/agent_execution/test_simple_request_context_builder.py +++ b/tests/server/agent_execution/test_simple_request_context_builder.py @@ -32,7 +32,7 @@ def create_sample_message( reference_task_ids=None, ): return Message( - messageId=msg_id, + message_id=msg_id, role=role, parts=[Part(root=TextPart(text=content))], referenceTaskIds=reference_task_ids if reference_task_ids else [], @@ -45,7 +45,7 @@ def create_sample_task( ): return Task( id=task_id, - contextId=context_id, + context_id=context_id, status=TaskStatus(state=status_state), ) @@ -211,7 +211,7 @@ async def test_build_populate_true_reference_ids_empty_or_none(self): # To explicitly test None in Message, we'd have to bypass Pydantic default or modify helper. # For now, this covers the "no IDs to process" case. msg_with_no_refs = Message( - messageId='m2', role=Role.user, parts=[], referenceTaskIds=None + message_id='m2', role=Role.user, parts=[], referenceTaskIds=None ) params_none_refs = MessageSendParams(message=msg_with_no_refs) request_context_none = await builder.build( diff --git a/tests/server/apps/jsonrpc/test_jsonrpc_app.py b/tests/server/apps/jsonrpc/test_jsonrpc_app.py index 6670e40b..9e5f88ba 100644 --- a/tests/server/apps/jsonrpc/test_jsonrpc_app.py +++ b/tests/server/apps/jsonrpc/test_jsonrpc_app.py @@ -68,7 +68,7 @@ def test_jsonrpc_app_build_method_abstract_raises_typeerror( # Ensure 'url' attribute exists on the mock_agent_card, as it's accessed in __init__ mock_agent_card.url = 'http://mockurl.com' # Ensure 'supportsAuthenticatedExtendedCard' attribute exists - mock_agent_card.supportsAuthenticatedExtendedCard = False + mock_agent_card.supports_authenticated_extended_card = False # This will fail at definition time if an abstract method is not implemented with pytest.raises( diff --git a/tests/server/apps/jsonrpc/test_serialization.py b/tests/server/apps/jsonrpc/test_serialization.py index 3091c0cd..2fae14e5 100644 --- a/tests/server/apps/jsonrpc/test_serialization.py +++ b/tests/server/apps/jsonrpc/test_serialization.py @@ -38,10 +38,10 @@ def agent_card_with_api_key(): url='http://example.com/apikey-agent', version='1.0.0', capabilities=AgentCapabilities(), - defaultInputModes=['text/plain'], - defaultOutputModes=['text/plain'], + default_input_modes=['text/plain'], + default_output_modes=['text/plain'], skills=[], - securitySchemes={'api_key_auth': SecurityScheme(root=api_key_scheme)}, + security_schemes={'api_key_auth': SecurityScheme(root=api_key_scheme)}, security=[{'api_key_auth': []}], ) return agent_card @@ -70,7 +70,7 @@ def test_starlette_agent_card_with_api_key_scheme_alias( try: parsed_card = AgentCard.model_validate(response_data) - parsed_scheme_wrapper = parsed_card.securitySchemes['api_key_auth'] + parsed_scheme_wrapper = parsed_card.security_schemes['api_key_auth'] assert isinstance(parsed_scheme_wrapper.root, APIKeySecurityScheme) assert parsed_scheme_wrapper.root.in_ == In.header except ValidationError as e: @@ -163,7 +163,7 @@ def test_handle_unicode_characters(agent_card_with_api_key: AgentCard): 'message': { 'role': 'user', 'parts': [{'kind': 'text', 'text': unicode_text}], - 'messageId': 'msg-unicode', + 'message_id': 'msg-unicode', } }, } @@ -172,7 +172,7 @@ def test_handle_unicode_characters(agent_card_with_api_key: AgentCard): handler.on_message_send.return_value = Message( role=Role.agent, parts=[Part(root=TextPart(text=f'Received: {unicode_text}'))], - messageId='response-unicode', + message_id='response-unicode', ) response = client.post('/', json=unicode_payload) diff --git a/tests/server/events/test_event_consumer.py b/tests/server/events/test_event_consumer.py index 3f6c5d70..9f061a8b 100644 --- a/tests/server/events/test_event_consumer.py +++ b/tests/server/events/test_event_consumer.py @@ -28,7 +28,7 @@ MINIMAL_TASK: dict[str, Any] = { 'id': '123', - 'contextId': 'session-xyz', + 'context_id': 'session-xyz', 'status': {'state': 'submitted'}, 'kind': 'task', } @@ -36,7 +36,7 @@ MESSAGE_PAYLOAD: dict[str, Any] = { 'role': 'agent', 'parts': [{'text': 'test message'}], - 'messageId': '111', + 'message_id': '111', } @@ -128,15 +128,15 @@ async def test_consume_all_multiple_events( events: list[Any] = [ Task(**MINIMAL_TASK), TaskArtifactUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', artifact=Artifact( - artifactId='11', parts=[Part(TextPart(text='text'))] + artifact_id='11', parts=[Part(TextPart(text='text'))] ), ), TaskStatusUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', status=TaskStatus(state=TaskState.working), final=True, ), @@ -170,16 +170,16 @@ async def test_consume_until_message( events: list[Any] = [ Task(**MINIMAL_TASK), TaskArtifactUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', artifact=Artifact( - artifactId='11', parts=[Part(TextPart(text='text'))] + artifact_id='11', parts=[Part(TextPart(text='text'))] ), ), Message(**MESSAGE_PAYLOAD), TaskStatusUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', status=TaskStatus(state=TaskState.working), final=True, ), @@ -276,7 +276,7 @@ async def test_consume_all_continues_on_queue_empty_if_not_really_closed( ): """Test that QueueClosed with is_closed=False allows loop to continue via timeout.""" payload = MESSAGE_PAYLOAD.copy() - payload['messageId'] = 'final_event_id' + payload['message_id'] = 'final_event_id' final_event = Message(**payload) # Setup dequeue_event behavior: diff --git a/tests/server/events/test_event_queue.py b/tests/server/events/test_event_queue.py index d66e62b6..ffe74877 100644 --- a/tests/server/events/test_event_queue.py +++ b/tests/server/events/test_event_queue.py @@ -28,14 +28,14 @@ MINIMAL_TASK: dict[str, Any] = { 'id': '123', - 'contextId': 'session-xyz', + 'context_id': 'session-xyz', 'status': {'state': 'submitted'}, 'kind': 'task', } MESSAGE_PAYLOAD: dict[str, Any] = { 'role': 'agent', 'parts': [{'text': 'test message'}], - 'messageId': '111', + 'message_id': '111', } @@ -100,8 +100,8 @@ async def test_dequeue_event_empty_queue_no_wait( async def test_dequeue_event_wait(event_queue: EventQueue) -> None: """Test dequeue_event with the default wait behavior.""" event = TaskStatusUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', status=TaskStatus(state=TaskState.working), final=True, ) @@ -114,9 +114,11 @@ async def test_dequeue_event_wait(event_queue: EventQueue) -> None: async def test_task_done(event_queue: EventQueue) -> None: """Test the task_done method.""" event = TaskArtifactUpdateEvent( - taskId='task_123', - contextId='session-xyz', - artifact=Artifact(artifactId='11', parts=[Part(TextPart(text='text'))]), + task_id='task_123', + context_id='session-xyz', + artifact=Artifact( + artifact_id='11', parts=[Part(TextPart(text='text'))] + ), ) await event_queue.enqueue_event(event) _ = await event_queue.dequeue_event() diff --git a/tests/server/request_handlers/test_default_request_handler.py b/tests/server/request_handlers/test_default_request_handler.py index 06243d9d..0defc67e 100644 --- a/tests/server/request_handlers/test_default_request_handler.py +++ b/tests/server/request_handlers/test_default_request_handler.py @@ -82,7 +82,7 @@ def create_sample_task( ) -> Task: return Task( id=task_id, - contextId=context_id, + context_id=context_id, status=TaskStatus(state=status_state), ) @@ -276,7 +276,7 @@ async def test_on_cancel_task_invalid_result_type(): # Mock ResultAggregator to return a Message mock_result_aggregator_instance = AsyncMock(spec=ResultAggregator) mock_result_aggregator_instance.consume_all.return_value = Message( - messageId='unexpected_msg', role=Role.agent, parts=[] + message_id='unexpected_msg', role=Role.agent, parts=[] ) request_handler = DefaultRequestHandler( @@ -343,16 +343,16 @@ async def test_on_message_send_with_push_notification(): push_config = PushNotificationConfig(url='http://callback.com/push') message_config = MessageSendConfiguration( - pushNotificationConfig=push_config, - acceptedOutputModes=['text/plain'], # Added required field + push_notification_config=push_config, + accepted_output_modes=['text/plain'], # Added required field ) params = MessageSendParams( message=Message( role=Role.user, - messageId='msg_push', + message_id='msg_push', parts=[], - taskId=task_id, - contextId=context_id, + task_id=task_id, + context_id=context_id, ), configuration=message_config, ) @@ -431,11 +431,11 @@ async def test_on_message_send_with_push_notification_no_existing_Task(): push_config = PushNotificationConfig(url='http://callback.com/push') message_config = MessageSendConfiguration( - pushNotificationConfig=push_config, - acceptedOutputModes=['text/plain'], # Added required field + push_notification_config=push_config, + accepted_output_modes=['text/plain'], # Added required field ) params = MessageSendParams( - message=Message(role=Role.user, messageId='msg_push', parts=[]), + message=Message(role=Role.user, message_id='msg_push', parts=[]), configuration=message_config, ) @@ -498,7 +498,7 @@ async def test_on_message_send_no_result_from_aggregator(): request_context_builder=mock_request_context_builder, ) params = MessageSendParams( - message=Message(role=Role.user, messageId='msg_no_res', parts=[]) + message=Message(role=Role.user, message_id='msg_no_res', parts=[]) ) mock_result_aggregator_instance = AsyncMock(spec=ResultAggregator) @@ -548,7 +548,7 @@ async def test_on_message_send_task_id_mismatch(): request_context_builder=mock_request_context_builder, ) params = MessageSendParams( - message=Message(role=Role.user, messageId='msg_id_mismatch', parts=[]) + message=Message(role=Role.user, message_id='msg_id_mismatch', parts=[]) ) mock_result_aggregator_instance = AsyncMock(spec=ResultAggregator) @@ -598,7 +598,7 @@ async def test_on_message_send_interrupted_flow(): request_context_builder=mock_request_context_builder, ) params = MessageSendParams( - message=Message(role=Role.user, messageId='msg_interrupt', parts=[]) + message=Message(role=Role.user, message_id='msg_interrupt', parts=[]) ) mock_result_aggregator_instance = AsyncMock(spec=ResultAggregator) @@ -685,16 +685,16 @@ async def test_on_message_send_stream_with_push_notification(): push_config = PushNotificationConfig(url='http://callback.stream.com/push') message_config = MessageSendConfiguration( - pushNotificationConfig=push_config, - acceptedOutputModes=['text/plain'], # Added required field + push_notification_config=push_config, + accepted_output_modes=['text/plain'], # Added required field ) params = MessageSendParams( message=Message( role=Role.user, - messageId='msg_stream_push', + message_id='msg_stream_push', parts=[], - taskId=task_id, - contextId=context_id, + task_id=task_id, + context_id=context_id, ), configuration=message_config, ) @@ -947,7 +947,7 @@ async def test_on_message_send_stream_task_id_mismatch(): ) params = MessageSendParams( message=Message( - role=Role.user, messageId='msg_stream_mismatch', parts=[] + role=Role.user, message_id='msg_stream_mismatch', parts=[] ) ) @@ -1031,8 +1031,10 @@ async def test_set_task_push_notification_config_no_notifier(): push_config_store=None, # Explicitly None ) params = TaskPushNotificationConfig( - taskId='task1', - pushNotificationConfig=PushNotificationConfig(url='http://example.com'), + task_id='task1', + push_notification_config=PushNotificationConfig( + url='http://example.com' + ), ) from a2a.utils.errors import ServerError # Local import @@ -1058,8 +1060,10 @@ async def test_set_task_push_notification_config_task_not_found(): push_sender=mock_push_sender, ) params = TaskPushNotificationConfig( - taskId='non_existent_task', - pushNotificationConfig=PushNotificationConfig(url='http://example.com'), + task_id='non_existent_task', + push_notification_config=PushNotificationConfig( + url='http://example.com' + ), ) from a2a.utils.errors import ServerError # Local import @@ -1161,8 +1165,8 @@ async def test_get_task_push_notification_config_info_with_config(): ) set_config_params = TaskPushNotificationConfig( - taskId='task_1', - pushNotificationConfig=PushNotificationConfig( + task_id='task_1', + push_notification_config=PushNotificationConfig( id='config_id', url='http://1.example.com' ), ) @@ -1171,7 +1175,7 @@ async def test_get_task_push_notification_config_info_with_config(): ) params = GetTaskPushNotificationConfigParams( - id='task_1', pushNotificationConfigId='config_id' + id='task_1', push_notification_config_id='config_id' ) result: TaskPushNotificationConfig = ( @@ -1181,12 +1185,12 @@ async def test_get_task_push_notification_config_info_with_config(): ) assert result is not None - assert result.taskId == 'task_1' + assert result.task_id == 'task_1' assert ( - result.pushNotificationConfig.url - == set_config_params.pushNotificationConfig.url + result.push_notification_config.url + == set_config_params.push_notification_config.url ) - assert result.pushNotificationConfig.id == 'config_id' + assert result.push_notification_config.id == 'config_id' @pytest.mark.asyncio @@ -1203,7 +1207,7 @@ async def test_get_task_push_notification_config_info_with_config_no_id(): ) set_config_params = TaskPushNotificationConfig( - taskId='task_1', + task_id='task_1', pushNotificationConfig=PushNotificationConfig( url='http://1.example.com' ), @@ -1221,12 +1225,12 @@ async def test_get_task_push_notification_config_info_with_config_no_id(): ) assert result is not None - assert result.taskId == 'task_1' + assert result.task_id == 'task_1' assert ( - result.pushNotificationConfig.url - == set_config_params.pushNotificationConfig.url + result.push_notification_config.url + == set_config_params.push_notification_config.url ) - assert result.pushNotificationConfig.id == 'task_1' + assert result.push_notification_config.id == 'task_1' @pytest.mark.asyncio @@ -1293,7 +1297,7 @@ async def test_on_message_send_stream(): message_params = MessageSendParams( message=Message( role=Role.user, - messageId='msg-123', + message_id='msg-123', parts=[Part(root=TextPart(text='How are you?'))], ), ) @@ -1421,10 +1425,10 @@ async def test_list_task_push_notification_config_info_with_config(): ) assert len(result) == 2 - assert result[0].taskId == 'task_1' - assert result[0].pushNotificationConfig == push_config1 - assert result[1].taskId == 'task_1' - assert result[1].pushNotificationConfig == push_config2 + assert result[0].task_id == 'task_1' + assert result[0].push_notification_config == push_config1 + assert result[1].task_id == 'task_1' + assert result[1].push_notification_config == push_config2 @pytest.mark.asyncio @@ -1442,7 +1446,7 @@ async def test_list_task_push_notification_config_info_with_config_and_no_id(): # multiple calls without config id should replace the existing set_config_params1 = TaskPushNotificationConfig( - taskId='task_1', + task_id='task_1', pushNotificationConfig=PushNotificationConfig( url='http://1.example.com' ), @@ -1452,7 +1456,7 @@ async def test_list_task_push_notification_config_info_with_config_and_no_id(): ) set_config_params2 = TaskPushNotificationConfig( - taskId='task_1', + task_id='task_1', pushNotificationConfig=PushNotificationConfig( url='http://2.example.com' ), @@ -1470,12 +1474,12 @@ async def test_list_task_push_notification_config_info_with_config_and_no_id(): ) assert len(result) == 1 - assert result[0].taskId == 'task_1' + assert result[0].task_id == 'task_1' assert ( - result[0].pushNotificationConfig.url - == set_config_params2.pushNotificationConfig.url + result[0].push_notification_config.url + == set_config_params2.push_notification_config.url ) - assert result[0].pushNotificationConfig.id == 'task_1' + assert result[0].push_notification_config.id == 'task_1' @pytest.mark.asyncio @@ -1487,7 +1491,7 @@ async def test_delete_task_push_notification_config_no_store(): push_config_store=None, # Explicitly None ) params = DeleteTaskPushNotificationConfigParams( - id='task1', pushNotificationConfigId='config1' + id='task1', push_notification_config_id='config1' ) from a2a.utils.errors import ServerError # Local import @@ -1511,7 +1515,7 @@ async def test_delete_task_push_notification_config_task_not_found(): push_config_store=mock_push_store, ) params = DeleteTaskPushNotificationConfigParams( - id='non_existent_task', pushNotificationConfigId='config1' + id='non_existent_task', push_notification_config_id='config1' ) from a2a.utils.errors import ServerError # Local import @@ -1545,7 +1549,7 @@ async def test_delete_no_task_push_notification_config_info(): push_config_store=push_store, ) params = DeleteTaskPushNotificationConfigParams( - id='task1', pushNotificationConfigId='config_non_existant' + id='task1', push_notification_config_id='config_non_existant' ) result = await request_handler.on_delete_task_push_notification_config( @@ -1554,7 +1558,7 @@ async def test_delete_no_task_push_notification_config_info(): assert result == None params = DeleteTaskPushNotificationConfigParams( - id='task2', pushNotificationConfigId='config_non_existant' + id='task2', push_notification_config_id='config_non_existant' ) result = await request_handler.on_delete_task_push_notification_config( @@ -1589,7 +1593,7 @@ async def test_delete_task_push_notification_config_info_with_config(): push_config_store=push_store, ) params = DeleteTaskPushNotificationConfigParams( - id='task_1', pushNotificationConfigId='config_1' + id='task_1', push_notification_config_id='config_1' ) result1 = await request_handler.on_delete_task_push_notification_config( @@ -1604,8 +1608,8 @@ async def test_delete_task_push_notification_config_info_with_config(): ) assert len(result2) == 1 - assert result2[0].taskId == 'task_1' - assert result2[0].pushNotificationConfig == push_config2 + assert result2[0].task_id == 'task_1' + assert result2[0].push_notification_config == push_config2 @pytest.mark.asyncio @@ -1629,7 +1633,7 @@ async def test_delete_task_push_notification_config_info_with_config_and_no_id() push_config_store=push_store, ) params = DeleteTaskPushNotificationConfigParams( - id='task_1', pushNotificationConfigId='task_1' + id='task_1', push_notification_config_id='task_1' ) result = await request_handler.on_delete_task_push_notification_config( @@ -1675,9 +1679,9 @@ async def test_on_message_send_task_in_terminal_state(terminal_state): params = MessageSendParams( message=Message( role=Role.user, - messageId='msg_terminal', + message_id='msg_terminal', parts=[], - taskId=task_id, + task_id=task_id, ) ) @@ -1719,9 +1723,9 @@ async def test_on_message_send_stream_task_in_terminal_state(terminal_state): params = MessageSendParams( message=Message( role=Role.user, - messageId='msg_terminal_stream', + message_id='msg_terminal_stream', parts=[], - taskId=task_id, + task_id=task_id, ) ) diff --git a/tests/server/request_handlers/test_grpc_handler.py b/tests/server/request_handlers/test_grpc_handler.py index e1b8b940..852707c9 100644 --- a/tests/server/request_handlers/test_grpc_handler.py +++ b/tests/server/request_handlers/test_grpc_handler.py @@ -32,10 +32,10 @@ def sample_agent_card() -> types.AgentCard: url='http://localhost', version='1.0.0', capabilities=types.AgentCapabilities( - streaming=True, pushNotifications=True + streaming=True, push_notifications=True ), - defaultInputModes=['text/plain'], - defaultOutputModes=['text/plain'], + default_input_modes=['text/plain'], + default_output_modes=['text/plain'], skills=[], ) @@ -64,7 +64,7 @@ async def test_send_message_success( ) response_model = types.Task( id='task-1', - contextId='ctx-1', + context_id='ctx-1', status=types.TaskStatus(state=types.TaskState.completed), ) mock_request_handler.on_message_send.return_value = response_model @@ -105,7 +105,7 @@ async def test_get_task_success( request_proto = a2a_pb2.GetTaskRequest(name='tasks/task-1') response_model = types.Task( id='task-1', - contextId='ctx-1', + context_id='ctx-1', status=types.TaskStatus(state=types.TaskState.working), ) mock_request_handler.on_get_task.return_value = response_model @@ -164,7 +164,7 @@ async def test_send_streaming_message( async def mock_stream(): yield types.Task( id='task-1', - contextId='ctx-1', + context_id='ctx-1', status=types.TaskStatus(state=types.TaskState.working), ) diff --git a/tests/server/request_handlers/test_jsonrpc_handler.py b/tests/server/request_handlers/test_jsonrpc_handler.py index 1f421aef..2ff3fe78 100644 --- a/tests/server/request_handlers/test_jsonrpc_handler.py +++ b/tests/server/request_handlers/test_jsonrpc_handler.py @@ -273,8 +273,8 @@ async def streaming_coro(): params=MessageSendParams( message=Message( **MESSAGE_PAYLOAD, - taskId=mock_task.id, - contextId=mock_task.contextId, + task_id=mock_task.id, + context_id=mock_task.context_id, ) ), ) @@ -341,15 +341,15 @@ async def test_on_message_stream_new_message_success( events: list[Any] = [ Task(**MINIMAL_TASK), TaskArtifactUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', artifact=Artifact( - artifactId='11', parts=[Part(TextPart(text='text'))] + artifact_id='11', parts=[Part(TextPart(text='text'))] ), ), TaskStatusUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', status=TaskStatus(state=TaskState.completed), final=True, ), @@ -398,15 +398,15 @@ async def test_on_message_stream_new_message_existing_task_success( events: list[Any] = [ mock_task, TaskArtifactUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', artifact=Artifact( - artifactId='11', parts=[Part(TextPart(text='text'))] + artifact_id='11', parts=[Part(TextPart(text='text'))] ), ), TaskStatusUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', status=TaskStatus(state=TaskState.working), final=True, ), @@ -427,8 +427,8 @@ async def streaming_coro(): params=MessageSendParams( message=Message( **MESSAGE_PAYLOAD, - taskId=mock_task.id, - contextId=mock_task.contextId, + task_id=mock_task.id, + context_id=mock_task.context_id, ) ), ) @@ -452,13 +452,13 @@ async def test_set_push_notification_success(self) -> None: push_config_store=mock_push_notification_store, ) self.mock_agent_card.capabilities = AgentCapabilities( - streaming=True, pushNotifications=True + streaming=True, push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) mock_task = Task(**MINIMAL_TASK) mock_task_store.get.return_value = mock_task task_push_config = TaskPushNotificationConfig( - taskId=mock_task.id, + task_id=mock_task.id, pushNotificationConfig=PushNotificationConfig( url='http://example.com' ), @@ -474,7 +474,7 @@ async def test_set_push_notification_success(self) -> None: ) assert response.root.result == task_push_config # type: ignore mock_push_notification_store.set_info.assert_called_once_with( - mock_task.id, task_push_config.pushNotificationConfig + mock_task.id, task_push_config.push_notification_config ) async def test_get_push_notification_success(self) -> None: @@ -487,13 +487,13 @@ async def test_get_push_notification_success(self) -> None: push_config_store=push_notification_store, ) self.mock_agent_card.capabilities = AgentCapabilities( - streaming=True, pushNotifications=True + streaming=True, push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) mock_task = Task(**MINIMAL_TASK) mock_task_store.get.return_value = mock_task task_push_config = TaskPushNotificationConfig( - taskId=mock_task.id, + task_id=mock_task.id, pushNotificationConfig=PushNotificationConfig( url='http://example.com' ), @@ -536,7 +536,7 @@ async def test_on_message_stream_new_message_send_push_notification_success( push_sender=push_notification_sender, ) self.mock_agent_card.capabilities = AgentCapabilities( - streaming=True, pushNotifications=True + streaming=True, push_notifications=True ) _mock_builder_build.return_value = RequestContext( request=MagicMock(), @@ -550,15 +550,15 @@ async def test_on_message_stream_new_message_send_push_notification_success( events: list[Any] = [ Task(**MINIMAL_TASK), TaskArtifactUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', artifact=Artifact( - artifactId='11', parts=[Part(TextPart(text='text'))] + artifact_id='11', parts=[Part(TextPart(text='text'))] ), ), TaskStatusUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', status=TaskStatus(state=TaskState.completed), final=True, ), @@ -580,7 +580,7 @@ async def streaming_coro(): params=MessageSendParams(message=Message(**MESSAGE_PAYLOAD)), ) request.params.configuration = MessageSendConfiguration( - acceptedOutputModes=['text'], + accepted_output_modes=['text'], pushNotificationConfig=PushNotificationConfig( url='http://example.com' ), @@ -661,15 +661,15 @@ async def test_on_resubscribe_existing_task_success( mock_task = Task(**MINIMAL_TASK, history=[]) events: list[Any] = [ TaskArtifactUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', artifact=Artifact( - artifactId='11', parts=[Part(TextPart(text='text'))] + artifact_id='11', parts=[Part(TextPart(text='text'))] ), ), TaskStatusUpdateEvent( - taskId='task_123', - contextId='session-xyz', + task_id='task_123', + context_id='session-xyz', status=TaskStatus(state=TaskState.completed), final=True, ), @@ -756,13 +756,13 @@ async def test_push_notifications_not_supported_error(self) -> None: ) # Create agent card with push notifications capability disabled self.mock_agent_card.capabilities = AgentCapabilities( - pushNotifications=False, streaming=True + push_notifications=False, streaming=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) # Act & Assert task_push_config = TaskPushNotificationConfig( - taskId='task_123', + task_id='task_123', pushNotificationConfig=PushNotificationConfig( url='http://example.com' ), @@ -790,7 +790,7 @@ async def test_on_get_push_notification_no_push_config_store(self) -> None: mock_agent_executor, mock_task_store ) self.mock_agent_card.capabilities = AgentCapabilities( - pushNotifications=True + push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) @@ -817,7 +817,7 @@ async def test_on_set_push_notification_no_push_config_store(self) -> None: mock_agent_executor, mock_task_store ) self.mock_agent_card.capabilities = AgentCapabilities( - pushNotifications=True + push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) @@ -826,7 +826,7 @@ async def test_on_set_push_notification_no_push_config_store(self) -> None: # Act task_push_config = TaskPushNotificationConfig( - taskId=mock_task.id, + task_id=mock_task.id, pushNotificationConfig=PushNotificationConfig( url='http://example.com' ), @@ -965,8 +965,8 @@ async def consume_raises_error(*args, **kwargs) -> NoReturn: params=MessageSendParams( message=Message( **MESSAGE_PAYLOAD, - taskId=mock_task.id, - contextId=mock_task.contextId, + task_id=mock_task.id, + context_id=mock_task.context_id, ) ), ) @@ -1050,7 +1050,7 @@ async def test_on_get_push_notification(self) -> None: # Create request handler without a push notifier request_handler = AsyncMock(spec=DefaultRequestHandler) task_push_config = TaskPushNotificationConfig( - taskId=mock_task.id, + task_id=mock_task.id, pushNotificationConfig=PushNotificationConfig( id='config1', url='http://example.com' ), @@ -1060,13 +1060,13 @@ async def test_on_get_push_notification(self) -> None: ) self.mock_agent_card.capabilities = AgentCapabilities( - pushNotifications=True + push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) list_request = GetTaskPushNotificationConfigRequest( id='1', params=GetTaskPushNotificationConfigParams( - id=mock_task.id, pushNotificationConfigId='config1' + id=mock_task.id, push_notification_config_id='config1' ), ) response = await handler.get_push_notification_config(list_request) @@ -1086,7 +1086,7 @@ async def test_on_list_push_notification(self) -> None: # Create request handler without a push notifier request_handler = AsyncMock(spec=DefaultRequestHandler) task_push_config = TaskPushNotificationConfig( - taskId=mock_task.id, + task_id=mock_task.id, pushNotificationConfig=PushNotificationConfig( url='http://example.com' ), @@ -1096,7 +1096,7 @@ async def test_on_list_push_notification(self) -> None: ] self.mock_agent_card.capabilities = AgentCapabilities( - pushNotifications=True + push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) list_request = ListTaskPushNotificationConfigRequest( @@ -1119,7 +1119,7 @@ async def test_on_list_push_notification_error(self) -> None: # Create request handler without a push notifier request_handler = AsyncMock(spec=DefaultRequestHandler) task_push_config = TaskPushNotificationConfig( - taskId=mock_task.id, + task_id=mock_task.id, pushNotificationConfig=PushNotificationConfig( url='http://example.com' ), @@ -1130,7 +1130,7 @@ async def test_on_list_push_notification_error(self) -> None: ) self.mock_agent_card.capabilities = AgentCapabilities( - pushNotifications=True + push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) list_request = ListTaskPushNotificationConfigRequest( @@ -1151,13 +1151,13 @@ async def test_on_delete_push_notification(self) -> None: ) self.mock_agent_card.capabilities = AgentCapabilities( - pushNotifications=True + push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) delete_request = DeleteTaskPushNotificationConfigRequest( id='1', params=DeleteTaskPushNotificationConfigParams( - id='task1', pushNotificationConfigId='config1' + id='task1', push_notification_config_id='config1' ), ) response = await handler.delete_push_notification_config(delete_request) @@ -1178,13 +1178,13 @@ async def test_on_delete_push_notification_error(self) -> None: ) self.mock_agent_card.capabilities = AgentCapabilities( - pushNotifications=True + push_notifications=True ) handler = JSONRPCHandler(self.mock_agent_card, request_handler) delete_request = DeleteTaskPushNotificationConfigRequest( id='1', params=DeleteTaskPushNotificationConfigParams( - id='task1', pushNotificationConfigId='config1' + id='task1', push_notification_config_id='config1' ), ) response = await handler.delete_push_notification_config(delete_request) diff --git a/tests/server/request_handlers/test_response_helpers.py b/tests/server/request_handlers/test_response_helpers.py index e61690f1..96e79e51 100644 --- a/tests/server/request_handlers/test_response_helpers.py +++ b/tests/server/request_handlers/test_response_helpers.py @@ -96,7 +96,7 @@ def test_build_error_response_with_request_id_none(self): def _create_sample_task(self, task_id='task123', context_id='ctx456'): return Task( id=task_id, - contextId=context_id, + context_id=context_id, status=TaskStatus(state=TaskState.submitted), history=[], ) diff --git a/tests/server/tasks/test_database_push_notification_config_store.py b/tests/server/tasks/test_database_push_notification_config_store.py index 95222558..3448bee9 100644 --- a/tests/server/tasks/test_database_push_notification_config_store.py +++ b/tests/server/tasks/test_database_push_notification_config_store.py @@ -84,7 +84,7 @@ ) MINIMAL_TASK_OBJ = Task( id='task-abc', - contextId='session-xyz', + context_id='session-xyz', status=task_status_submitted, kind='task', metadata={'test_key': 'test_value'}, diff --git a/tests/server/tasks/test_database_task_store.py b/tests/server/tasks/test_database_task_store.py index 993b3636..87069be4 100644 --- a/tests/server/tasks/test_database_task_store.py +++ b/tests/server/tasks/test_database_task_store.py @@ -76,7 +76,7 @@ ) MINIMAL_TASK_OBJ = Task( id='task-abc', - contextId='session-xyz', + context_id='session-xyz', status=task_status_submitted, kind='task', metadata={'test_key': 'test_value'}, @@ -166,7 +166,7 @@ async def test_get_task(db_store_parameterized: DatabaseTaskStore) -> None: retrieved_task = await db_store_parameterized.get(task_to_save.id) assert retrieved_task is not None assert retrieved_task.id == task_to_save.id - assert retrieved_task.contextId == task_to_save.contextId + assert retrieved_task.context_id == task_to_save.context_id assert retrieved_task.status.state == TaskState.submitted await db_store_parameterized.delete(task_to_save.id) # Cleanup @@ -212,7 +212,7 @@ async def test_save_and_get_detailed_task( task_id = f'detailed-task-{db_store_parameterized.engine.url.drivername}' test_task = Task( id=task_id, - contextId='test-session-1', + context_id='test-session-1', status=TaskStatus( state=TaskState.working, timestamp='2023-01-01T12:00:00Z' ), @@ -220,13 +220,13 @@ async def test_save_and_get_detailed_task( metadata={'key1': 'value1', 'key2': 123}, artifacts=[ Artifact( - artifactId='artifact-1', + artifact_id='artifact-1', parts=[Part(root=TextPart(text='hello'))], ) ], history=[ Message( - messageId='msg-1', + message_id='msg-1', role=Role.user, parts=[Part(root=TextPart(text='user input'))], ) @@ -238,7 +238,7 @@ async def test_save_and_get_detailed_task( assert retrieved_task is not None assert retrieved_task.id == test_task.id - assert retrieved_task.contextId == test_task.contextId + assert retrieved_task.context_id == test_task.context_id assert retrieved_task.status.state == TaskState.working assert retrieved_task.status.timestamp == '2023-01-01T12:00:00Z' assert retrieved_task.metadata == {'key1': 'value1', 'key2': 123} @@ -263,7 +263,7 @@ async def test_update_task(db_store_parameterized: DatabaseTaskStore) -> None: task_id = f'update-test-task-{db_store_parameterized.engine.url.drivername}' original_task = Task( id=task_id, - contextId='session-update', + context_id='session-update', status=TaskStatus( state=TaskState.submitted, timestamp='2023-01-02T10:00:00Z' ), @@ -310,7 +310,7 @@ async def test_metadata_field_mapping( # Test 1: Task with no metadata (None) task_no_metadata = Task( id='task-metadata-test-1', - contextId='session-meta-1', + context_id='session-meta-1', status=TaskStatus(state=TaskState.submitted), kind='task', metadata=None, @@ -326,7 +326,7 @@ async def test_metadata_field_mapping( simple_metadata = {'key': 'value', 'number': 42, 'boolean': True} task_simple_metadata = Task( id='task-metadata-test-2', - contextId='session-meta-2', + context_id='session-meta-2', status=TaskStatus(state=TaskState.working), kind='task', metadata=simple_metadata, @@ -351,7 +351,7 @@ async def test_metadata_field_mapping( } task_complex_metadata = Task( id='task-metadata-test-3', - contextId='session-meta-3', + context_id='session-meta-3', status=TaskStatus(state=TaskState.completed), kind='task', metadata=complex_metadata, @@ -364,7 +364,7 @@ async def test_metadata_field_mapping( # Test 4: Update metadata from None to dict task_update_metadata = Task( id='task-metadata-test-4', - contextId='session-meta-4', + context_id='session-meta-4', status=TaskStatus(state=TaskState.submitted), kind='task', metadata=None, diff --git a/tests/server/tasks/test_inmemory_push_notifications.py b/tests/server/tasks/test_inmemory_push_notifications.py index 7913952e..ed624e6c 100644 --- a/tests/server/tasks/test_inmemory_push_notifications.py +++ b/tests/server/tasks/test_inmemory_push_notifications.py @@ -20,7 +20,7 @@ def create_sample_task(task_id='task123', status_state=TaskState.completed): return Task( id=task_id, - contextId='ctx456', + context_id='ctx456', status=TaskStatus(state=status_state), ) diff --git a/tests/server/tasks/test_inmemory_task_store.py b/tests/server/tasks/test_inmemory_task_store.py index f5d9df1d..c41e3559 100644 --- a/tests/server/tasks/test_inmemory_task_store.py +++ b/tests/server/tasks/test_inmemory_task_store.py @@ -8,7 +8,7 @@ MINIMAL_TASK: dict[str, Any] = { 'id': 'task-abc', - 'contextId': 'session-xyz', + 'context_id': 'session-xyz', 'status': {'state': 'submitted'}, 'kind': 'task', } diff --git a/tests/server/tasks/test_push_notification_sender.py b/tests/server/tasks/test_push_notification_sender.py index 7f547cd0..88264181 100644 --- a/tests/server/tasks/test_push_notification_sender.py +++ b/tests/server/tasks/test_push_notification_sender.py @@ -19,7 +19,7 @@ def create_sample_task(task_id='task123', status_state=TaskState.completed): return Task( id=task_id, - contextId='ctx456', + context_id='ctx456', status=TaskStatus(state=status_state), ) diff --git a/tests/server/tasks/test_result_aggregator.py b/tests/server/tasks/test_result_aggregator.py index 025c940b..7ff5915e 100644 --- a/tests/server/tasks/test_result_aggregator.py +++ b/tests/server/tasks/test_result_aggregator.py @@ -24,7 +24,7 @@ def create_sample_message( content='test message', msg_id='msg1', role=Role.user ): return Message( - messageId=msg_id, + message_id=msg_id, role=role, parts=[Part(root=TextPart(text=content))], ) @@ -36,7 +36,7 @@ def create_sample_task( ): return Task( id=task_id, - contextId=context_id, + context_id=context_id, status=TaskStatus(state=status_state), ) @@ -46,8 +46,8 @@ def create_sample_status_update( task_id='task1', status_state=TaskState.working, context_id='ctx1' ): return TaskStatusUpdateEvent( - taskId=task_id, - contextId=context_id, + task_id=task_id, + context_id=context_id, status=TaskStatus(state=status_state), final=False, # Typically false unless it's the very last update ) diff --git a/tests/server/tasks/test_task_manager.py b/tests/server/tasks/test_task_manager.py index 0f32864b..4f243157 100644 --- a/tests/server/tasks/test_task_manager.py +++ b/tests/server/tasks/test_task_manager.py @@ -22,7 +22,7 @@ MINIMAL_TASK: dict[str, Any] = { 'id': 'task-abc', - 'contextId': 'session-xyz', + 'context_id': 'session-xyz', 'status': {'state': 'submitted'}, 'kind': 'task', } @@ -39,7 +39,7 @@ def task_manager(mock_task_store: AsyncMock) -> TaskManager: """Fixture for a TaskManager with a mock TaskStore.""" return TaskManager( task_id=MINIMAL_TASK['id'], - context_id=MINIMAL_TASK['contextId'], + context_id=MINIMAL_TASK['context_id'], task_store=mock_task_store, initial_message=None, ) @@ -104,12 +104,12 @@ async def test_save_task_event_status_update( message=Message( role=Role.agent, parts=[Part(TextPart(text='content'))], - messageId='message-id', + message_id='message-id', ), ) event = TaskStatusUpdateEvent( - taskId=MINIMAL_TASK['id'], - contextId=MINIMAL_TASK['contextId'], + task_id=MINIMAL_TASK['id'], + context_id=MINIMAL_TASK['context_id'], status=new_status, final=False, ) @@ -127,13 +127,13 @@ async def test_save_task_event_artifact_update( initial_task = Task(**MINIMAL_TASK) mock_task_store.get.return_value = initial_task new_artifact = Artifact( - artifactId='artifact-id', + artifact_id='artifact-id', name='artifact1', parts=[Part(TextPart(text='content'))], ) event = TaskArtifactUpdateEvent( - taskId=MINIMAL_TASK['id'], - contextId=MINIMAL_TASK['contextId'], + task_id=MINIMAL_TASK['id'], + context_id=MINIMAL_TASK['context_id'], artifact=new_artifact, ) await task_manager.save_task_event(event) @@ -152,8 +152,8 @@ async def test_save_task_event_metadata_update( new_metadata = {'meta_key_test': 'meta_value_test'} event = TaskStatusUpdateEvent( - taskId=MINIMAL_TASK['id'], - contextId=MINIMAL_TASK['contextId'], + task_id=MINIMAL_TASK['id'], + context_id=MINIMAL_TASK['context_id'], metadata=new_metadata, status=TaskStatus(state=TaskState.working), final=False, @@ -172,8 +172,8 @@ async def test_ensure_task_existing( expected_task = Task(**MINIMAL_TASK) mock_task_store.get.return_value = expected_task event = TaskStatusUpdateEvent( - taskId=MINIMAL_TASK['id'], - contextId=MINIMAL_TASK['contextId'], + task_id=MINIMAL_TASK['id'], + context_id=MINIMAL_TASK['context_id'], status=TaskStatus(state=TaskState.working), final=False, ) @@ -195,14 +195,14 @@ async def test_ensure_task_nonexistent( initial_message=None, ) event = TaskStatusUpdateEvent( - taskId='new-task', - contextId='some-context', + task_id='new-task', + context_id='some-context', status=TaskStatus(state=TaskState.submitted), final=False, ) new_task = await task_manager_without_id.ensure_task(event) assert new_task.id == 'new-task' - assert new_task.contextId == 'some-context' + assert new_task.context_id == 'some-context' assert new_task.status.state == TaskState.submitted mock_task_store.save.assert_called_once_with(new_task) assert task_manager_without_id.task_id == 'new-task' @@ -213,7 +213,7 @@ def test_init_task_obj(task_manager: TaskManager) -> None: """Test initializing a new task object.""" new_task = task_manager._init_task_obj('new-task', 'new-context') # type: ignore assert new_task.id == 'new-task' - assert new_task.contextId == 'new-context' + assert new_task.context_id == 'new-context' assert new_task.status.state == TaskState.submitted assert new_task.history == [] @@ -236,7 +236,7 @@ async def test_save_task_event_mismatched_id_raises_error( # The task_manager is initialized with 'task-abc' mismatched_task = Task( id='wrong-id', - contextId='session-xyz', + context_id='session-xyz', status=TaskStatus(state=TaskState.submitted), ) @@ -258,7 +258,7 @@ async def test_save_task_event_new_task_no_task_id( ) task_data: dict[str, Any] = { 'id': 'new-task-id', - 'contextId': 'some-context', + 'context_id': 'some-context', 'status': {'state': 'working'}, 'kind': 'task', } @@ -300,8 +300,8 @@ async def test_save_task_event_no_task_existing( ) mock_task_store.get.return_value = None event = TaskStatusUpdateEvent( - taskId='event-task-id', - contextId='some-context', + task_id='event-task-id', + context_id='some-context', status=TaskStatus(state=TaskState.completed), final=True, ) @@ -311,7 +311,7 @@ async def test_save_task_event_no_task_existing( assert call_args is not None saved_task = call_args[0][0] assert saved_task.id == 'event-task-id' - assert saved_task.contextId == 'some-context' + assert saved_task.context_id == 'some-context' assert saved_task.status.state == TaskState.completed assert task_manager_without_id.task_id == 'event-task-id' assert task_manager_without_id.context_id == 'some-context' diff --git a/tests/server/tasks/test_task_updater.py b/tests/server/tasks/test_task_updater.py index 1a633e6a..7e1b089a 100644 --- a/tests/server/tasks/test_task_updater.py +++ b/tests/server/tasks/test_task_updater.py @@ -38,9 +38,9 @@ def sample_message(): """Create a sample message for testing.""" return Message( role=Role.agent, - taskId='test-task-id', - contextId='test-context-id', - messageId='test-message-id', + task_id='test-task-id', + context_id='test-context-id', + message_id='test-message-id', parts=[Part(root=TextPart(text='Test message'))], ) @@ -73,8 +73,8 @@ async def test_update_status_without_message(task_updater, event_queue): event = event_queue.enqueue_event.call_args[0][0] assert isinstance(event, TaskStatusUpdateEvent) - assert event.taskId == 'test-task-id' - assert event.contextId == 'test-context-id' + assert event.task_id == 'test-task-id' + assert event.context_id == 'test-context-id' assert event.final is False assert event.status.state == TaskState.working assert event.status.message is None @@ -91,8 +91,8 @@ async def test_update_status_with_message( event = event_queue.enqueue_event.call_args[0][0] assert isinstance(event, TaskStatusUpdateEvent) - assert event.taskId == 'test-task-id' - assert event.contextId == 'test-context-id' + assert event.task_id == 'test-task-id' + assert event.context_id == 'test-context-id' assert event.final is False assert event.status.state == TaskState.working assert event.status.message == sample_message @@ -126,7 +126,7 @@ async def test_add_artifact_with_custom_id_and_name( event = event_queue.enqueue_event.call_args[0][0] assert isinstance(event, TaskArtifactUpdateEvent) - assert event.artifact.artifactId == 'custom-artifact-id' + assert event.artifact.artifact_id == 'custom-artifact-id' assert event.artifact.name == 'Custom Artifact' assert event.artifact.parts == sample_parts @@ -144,10 +144,10 @@ async def test_add_artifact_generates_id( event = event_queue.enqueue_event.call_args[0][0] assert isinstance(event, TaskArtifactUpdateEvent) - assert event.artifact.artifactId == str(known_uuid) + assert event.artifact.artifact_id == str(known_uuid) assert event.artifact.parts == sample_parts assert event.append == None - assert event.lastChunk == None + assert event.last_chunk == None @pytest.mark.asyncio @@ -175,10 +175,10 @@ async def test_add_artifact_with_append_last_chunk( event = event_queue.enqueue_event.call_args[0][0] assert isinstance(event, TaskArtifactUpdateEvent) - assert event.artifact.artifactId == 'id1' + assert event.artifact.artifact_id == 'id1' assert event.artifact.parts == sample_parts assert event.append == append_val - assert event.lastChunk == last_chunk_val + assert event.last_chunk == last_chunk_val @pytest.mark.asyncio @@ -276,9 +276,9 @@ def test_new_agent_message(task_updater, sample_parts): message = task_updater.new_agent_message(parts=sample_parts) assert message.role == Role.agent - assert message.taskId == 'test-task-id' - assert message.contextId == 'test-context-id' - assert message.messageId == '12345678-1234-5678-1234-567812345678' + assert message.task_id == 'test-task-id' + assert message.context_id == 'test-context-id' + assert message.message_id == '12345678-1234-5678-1234-567812345678' assert message.parts == sample_parts assert message.metadata is None @@ -296,9 +296,9 @@ def test_new_agent_message_with_metadata(task_updater, sample_parts): ) assert message.role == Role.agent - assert message.taskId == 'test-task-id' - assert message.contextId == 'test-context-id' - assert message.messageId == '12345678-1234-5678-1234-567812345678' + assert message.task_id == 'test-task-id' + assert message.context_id == 'test-context-id' + assert message.message_id == '12345678-1234-5678-1234-567812345678' assert message.parts == sample_parts assert message.metadata == metadata diff --git a/tests/server/test_integration.py b/tests/server/test_integration.py index 5581711e..a099eb7c 100644 --- a/tests/server/test_integration.py +++ b/tests/server/test_integration.py @@ -59,7 +59,7 @@ MINIMAL_AGENT_AUTH: dict[str, Any] = {'schemes': ['Bearer']} AGENT_CAPS = AgentCapabilities( - pushNotifications=True, stateTransitionHistory=False, streaming=True + push_notifications=True, state_transition_history=False, streaming=True ) MINIMAL_AGENT_CARD: dict[str, Any] = { @@ -95,7 +95,7 @@ MINIMAL_MESSAGE_USER: dict[str, Any] = { 'role': 'user', 'parts': [TEXT_PART_DATA], - 'messageId': 'msg-123', + 'message_id': 'msg-123', 'kind': 'message', } @@ -160,7 +160,7 @@ def test_authenticated_extended_agent_card_endpoint_not_supported( ): """Test extended card endpoint returns 404 if not supported by main card.""" # Ensure supportsAuthenticatedExtendedCard is False or None - agent_card.supportsAuthenticatedExtendedCard = False + agent_card.supports_authenticated_extended_card = False app_instance = A2AStarletteApplication(agent_card, handler) # The route should not even be added if supportsAuthenticatedExtendedCard is false # So, building the app and trying to hit it should result in 404 from Starlette itself @@ -174,7 +174,7 @@ def test_authenticated_extended_agent_card_endpoint_not_supported_fastapi( ): """Test extended card endpoint returns 404 if not supported by main card.""" # Ensure supportsAuthenticatedExtendedCard is False or None - agent_card.supportsAuthenticatedExtendedCard = False + agent_card.supports_authenticated_extended_card = False app_instance = A2AFastAPIApplication(agent_card, handler) # The route should not even be added if supportsAuthenticatedExtendedCard is false # So, building the app and trying to hit it should result in 404 from FastAPI itself @@ -189,7 +189,7 @@ def test_authenticated_extended_agent_card_endpoint_supported_with_specific_exte handler: mock.AsyncMock, ): """Test extended card endpoint returns the specific extended card when provided.""" - agent_card.supportsAuthenticatedExtendedCard = ( + agent_card.supports_authenticated_extended_card = ( True # Main card must support it ) print(agent_card) @@ -216,7 +216,7 @@ def test_authenticated_extended_agent_card_endpoint_supported_with_specific_exte handler: mock.AsyncMock, ): """Test extended card endpoint returns the specific extended card when provided.""" - agent_card.supportsAuthenticatedExtendedCard = ( + agent_card.supports_authenticated_extended_card = ( True # Main card must support it ) app_instance = A2AFastAPIApplication( @@ -254,7 +254,7 @@ def test_starlette_rpc_endpoint_custom_url( # Provide a valid Task object as the return value task_status = TaskStatus(**MINIMAL_TASK_STATUS) task = Task( - id='task1', contextId='ctx1', state='completed', status=task_status + id='task1', context_id='ctx1', state='completed', status=task_status ) handler.on_get_task.return_value = task client = TestClient(app.build(rpc_url='/api/rpc')) @@ -279,7 +279,7 @@ def test_fastapi_rpc_endpoint_custom_url( # Provide a valid Task object as the return value task_status = TaskStatus(**MINIMAL_TASK_STATUS) task = Task( - id='task1', contextId='ctx1', state='completed', status=task_status + id='task1', context_id='ctx1', state='completed', status=task_status ) handler.on_get_task.return_value = task client = TestClient(app.build(rpc_url='/api/rpc')) @@ -354,7 +354,7 @@ def test_send_message(client: TestClient, handler: mock.AsyncMock): task_status = TaskStatus(**MINIMAL_TASK_STATUS) mock_task = Task( id='task1', - contextId='session-xyz', + context_id='session-xyz', status=task_status, ) handler.on_message_send.return_value = mock_task @@ -370,10 +370,10 @@ def test_send_message(client: TestClient, handler: mock.AsyncMock): 'message': { 'role': 'agent', 'parts': [{'kind': 'text', 'text': 'Hello'}], - 'messageId': '111', + 'message_id': '111', 'kind': 'message', - 'taskId': 'task1', - 'contextId': 'session-xyz', + 'task_id': 'task1', + 'context_id': 'session-xyz', } }, }, @@ -396,7 +396,7 @@ def test_cancel_task(client: TestClient, handler: mock.AsyncMock): task_status = TaskStatus(**MINIMAL_TASK_STATUS) task_status.state = TaskState.canceled # 'cancelled' # task = Task( - id='task1', contextId='ctx1', state='cancelled', status=task_status + id='task1', context_id='ctx1', state='cancelled', status=task_status ) handler.on_cancel_task.return_value = task @@ -426,7 +426,7 @@ def test_get_task(client: TestClient, handler: mock.AsyncMock): # Setup mock response task_status = TaskStatus(**MINIMAL_TASK_STATUS) task = Task( - id='task1', contextId='ctx1', state='completed', status=task_status + id='task1', context_id='ctx1', state='completed', status=task_status ) handler.on_get_task.return_value = task # JSONRPCResponse(root=task) @@ -456,7 +456,7 @@ def test_set_push_notification_config( """Test setting push notification configuration.""" # Setup mock response task_push_config = TaskPushNotificationConfig( - taskId='t2', + task_id='t2', pushNotificationConfig=PushNotificationConfig( url='https://example.com', token='secret-token' ), @@ -471,7 +471,7 @@ def test_set_push_notification_config( 'id': '123', 'method': 'tasks/pushNotificationConfig/set', 'params': { - 'taskId': 't2', + 'task_id': 't2', 'pushNotificationConfig': { 'url': 'https://example.com', 'token': 'secret-token', @@ -495,8 +495,8 @@ def test_get_push_notification_config( """Test getting push notification configuration.""" # Setup mock response task_push_config = TaskPushNotificationConfig( - taskId='task1', - pushNotificationConfig=PushNotificationConfig( + task_id='task1', + push_notification_config=PushNotificationConfig( url='https://example.com', token='secret-token' ), ) @@ -543,8 +543,8 @@ async def authenticate( # Set the output message to be the authenticated user name handler.on_message_send.side_effect = lambda params, context: Message( - contextId='session-xyz', - messageId='112', + context_id='session-xyz', + message_id='112', role=Role.agent, parts=[ Part(TextPart(text=context.user.user_name)), @@ -562,10 +562,10 @@ async def authenticate( 'message': { 'role': 'agent', 'parts': [{'kind': 'text', 'text': 'Hello'}], - 'messageId': '111', + 'message_id': '111', 'kind': 'message', - 'taskId': 'task1', - 'contextId': 'session-xyz', + 'task_id': 'task1', + 'context_id': 'session-xyz', } }, }, @@ -599,15 +599,15 @@ async def stream_generator(): text_part = TextPart(**TEXT_PART_DATA) data_part = DataPart(**DATA_PART_DATA) artifact = Artifact( - artifactId=f'artifact-{i}', + artifact_id=f'artifact-{i}', name='result_data', parts=[Part(root=text_part), Part(root=data_part)], ) last = [False, False, True] task_artifact_update_event_data: dict[str, Any] = { 'artifact': artifact, - 'taskId': 'task_id', - 'contextId': 'session-xyz', + 'task_id': 'task_id', + 'context_id': 'session-xyz', 'append': False, 'lastChunk': last[i], 'kind': 'artifact-update', @@ -635,10 +635,10 @@ async def stream_generator(): 'message': { 'role': 'agent', 'parts': [{'kind': 'text', 'text': 'Hello'}], - 'messageId': '111', + 'message_id': '111', 'kind': 'message', - 'taskId': 'taskId', - 'contextId': 'session-xyz', + 'task_id': 'task_id', + 'context_id': 'session-xyz', } }, }, @@ -689,15 +689,15 @@ async def stream_generator(): text_part = TextPart(**TEXT_PART_DATA) data_part = DataPart(**DATA_PART_DATA) artifact = Artifact( - artifactId=f'artifact-{i}', + artifact_id=f'artifact-{i}', name='result_data', parts=[Part(root=text_part), Part(root=data_part)], ) last = [False, False, True] task_artifact_update_event_data: dict[str, Any] = { 'artifact': artifact, - 'taskId': 'task_id', - 'contextId': 'session-xyz', + 'task_id': 'task_id', + 'context_id': 'session-xyz', 'append': False, 'lastChunk': last[i], 'kind': 'artifact-update', @@ -749,7 +749,7 @@ async def stream_generator(): b'"artifactId":"artifact-0"' in content ) # Check for the actual JSON payload assert ( - b'"artifactId":"artifact-1"' in content + b'"artifact_id":"artifact-1"' in content ) # Check for the actual JSON payload assert ( b'"artifactId":"artifact-2"' in content diff --git a/tests/test_types.py b/tests/test_types.py index 1bae000d..b406f4b7 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -124,7 +124,7 @@ MINIMAL_MESSAGE_USER: dict[str, Any] = { 'role': 'user', 'parts': [TEXT_PART_DATA], - 'messageId': 'msg-123', + 'message_id': 'msg-123', 'kind': 'message', } @@ -132,7 +132,7 @@ 'role': 'agent', 'parts': [TEXT_PART_DATA, FILE_URI_PART_DATA], 'metadata': {'timestamp': 'now'}, - 'messageId': 'msg-456', + 'message_id': 'msg-456', } MINIMAL_TASK_STATUS: dict[str, Any] = {'state': 'submitted'} @@ -144,13 +144,13 @@ MINIMAL_TASK: dict[str, Any] = { 'id': 'task-abc', - 'contextId': 'session-xyz', + 'context_id': 'session-xyz', 'status': MINIMAL_TASK_STATUS, 'kind': 'task', } FULL_TASK: dict[str, Any] = { 'id': 'task-abc', - 'contextId': 'session-xyz', + 'context_id': 'session-xyz', 'status': FULL_TASK_STATUS, 'history': [MINIMAL_MESSAGE_USER, AGENT_MESSAGE_WITH_FILE], 'artifacts': [ @@ -201,17 +201,17 @@ def test_security_scheme_invalid(): def test_agent_capabilities(): caps = AgentCapabilities( - streaming=None, stateTransitionHistory=None, pushNotifications=None + streaming=None, state_transition_history=None, push_notifications=None ) # All optional - assert caps.pushNotifications is None - assert caps.stateTransitionHistory is None + assert caps.push_notifications is None + assert caps.state_transition_history is None assert caps.streaming is None caps_full = AgentCapabilities( - pushNotifications=True, stateTransitionHistory=False, streaming=True + push_notifications=True, state_transition_history=False, streaming=True ) - assert caps_full.pushNotifications is True - assert caps_full.stateTransitionHistory is False + assert caps_full.push_notifications is True + assert caps_full.state_transition_history is False assert caps_full.streaming is True @@ -234,7 +234,7 @@ def test_agent_skill_valid(): skill_full = AgentSkill(**FULL_AGENT_SKILL) assert skill_full.examples == ['Find me a pasta recipe'] - assert skill_full.inputModes == ['text/plain'] + assert skill_full.input_modes == ['text/plain'] def test_agent_skill_invalid(): @@ -286,12 +286,12 @@ def test_text_part(): def test_file_part_variants(): # URI variant file_uri = FileWithUri( - uri='file:///path/to/file.txt', mimeType='text/plain' + uri='file:///path/to/file.txt', mime_type='text/plain' ) part_uri = FilePart(kind='file', file=file_uri) assert isinstance(part_uri.file, FileWithUri) assert part_uri.file.uri == 'file:///path/to/file.txt' - assert part_uri.file.mimeType == 'text/plain' + assert part_uri.file.mime_type == 'text/plain' assert not hasattr(part_uri.file, 'bytes') # Bytes variant @@ -392,7 +392,7 @@ def test_task_status(): def test_task(): task = Task(**MINIMAL_TASK) assert task.id == 'task-abc' - assert task.contextId == 'session-xyz' + assert task.context_id == 'session-xyz' assert task.status.state == TaskState.submitted assert task.history is None assert task.artifacts is None @@ -535,7 +535,7 @@ def test_send_subscribe_request() -> None: def test_get_task_request() -> None: - params = TaskQueryParams(id='task-1', historyLength=2) + params = TaskQueryParams(id='task-1', history_length=2) req_data: dict[str, Any] = { 'jsonrpc': '2.0', 'method': 'tasks/get', @@ -546,7 +546,7 @@ def test_get_task_request() -> None: assert req.method == 'tasks/get' assert isinstance(req.params, TaskQueryParams) assert req.params.id == 'task-1' - assert req.params.historyLength == 2 + assert req.params.history_length == 2 with pytest.raises(ValidationError): # Wrong method literal GetTaskRequest.model_validate({**req_data, 'method': 'wrong/method'}) @@ -655,7 +655,7 @@ def test_send_message_streaming_status_update_response() -> None: task_status_update_event_data: dict[str, Any] = { 'status': MINIMAL_TASK_STATUS, 'taskId': '1', - 'contextId': '2', + 'context_id': '2', 'final': False, 'kind': 'status-update', } @@ -670,7 +670,7 @@ def test_send_message_streaming_status_update_response() -> None: assert isinstance(response.root, SendStreamingMessageSuccessResponse) assert isinstance(response.root.result, TaskStatusUpdateEvent) assert response.root.result.status.state == TaskState.submitted - assert response.root.result.taskId == '1' + assert response.root.result.task_id == '1' assert not response.root.result.final with pytest.raises( @@ -707,14 +707,14 @@ def test_send_message_streaming_artifact_update_response() -> None: text_part = TextPart(**TEXT_PART_DATA) data_part = DataPart(**DATA_PART_DATA) artifact = Artifact( - artifactId='artifact-123', + artifact_id='artifact-123', name='result_data', parts=[Part(root=text_part), Part(root=data_part)], ) task_artifact_update_event_data: dict[str, Any] = { 'artifact': artifact, 'taskId': 'task_id', - 'contextId': '2', + 'context_id': '2', 'append': False, 'lastChunk': True, 'kind': 'artifact-update', @@ -728,11 +728,11 @@ def test_send_message_streaming_artifact_update_response() -> None: assert response.root.id == 1 assert isinstance(response.root, SendStreamingMessageSuccessResponse) assert isinstance(response.root.result, TaskArtifactUpdateEvent) - assert response.root.result.artifact.artifactId == 'artifact-123' + assert response.root.result.artifact.artifact_id == 'artifact-123' assert response.root.result.artifact.name == 'result_data' - assert response.root.result.taskId == 'task_id' + assert response.root.result.task_id == 'task_id' assert not response.root.result.append - assert response.root.result.lastChunk + assert response.root.result.last_chunk assert len(response.root.result.artifact.parts) == 2 assert isinstance(response.root.result.artifact.parts[0].root, TextPart) assert isinstance(response.root.result.artifact.parts[1].root, DataPart) @@ -740,7 +740,7 @@ def test_send_message_streaming_artifact_update_response() -> None: def test_set_task_push_notification_response() -> None: task_push_config = TaskPushNotificationConfig( - taskId='t2', + task_id='t2', pushNotificationConfig=PushNotificationConfig( url='https://example.com', token='token' ), @@ -754,16 +754,18 @@ def test_set_task_push_notification_response() -> None: assert resp.root.id == 1 assert isinstance(resp.root, SetTaskPushNotificationConfigSuccessResponse) assert isinstance(resp.root.result, TaskPushNotificationConfig) - assert resp.root.result.taskId == 't2' - assert resp.root.result.pushNotificationConfig.url == 'https://example.com' - assert resp.root.result.pushNotificationConfig.token == 'token' - assert resp.root.result.pushNotificationConfig.authentication is None + assert resp.root.result.task_id == 't2' + assert ( + resp.root.result.push_notification_config.url == 'https://example.com' + ) + assert resp.root.result.push_notification_config.token == 'token' + assert resp.root.result.push_notification_config.authentication is None auth_info_dict: dict[str, Any] = { 'schemes': ['Bearer', 'Basic'], 'credentials': 'user:pass', } - task_push_config.pushNotificationConfig.authentication = ( + task_push_config.push_notification_config.authentication = ( PushNotificationAuthenticationInfo(**auth_info_dict) ) resp_data = { @@ -773,13 +775,13 @@ def test_set_task_push_notification_response() -> None: } resp = SetTaskPushNotificationConfigResponse.model_validate(resp_data) assert isinstance(resp.root, SetTaskPushNotificationConfigSuccessResponse) - assert resp.root.result.pushNotificationConfig.authentication is not None - assert resp.root.result.pushNotificationConfig.authentication.schemes == [ + assert resp.root.result.push_notification_config.authentication is not None + assert resp.root.result.push_notification_config.authentication.schemes == [ 'Bearer', 'Basic', ] assert ( - resp.root.result.pushNotificationConfig.authentication.credentials + resp.root.result.push_notification_config.authentication.credentials == 'user:pass' ) @@ -799,7 +801,7 @@ def test_set_task_push_notification_response() -> None: def test_get_task_push_notification_response() -> None: task_push_config = TaskPushNotificationConfig( - taskId='t2', + task_id='t2', pushNotificationConfig=PushNotificationConfig( url='https://example.com', token='token' ), @@ -813,16 +815,18 @@ def test_get_task_push_notification_response() -> None: assert resp.root.id == 1 assert isinstance(resp.root, GetTaskPushNotificationConfigSuccessResponse) assert isinstance(resp.root.result, TaskPushNotificationConfig) - assert resp.root.result.taskId == 't2' - assert resp.root.result.pushNotificationConfig.url == 'https://example.com' - assert resp.root.result.pushNotificationConfig.token == 'token' - assert resp.root.result.pushNotificationConfig.authentication is None + assert resp.root.result.task_id == 't2' + assert ( + resp.root.result.push_notification_config.url == 'https://example.com' + ) + assert resp.root.result.push_notification_config.token == 'token' + assert resp.root.result.push_notification_config.authentication is None auth_info_dict: dict[str, Any] = { 'schemes': ['Bearer', 'Basic'], 'credentials': 'user:pass', } - task_push_config.pushNotificationConfig.authentication = ( + task_push_config.push_notification_config.authentication = ( PushNotificationAuthenticationInfo(**auth_info_dict) ) resp_data = { @@ -832,13 +836,13 @@ def test_get_task_push_notification_response() -> None: } resp = GetTaskPushNotificationConfigResponse.model_validate(resp_data) assert isinstance(resp.root, GetTaskPushNotificationConfigSuccessResponse) - assert resp.root.result.pushNotificationConfig.authentication is not None - assert resp.root.result.pushNotificationConfig.authentication.schemes == [ + assert resp.root.result.push_notification_config.authentication is not None + assert resp.root.result.push_notification_config.authentication.schemes == [ 'Bearer', 'Basic', ] assert ( - resp.root.result.pushNotificationConfig.authentication.credentials + resp.root.result.push_notification_config.authentication.credentials == 'user:pass' ) @@ -909,7 +913,7 @@ def test_a2a_request_root_model() -> None: # SetTaskPushNotificationConfigRequest task_push_config = TaskPushNotificationConfig( - taskId='t2', + task_id='t2', pushNotificationConfig=PushNotificationConfig( url='https://example.com', token='token' ), @@ -1017,7 +1021,7 @@ def test_a2a_request_root_model_id_validation() -> None: # SetTaskPushNotificationConfigRequest task_push_config = TaskPushNotificationConfig( - taskId='t2', + task_id='t2', pushNotificationConfig=PushNotificationConfig( url='https://example.com', token='token' ), @@ -1026,7 +1030,7 @@ def test_a2a_request_root_model_id_validation() -> None: 'jsonrpc': '2.0', 'method': 'tasks/pushNotificationConfig/set', 'params': task_push_config.model_dump(), - 'taskId': 2, + 'task_id': 2, } with pytest.raises(ValidationError): A2ARequest.model_validate(set_push_notif_req_data) # missing id @@ -1037,7 +1041,7 @@ def test_a2a_request_root_model_id_validation() -> None: 'jsonrpc': '2.0', 'method': 'tasks/pushNotificationConfig/get', 'params': id_params.model_dump(), - 'taskId': 2, + 'task_id': 2, } with pytest.raises(ValidationError): A2ARequest.model_validate(get_push_notif_req_data) @@ -1300,11 +1304,11 @@ def test_task_push_notification_config() -> None: assert push_notification_config.authentication == auth_info task_push_notification_config = TaskPushNotificationConfig( - taskId='task-123', pushNotificationConfig=push_notification_config + task_id='task-123', pushNotificationConfig=push_notification_config ) - assert task_push_notification_config.taskId == 'task-123' + assert task_push_notification_config.task_id == 'task-123' assert ( - task_push_notification_config.pushNotificationConfig + task_push_notification_config.push_notification_config == push_notification_config ) assert task_push_notification_config.model_dump(exclude_none=True) == { @@ -1356,22 +1360,22 @@ def test_file_base_valid(): """Tests successful validation of FileBase.""" # No optional fields base1 = FileBase() - assert base1.mimeType is None + assert base1.mime_type is None assert base1.name is None - # With mimeType only - base2 = FileBase(mimeType='image/png') - assert base2.mimeType == 'image/png' + # With mime_type only + base2 = FileBase(mime_type='image/png') + assert base2.mime_type == 'image/png' assert base2.name is None # With name only base3 = FileBase(name='document.pdf') - assert base3.mimeType is None + assert base3.mime_type is None assert base3.name == 'document.pdf' # With both fields - base4 = FileBase(mimeType='application/json', name='data.json') - assert base4.mimeType == 'application/json' + base4 = FileBase(mime_type='application/json', name='data.json') + assert base4.mime_type == 'application/json' assert base4.name == 'data.json' @@ -1379,10 +1383,10 @@ def test_file_base_invalid(): """Tests validation errors for FileBase.""" FileBase(extra_field='allowed') # type: ignore - # Incorrect type for mimeType + # Incorrect type for mime_type with pytest.raises(ValidationError) as excinfo_type_mime: - FileBase(mimeType=123) # type: ignore - assert 'mimeType' in str(excinfo_type_mime.value) + FileBase(mime_type=123) # type: ignore + assert 'mime_type' in str(excinfo_type_mime.value) # Incorrect type for name with pytest.raises(ValidationError) as excinfo_type_name: diff --git a/tests/utils/test_artifact.py b/tests/utils/test_artifact.py index 03a04d2c..132d0567 100644 --- a/tests/utils/test_artifact.py +++ b/tests/utils/test_artifact.py @@ -17,7 +17,7 @@ def test_new_artifact_generates_id(self, mock_uuid4): mock_uuid = uuid.UUID('abcdef12-1234-5678-1234-567812345678') mock_uuid4.return_value = mock_uuid artifact = new_artifact(parts=[], name='test_artifact') - self.assertEqual(artifact.artifactId, str(mock_uuid)) + self.assertEqual(artifact.artifact_id, str(mock_uuid)) def test_new_artifact_assigns_parts_name_description(self): parts = [Part(root=TextPart(text='Sample text'))] diff --git a/tests/utils/test_helpers.py b/tests/utils/test_helpers.py index 16469a02..28acd27c 100644 --- a/tests/utils/test_helpers.py +++ b/tests/utils/test_helpers.py @@ -32,7 +32,7 @@ MINIMAL_MESSAGE_USER: dict[str, Any] = { 'role': 'user', 'parts': [TEXT_PART_DATA], - 'messageId': 'msg-123', + 'message_id': 'msg-123', 'type': 'message', } @@ -40,7 +40,7 @@ MINIMAL_TASK: dict[str, Any] = { 'id': 'task-abc', - 'contextId': 'session-xyz', + 'context_id': 'session-xyz', 'status': MINIMAL_TASK_STATUS, 'type': 'task', } @@ -53,52 +53,52 @@ def test_create_task_obj(): task = create_task_obj(send_params) assert task.id is not None - assert task.contextId == message.contextId + assert task.context_id == message.context_id assert task.status.state == TaskState.submitted assert len(task.history) == 1 assert task.history[0] == message def test_create_task_obj_generates_context_id(): - """Test that create_task_obj generates contextId if not present and uses it for the task.""" - # Message without contextId + """Test that create_task_obj generates context_id if not present and uses it for the task.""" + # Message without context_id message_no_context_id = Message( role=Role.user, parts=[Part(root=TextPart(text='test'))], - messageId='msg-no-ctx', - taskId='task-from-msg', # Provide a taskId to differentiate from generated task.id + message_id='msg-no-ctx', + task_id='task-from-msg', # Provide a task_id to differentiate from generated task.id ) send_params = MessageSendParams(message=message_no_context_id) - # Ensure message.contextId is None initially - assert send_params.message.contextId is None + # Ensure message.context_id is None initially + assert send_params.message.context_id is None known_task_uuid = uuid.UUID('11111111-1111-1111-1111-111111111111') known_context_uuid = uuid.UUID('22222222-2222-2222-2222-222222222222') # Patch uuid.uuid4 to return specific UUIDs in sequence - # The first call will be for message.contextId (if None), the second for task.id. + # The first call will be for message.context_id (if None), the second for task.id. with patch( 'a2a.utils.helpers.uuid4', side_effect=[known_context_uuid, known_task_uuid], ) as mock_uuid4: task = create_task_obj(send_params) - # Assert that uuid4 was called twice (once for contextId, once for task.id) + # Assert that uuid4 was called twice (once for context_id, once for task.id) assert mock_uuid4.call_count == 2 - # Assert that message.contextId was set to the first generated UUID - assert send_params.message.contextId == str(known_context_uuid) + # Assert that message.context_id was set to the first generated UUID + assert send_params.message.context_id == str(known_context_uuid) - # Assert that task.contextId is the same generated UUID - assert task.contextId == str(known_context_uuid) + # Assert that task.context_id is the same generated UUID + assert task.context_id == str(known_context_uuid) # Assert that task.id is the second generated UUID assert task.id == str(known_task_uuid) - # Ensure the original message in history also has the updated contextId + # Ensure the original message in history also has the updated context_id assert len(task.history) == 1 - assert task.history[0].contextId == str(known_context_uuid) + assert task.history[0].context_id == str(known_context_uuid) # Test append_artifact_to_task @@ -106,7 +106,7 @@ def test_append_artifact_to_task(): # Prepare base task task = Task(**MINIMAL_TASK) assert task.id == 'task-abc' - assert task.contextId == 'session-xyz' + assert task.context_id == 'session-xyz' assert task.status.state == TaskState.submitted assert task.history is None assert task.artifacts is None @@ -114,42 +114,45 @@ def test_append_artifact_to_task(): # Prepare appending artifact and event artifact_1 = Artifact( - artifactId='artifact-123', parts=[Part(root=TextPart(text='Hello'))] + artifact_id='artifact-123', parts=[Part(root=TextPart(text='Hello'))] ) append_event_1 = TaskArtifactUpdateEvent( - artifact=artifact_1, append=False, taskId='123', contextId='123' + artifact=artifact_1, append=False, task_id='123', context_id='123' ) # Test adding a new artifact (not appending) append_artifact_to_task(task, append_event_1) assert len(task.artifacts) == 1 - assert task.artifacts[0].artifactId == 'artifact-123' + assert task.artifacts[0].artifact_id == 'artifact-123' assert task.artifacts[0].name is None assert len(task.artifacts[0].parts) == 1 assert task.artifacts[0].parts[0].root.text == 'Hello' # Test replacing the artifact artifact_2 = Artifact( - artifactId='artifact-123', + artifact_id='artifact-123', name='updated name', parts=[Part(root=TextPart(text='Updated'))], ) append_event_2 = TaskArtifactUpdateEvent( - artifact=artifact_2, append=False, taskId='123', contextId='123' + artifact=artifact_2, append=False, task_id='123', context_id='123' ) append_artifact_to_task(task, append_event_2) assert len(task.artifacts) == 1 # Should still have one artifact - assert task.artifacts[0].artifactId == 'artifact-123' + assert task.artifacts[0].artifact_id == 'artifact-123' assert task.artifacts[0].name == 'updated name' assert len(task.artifacts[0].parts) == 1 assert task.artifacts[0].parts[0].root.text == 'Updated' # Test appending parts to an existing artifact artifact_with_parts = Artifact( - artifactId='artifact-123', parts=[Part(root=TextPart(text='Part 2'))] + artifact_id='artifact-123', parts=[Part(root=TextPart(text='Part 2'))] ) append_event_3 = TaskArtifactUpdateEvent( - artifact=artifact_with_parts, append=True, taskId='123', contextId='123' + artifact=artifact_with_parts, + append=True, + task_id='123', + context_id='123', ) append_artifact_to_task(task, append_event_3) assert len(task.artifacts[0].parts) == 2 @@ -158,31 +161,31 @@ def test_append_artifact_to_task(): # Test adding another new artifact another_artifact_with_parts = Artifact( - artifactId='new_artifact', + artifact_id='new_artifact', parts=[Part(root=TextPart(text='new artifact Part 1'))], ) append_event_4 = TaskArtifactUpdateEvent( artifact=another_artifact_with_parts, append=False, - taskId='123', - contextId='123', + task_id='123', + context_id='123', ) append_artifact_to_task(task, append_event_4) assert len(task.artifacts) == 2 - assert task.artifacts[0].artifactId == 'artifact-123' - assert task.artifacts[1].artifactId == 'new_artifact' + assert task.artifacts[0].artifact_id == 'artifact-123' + assert task.artifacts[1].artifact_id == 'new_artifact' assert len(task.artifacts[0].parts) == 2 assert len(task.artifacts[1].parts) == 1 # Test appending part to a task that does not have a matching artifact non_existing_artifact_with_parts = Artifact( - artifactId='artifact-456', parts=[Part(root=TextPart(text='Part 1'))] + artifact_id='artifact-456', parts=[Part(root=TextPart(text='Part 1'))] ) append_event_5 = TaskArtifactUpdateEvent( artifact=non_existing_artifact_with_parts, append=True, - taskId='123', - contextId='123', + task_id='123', + context_id='123', ) append_artifact_to_task(task, append_event_5) assert len(task.artifacts) == 2 @@ -196,7 +199,7 @@ def test_build_text_artifact(): text = 'This is a sample text' artifact = build_text_artifact(text, artifact_id) - assert artifact.artifactId == artifact_id + assert artifact.artifact_id == artifact_id assert len(artifact.parts) == 1 assert artifact.parts[0].root.text == text diff --git a/tests/utils/test_message.py b/tests/utils/test_message.py index 86358b7f..3270eab7 100644 --- a/tests/utils/test_message.py +++ b/tests/utils/test_message.py @@ -38,9 +38,9 @@ def test_new_agent_text_message_basic(self): assert message.role == Role.agent assert len(message.parts) == 1 assert message.parts[0].root.text == text - assert message.messageId == '12345678-1234-5678-1234-567812345678' - assert message.taskId is None - assert message.contextId is None + assert message.message_id == '12345678-1234-5678-1234-567812345678' + assert message.task_id is None + assert message.context_id is None def test_new_agent_text_message_with_context_id(self): # Setup @@ -57,9 +57,9 @@ def test_new_agent_text_message_with_context_id(self): # Verify assert message.role == Role.agent assert message.parts[0].root.text == text - assert message.messageId == '12345678-1234-5678-1234-567812345678' - assert message.contextId == context_id - assert message.taskId is None + assert message.message_id == '12345678-1234-5678-1234-567812345678' + assert message.context_id == context_id + assert message.task_id is None def test_new_agent_text_message_with_task_id(self): # Setup @@ -76,9 +76,9 @@ def test_new_agent_text_message_with_task_id(self): # Verify assert message.role == Role.agent assert message.parts[0].root.text == text - assert message.messageId == '12345678-1234-5678-1234-567812345678' - assert message.taskId == task_id - assert message.contextId is None + assert message.message_id == '12345678-1234-5678-1234-567812345678' + assert message.task_id == task_id + assert message.context_id is None def test_new_agent_text_message_with_both_ids(self): # Setup @@ -98,9 +98,9 @@ def test_new_agent_text_message_with_both_ids(self): # Verify assert message.role == Role.agent assert message.parts[0].root.text == text - assert message.messageId == '12345678-1234-5678-1234-567812345678' - assert message.contextId == context_id - assert message.taskId == task_id + assert message.message_id == '12345678-1234-5678-1234-567812345678' + assert message.context_id == context_id + assert message.task_id == task_id def test_new_agent_text_message_empty_text(self): # Setup @@ -116,7 +116,7 @@ def test_new_agent_text_message_empty_text(self): # Verify assert message.role == Role.agent assert message.parts[0].root.text == '' - assert message.messageId == '12345678-1234-5678-1234-567812345678' + assert message.message_id == '12345678-1234-5678-1234-567812345678' class TestNewAgentPartsMessage: @@ -142,9 +142,9 @@ def test_new_agent_parts_message(self): # Verify assert message.role == Role.agent assert message.parts == parts - assert message.contextId == context_id - assert message.taskId == task_id - assert message.messageId == 'abcdefab-cdef-abcd-efab-cdefabcdefab' + assert message.context_id == context_id + assert message.task_id == task_id + assert message.message_id == 'abcdefab-cdef-abcd-efab-cdefabcdefab' class TestGetTextParts: @@ -261,11 +261,11 @@ def test_get_file_parts_single_file_part(self): def test_get_file_parts_multiple_file_parts(self): # Setup file_with_uri1 = FileWithUri( - uri='file://path/to/file1', mimeType='text/plain' + uri='file://path/to/file1', mime_type='text/plain' ) file_with_bytes = FileWithBytes( bytes='ZmlsZSBjb250ZW50', - mimeType='application/octet-stream', # 'file content' + mime_type='application/octet-stream', # 'file content' ) parts = [ Part(root=FilePart(file=file_with_uri1)), @@ -281,7 +281,7 @@ def test_get_file_parts_multiple_file_parts(self): def test_get_file_parts_mixed_parts(self): # Setup file_with_uri = FileWithUri( - uri='file://path/to/file', mimeType='text/plain' + uri='file://path/to/file', mime_type='text/plain' ) parts = [ Part(root=TextPart(text='some text')), @@ -324,7 +324,7 @@ def test_get_message_text_single_part(self): message = Message( role=Role.agent, parts=[Part(root=TextPart(text='Hello world'))], - messageId='test-message-id', + message_id='test-message-id', ) # Exercise @@ -342,7 +342,7 @@ def test_get_message_text_multiple_parts(self): Part(root=TextPart(text='Second line')), Part(root=TextPart(text='Third line')), ], - messageId='test-message-id', + message_id='test-message-id', ) # Exercise @@ -360,7 +360,7 @@ def test_get_message_text_custom_delimiter(self): Part(root=TextPart(text='Second part')), Part(root=TextPart(text='Third part')), ], - messageId='test-message-id', + message_id='test-message-id', ) # Exercise @@ -374,7 +374,7 @@ def test_get_message_text_empty_parts(self): message = Message( role=Role.agent, parts=[], - messageId='test-message-id', + message_id='test-message-id', ) # Exercise diff --git a/tests/utils/test_proto_utils.py b/tests/utils/test_proto_utils.py index b1a73fff..e5dcac6c 100644 --- a/tests/utils/test_proto_utils.py +++ b/tests/utils/test_proto_utils.py @@ -14,9 +14,9 @@ @pytest.fixture def sample_message() -> types.Message: return types.Message( - messageId='msg-1', - contextId='ctx-1', - taskId='task-1', + message_id='msg-1', + context_id='ctx-1', + task_id='task-1', role=types.Role.user, parts=[ types.Part(root=types.TextPart(text='Hello')), @@ -35,14 +35,14 @@ def sample_message() -> types.Message: def sample_task(sample_message: types.Message) -> types.Task: return types.Task( id='task-1', - contextId='ctx-1', + context_id='ctx-1', status=types.TaskStatus( state=types.TaskState.working, message=sample_message ), history=[sample_message], artifacts=[ types.Artifact( - artifactId='art-1', + artifact_id='art-1', parts=[ types.Part(root=types.TextPart(text='Artifact content')) ], @@ -59,10 +59,10 @@ def sample_agent_card() -> types.AgentCard: url='http://localhost', version='1.0.0', capabilities=types.AgentCapabilities( - streaming=True, pushNotifications=True + streaming=True, push_notifications=True ), - defaultInputModes=['text/plain'], - defaultOutputModes=['text/plain'], + default_input_modes=['text/plain'], + default_output_modes=['text/plain'], skills=[ types.AgentSkill( id='skill1', @@ -75,12 +75,12 @@ def sample_agent_card() -> types.AgentCard: organization='Test Org', url='http://test.org' ), security=[{'oauth_scheme': ['read', 'write']}], - securitySchemes={ + security_schemes={ 'oauth_scheme': types.SecurityScheme( root=types.OAuth2SecurityScheme( flows=types.OAuthFlows( - clientCredentials=types.ClientCredentialsOAuthFlow( - tokenUrl='http://token.url', + client_credentials=types.ClientCredentialsOAuthFlow( + token_url='http://token.url', scopes={ 'read': 'Read access', 'write': 'Write access', @@ -99,7 +99,7 @@ def sample_agent_card() -> types.AgentCard: ), 'oidc': types.SecurityScheme( root=types.OpenIdConnectSecurityScheme( - openIdConnectUrl='http://oidc.url' + open_id_connect_url='http://oidc.url' ) ), }, @@ -189,7 +189,7 @@ def test_oauth_flows_conversion(self): # Test password flow password_flow = types.OAuthFlows( password=types.PasswordOAuthFlow( - tokenUrl='http://token.url', scopes={'read': 'Read'} + token_url='http://token.url', scopes={'read': 'Read'} ) ) proto_password_flow = proto_utils.ToProto.oauth2_flows(password_flow) @@ -198,7 +198,7 @@ def test_oauth_flows_conversion(self): # Test implicit flow implicit_flow = types.OAuthFlows( implicit=types.ImplicitOAuthFlow( - authorizationUrl='http://auth.url', scopes={'read': 'Read'} + authorization_url='http://auth.url', scopes={'read': 'Read'} ) ) proto_implicit_flow = proto_utils.ToProto.oauth2_flows(implicit_flow) @@ -206,9 +206,9 @@ def test_oauth_flows_conversion(self): # Test authorization code flow auth_code_flow = types.OAuthFlows( - authorizationCode=types.AuthorizationCodeOAuthFlow( - authorizationUrl='http://auth.url', - tokenUrl='http://token.url', + authorization_code=types.AuthorizationCodeOAuthFlow( + authorization_url='http://auth.url', + token_url='http://token.url', scopes={'read': 'read'}, ) ) diff --git a/tests/utils/test_task.py b/tests/utils/test_task.py index 0e391b74..36ef9f71 100644 --- a/tests/utils/test_task.py +++ b/tests/utils/test_task.py @@ -14,7 +14,7 @@ def test_new_task_status(self): message = Message( role=Role.user, parts=[Part(root=TextPart(text='test message'))], - messageId=str(uuid.uuid4()), + message_id=str(uuid.uuid4()), ) task = new_task(message) self.assertEqual(task.status.state.value, 'submitted') @@ -26,11 +26,11 @@ def test_new_task_generates_ids(self, mock_uuid4): message = Message( role=Role.user, parts=[Part(root=TextPart(text='test message'))], - messageId=str(uuid.uuid4()), + message_id=str(uuid.uuid4()), ) task = new_task(message) self.assertEqual(task.id, str(mock_uuid)) - self.assertEqual(task.contextId, str(mock_uuid)) + self.assertEqual(task.context_id, str(mock_uuid)) def test_new_task_uses_provided_ids(self): task_id = str(uuid.uuid4()) @@ -38,19 +38,19 @@ def test_new_task_uses_provided_ids(self): message = Message( role=Role.user, parts=[Part(root=TextPart(text='test message'))], - messageId=str(uuid.uuid4()), - taskId=task_id, - contextId=context_id, + message_id=str(uuid.uuid4()), + task_id=task_id, + context_id=context_id, ) task = new_task(message) self.assertEqual(task.id, task_id) - self.assertEqual(task.contextId, context_id) + self.assertEqual(task.context_id, context_id) def test_new_task_initial_message_in_history(self): message = Message( role=Role.user, parts=[Part(root=TextPart(text='test message'))], - messageId=str(uuid.uuid4()), + message_id=str(uuid.uuid4()), ) task = new_task(message) self.assertEqual(len(task.history), 1) @@ -61,7 +61,7 @@ def test_completed_task_status(self): context_id = str(uuid.uuid4()) artifacts = [ Artifact( - artifactId='artifact_1', + artifact_id='artifact_1', parts=[Part(root=TextPart(text='some content'))], ) ] @@ -78,7 +78,7 @@ def test_completed_task_assigns_ids_and_artifacts(self): context_id = str(uuid.uuid4()) artifacts = [ Artifact( - artifactId='artifact_1', + artifact_id='artifact_1', parts=[Part(root=TextPart(text='some content'))], ) ] @@ -89,7 +89,7 @@ def test_completed_task_assigns_ids_and_artifacts(self): history=[], ) self.assertEqual(task.id, task_id) - self.assertEqual(task.contextId, context_id) + self.assertEqual(task.context_id, context_id) self.assertEqual(task.artifacts, artifacts) def test_completed_task_empty_history_if_not_provided(self): @@ -97,7 +97,7 @@ def test_completed_task_empty_history_if_not_provided(self): context_id = str(uuid.uuid4()) artifacts = [ Artifact( - artifactId='artifact_1', + artifact_id='artifact_1', parts=[Part(root=TextPart(text='some content'))], ) ] @@ -111,7 +111,7 @@ def test_completed_task_uses_provided_history(self): context_id = str(uuid.uuid4()) artifacts = [ Artifact( - artifactId='artifact_1', + artifact_id='artifact_1', parts=[Part(root=TextPart(text='some content'))], ) ] @@ -119,12 +119,12 @@ def test_completed_task_uses_provided_history(self): Message( role=Role.user, parts=[Part(root=TextPart(text='Hello'))], - messageId=str(uuid.uuid4()), + message_id=str(uuid.uuid4()), ), Message( role=Role.agent, parts=[Part(root=TextPart(text='Hi there'))], - messageId=str(uuid.uuid4()), + message_id=str(uuid.uuid4()), ), ] task = completed_task( @@ -141,7 +141,7 @@ def test_new_task_invalid_message_empty_parts(self): Message( role=Role.user, parts=[], - messageId=str(uuid.uuid4()), + message_id=str(uuid.uuid4()), ) ) @@ -150,7 +150,7 @@ def test_new_task_invalid_message_none_role(self): msg = Message.model_construct( role=None, parts=[Part(root=TextPart(text='test message'))], - messageId=str(uuid.uuid4()), + message_id=str(uuid.uuid4()), ) new_task(msg)