288ff276b3
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 17s
CI / lint (pull_request) Failing after 23s
CI / helm (pull_request) Successful in 23s
CI / quality (pull_request) Successful in 34s
CI / security (pull_request) Failing after 47s
CI / typecheck (pull_request) Failing after 50s
CI / coverage (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
CI / unit_tests (pull_request) Failing after 1m47s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Failing after 13m17s
CI / integration_tests (pull_request) Failing after 21m52s
CI / status-check (pull_request) Failing after 1s
- Add _EVENT_TYPE_TO_METHOD class-level mapping (ClassVar[dict[str, str]]) to
convert A2A event types to JSON-RPC 2.0 method names:
TaskStatusUpdateEvent → task/statusUpdate
TaskArtifactUpdateEvent → task/artifactUpdate
- Refactor SseEventFormatter.format() to produce JSON-RPC 2.0 notification
envelope: {"jsonrpc": "2.0", "method": "...", "params": {...}}
- Move event data fields into params object; include taskId (from plan_id)
in params when plan_id is present, per spec §Streaming Architecture
- Remove non-spec fields (event_id, event_type, timestamp, plan_id) from
the data payload; these remain in SSE envelope headers (event: and id:)
- Update BDD feature to verify JSON-RPC 2.0 structure for both event types,
events with/without plan_id, custom data in params, and exclusion of
non-spec fields
- Fix pre-existing type errors in step definitions: replace try/except
ImportError pattern with direct imports and use behave.runner.Context
for proper static typing (0 pyright errors)
ISSUES CLOSED: #1502
90 lines
4.3 KiB
Gherkin
90 lines
4.3 KiB
Gherkin
@mock_only
|
|
Feature: A2A SSE streaming for task updates and artifacts
|
|
As a CleverAgents developer
|
|
I want the A2A event system to support SSE streaming with JSON-RPC 2.0 compliance
|
|
So that clients can receive real-time task status and artifact updates in a standard format
|
|
|
|
Scenario: SSE event formatter produces valid text/event-stream output
|
|
Given an A2aEvent with type "TaskStatusUpdateEvent" and plan_id "plan-001"
|
|
When I format the event as SSE
|
|
Then the SSE output should contain "event: TaskStatusUpdateEvent"
|
|
And the SSE output should contain "id: "
|
|
And the SSE output should contain "data: "
|
|
And the SSE output should end with two newlines
|
|
|
|
Scenario: SSE keepalive produces a comment line
|
|
When I format a keepalive SSE message
|
|
Then the keepalive should start with ":"
|
|
|
|
Scenario: EventBusBridge translates plan status events
|
|
Given an A2aEventQueue for SSE testing
|
|
And a mock EventBus
|
|
And an EventBusBridge connecting bus to queue
|
|
When the bridge receives a PLAN_CREATED domain event
|
|
Then the queue should contain a TaskStatusUpdateEvent
|
|
|
|
Scenario: EventBusBridge translates artifact events
|
|
Given an A2aEventQueue for SSE testing
|
|
And a mock EventBus
|
|
And an EventBusBridge connecting bus to queue
|
|
When the bridge receives a CHECKPOINT_RESTORED domain event
|
|
Then the queue should contain a TaskArtifactUpdateEvent
|
|
|
|
Scenario: EventBusBridge handles closed queue gracefully
|
|
Given an A2aEventQueue for SSE testing
|
|
And a mock EventBus
|
|
And an EventBusBridge connecting bus to queue
|
|
When the queue is closed
|
|
And the bridge receives a PLAN_CREATED domain event
|
|
Then no error should be raised from the bridge
|
|
|
|
Scenario: TaskStatusUpdateEvent type constant is defined
|
|
Then the TASK_STATUS_UPDATE constant should equal "TaskStatusUpdateEvent"
|
|
|
|
Scenario: TaskArtifactUpdateEvent type constant is defined
|
|
Then the TASK_ARTIFACT_UPDATE constant should equal "TaskArtifactUpdateEvent"
|
|
|
|
Scenario: SseEventFormatter produces JSON-RPC 2.0 compliant data payload
|
|
Given an A2aEvent with type "TaskStatusUpdateEvent" and plan_id "plan-002"
|
|
When I format the event as SSE
|
|
Then the SSE data line should contain valid JSON
|
|
And the JSON should have key "jsonrpc" with value "2.0"
|
|
And the JSON should have key "method" with value "task/statusUpdate"
|
|
And the JSON should have a "params" object
|
|
And the JSON params should have key "taskId" with value "plan-002"
|
|
|
|
Scenario: SseEventFormatter produces JSON-RPC 2.0 for TaskArtifactUpdateEvent
|
|
Given an A2aEvent with type "TaskArtifactUpdateEvent" and plan_id "plan-003"
|
|
When I format the event as SSE
|
|
Then the SSE data line should contain valid JSON
|
|
And the JSON should have key "jsonrpc" with value "2.0"
|
|
And the JSON should have key "method" with value "task/artifactUpdate"
|
|
And the JSON should have a "params" object
|
|
And the JSON params should have key "taskId" with value "plan-003"
|
|
|
|
Scenario: SseEventFormatter includes event data fields in params
|
|
Given an A2aEvent with type "TaskStatusUpdateEvent" and plan_id "plan-004" and data {"state": "working", "progress": 0.5}
|
|
When I format the event as SSE
|
|
Then the SSE data line should contain valid JSON
|
|
And the JSON params should have key "state" with value "working"
|
|
And the JSON params should have key "progress" with numeric value 0.5
|
|
And the JSON params should have key "taskId" with value "plan-004"
|
|
|
|
Scenario: SseEventFormatter handles events without plan_id
|
|
Given an A2aEvent with type "TaskStatusUpdateEvent" and no plan_id
|
|
When I format the event as SSE
|
|
Then the SSE data line should contain valid JSON
|
|
And the JSON should have key "jsonrpc" with value "2.0"
|
|
And the JSON should have key "method" with value "task/statusUpdate"
|
|
And the JSON should have a "params" object
|
|
And the JSON params should not have key "taskId"
|
|
|
|
Scenario: SseEventFormatter excludes non-spec fields from data payload
|
|
Given an A2aEvent with type "TaskStatusUpdateEvent" and plan_id "plan-005"
|
|
When I format the event as SSE
|
|
Then the SSE data line should contain valid JSON
|
|
And the JSON should not have key "event_id"
|
|
And the JSON should not have key "event_type"
|
|
And the JSON should not have key "timestamp"
|
|
And the JSON should not have key "plan_id"
|