opencode-a2a 1.3.0__tar.gz → 1.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opencode_a2a-1.3.2/.github/ISSUE_TEMPLATE/bug_report.yml +43 -0
- opencode_a2a-1.3.2/.github/ISSUE_TEMPLATE/config.yml +8 -0
- opencode_a2a-1.3.2/.github/ISSUE_TEMPLATE/feature_request.yml +39 -0
- opencode_a2a-1.3.2/.github/pull_request_template.md +18 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.github/workflows/validate.yml +2 -2
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/CONTRIBUTING.md +11 -3
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/PKG-INFO +4 -2
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/README.md +2 -1
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/architecture.md +1 -1
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/compatibility.md +4 -4
- opencode_a2a-1.3.2/docs/conformance.md +50 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/guide.md +7 -6
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/security-architecture.md +9 -5
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/pyproject.toml +6 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/README.md +2 -2
- opencode_a2a-1.3.2/scripts/conformance.sh +114 -0
- opencode_a2a-1.3.2/scripts/conformance_probe.py +208 -0
- opencode_a2a-1.3.2/scripts/conformance_sut.py +28 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/auth.py +0 -6
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/request_context.py +9 -12
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/config.py +1 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/compatibility.py +0 -9
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/identifiers.py +0 -1
- opencode_a2a-1.3.2/src/opencode_a2a/execution/metrics.py +81 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/extension_negotiation.py +0 -17
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/application.py +5 -1
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/dispatch.py +0 -7
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/profile/runtime.py +9 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/agent_card.py +6 -3
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/application.py +25 -14
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/database.py +33 -8
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/openapi.py +3 -1
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/request_parsing.py +18 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/PKG-INFO +4 -2
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/SOURCES.txt +7 -1
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_client_facade.py +11 -9
- opencode_a2a-1.3.2/tests/client/test_client_http_headers.py +150 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_request_context.py +10 -12
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/config/test_settings.py +3 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_cancellation.py +2 -2
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_metrics.py +16 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_opencode_agent_session_binding.py +3 -3
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_application_dispatch.py +21 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_jsonrpc_unsupported_method.py +2 -2
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/profile/test_profile_runtime.py +7 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/scripts/test_script_health_contract.py +37 -6
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_agent_card.py +1 -7
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_app_behaviors.py +69 -11
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_cancel_contract.py +5 -8
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_database.py +50 -1
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_output_negotiation.py +9 -18
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_runtime_limits.py +2 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_state_store.py +9 -5
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_task_store_factory.py +15 -7
- opencode_a2a-1.3.0/docs/conformance-triage.md +0 -32
- opencode_a2a-1.3.0/docs/conformance.md +0 -67
- opencode_a2a-1.3.0/scripts/conformance.sh +0 -248
- opencode_a2a-1.3.0/src/opencode_a2a/execution/metrics.py +0 -20
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.github/dependabot.yml +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.github/workflows/dependency-review.yml +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.github/workflows/publish.yml +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.gitignore +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.pre-commit-config.yaml +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.secrets.baseline +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/AGENTS.md +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/CODE_OF_CONDUCT.md +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/LICENSE +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/MANIFEST.in +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/SECURITY.md +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/SUPPORT.md +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/extension-specifications.md +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/maintainer-architecture.md +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/check_coverage.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/dependency_health.sh +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/doctor.sh +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/find_thin_wrappers.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/health_common.sh +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/lint.sh +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/live_opencode_smoke.sh +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/smoke_test_built_cli.sh +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/setup.cfg +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/a2a_protocol.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/a2a_utils.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/cli.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/agent_card.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/auth.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/client.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/config.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/error_mapping.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/errors.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/network_policy.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/payload_text.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/polling.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/capabilities.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/catalog.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/contract_docs.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/private_params.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/public_params.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/coordinator.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/event_helpers.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/executor.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/session_manager.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/stream_events.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/stream_runtime.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/stream_state.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/tool_error_mapping.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/tool_orchestration.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/upstream_error_translator.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/interrupt_request_tracker.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/error_responses.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/common.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/interrupt_callbacks.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/interrupt_queries.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/provider_discovery.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/session_control.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/session_lifecycle.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/session_queries.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/workspace_control.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/methods.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/models.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/params.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/metadata_access.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/opencode_upstream_client.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/output_modes.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/parsing.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/parts/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/parts/mapping.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/parts/text.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/profile/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/protocol_versions.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/py.typed +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/redact.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/runtime_state.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/sandbox_policy.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/client_manager.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/context_helpers.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/lifespan.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/middleware.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/migrations.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/rest_tasks.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/runtime_limits.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/state_store.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/task_store.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/task_store_sdk_compat.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/task_states.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/trace_context.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/upstream_taxonomy.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/dependency_links.txt +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/entry_points.txt +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/requires.txt +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/top_level.txt +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_agent_card.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_client_config.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_error_mapping.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_network_policy.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_payload_text.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_polling.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/config/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/conftest.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/contracts/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/contracts/test_extension_contract_consistency.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_agent_errors.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_agent_helpers.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_directory_validation.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_error_redaction.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_multipart_input.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_session_lock_lifecycle.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_session_ownership.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_streaming_output_contract_blocks.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_streaming_output_contract_core.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_streaming_output_contract_interrupts.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_streaming_output_contract_logging.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_dispatch_registry.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_error_redaction.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_error_responses.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_jsonrpc_methods.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_jsonrpc_params.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_commands.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_interrupts.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_lifecycle.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_prompt_async.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_queries.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_workspace_control_extension.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/package/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/package/test_logging.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/package/test_typing_contract.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/package/test_version.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/parts/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/parts/test_parts_text.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/profile/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/scripts/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_a2a_client_manager.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_auth.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_call_context_builder.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_cli.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_context_helpers.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_database_app_persistence.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_http_boundary.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_transport_contract.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/async_iterators.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/fake_client_errors.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/helpers.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/interrupt_clients.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/jsonrpc_error_assertions.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/session_extensions.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/session_query_client.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/settings.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/streaming_output.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/workspace_control_client.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_a2a_utils.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_metadata_access.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_parsing.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_redact.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_trace_context.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/upstream/__init__.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/upstream/test_opencode_upstream_client_params.py +0 -0
- {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/uv.lock +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a reproducible runtime, protocol, or documentation issue
|
|
3
|
+
title: "[Bug] "
|
|
4
|
+
labels: [bug]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: Remove secrets and sensitive data from logs and protocol payloads before submitting.
|
|
9
|
+
- type: textarea
|
|
10
|
+
id: problem
|
|
11
|
+
attributes:
|
|
12
|
+
label: Problem description
|
|
13
|
+
description: What happened, and what behavior did you expect?
|
|
14
|
+
validations:
|
|
15
|
+
required: true
|
|
16
|
+
- type: textarea
|
|
17
|
+
id: reproduce
|
|
18
|
+
attributes:
|
|
19
|
+
label: Reproduction steps
|
|
20
|
+
description: Provide minimal, repeatable steps and sanitized requests.
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
- type: input
|
|
24
|
+
id: version
|
|
25
|
+
attributes:
|
|
26
|
+
label: Version and environment
|
|
27
|
+
description: Include the opencode-a2a, OpenCode, Python, and operating system versions.
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
- type: textarea
|
|
31
|
+
id: evidence
|
|
32
|
+
attributes:
|
|
33
|
+
label: Supporting evidence
|
|
34
|
+
description: Include sanitized logs, error responses, or relevant links.
|
|
35
|
+
- type: checkboxes
|
|
36
|
+
id: checks
|
|
37
|
+
attributes:
|
|
38
|
+
label: Pre-submission checklist
|
|
39
|
+
options:
|
|
40
|
+
- label: I searched the open issues and found no duplicate report.
|
|
41
|
+
required: true
|
|
42
|
+
- label: I confirm that this submission contains no tokens, passwords, or `.env` contents.
|
|
43
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability reporting
|
|
4
|
+
url: https://github.com/Intelligent-Internet/opencode-a2a/blob/main/SECURITY.md
|
|
5
|
+
about: Read the private disclosure guidance before reporting sensitive information. Do not disclose it in a public issue.
|
|
6
|
+
- name: Support scope
|
|
7
|
+
url: https://github.com/Intelligent-Internet/opencode-a2a/blob/main/SUPPORT.md
|
|
8
|
+
about: Review the supported scope before opening an issue.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a new A2A, OpenCode, or engineering capability
|
|
3
|
+
title: "[Feature] "
|
|
4
|
+
labels: [enhancement]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: problem
|
|
8
|
+
attributes:
|
|
9
|
+
label: User problem
|
|
10
|
+
description: What specific problem needs to be solved? Avoid describing only an implementation.
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: proposal
|
|
15
|
+
attributes:
|
|
16
|
+
label: Proposed solution
|
|
17
|
+
description: Describe the expected behavior, protocol or extension boundary, and alternatives.
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
- type: dropdown
|
|
21
|
+
id: surface
|
|
22
|
+
attributes:
|
|
23
|
+
label: Affected surface
|
|
24
|
+
options:
|
|
25
|
+
- A2A core / transport
|
|
26
|
+
- OpenCode provider-private extension
|
|
27
|
+
- Operations / observability
|
|
28
|
+
- Documentation / open source engineering
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
- type: checkboxes
|
|
32
|
+
id: checks
|
|
33
|
+
attributes:
|
|
34
|
+
label: Pre-submission checklist
|
|
35
|
+
options:
|
|
36
|
+
- label: I searched the open issues and found no duplicate request.
|
|
37
|
+
required: true
|
|
38
|
+
- label: I explained whether this capability belongs to A2A core, a shared extension, or a provider-private surface.
|
|
39
|
+
required: true
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
Describe the problem, solution, and user-visible impact.
|
|
4
|
+
|
|
5
|
+
## Related issue
|
|
6
|
+
|
|
7
|
+
Closes #
|
|
8
|
+
|
|
9
|
+
## Validation
|
|
10
|
+
|
|
11
|
+
- [ ] Ran `./scripts/doctor.sh`
|
|
12
|
+
- [ ] Ran `./scripts/conformance.sh` when changing an A2A transport or contract
|
|
13
|
+
- [ ] Verified that the Agent Card, OpenAPI, machine-readable contracts, and documentation remain synchronized
|
|
14
|
+
- [ ] Confirmed that logs, test data, and commits contain no secrets or `.env` contents
|
|
15
|
+
|
|
16
|
+
## Compatibility and risk
|
|
17
|
+
|
|
18
|
+
Describe protocol, SDK or Python support boundaries, deployment impact, and security considerations. Write "None" when not applicable.
|
|
@@ -21,7 +21,7 @@ jobs:
|
|
|
21
21
|
- name: Set up Python
|
|
22
22
|
uses: actions/setup-python@v6
|
|
23
23
|
with:
|
|
24
|
-
python-version: "3.
|
|
24
|
+
python-version: "3.14"
|
|
25
25
|
|
|
26
26
|
- name: Set up uv
|
|
27
27
|
uses: astral-sh/setup-uv@v7
|
|
@@ -66,7 +66,7 @@ jobs:
|
|
|
66
66
|
strategy:
|
|
67
67
|
fail-fast: false
|
|
68
68
|
matrix:
|
|
69
|
-
python-version: ["3.11", "3.12"]
|
|
69
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
70
70
|
|
|
71
71
|
steps:
|
|
72
72
|
- name: Checkout
|
|
@@ -14,7 +14,7 @@ This repository maintains an OpenCode A2A runtime. Changes should keep runtime b
|
|
|
14
14
|
|
|
15
15
|
Requirements:
|
|
16
16
|
|
|
17
|
-
- Python 3.11, 3.12, or 3.
|
|
17
|
+
- Python 3.11, 3.12, 3.13, or 3.14
|
|
18
18
|
- `uv`
|
|
19
19
|
- A reachable OpenCode runtime if you need end-to-end manual checks
|
|
20
20
|
|
|
@@ -56,13 +56,13 @@ bash -n scripts/doctor.sh
|
|
|
56
56
|
bash -n scripts/lint.sh
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
Repository-owned black-box compatibility probes stay outside the default regression baseline. Run them when transport or A2A protocol behavior changes:
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
62
|
bash ./scripts/conformance.sh
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
The script does not download or bind to an external TCK. It checks the public Agent Card and both shipped transports against invariants maintained by this repository. A third-party TCK may be used independently as investigation input, but is not a repository dependency or certification claim.
|
|
66
66
|
|
|
67
67
|
If you change extension methods, extension metadata, or Agent Card/OpenAPI contract surfaces, also make sure the targeted contract checks stay green:
|
|
68
68
|
|
|
@@ -71,6 +71,14 @@ uv run pytest tests/contracts/test_extension_contract_consistency.py
|
|
|
71
71
|
uv run mypy src/opencode_a2a
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
If you change outbound authentication, tracing, protocol-version, or extension headers, run the SDK transport regression directly:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
uv run pytest --no-cov tests/client/test_client_http_headers.py
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Assertions against a mocked SDK client or `ClientCallContext` alone do not prove that headers reached the HTTP request. Keep at least one regression test across Agent Card resolution, the real SDK transport, and the final `httpx.Request` boundary.
|
|
81
|
+
|
|
74
82
|
## Change Expectations
|
|
75
83
|
|
|
76
84
|
- Keep code, comments, and docs in English.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencode-a2a
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: OpenCode A2A runtime
|
|
5
5
|
Author: liujuanjuan1984@Intelligent-Internet
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
18
|
Classifier: Framework :: FastAPI
|
|
18
19
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
19
20
|
Requires-Python: >=3.11
|
|
@@ -142,6 +143,7 @@ curl http://127.0.0.1:8000/.well-known/agent-card.json
|
|
|
142
143
|
- Session continuity through `metadata.shared.session.id`
|
|
143
144
|
- Request-scoped model selection through `metadata.shared.model`
|
|
144
145
|
- OpenCode-oriented JSON-RPC extensions for session and model/provider queries
|
|
146
|
+
- Authenticated Prometheus-compatible process metrics at `GET /metrics`
|
|
145
147
|
|
|
146
148
|
## A2A Protocol Support
|
|
147
149
|
|
|
@@ -219,7 +221,7 @@ Read before deployment:
|
|
|
219
221
|
- [docs/compatibility.md](docs/compatibility.md) Compatibility-sensitive surface and contract-honesty guidance.
|
|
220
222
|
- [docs/guide.md](docs/guide.md) Usage guide, transport details, streaming behavior, extensions, and examples.
|
|
221
223
|
- [docs/security-architecture.md](docs/security-architecture.md) Security surface, boundaries, and residual-risk register.
|
|
222
|
-
- [docs/conformance.md](docs/conformance.md)
|
|
224
|
+
- [docs/conformance.md](docs/conformance.md) Repository-owned black-box compatibility probes and artifact handling.
|
|
223
225
|
- [SECURITY.md](SECURITY.md) Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
224
226
|
|
|
225
227
|
## Development
|
|
@@ -100,6 +100,7 @@ curl http://127.0.0.1:8000/.well-known/agent-card.json
|
|
|
100
100
|
- Session continuity through `metadata.shared.session.id`
|
|
101
101
|
- Request-scoped model selection through `metadata.shared.model`
|
|
102
102
|
- OpenCode-oriented JSON-RPC extensions for session and model/provider queries
|
|
103
|
+
- Authenticated Prometheus-compatible process metrics at `GET /metrics`
|
|
103
104
|
|
|
104
105
|
## A2A Protocol Support
|
|
105
106
|
|
|
@@ -177,7 +178,7 @@ Read before deployment:
|
|
|
177
178
|
- [docs/compatibility.md](docs/compatibility.md) Compatibility-sensitive surface and contract-honesty guidance.
|
|
178
179
|
- [docs/guide.md](docs/guide.md) Usage guide, transport details, streaming behavior, extensions, and examples.
|
|
179
180
|
- [docs/security-architecture.md](docs/security-architecture.md) Security surface, boundaries, and residual-risk register.
|
|
180
|
-
- [docs/conformance.md](docs/conformance.md)
|
|
181
|
+
- [docs/conformance.md](docs/conformance.md) Repository-owned black-box compatibility probes and artifact handling.
|
|
181
182
|
- [SECURITY.md](SECURITY.md) Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
182
183
|
|
|
183
184
|
## Development
|
|
@@ -97,6 +97,6 @@ Use the docs by responsibility:
|
|
|
97
97
|
- [Maintainer Architecture Guide](maintainer-architecture.md): internal module boundaries, request call chains, and persistence touchpoints
|
|
98
98
|
- [Extension Specifications](extension-specifications.md): stable extension URI/spec index and disclosure policy
|
|
99
99
|
- [Security Architecture](security-architecture.md): security surface mapping and residual-risk register
|
|
100
|
-
- [Conformance Notes](conformance.md):
|
|
100
|
+
- [Conformance Notes](conformance.md): repository-owned black-box compatibility probes
|
|
101
101
|
- [Contributing Guide](../CONTRIBUTING.md): contributor workflow and validation
|
|
102
102
|
- [Security Policy](../SECURITY.md): threat model and disclosure guidance
|
|
@@ -4,7 +4,7 @@ This document defines the compatibility promises `opencode-a2a` currently uphold
|
|
|
4
4
|
|
|
5
5
|
## Runtime Support
|
|
6
6
|
|
|
7
|
-
- Python versions: 3.11, 3.12, 3.13
|
|
7
|
+
- Python versions: 3.11, 3.12, 3.13, 3.14
|
|
8
8
|
- A2A SDK line: `1.x.y`
|
|
9
9
|
- Supported A2A protocol line: `1.0`
|
|
10
10
|
- OpenCode runtime line: `1.18.x` (verified with `1.18.19`)
|
|
@@ -27,7 +27,7 @@ If runtime support is not implemented, do not publish it as a supported machine-
|
|
|
27
27
|
|
|
28
28
|
Consumer guidance:
|
|
29
29
|
|
|
30
|
-
-
|
|
30
|
+
- Discover the complete SDK-owned v1 core method set from `core.jsonrpc_methods`; do not infer it from a shortened documentation list.
|
|
31
31
|
- Treat `urn:opencode-a2a:extension:...` entries in this repository as repository-governed extension identifiers, not as a claim that they are part of the A2A core baseline.
|
|
32
32
|
- Treat `opencode.*` methods and `metadata.opencode.*` fields as provider-private OpenCode control and discovery surfaces layered on top of the portable A2A baseline.
|
|
33
33
|
- Treat [extension-specifications.md](./extension-specifications.md) as the stable URI/spec index, not as the main usage guide.
|
|
@@ -40,7 +40,7 @@ When docs or reference material disagree, treat these as normative in this order
|
|
|
40
40
|
- machine-readable discovery output such as Agent Card, authenticated extended card, and OpenAPI metadata
|
|
41
41
|
- repository-owned docs in `README.md`, `docs/`, and `CONTRIBUTING.md`
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
The repository-owned black-box compatibility probes protect selected runtime invariants but are not a complete conformance suite. Third-party TCK output is investigation input only and does not override the repository's declared contract by itself.
|
|
44
44
|
|
|
45
45
|
## Compatibility-Sensitive Surface
|
|
46
46
|
|
|
@@ -60,7 +60,7 @@ Changes to those surfaces should be treated as compatibility-sensitive and shoul
|
|
|
60
60
|
|
|
61
61
|
Service-level behavior layered on top of those core methods should also be declared explicitly when interoperability depends on it. Current examples:
|
|
62
62
|
|
|
63
|
-
- `SubscribeToTask`
|
|
63
|
+
- `SubscribeToTask` rejection with `UnsupportedOperationError` for terminal tasks
|
|
64
64
|
- first-terminal-state-wins task persistence policy
|
|
65
65
|
- task-scoped `acceptedOutputModes` negotiation persistence across send / stream / get / subscribe
|
|
66
66
|
- request-body rejection behavior for oversized transport payloads
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Repository-Owned Compatibility Probes
|
|
2
|
+
|
|
3
|
+
`./scripts/conformance.sh` runs black-box checks maintained and reviewed with this repository. It deliberately does not clone, pin, or execute the official A2A TCK.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
The probe verifies a small set of high-value A2A 1.0 invariants through public HTTP boundaries:
|
|
8
|
+
|
|
9
|
+
- Agent Card discovery advertises both HTTP+JSON and JSON-RPC interfaces
|
|
10
|
+
- empty `SendMessage` input is rejected before execution
|
|
11
|
+
- unsupported push notification configuration uses the protocol-specific error
|
|
12
|
+
- subscribing to a terminal task returns `UnsupportedOperationError` on both transports
|
|
13
|
+
- `ListTasks` is reachable through both shipped transports
|
|
14
|
+
|
|
15
|
+
These checks protect this runtime's declared contract. They are not a complete A2A conformance suite and must not be presented as certification.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
Run against the local dummy-backed runtime:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bash ./scripts/conformance.sh
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Run against an existing deployment:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
CONFORMANCE_SUT_URL=http://127.0.0.1:8000 \
|
|
29
|
+
CONFORMANCE_AUTH_TOKEN=dev-token \
|
|
30
|
+
CONFORMANCE_ALLOW_EXTERNAL=1 \
|
|
31
|
+
bash ./scripts/conformance.sh
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The probe creates a real task and reads task state. Use a dedicated test deployment, never a production target. `CONFORMANCE_ALLOW_EXTERNAL=1` is a required explicit acknowledgement, and `CONFORMANCE_AUTH_TOKEN` is required for an existing deployment. The default `test-token` is used only for the locally launched test SUT.
|
|
35
|
+
|
|
36
|
+
Use `CONFORMANCE_OUTPUT_DIR` to select the artifact directory and `CONFORMANCE_SKIP_REPO_SYNC=1` only when the locked environment has already been verified.
|
|
37
|
+
|
|
38
|
+
## Artifacts
|
|
39
|
+
|
|
40
|
+
Each run writes:
|
|
41
|
+
|
|
42
|
+
- `agent-card.json`: the discovered public Agent Card
|
|
43
|
+
- `report.json`: versioned check results and repository revision
|
|
44
|
+
- `probe.log`: human-readable probe output
|
|
45
|
+
- `sut.log`: local test-runtime output, when the script launches it
|
|
46
|
+
- `repo-health.log`: repository environment checks, unless explicitly skipped
|
|
47
|
+
|
|
48
|
+
## External Tools
|
|
49
|
+
|
|
50
|
+
Maintainers may run third-party TCKs independently to investigate interoperability. Record exact tool revisions and wire payloads when reporting a finding. External output is evidence to triage, not an automatic merge gate, source of runtime truth, or reason to restore obsolete protocol behavior.
|
|
@@ -43,6 +43,7 @@ Key variables to understand protocol behavior:
|
|
|
43
43
|
- `A2A_ALLOWED_HOSTS`: comma-separated `Host` header allowlist (exact names or `*.example.com` wildcards). When configured, every inbound request must present a matching `Host` header. Binding to a non-loopback address without this allowlist logs a startup warning (DNS rebinding risk).
|
|
44
44
|
- `A2A_LOG_LEVEL`: runtime log level. Default: `WARNING`.
|
|
45
45
|
- `A2A_LOG_PAYLOADS` / `A2A_LOG_BODY_LIMIT`: payload logging behavior and truncation. When `A2A_LOG_LEVEL=DEBUG`, upstream OpenCode stream events are also logged with preview truncation controlled by `A2A_LOG_BODY_LIMIT`.
|
|
46
|
+
- `A2A_METRICS_ENABLED`: expose process-local Prometheus text metrics at authenticated `GET /metrics`. Default: `true`.
|
|
46
47
|
- The runtime accepts W3C `traceparent` / `tracestate` headers on inbound requests. When `traceparent` is missing or invalid, the runtime generates a fresh valid value and exposes it on the HTTP response header.
|
|
47
48
|
- The active `traceparent` / `tracestate` pair is propagated across inbound A2A handling, OpenCode upstream requests, and outbound peer A2A calls triggered through the embedded client or `a2a_call` tool path.
|
|
48
49
|
- Logs derive a stable `trace_id` from the active `traceparent` so request-scoped log lines can be correlated without introducing high-cardinality metric labels.
|
|
@@ -341,7 +342,7 @@ Current behavior:
|
|
|
341
342
|
- The current SDK-owned core JSON-RPC surface includes `GetExtendedAgentCard` and `tasks/pushNotificationConfig/*`.
|
|
342
343
|
- The current SDK-owned REST surface also includes `GET /tasks` and the task push notification config routes.
|
|
343
344
|
- The SDK-owned core JSON-RPC method set follows the pinned `a2a-sdk` release and is locked by repository tests; review that surface deliberately when upgrading the SDK.
|
|
344
|
-
- Push notification config routes/methods are currently exposed only because they are part of the SDK-owned core surface. This runtime does not configure a push config store or push sender, so
|
|
345
|
+
- Push notification config routes/methods are currently exposed only because they are part of the SDK-owned core surface. This runtime does not configure a push config store or push sender, so operations return the A2A 1.0 `PushNotificationNotSupportedError` contract: HTTP `400` for REST and JSON-RPC code `-32003`.
|
|
345
346
|
|
|
346
347
|
When `A2A_ENABLE_SESSION_SHELL=false`, `opencode.sessions.shell` is omitted from `all_jsonrpc_methods` and exposed only through `extensions.conditionally_available_methods`.
|
|
347
348
|
|
|
@@ -384,7 +385,7 @@ Current compatibility matrix:
|
|
|
384
385
|
| Transport payloads and enums | Supported | Request/response payloads, enums, and schema details follow the current SDK-owned v1 baseline. |
|
|
385
386
|
| Error model | Supported | JSON-RPC and REST both use the v1 protocol-aware error shapes. |
|
|
386
387
|
| Pagination and list semantics | Supported | Cursor/list behavior follows the current SDK baseline. |
|
|
387
|
-
| Push notification surfaces | Unsupported | SDK-owned
|
|
388
|
+
| Push notification surfaces | Unsupported | SDK-owned routes remain exposed, but the runtime has no push sender/config store. REST returns HTTP `400`; JSON-RPC returns `-32003` (`PUSH_NOTIFICATION_NOT_SUPPORTED`). |
|
|
388
389
|
| Signatures and authenticated data | Supported | Security schemes and authenticated extended card discovery follow the shipped SDK schema. |
|
|
389
390
|
|
|
390
391
|
## Compatibility Profile
|
|
@@ -657,7 +658,7 @@ Detailed contract discovery for this provider-private surface is intentionally a
|
|
|
657
658
|
- Privacy guard: when `A2A_LOG_PAYLOADS=true`, request/response bodies are still suppressed for `method=opencode.sessions.*`
|
|
658
659
|
- Endpoint discovery: prefer `supportedInterfaces[]` with `protocolBinding=JSONRPC` from Agent Card
|
|
659
660
|
- The runtime still delegates SDK-owned JSON-RPC methods such as `GetExtendedAgentCard` and `tasks/pushNotificationConfig/*` to the base A2A implementation; they are not OpenCode-specific extensions.
|
|
660
|
-
- Push notification config methods remain
|
|
661
|
+
- Push notification config methods remain unsupported because no push config store or sender is configured; REST returns HTTP `400` and JSON-RPC returns `-32003` with `PUSH_NOTIFICATION_NOT_SUPPORTED` details.
|
|
661
662
|
- Notification behavior: for `opencode.sessions.*`, requests without `id` return HTTP `204 No Content`
|
|
662
663
|
- Result format:
|
|
663
664
|
- `opencode.sessions.status` => provider-private status summaries in `result.items`
|
|
@@ -1319,10 +1320,10 @@ If an SSE connection drops, use `GET /tasks/{task_id}:subscribe` to re-subscribe
|
|
|
1319
1320
|
- For running tasks, the service attempts upstream OpenCode `POST /session/{sessionID}/abort` to stop generation.
|
|
1320
1321
|
- Upstream interruption is best-effort: if upstream returns 404, network errors, or other HTTP errors, A2A cancellation still completes with `TaskState.TASK_STATE_CANCELED`.
|
|
1321
1322
|
- Idempotency contract: repeated `CancelTask` on an already `canceled` task returns the current terminal task state without error.
|
|
1322
|
-
- Terminal subscribe contract: calling `SubscribeToTask` or `GET /tasks/{task_id}:subscribe` on a terminal task
|
|
1323
|
+
- Terminal subscribe contract: calling `SubscribeToTask` or `GET /tasks/{task_id}:subscribe` on a terminal task returns `UnsupportedOperationError`, as required by A2A 1.0.
|
|
1323
1324
|
- Terminal persistence contract: once a terminal task snapshot is persisted, this service treats it as immutable. Producers must emit final text and artifact updates before the terminal event, and any final usage or stream metadata must be attached to that terminal event itself. Late terminal-state mutations are rejected by the task-store write policy.
|
|
1324
|
-
-
|
|
1325
|
-
- At `A2A_LOG_LEVEL=DEBUG`, the
|
|
1325
|
+
- The cancellation idempotency enhancement is also declared under machine-readable `service_behaviors`. Terminal-task subscription rejection remains a core A2A 1.0 rule and is therefore not republished as a custom enhancement.
|
|
1326
|
+
- The service records process-local metrics for authenticated Prometheus scraping at `GET /metrics`; `A2A_METRICS_ENABLED=false` disables the endpoint. At `A2A_LOG_LEVEL=DEBUG`, the same updates are emitted as lightweight metric log records (`logger=opencode_a2a.execution.executor`):
|
|
1326
1327
|
- `a2a_stream_requests_total`
|
|
1327
1328
|
- `a2a_stream_active` (`value=1` when a stream starts, `value=-1` when it closes)
|
|
1328
1329
|
- `opencode_stream_retries_total`
|
|
@@ -42,14 +42,17 @@ All REST routes are served at the root path (no `/v1` prefix).
|
|
|
42
42
|
| GET | `/tasks` | List tasks | Credential |
|
|
43
43
|
| GET/POST/DELETE | `/tasks/{id}/pushNotificationConfigs[/{push_id}]` | Push notification config (exposed-but-unsupported) | Credential |
|
|
44
44
|
| POST | `/` | JSON-RPC endpoint (core + extensions) | Credential |
|
|
45
|
-
| GET | `/health` | Health / runtime profile |
|
|
45
|
+
| GET | `/health` | Health / runtime profile | Credential |
|
|
46
|
+
| GET | `/metrics` | Process-local Prometheus metrics (when enabled) | Credential |
|
|
46
47
|
| GET | `/openapi.json` | Sanitized OpenAPI contract | Anonymous |
|
|
47
48
|
|
|
48
49
|
### JSON-RPC Surface
|
|
49
50
|
|
|
50
|
-
- Core A2A methods from the SDK dispatcher: `
|
|
51
|
-
`
|
|
52
|
-
`
|
|
51
|
+
- Core A2A methods from the SDK dispatcher: `SendMessage`,
|
|
52
|
+
`SendStreamingMessage`, `GetTask`, `ListTasks`, `CancelTask`,
|
|
53
|
+
`CreateTaskPushNotificationConfig`, `GetTaskPushNotificationConfig`,
|
|
54
|
+
`ListTaskPushNotificationConfigs`, `DeleteTaskPushNotificationConfig`,
|
|
55
|
+
`SubscribeToTask`, and `GetExtendedAgentCard`.
|
|
53
56
|
- Provider-private `opencode.*` extensions (authenticated extended card only):
|
|
54
57
|
- `opencode.sessions.*`: `status`, `list`, `messages.list`, `get`, `children`,
|
|
55
58
|
`todo`, `diff`, `message.get`, `prompt_async`, `command`, `fork`, `share`,
|
|
@@ -87,6 +90,7 @@ All REST routes are served at the root path (no `/v1` prefix).
|
|
|
87
90
|
| Rate limit | `A2A_RATE_LIMIT_ENABLED` / `_WINDOW_SECONDS` / `_MAX_REQUESTS` | On by default; 60 s window, 120 requests; 429 + `Retry-After` |
|
|
88
91
|
| Stream budgets | `A2A_STREAM_MAX_BYTES` / `_MAX_DURATION_SECONDS` / `_IDLE_TIMEOUT_SECONDS` | 64 MiB / 3600 s / 120 s; `0` disables |
|
|
89
92
|
| Payload logging | `A2A_LOG_PAYLOADS` / `A2A_LOG_BODY_LIMIT` | Opt-in; logs treated as sensitive |
|
|
93
|
+
| Metrics | `A2A_METRICS_ENABLED` | On by default; authenticated `/metrics`; process-local values |
|
|
90
94
|
|
|
91
95
|
### Outbound Side Effects
|
|
92
96
|
|
|
@@ -160,7 +164,7 @@ are skipped idempotently.
|
|
|
160
164
|
| R-3 | Non-loopback bind without `A2A_ALLOWED_HOSTS` only warns at startup | Accepted | Operator contract: trusted network or reverse proxy validates Host. [guide.md](./guide.md) "Inbound Origin and Host Boundary" |
|
|
161
165
|
| R-4 | Single-tenant shared-workspace boundary; static credentials only by default | Accepted by design | Threat model and tenant guidance in [SECURITY.md](../SECURITY.md) |
|
|
162
166
|
| R-5 | Payload logging can capture sensitive data when enabled | Accepted | Opt-in with `A2A_LOG_BODY_LIMIT` cap; treat logs as sensitive. [SECURITY.md](../SECURITY.md) |
|
|
163
|
-
| R-6 | Push notification config surface exposed-but-unsupported
|
|
167
|
+
| R-6 | Push notification config surface exposed-but-unsupported | Accepted | A2A 1.0-specific errors are stable (REST 400 / JSON-RPC -32003); capability recovery is intentionally deferred |
|
|
164
168
|
| R-7 | SQLite hardening exempts `:memory:` / `file:` URIs and non-POSIX platforms | Accepted | Plain absolute file path recommended for deployments. [guide.md](./guide.md) "SQLite Persistence Hardening" |
|
|
165
169
|
|
|
166
170
|
## Maintenance Rules
|
|
@@ -20,6 +20,7 @@ classifiers = [
|
|
|
20
20
|
"Programming Language :: Python :: 3.11",
|
|
21
21
|
"Programming Language :: Python :: 3.12",
|
|
22
22
|
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Programming Language :: Python :: 3.14",
|
|
23
24
|
"Framework :: FastAPI",
|
|
24
25
|
"Topic :: Internet :: WWW/HTTP",
|
|
25
26
|
]
|
|
@@ -102,3 +103,8 @@ ignore_missing_imports = true
|
|
|
102
103
|
|
|
103
104
|
[tool.pytest.ini_options]
|
|
104
105
|
addopts = "--cov=src/opencode_a2a --cov-report=term-missing --cov-report=json:.coverage.json --cov-fail-under=90"
|
|
106
|
+
filterwarnings = [
|
|
107
|
+
"error::pytest.PytestUnhandledThreadExceptionWarning",
|
|
108
|
+
"error::pytest.PytestUnraisableExceptionWarning",
|
|
109
|
+
"always:.*was deleted before being closed.*:ResourceWarning:aiosqlite.core",
|
|
110
|
+
]
|
|
@@ -12,7 +12,7 @@ Executable scripts live in this directory. This file is the entry index for the
|
|
|
12
12
|
## Other Scripts
|
|
13
13
|
|
|
14
14
|
- [`doctor.sh`](./doctor.sh): primary local development regression entrypoint with explicit fix/verify/package phases (uv sync + dependency compatibility + lint + mypy + tests + coverage + built-wheel smoke test)
|
|
15
|
-
- [`conformance.sh`](./conformance.sh):
|
|
15
|
+
- [`conformance.sh`](./conformance.sh): repository-owned A2A 1.0 black-box compatibility probes; can launch a dummy-backed local SUT and preserves machine-readable artifacts under `run/conformance/`
|
|
16
16
|
- [`live_opencode_smoke.sh`](./live_opencode_smoke.sh): local/manual live integration smoke against a real OpenCode runtime; boots an isolated password-hardened `opencode serve` plus the opencode-a2a runtime in throwaway directories and verifies upstream auth, JSON-RPC extension reads, and a streaming prompt round-trip
|
|
17
17
|
- [`dependency_health.sh`](./dependency_health.sh): development dependency review entrypoint (`sync`/`pip check` + outdated + dev audit), while blocking CI/publish audits focus on runtime dependencies
|
|
18
18
|
- [`check_coverage.py`](./check_coverage.py): enforces the overall coverage floor and per-file minimums for critical modules
|
|
@@ -26,4 +26,4 @@ Executable scripts live in this directory. This file is the entry index for the
|
|
|
26
26
|
- `doctor.sh` covers the default local validation baseline, while `dependency_health.sh` remains focused on standalone dependency review and audit flow.
|
|
27
27
|
- `doctor.sh` stops early when `pre-commit` rewrites files so you can review the changes and rerun `doctor.sh` from the updated worktree.
|
|
28
28
|
- [`.github/dependabot.yml`](../.github/dependabot.yml) prefers a single weekly grouped Dependabot PR for `uv`, while `dependency_health.sh` remains the explicit review/audit entrypoint.
|
|
29
|
-
-
|
|
29
|
+
- Repository-owned compatibility probes remain separate from the default regression path. See [`../docs/conformance.md`](../docs/conformance.md).
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Run repository-owned black-box A2A compatibility probes.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
# shellcheck source=./health_common.sh
|
|
6
|
+
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/health_common.sh"
|
|
7
|
+
|
|
8
|
+
usage() {
|
|
9
|
+
cat <<'EOF'
|
|
10
|
+
Usage:
|
|
11
|
+
bash ./scripts/conformance.sh
|
|
12
|
+
|
|
13
|
+
Purpose:
|
|
14
|
+
Run repository-owned A2A 1.0 black-box compatibility probes.
|
|
15
|
+
This script does not download or depend on an external TCK.
|
|
16
|
+
|
|
17
|
+
Selected environment variables:
|
|
18
|
+
CONFORMANCE_OUTPUT_DIR Artifact directory (default: run/conformance/<timestamp>)
|
|
19
|
+
CONFORMANCE_SUT_URL Probe an already running runtime instead of a local test SUT
|
|
20
|
+
CONFORMANCE_SUT_PORT Local test SUT port (default: 8011)
|
|
21
|
+
CONFORMANCE_AUTH_TOKEN Bearer token (default: test-token for the local test SUT)
|
|
22
|
+
CONFORMANCE_ALLOW_EXTERNAL=1 Required acknowledgement when CONFORMANCE_SUT_URL is set
|
|
23
|
+
CONFORMANCE_SKIP_REPO_SYNC=1 Skip uv sync/uv pip check
|
|
24
|
+
EOF
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
|
|
28
|
+
usage
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
if [[ "$#" -ne 0 ]]; then
|
|
32
|
+
echo "This entrypoint accepts no positional arguments." >&2
|
|
33
|
+
exit 2
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
37
|
+
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
38
|
+
timestamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
39
|
+
output_dir="${CONFORMANCE_OUTPUT_DIR:-${ROOT_DIR}/run/conformance/${timestamp}}"
|
|
40
|
+
sut_port="${CONFORMANCE_SUT_PORT:-8011}"
|
|
41
|
+
sut_log="${output_dir}/sut.log"
|
|
42
|
+
probe_log="${output_dir}/probe.log"
|
|
43
|
+
|
|
44
|
+
mkdir -p "${output_dir}"
|
|
45
|
+
|
|
46
|
+
cleanup() {
|
|
47
|
+
local exit_code="$1"
|
|
48
|
+
if [[ -n "${sut_pid:-}" ]] && kill -0 "${sut_pid}" >/dev/null 2>&1; then
|
|
49
|
+
kill "${sut_pid}" >/dev/null 2>&1 || true
|
|
50
|
+
wait "${sut_pid}" >/dev/null 2>&1 || true
|
|
51
|
+
fi
|
|
52
|
+
exit "${exit_code}"
|
|
53
|
+
}
|
|
54
|
+
trap 'cleanup $?' EXIT
|
|
55
|
+
|
|
56
|
+
cd "${ROOT_DIR}"
|
|
57
|
+
if [[ "${CONFORMANCE_SKIP_REPO_SYNC:-0}" != "1" ]]; then
|
|
58
|
+
run_shared_repo_health_prerequisites "conformance" >"${output_dir}/repo-health.log" 2>&1
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
sut_url="${CONFORMANCE_SUT_URL:-}"
|
|
62
|
+
auth_token="${CONFORMANCE_AUTH_TOKEN:-}"
|
|
63
|
+
if [[ -z "${sut_url}" ]]; then
|
|
64
|
+
sut_url="http://127.0.0.1:${sut_port}"
|
|
65
|
+
auth_token="${auth_token:-test-token}"
|
|
66
|
+
if ! uv run python -c \
|
|
67
|
+
'import socket, sys; server = socket.create_server(("127.0.0.1", int(sys.argv[1]))); server.close()' \
|
|
68
|
+
"${sut_port}"; then
|
|
69
|
+
echo "Local conformance port ${sut_port} is unavailable; choose CONFORMANCE_SUT_PORT." >&2
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
CONFORMANCE_SUT_PORT="${sut_port}" \
|
|
73
|
+
CONFORMANCE_SUT_URL="${sut_url}" \
|
|
74
|
+
CONFORMANCE_AUTH_TOKEN="${auth_token}" \
|
|
75
|
+
uv run python -m scripts.conformance_sut >"${sut_log}" 2>&1 &
|
|
76
|
+
sut_pid="$!"
|
|
77
|
+
|
|
78
|
+
sut_ready=0
|
|
79
|
+
for _ in $(seq 1 50); do
|
|
80
|
+
if curl --silent --fail --output /dev/null \
|
|
81
|
+
"${sut_url}/.well-known/agent-card.json" 2>/dev/null; then
|
|
82
|
+
sut_ready=1
|
|
83
|
+
break
|
|
84
|
+
fi
|
|
85
|
+
if ! kill -0 "${sut_pid}" >/dev/null 2>&1; then
|
|
86
|
+
echo "Local conformance SUT exited before becoming ready." >&2
|
|
87
|
+
cat "${sut_log}" >&2 || true
|
|
88
|
+
exit 1
|
|
89
|
+
fi
|
|
90
|
+
sleep 0.2
|
|
91
|
+
done
|
|
92
|
+
if [[ "${sut_ready}" != "1" ]]; then
|
|
93
|
+
echo "Local conformance SUT did not become ready at ${sut_url}." >&2
|
|
94
|
+
cat "${sut_log}" >&2 || true
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
elif [[ "${CONFORMANCE_ALLOW_EXTERNAL:-0}" != "1" ]]; then
|
|
98
|
+
echo "Set CONFORMANCE_ALLOW_EXTERNAL=1 to acknowledge external SUT side effects." >&2
|
|
99
|
+
exit 2
|
|
100
|
+
elif [[ -z "${auth_token}" ]]; then
|
|
101
|
+
echo "CONFORMANCE_AUTH_TOKEN is required with CONFORMANCE_SUT_URL." >&2
|
|
102
|
+
exit 2
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
set +e
|
|
106
|
+
CONFORMANCE_AUTH_TOKEN="${auth_token}" \
|
|
107
|
+
uv run python -m scripts.conformance_probe \
|
|
108
|
+
--base-url "${sut_url}" \
|
|
109
|
+
--output-dir "${output_dir}" 2>&1 | tee "${probe_log}"
|
|
110
|
+
probe_exit="${PIPESTATUS[0]}"
|
|
111
|
+
set -e
|
|
112
|
+
|
|
113
|
+
echo "Conformance artifacts: ${output_dir}"
|
|
114
|
+
exit "${probe_exit}"
|