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.
Files changed (231) hide show
  1. opencode_a2a-1.3.2/.github/ISSUE_TEMPLATE/bug_report.yml +43 -0
  2. opencode_a2a-1.3.2/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. opencode_a2a-1.3.2/.github/ISSUE_TEMPLATE/feature_request.yml +39 -0
  4. opencode_a2a-1.3.2/.github/pull_request_template.md +18 -0
  5. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.github/workflows/validate.yml +2 -2
  6. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/CONTRIBUTING.md +11 -3
  7. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/PKG-INFO +4 -2
  8. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/README.md +2 -1
  9. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/architecture.md +1 -1
  10. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/compatibility.md +4 -4
  11. opencode_a2a-1.3.2/docs/conformance.md +50 -0
  12. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/guide.md +7 -6
  13. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/security-architecture.md +9 -5
  14. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/pyproject.toml +6 -0
  15. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/README.md +2 -2
  16. opencode_a2a-1.3.2/scripts/conformance.sh +114 -0
  17. opencode_a2a-1.3.2/scripts/conformance_probe.py +208 -0
  18. opencode_a2a-1.3.2/scripts/conformance_sut.py +28 -0
  19. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/auth.py +0 -6
  20. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/request_context.py +9 -12
  21. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/config.py +1 -0
  22. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/compatibility.py +0 -9
  23. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/identifiers.py +0 -1
  24. opencode_a2a-1.3.2/src/opencode_a2a/execution/metrics.py +81 -0
  25. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/extension_negotiation.py +0 -17
  26. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/application.py +5 -1
  27. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/dispatch.py +0 -7
  28. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/profile/runtime.py +9 -0
  29. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/agent_card.py +6 -3
  30. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/application.py +25 -14
  31. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/database.py +33 -8
  32. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/openapi.py +3 -1
  33. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/request_parsing.py +18 -0
  34. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/PKG-INFO +4 -2
  35. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/SOURCES.txt +7 -1
  36. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_client_facade.py +11 -9
  37. opencode_a2a-1.3.2/tests/client/test_client_http_headers.py +150 -0
  38. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_request_context.py +10 -12
  39. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/config/test_settings.py +3 -0
  40. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_cancellation.py +2 -2
  41. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_metrics.py +16 -0
  42. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_opencode_agent_session_binding.py +3 -3
  43. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_application_dispatch.py +21 -0
  44. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_jsonrpc_unsupported_method.py +2 -2
  45. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/profile/test_profile_runtime.py +7 -0
  46. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/scripts/test_script_health_contract.py +37 -6
  47. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_agent_card.py +1 -7
  48. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_app_behaviors.py +69 -11
  49. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_cancel_contract.py +5 -8
  50. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_database.py +50 -1
  51. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_output_negotiation.py +9 -18
  52. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_runtime_limits.py +2 -0
  53. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_state_store.py +9 -5
  54. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_task_store_factory.py +15 -7
  55. opencode_a2a-1.3.0/docs/conformance-triage.md +0 -32
  56. opencode_a2a-1.3.0/docs/conformance.md +0 -67
  57. opencode_a2a-1.3.0/scripts/conformance.sh +0 -248
  58. opencode_a2a-1.3.0/src/opencode_a2a/execution/metrics.py +0 -20
  59. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.github/dependabot.yml +0 -0
  60. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.github/workflows/dependency-review.yml +0 -0
  61. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.github/workflows/publish.yml +0 -0
  62. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.gitignore +0 -0
  63. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.pre-commit-config.yaml +0 -0
  64. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/.secrets.baseline +0 -0
  65. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/AGENTS.md +0 -0
  66. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/CODE_OF_CONDUCT.md +0 -0
  67. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/LICENSE +0 -0
  68. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/MANIFEST.in +0 -0
  69. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/SECURITY.md +0 -0
  70. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/SUPPORT.md +0 -0
  71. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/extension-specifications.md +0 -0
  72. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/docs/maintainer-architecture.md +0 -0
  73. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/check_coverage.py +0 -0
  74. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/dependency_health.sh +0 -0
  75. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/doctor.sh +0 -0
  76. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/find_thin_wrappers.py +0 -0
  77. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/health_common.sh +0 -0
  78. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/lint.sh +0 -0
  79. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/live_opencode_smoke.sh +0 -0
  80. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/scripts/smoke_test_built_cli.sh +0 -0
  81. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/setup.cfg +0 -0
  82. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/__init__.py +0 -0
  83. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/a2a_protocol.py +0 -0
  84. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/a2a_utils.py +0 -0
  85. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/cli.py +0 -0
  86. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/__init__.py +0 -0
  87. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/agent_card.py +0 -0
  88. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/auth.py +0 -0
  89. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/client.py +0 -0
  90. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/config.py +0 -0
  91. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/error_mapping.py +0 -0
  92. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/errors.py +0 -0
  93. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/network_policy.py +0 -0
  94. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/payload_text.py +0 -0
  95. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/client/polling.py +0 -0
  96. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/__init__.py +0 -0
  97. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/__init__.py +0 -0
  98. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/capabilities.py +0 -0
  99. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/catalog.py +0 -0
  100. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/contract_docs.py +0 -0
  101. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/private_params.py +0 -0
  102. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/contracts/extensions/public_params.py +0 -0
  103. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/__init__.py +0 -0
  104. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/coordinator.py +0 -0
  105. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/event_helpers.py +0 -0
  106. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/executor.py +0 -0
  107. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/session_manager.py +0 -0
  108. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/stream_events.py +0 -0
  109. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/stream_runtime.py +0 -0
  110. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/stream_state.py +0 -0
  111. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/tool_error_mapping.py +0 -0
  112. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/tool_orchestration.py +0 -0
  113. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/execution/upstream_error_translator.py +0 -0
  114. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/interrupt_request_tracker.py +0 -0
  115. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/__init__.py +0 -0
  116. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/error_responses.py +0 -0
  117. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/__init__.py +0 -0
  118. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/common.py +0 -0
  119. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/interrupt_callbacks.py +0 -0
  120. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/interrupt_queries.py +0 -0
  121. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/provider_discovery.py +0 -0
  122. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/session_control.py +0 -0
  123. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/session_lifecycle.py +0 -0
  124. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/session_queries.py +0 -0
  125. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/handlers/workspace_control.py +0 -0
  126. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/methods.py +0 -0
  127. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/models.py +0 -0
  128. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/jsonrpc/params.py +0 -0
  129. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/metadata_access.py +0 -0
  130. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/opencode_upstream_client.py +0 -0
  131. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/output_modes.py +0 -0
  132. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/parsing.py +0 -0
  133. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/parts/__init__.py +0 -0
  134. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/parts/mapping.py +0 -0
  135. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/parts/text.py +0 -0
  136. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/profile/__init__.py +0 -0
  137. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/protocol_versions.py +0 -0
  138. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/py.typed +0 -0
  139. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/redact.py +0 -0
  140. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/runtime_state.py +0 -0
  141. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/sandbox_policy.py +0 -0
  142. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/__init__.py +0 -0
  143. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/client_manager.py +0 -0
  144. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/context_helpers.py +0 -0
  145. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/lifespan.py +0 -0
  146. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/middleware.py +0 -0
  147. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/migrations.py +0 -0
  148. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/rest_tasks.py +0 -0
  149. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/runtime_limits.py +0 -0
  150. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/state_store.py +0 -0
  151. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/task_store.py +0 -0
  152. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/server/task_store_sdk_compat.py +0 -0
  153. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/task_states.py +0 -0
  154. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/trace_context.py +0 -0
  155. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a/upstream_taxonomy.py +0 -0
  156. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/dependency_links.txt +0 -0
  157. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/entry_points.txt +0 -0
  158. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/requires.txt +0 -0
  159. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/src/opencode_a2a.egg-info/top_level.txt +0 -0
  160. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/__init__.py +0 -0
  161. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/__init__.py +0 -0
  162. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_agent_card.py +0 -0
  163. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_client_config.py +0 -0
  164. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_error_mapping.py +0 -0
  165. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_network_policy.py +0 -0
  166. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_payload_text.py +0 -0
  167. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/client/test_polling.py +0 -0
  168. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/config/__init__.py +0 -0
  169. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/conftest.py +0 -0
  170. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/contracts/__init__.py +0 -0
  171. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/contracts/test_extension_contract_consistency.py +0 -0
  172. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/__init__.py +0 -0
  173. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_agent_errors.py +0 -0
  174. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_agent_helpers.py +0 -0
  175. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_directory_validation.py +0 -0
  176. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_error_redaction.py +0 -0
  177. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_multipart_input.py +0 -0
  178. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_session_lock_lifecycle.py +0 -0
  179. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_session_ownership.py +0 -0
  180. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_streaming_output_contract_blocks.py +0 -0
  181. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_streaming_output_contract_core.py +0 -0
  182. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_streaming_output_contract_interrupts.py +0 -0
  183. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/execution/test_streaming_output_contract_logging.py +0 -0
  184. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/__init__.py +0 -0
  185. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_dispatch_registry.py +0 -0
  186. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_error_redaction.py +0 -0
  187. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_error_responses.py +0 -0
  188. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_jsonrpc_methods.py +0 -0
  189. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_jsonrpc_params.py +0 -0
  190. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_commands.py +0 -0
  191. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_interrupts.py +0 -0
  192. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_lifecycle.py +0 -0
  193. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_prompt_async.py +0 -0
  194. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_session_extension_queries.py +0 -0
  195. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/jsonrpc/test_opencode_workspace_control_extension.py +0 -0
  196. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/package/__init__.py +0 -0
  197. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/package/test_logging.py +0 -0
  198. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/package/test_typing_contract.py +0 -0
  199. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/package/test_version.py +0 -0
  200. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/parts/__init__.py +0 -0
  201. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/parts/test_parts_text.py +0 -0
  202. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/profile/__init__.py +0 -0
  203. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/scripts/__init__.py +0 -0
  204. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/__init__.py +0 -0
  205. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_a2a_client_manager.py +0 -0
  206. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_auth.py +0 -0
  207. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_call_context_builder.py +0 -0
  208. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_cli.py +0 -0
  209. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_context_helpers.py +0 -0
  210. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_database_app_persistence.py +0 -0
  211. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_http_boundary.py +0 -0
  212. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/server/test_transport_contract.py +0 -0
  213. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/__init__.py +0 -0
  214. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/async_iterators.py +0 -0
  215. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/fake_client_errors.py +0 -0
  216. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/helpers.py +0 -0
  217. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/interrupt_clients.py +0 -0
  218. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/jsonrpc_error_assertions.py +0 -0
  219. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/session_extensions.py +0 -0
  220. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/session_query_client.py +0 -0
  221. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/settings.py +0 -0
  222. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/streaming_output.py +0 -0
  223. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/support/workspace_control_client.py +0 -0
  224. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_a2a_utils.py +0 -0
  225. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_metadata_access.py +0 -0
  226. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_parsing.py +0 -0
  227. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_redact.py +0 -0
  228. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/test_trace_context.py +0 -0
  229. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/upstream/__init__.py +0 -0
  230. {opencode_a2a-1.3.0 → opencode_a2a-1.3.2}/tests/upstream/test_opencode_upstream_client_params.py +0 -0
  231. {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.13"
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.13
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
- External interoperability experiments stay outside the default regression baseline. When you need to reproduce current official-tool behavior, run:
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
- Treat that output as investigation input. Do not fold it into `doctor.sh` or the default CI quality gate unless the repository explicitly decides to promote a specific experiment into a maintained policy.
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.0
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) External TCK experiment workflow and artifact handling.
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) External TCK experiment workflow and artifact handling.
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): external TCK experiment workflow
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
- - Treat the v1 core A2A methods (`SendMessage`, `SendStreamingMessage`, `GetTask`, `CancelTask`, `SubscribeToTask`) as the portable baseline.
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
- External TCK runs and local conformance experiments are investigation inputs. They do not override the repository's declared contract by themselves.
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` replay-once behavior for terminal updates
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 push notification operations remain unsupported. REST routes currently return HTTP `501`, while JSON-RPC methods surface SDK-owned unsupported error envelopes.
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 task push-notification routes are still exposed, but this runtime does not enable push sender/config-store support. REST routes return HTTP `501`, while JSON-RPC methods remain unsupported via SDK-owned error envelopes. |
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 effectively unsupported in the current runtime because no push config store or push sender is configured; REST routes return HTTP `501`, while JSON-RPC methods stay on SDK-owned unsupported error handling.
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 replays one terminal `Task` snapshot and then closes the stream.
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
- - These two semantics are also declared as machine-readable `service_behaviors` in the compatibility profile and wire contract extensions.
1325
- - At `A2A_LOG_LEVEL=DEBUG`, the service emits lightweight metric log records (`logger=opencode_a2a.execution.executor`):
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 | Anonymous |
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: `message/send`, `message/stream`,
51
- `tasks/get`, `tasks/cancel`, `tasks/list`, `tasks/subscribe`,
52
- `tasks/pushNotificationConfig/*`.
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 (HTTP 501 / JSON-RPC unsupported) | Accepted | Contract kept explicitly unsupported; capability recovery is intentionally deferred |
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): local/manual external A2A conformance experiment entrypoint; caches the official TCK, can launch a dummy-backed local SUT, and preserves raw artifacts under `run/conformance/`
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
- - External conformance experiments remain intentionally separate from the default regression path. See [`../docs/conformance.md`](../docs/conformance.md).
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}"