opencode-a2a 0.7.0__tar.gz → 0.8.0__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 (184) hide show
  1. opencode_a2a-0.8.0/.github/dependabot.yml +16 -0
  2. opencode_a2a-0.7.0/.github/workflows/dependency-health.yml → opencode_a2a-0.8.0/.github/workflows/dependency-review.yml +4 -3
  3. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/.github/workflows/publish.yml +7 -6
  4. opencode_a2a-0.7.0/.github/workflows/ci.yml → opencode_a2a-0.8.0/.github/workflows/validate.yml +12 -10
  5. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/.gitignore +3 -0
  6. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/CONTRIBUTING.md +5 -4
  7. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/PKG-INFO +8 -3
  8. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/README.md +5 -1
  9. opencode_a2a-0.8.0/docs/architecture.md +101 -0
  10. opencode_a2a-0.8.0/docs/compatibility.md +147 -0
  11. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/docs/extension-specifications.md +1 -1
  12. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/docs/guide.md +5 -1
  13. opencode_a2a-0.8.0/docs/maintainer-architecture.md +132 -0
  14. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/pyproject.toml +2 -1
  15. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/scripts/README.md +3 -1
  16. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/scripts/doctor.sh +10 -0
  17. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/polling.py +3 -9
  18. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/executor.py +1 -7
  19. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/request_context.py +12 -23
  20. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/stream_runtime.py +15 -1
  21. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/common.py +261 -41
  22. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/interrupt_callbacks.py +9 -9
  23. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/interrupt_queries.py +9 -11
  24. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/provider_discovery.py +25 -50
  25. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/session_control.py +90 -144
  26. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/session_lifecycle.py +209 -259
  27. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/session_queries.py +34 -49
  28. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/workspace_control.py +158 -106
  29. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/methods.py +84 -94
  30. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/params.py +37 -78
  31. opencode_a2a-0.8.0/src/opencode_a2a/metadata_access.py +39 -0
  32. opencode_a2a-0.8.0/src/opencode_a2a/output_modes.py +386 -0
  33. opencode_a2a-0.8.0/src/opencode_a2a/parsing.py +86 -0
  34. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/application.py +44 -4
  35. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/rest_tasks.py +48 -29
  36. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/task_store.py +6 -13
  37. opencode_a2a-0.8.0/src/opencode_a2a/task_states.py +12 -0
  38. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a.egg-info/PKG-INFO +8 -3
  39. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a.egg-info/SOURCES.txt +11 -2
  40. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a.egg-info/requires.txt +2 -1
  41. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_streaming_output_contract_blocks.py +4 -2
  42. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/scripts/test_script_health_contract.py +13 -0
  43. opencode_a2a-0.8.0/tests/server/test_output_negotiation.py +217 -0
  44. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_transport_contract.py +60 -0
  45. opencode_a2a-0.8.0/tests/test_metadata_access.py +49 -0
  46. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/uv.lock +128 -115
  47. opencode_a2a-0.7.0/src/opencode_a2a/output_modes.py +0 -29
  48. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/.pre-commit-config.yaml +0 -0
  49. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/.secrets.baseline +0 -0
  50. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/AGENTS.md +0 -0
  51. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/CODE_OF_CONDUCT.md +0 -0
  52. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/LICENSE +0 -0
  53. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/SECURITY.md +0 -0
  54. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/SUPPORT.md +0 -0
  55. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/docs/conformance-triage.md +0 -0
  56. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/docs/conformance.md +0 -0
  57. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/scripts/check_coverage.py +0 -0
  58. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/scripts/conformance.sh +0 -0
  59. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/scripts/dependency_health.sh +0 -0
  60. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/scripts/health_common.sh +0 -0
  61. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/scripts/lint.sh +0 -0
  62. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/scripts/smoke_test_built_cli.sh +0 -0
  63. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/setup.cfg +0 -0
  64. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/__init__.py +0 -0
  65. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/auth.py +0 -0
  66. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/cli.py +0 -0
  67. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/__init__.py +0 -0
  68. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/agent_card.py +0 -0
  69. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/auth.py +0 -0
  70. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/client.py +0 -0
  71. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/config.py +0 -0
  72. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/error_mapping.py +0 -0
  73. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/errors.py +0 -0
  74. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/payload_text.py +0 -0
  75. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/client/request_context.py +0 -0
  76. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/config.py +0 -0
  77. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/contracts/__init__.py +0 -0
  78. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/contracts/extensions.py +0 -0
  79. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/__init__.py +0 -0
  80. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/coordinator.py +0 -0
  81. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/event_helpers.py +0 -0
  82. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/metrics.py +0 -0
  83. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/session_manager.py +0 -0
  84. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/stream_events.py +0 -0
  85. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/stream_state.py +0 -0
  86. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/tool_error_mapping.py +0 -0
  87. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/tool_orchestration.py +0 -0
  88. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/execution/upstream_error_translator.py +0 -0
  89. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/invocation.py +0 -0
  90. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/__init__.py +0 -0
  91. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/application.py +0 -0
  92. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/dispatch.py +0 -0
  93. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/error_responses.py +0 -0
  94. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/jsonrpc/handlers/__init__.py +0 -0
  95. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/opencode_upstream_client.py +0 -0
  96. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/parts/__init__.py +0 -0
  97. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/parts/mapping.py +0 -0
  98. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/parts/text.py +0 -0
  99. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/profile/__init__.py +0 -0
  100. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/profile/runtime.py +0 -0
  101. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/protocol_versions.py +0 -0
  102. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/py.typed +0 -0
  103. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/runtime_state.py +0 -0
  104. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/sandbox_policy.py +0 -0
  105. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/__init__.py +0 -0
  106. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/agent_card.py +0 -0
  107. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/client_manager.py +0 -0
  108. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/lifespan.py +0 -0
  109. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/middleware.py +0 -0
  110. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/migrations.py +0 -0
  111. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/openapi.py +0 -0
  112. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/request_parsing.py +0 -0
  113. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/server/state_store.py +0 -0
  114. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/trace_context.py +0 -0
  115. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a/upstream_taxonomy.py +0 -0
  116. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a.egg-info/dependency_links.txt +0 -0
  117. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a.egg-info/entry_points.txt +0 -0
  118. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/src/opencode_a2a.egg-info/top_level.txt +0 -0
  119. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/__init__.py +0 -0
  120. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/client/__init__.py +0 -0
  121. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/client/test_agent_card.py +0 -0
  122. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/client/test_client_config.py +0 -0
  123. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/client/test_client_facade.py +0 -0
  124. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/client/test_error_mapping.py +0 -0
  125. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/client/test_payload_text.py +0 -0
  126. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/client/test_polling.py +0 -0
  127. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/client/test_request_context.py +0 -0
  128. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/config/__init__.py +0 -0
  129. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/config/test_settings.py +0 -0
  130. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/conftest.py +0 -0
  131. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/contracts/__init__.py +0 -0
  132. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/contracts/test_extension_contract_consistency.py +0 -0
  133. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/__init__.py +0 -0
  134. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_agent_errors.py +0 -0
  135. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_agent_helpers.py +0 -0
  136. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_cancellation.py +0 -0
  137. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_directory_validation.py +0 -0
  138. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_metrics.py +0 -0
  139. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_multipart_input.py +0 -0
  140. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_opencode_agent_session_binding.py +0 -0
  141. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_session_lock_lifecycle.py +0 -0
  142. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_session_ownership.py +0 -0
  143. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_streaming_output_contract_core.py +0 -0
  144. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_streaming_output_contract_interrupts.py +0 -0
  145. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/execution/test_streaming_output_contract_logging.py +0 -0
  146. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/__init__.py +0 -0
  147. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_dispatch_registry.py +0 -0
  148. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_error_responses.py +0 -0
  149. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_jsonrpc_methods.py +0 -0
  150. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_jsonrpc_params.py +0 -0
  151. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_jsonrpc_unsupported_method.py +0 -0
  152. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_opencode_session_extension_commands.py +0 -0
  153. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_opencode_session_extension_interrupts.py +0 -0
  154. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_opencode_session_extension_lifecycle.py +0 -0
  155. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_opencode_session_extension_prompt_async.py +0 -0
  156. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_opencode_session_extension_queries.py +0 -0
  157. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/jsonrpc/test_opencode_workspace_control_extension.py +0 -0
  158. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/package/__init__.py +0 -0
  159. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/package/test_logging.py +0 -0
  160. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/package/test_typing_contract.py +0 -0
  161. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/package/test_version.py +0 -0
  162. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/parts/__init__.py +0 -0
  163. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/parts/test_parts_text.py +0 -0
  164. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/profile/__init__.py +0 -0
  165. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/profile/test_profile_runtime.py +0 -0
  166. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/scripts/__init__.py +0 -0
  167. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/__init__.py +0 -0
  168. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_a2a_client_manager.py +0 -0
  169. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_agent_card.py +0 -0
  170. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_app_behaviors.py +0 -0
  171. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_auth.py +0 -0
  172. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_call_context_builder.py +0 -0
  173. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_cancel_contract.py +0 -0
  174. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_cli.py +0 -0
  175. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_database_app_persistence.py +0 -0
  176. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_state_store.py +0 -0
  177. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/server/test_task_store_factory.py +0 -0
  178. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/support/__init__.py +0 -0
  179. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/support/helpers.py +0 -0
  180. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/support/session_extensions.py +0 -0
  181. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/support/streaming_output.py +0 -0
  182. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/test_trace_context.py +0 -0
  183. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/upstream/__init__.py +0 -0
  184. {opencode_a2a-0.7.0 → opencode_a2a-0.8.0}/tests/upstream/test_opencode_upstream_client_params.py +0 -0
@@ -0,0 +1,16 @@
1
+ version: 2
2
+
3
+ updates:
4
+ - package-ecosystem: "uv"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ open-pull-requests-limit: 1
9
+ commit-message:
10
+ prefix: "deps"
11
+ labels:
12
+ - "dependencies"
13
+ groups:
14
+ uv-all-updates:
15
+ patterns:
16
+ - "*"
@@ -1,4 +1,4 @@
1
- name: Dependency Health
1
+ name: Review Development Dependencies
2
2
 
3
3
  on:
4
4
  workflow_dispatch:
@@ -11,18 +11,19 @@ permissions:
11
11
 
12
12
  jobs:
13
13
  dependency-health:
14
+ name: Audit Development Dependencies
14
15
  runs-on: ubuntu-latest
15
16
 
16
17
  steps:
17
18
  - name: Checkout
18
19
  uses: actions/checkout@v6
19
20
 
20
- - name: Setup Python
21
+ - name: Set up Python
21
22
  uses: actions/setup-python@v6
22
23
  with:
23
24
  python-version: "3.13"
24
25
 
25
- - name: Setup uv
26
+ - name: Set up uv
26
27
  uses: astral-sh/setup-uv@v7
27
28
  with:
28
29
  enable-cache: false
@@ -1,4 +1,4 @@
1
- name: Publish
1
+ name: Release Publish and Repair
2
2
 
3
3
  on:
4
4
  push:
@@ -31,6 +31,7 @@ permissions:
31
31
 
32
32
  jobs:
33
33
  publish:
34
+ name: Build and Publish Release Artifacts
34
35
  runs-on: ubuntu-latest
35
36
 
36
37
  steps:
@@ -40,17 +41,17 @@ jobs:
40
41
  fetch-depth: 0
41
42
  ref: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
42
43
 
43
- - name: Setup Python
44
+ - name: Set up Python
44
45
  uses: actions/setup-python@v6
45
46
  with:
46
47
  python-version: "3.13"
47
48
 
48
- - name: Setup uv
49
+ - name: Set up uv
49
50
  uses: astral-sh/setup-uv@v7
50
51
  with:
51
52
  enable-cache: false
52
53
 
53
- - name: Run regression baseline
54
+ - name: Run default regression baseline
54
55
  run: bash ./scripts/doctor.sh
55
56
 
56
57
  - name: Export runtime requirements for vulnerability audit
@@ -94,10 +95,10 @@ jobs:
94
95
  print(f"Validated release version: {version}")
95
96
  PY
96
97
 
97
- - name: Smoke test wheel install
98
+ - name: Smoke test wheel artifact
98
99
  run: bash ./scripts/smoke_test_built_cli.sh dist/opencode_a2a-*.whl
99
100
 
100
- - name: Smoke test sdist install
101
+ - name: Smoke test sdist artifact
101
102
  run: bash ./scripts/smoke_test_built_cli.sh dist/opencode_a2a-*.tar.gz
102
103
 
103
104
  - name: Publish to PyPI
@@ -1,4 +1,4 @@
1
- name: CI
1
+ name: Validate PRs and Main
2
2
 
3
3
  on:
4
4
  pull_request:
@@ -11,29 +11,30 @@ permissions:
11
11
 
12
12
  jobs:
13
13
  quality-gate:
14
+ name: Validate Default Toolchain
14
15
  runs-on: ubuntu-latest
15
16
 
16
17
  steps:
17
18
  - name: Checkout
18
19
  uses: actions/checkout@v6
19
20
 
20
- - name: Setup Python
21
+ - name: Set up Python
21
22
  uses: actions/setup-python@v6
22
23
  with:
23
24
  python-version: "3.13"
24
25
 
25
- - name: Setup uv
26
+ - name: Set up uv
26
27
  uses: astral-sh/setup-uv@v7
27
28
  with:
28
29
  enable-cache: false
29
30
 
30
- - name: Sync Dependencies
31
+ - name: Sync locked dependencies
31
32
  run: uv sync --all-extras --frozen
32
33
 
33
- - name: Run pre-commit
34
+ - name: Run lint checks
34
35
  run: bash ./scripts/lint.sh
35
36
 
36
- - name: Run pytest
37
+ - name: Run test suite
37
38
  run: uv run pytest
38
39
 
39
40
  - name: Enforce coverage policy
@@ -60,6 +61,7 @@ jobs:
60
61
  run: bash ./scripts/smoke_test_built_cli.sh dist/opencode_a2a-*.tar.gz
61
62
 
62
63
  runtime-matrix:
64
+ name: Validate Runtime Matrix (Python ${{ matrix.python-version }})
63
65
  runs-on: ubuntu-latest
64
66
  strategy:
65
67
  fail-fast: false
@@ -70,18 +72,18 @@ jobs:
70
72
  - name: Checkout
71
73
  uses: actions/checkout@v6
72
74
 
73
- - name: Setup Python
75
+ - name: Set up Python
74
76
  uses: actions/setup-python@v6
75
77
  with:
76
78
  python-version: ${{ matrix.python-version }}
77
79
 
78
- - name: Setup uv
80
+ - name: Set up uv
79
81
  uses: astral-sh/setup-uv@v7
80
82
  with:
81
83
  enable-cache: false
82
84
 
83
- - name: Sync Dependencies
85
+ - name: Sync locked dependencies
84
86
  run: uv sync --all-extras --frozen
85
87
 
86
- - name: Run pytest runtime matrix
88
+ - name: Run runtime regression tests
87
89
  run: uv run pytest --no-cov
@@ -225,3 +225,6 @@ temp_*.*
225
225
  docs/operations/opencode/
226
226
  .swival/
227
227
  *.db
228
+ .codex-a2a/
229
+ opencode-a2a.db
230
+ opencode-a2a.db*
@@ -44,10 +44,11 @@ uv run opencode-a2a serve
44
44
  Run the default validation baseline before opening a PR:
45
45
 
46
46
  ```bash
47
- uv run pre-commit run --all-files
48
- uv run pytest
47
+ bash ./scripts/doctor.sh
49
48
  ```
50
49
 
50
+ `doctor.sh` is the primary repository validation entrypoint. It currently runs locked-environment sync, dependency compatibility checks, `pre-commit`, `mypy`, `pytest`, the repository coverage gate, package build, and a built-wheel smoke test.
51
+
51
52
  If you change shell scripts, also run `bash -n` on each modified script, for example:
52
53
 
53
54
  ```bash
@@ -63,7 +64,7 @@ bash ./scripts/conformance.sh
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
66
 
66
- If you change extension methods, extension metadata, or Agent Card/OpenAPI contract surfaces, also run:
67
+ If you change extension methods, extension metadata, or Agent Card/OpenAPI contract surfaces, also make sure the targeted contract checks stay green:
67
68
 
68
69
  ```bash
69
70
  uv run pytest tests/contracts/test_extension_contract_consistency.py
@@ -107,7 +108,7 @@ Update docs together with code whenever you change:
107
108
  - user-facing request or response shapes
108
109
  - operational scripts
109
110
 
110
- Keep compatibility guidance centralized in [docs/guide.md](docs/guide.md) unless a new standalone document is clearly necessary.
111
+ Keep usage details in [docs/guide.md](docs/guide.md) and compatibility-sensitive stability guidance in [docs/compatibility.md](docs/compatibility.md).
111
112
 
112
113
  When changing extension contracts, update [`src/opencode_a2a/contracts/extensions.py`](src/opencode_a2a/contracts/extensions.py) first and keep these generated/documented surfaces aligned:
113
114
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencode-a2a
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: OpenCode A2A runtime
5
5
  Author: liujuanjuan1984@Intelligent-Internet
6
6
  License-Expression: Apache-2.0
@@ -19,7 +19,7 @@ Classifier: Topic :: Internet :: WWW/HTTP
19
19
  Requires-Python: >=3.11
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
- Requires-Dist: a2a-sdk==0.3.25
22
+ Requires-Dist: a2a-sdk==0.3.26
23
23
  Requires-Dist: aiosqlite<1.0,>=0.20
24
24
  Requires-Dist: fastapi<1.0,>=0.110
25
25
  Requires-Dist: httpx<1.0,>=0.27
@@ -32,6 +32,7 @@ Provides-Extra: dev
32
32
  Requires-Dist: mypy<2.0,>=1.19.1; extra == "dev"
33
33
  Requires-Dist: pip-audit<3.0,>=2.9; extra == "dev"
34
34
  Requires-Dist: pre-commit<5.0,>=4.5.1; extra == "dev"
35
+ Requires-Dist: pygments<3.0,>=2.20.0; extra == "dev"
35
36
  Requires-Dist: pytest<10.0,>=8.0; extra == "dev"
36
37
  Requires-Dist: pytest-asyncio<2.0,>=0.23; extra == "dev"
37
38
  Requires-Dist: pytest-cov<8.0.0,>=7.0.0; extra == "dev"
@@ -138,7 +139,7 @@ curl http://127.0.0.1:8000/.well-known/agent-card.json
138
139
  - Declared supported protocol lines: `0.3`, `1.0`
139
140
  - `0.3` is the stable interoperability baseline for the current runtime surface.
140
141
  - `1.0` currently covers version negotiation plus protocol-aware JSON-RPC and REST error shaping, while transport payloads, enums, pagination, signatures, and interface-level protocol declarations still follow the shipped SDK baseline.
141
- - The detailed compatibility matrix and machine-readable support boundary are documented in [`docs/guide.md`](docs/guide.md).
142
+ - The detailed compatibility matrix and machine-readable support boundary are documented in [`docs/guide.md`](docs/guide.md) and [`docs/compatibility.md`](docs/compatibility.md).
142
143
 
143
144
  ## Peering Node / Outbound Access
144
145
 
@@ -202,7 +203,11 @@ Read before deployment:
202
203
 
203
204
  ## Further Reading
204
205
 
206
+ - [docs/architecture.md](docs/architecture.md) Service responsibility boundaries and request flow.
207
+ - [docs/maintainer-architecture.md](docs/maintainer-architecture.md) Internal module boundaries and maintainer call chains.
208
+ - [docs/compatibility.md](docs/compatibility.md) Compatibility-sensitive surface and contract-honesty guidance.
205
209
  - [docs/guide.md](docs/guide.md) Usage guide, transport details, streaming behavior, extensions, and examples.
210
+ - [docs/conformance.md](docs/conformance.md) External TCK experiment workflow and artifact handling.
206
211
  - [SECURITY.md](SECURITY.md) Threat model, deployment caveats, and vulnerability disclosure guidance.
207
212
 
208
213
  ## Development
@@ -98,7 +98,7 @@ curl http://127.0.0.1:8000/.well-known/agent-card.json
98
98
  - Declared supported protocol lines: `0.3`, `1.0`
99
99
  - `0.3` is the stable interoperability baseline for the current runtime surface.
100
100
  - `1.0` currently covers version negotiation plus protocol-aware JSON-RPC and REST error shaping, while transport payloads, enums, pagination, signatures, and interface-level protocol declarations still follow the shipped SDK baseline.
101
- - The detailed compatibility matrix and machine-readable support boundary are documented in [`docs/guide.md`](docs/guide.md).
101
+ - The detailed compatibility matrix and machine-readable support boundary are documented in [`docs/guide.md`](docs/guide.md) and [`docs/compatibility.md`](docs/compatibility.md).
102
102
 
103
103
  ## Peering Node / Outbound Access
104
104
 
@@ -162,7 +162,11 @@ Read before deployment:
162
162
 
163
163
  ## Further Reading
164
164
 
165
+ - [docs/architecture.md](docs/architecture.md) Service responsibility boundaries and request flow.
166
+ - [docs/maintainer-architecture.md](docs/maintainer-architecture.md) Internal module boundaries and maintainer call chains.
167
+ - [docs/compatibility.md](docs/compatibility.md) Compatibility-sensitive surface and contract-honesty guidance.
165
168
  - [docs/guide.md](docs/guide.md) Usage guide, transport details, streaming behavior, extensions, and examples.
169
+ - [docs/conformance.md](docs/conformance.md) External TCK experiment workflow and artifact handling.
166
170
  - [SECURITY.md](SECURITY.md) Threat model, deployment caveats, and vulnerability disclosure guidance.
167
171
 
168
172
  ## Development
@@ -0,0 +1,101 @@
1
+ # Architecture Guide
2
+
3
+ This document explains what `opencode-a2a` is responsible for, what remains inside OpenCode, and how requests move through the adapter boundary.
4
+
5
+ ## System Role
6
+
7
+ `opencode-a2a` is an adapter layer between A2A clients and an OpenCode runtime.
8
+
9
+ It is responsible for:
10
+
11
+ - exposing A2A-facing HTTP+JSON and JSON-RPC endpoints
12
+ - normalizing transport, streaming, session, and interrupt contracts
13
+ - applying authentication, logging, persistence, and deployment-side guardrails
14
+ - hosting an outbound A2A client for peer calls triggered by CLI usage or `a2a_call`
15
+
16
+ It is not responsible for:
17
+
18
+ - replacing OpenCode's own provider or model selection internals
19
+ - hard multi-tenant isolation inside one shared deployment by default
20
+ - acting as a general OpenCode process supervisor
21
+
22
+ ## Adapter Layers
23
+
24
+ ```mermaid
25
+ flowchart LR
26
+ Client["A2A Client / Hub / Gateway"] --> Gateway["opencode-a2a"]
27
+ Gateway --> Contracts["A2A contracts\ntransport/session/interrupt"]
28
+ Gateway --> Ops["Auth / logging / persistence / deployment boundary"]
29
+ Contracts --> OpenCode["OpenCode runtime"]
30
+ Ops --> OpenCode
31
+ Gateway --> Peer["Embedded outbound A2A client"]
32
+ ```
33
+
34
+ This view emphasizes service responsibility boundaries rather than internal module structure. The root [README](../README.md) keeps the overview path for first-time readers, while [maintainer-architecture.md](./maintainer-architecture.md) covers module boundaries and request call chains for contributors.
35
+
36
+ ## Request Flow
37
+
38
+ ### Standard send/stream flow
39
+
40
+ 1. A client calls the REST or JSON-RPC endpoint.
41
+ 2. FastAPI middleware validates auth, request size, protocol version, and logging policy.
42
+ 3. The adapter maps transport payloads into the OpenCode-facing execution path.
43
+ 4. The execution layer calls the upstream OpenCode runtime and consumes its stream or unary response.
44
+ 5. The service maps the result back into shared A2A-facing task, message, and stream event contracts.
45
+
46
+ ### Streaming flow
47
+
48
+ For streaming requests, the adapter does more than simple passthrough:
49
+
50
+ - classifies stream blocks into shared types such as `text`, `reasoning`, and `tool_call`
51
+ - preserves stable event and message identity where possible
52
+ - emits shared interrupt lifecycle state
53
+ - avoids duplicate final snapshots when streaming already produced the final text
54
+
55
+ Detailed streaming contract: [Usage Guide](guide.md)
56
+
57
+ ### Session flow
58
+
59
+ The service keeps a shared session continuation contract around `metadata.shared.session.id` and adapter-derived `contextId`, so clients can continue work without binding directly to raw OpenCode session IDs.
60
+
61
+ ### Outbound peer flow
62
+
63
+ The same process can also act as an embedded A2A client:
64
+
65
+ - CLI calls route through the local client facade
66
+ - server-side `a2a_call` tool execution uses the same outbound client settings
67
+ - outbound auth, timeouts, and transport preferences are configured independently from inbound auth
68
+
69
+ ## Boundary Model
70
+
71
+ The adapter improves the runtime boundary, but it is not a full trust-boundary replacement.
72
+
73
+ ### What the adapter boundary helps with
74
+
75
+ - stable A2A-facing contract shape
76
+ - auth enforcement on A2A entrypoints
77
+ - payload logging controls
78
+ - lightweight persistence for SDK task rows plus adapter-managed runtime state
79
+ - compatibility metadata for clients and operators
80
+
81
+ ### What still belongs to the OpenCode runtime boundary
82
+
83
+ - provider credential consumption
84
+ - workspace side effects
85
+ - upstream model/provider behavior
86
+ - host-level process supervision and isolation
87
+
88
+ That is why deployments should still be treated as trusted or controlled unless stronger isolation is added outside this repository.
89
+
90
+ ## Documentation Split
91
+
92
+ Use the docs by responsibility:
93
+
94
+ - [README](../README.md): project overview, install/start path, and entry navigation
95
+ - [Compatibility Guide](compatibility.md): compatibility-sensitive surface and stability expectations
96
+ - [Usage Guide](guide.md): runtime configuration, transport contracts, extensions, and examples
97
+ - [Maintainer Architecture Guide](maintainer-architecture.md): internal module boundaries, request call chains, and persistence touchpoints
98
+ - [Extension Specifications](extension-specifications.md): stable extension URI/spec index and disclosure policy
99
+ - [Conformance Notes](conformance.md): external TCK experiment workflow
100
+ - [Contributing Guide](../CONTRIBUTING.md): contributor workflow and validation
101
+ - [Security Policy](../SECURITY.md): threat model and disclosure guidance
@@ -0,0 +1,147 @@
1
+ # Compatibility Guide
2
+
3
+ This document explains the compatibility promises `opencode-a2a` currently tries to uphold for A2A consumers, operators, and maintainers.
4
+
5
+ ## Runtime Support
6
+
7
+ - Python versions: 3.11, 3.12, 3.13
8
+ - A2A SDK line: `0.3.x`
9
+ - Default advertised protocol line: `0.3`
10
+ - Declared supported protocol lines: `0.3`, `1.0`
11
+
12
+ The repository pins the SDK version in `pyproject.toml`. Upgrade the SDK deliberately rather than relying on floating dependency resolution.
13
+
14
+ ## Contract Honesty
15
+
16
+ Machine-readable discovery surfaces must reflect actual runtime behavior:
17
+
18
+ - public Agent Card
19
+ - authenticated extended card
20
+ - OpenAPI metadata
21
+ - JSON-RPC wire contract
22
+ - compatibility profile
23
+
24
+ If runtime support is not actually implemented, do not publish it as a supported machine-readable capability.
25
+
26
+ Consumer guidance:
27
+
28
+ - Treat the core A2A send / stream / task methods as the portable baseline.
29
+ - Treat `urn:a2a:*` entries in this repository as shared repo-family conventions, not as a claim that they are part of the A2A core baseline.
30
+ - Treat `opencode.*` methods and `metadata.opencode.*` fields as provider-private OpenCode control and discovery surfaces layered on top of the portable A2A baseline.
31
+ - Treat [extension-specifications.md](./extension-specifications.md) as the stable URI/spec index, not as the main usage guide.
32
+
33
+ ## Normative Sources
34
+
35
+ When docs or reference material disagree, treat these as normative in this order:
36
+
37
+ - runtime behavior validated by tests
38
+ - machine-readable discovery output such as Agent Card, authenticated extended card, and OpenAPI metadata
39
+ - repository-owned docs in `README.md`, `docs/`, and `CONTRIBUTING.md`
40
+
41
+ External TCK runs and local conformance experiments are investigation inputs. They do not override the repository's declared contract by themselves.
42
+
43
+ ## Compatibility-Sensitive Surface
44
+
45
+ This repository still ships as an alpha project. Within that alpha line, these declared surfaces should not drift silently:
46
+
47
+ - core A2A send / stream / task methods
48
+ - version negotiation and protocol-aware error shaping
49
+ - shared session-binding metadata
50
+ - shared model-selection metadata
51
+ - shared streaming metadata
52
+ - declared custom JSON-RPC extension methods
53
+ - authenticated extended card and OpenAPI wire-contract metadata
54
+
55
+ Changes to those surfaces should be treated as compatibility-sensitive and should include corresponding test updates.
56
+
57
+ Service-level behavior layered on top of those core methods should also be declared explicitly when interoperability depends on it. Current examples:
58
+
59
+ - `tasks/resubscribe` replay-once behavior for terminal updates
60
+ - first-terminal-state-wins task persistence policy
61
+ - task-scoped `acceptedOutputModes` negotiation persistence across send / stream / get / resubscribe
62
+ - request-body rejection behavior for oversized transport payloads
63
+
64
+ ## Deployment Profile
65
+
66
+ The current service profile is intentionally:
67
+
68
+ - single-tenant
69
+ - shared-workspace
70
+ - adapter boundary around one OpenCode deployment
71
+
72
+ One deployed instance should be treated as a single-tenant trust boundary, not as a secure multi-tenant runtime boundary.
73
+
74
+ Execution-environment boundary fields published through the runtime profile are declarative deployment metadata. They are not promises that every host-side approval, sandbox escalation, or filesystem change will be reflected live per request.
75
+
76
+ ## Persistence Compatibility
77
+
78
+ Task durability is deployment-dependent:
79
+
80
+ - `A2A_TASK_STORE_BACKEND=database` preserves SDK task rows plus adapter-managed session and interrupt state across restarts
81
+ - `A2A_TASK_STORE_BACKEND=memory` keeps the service in an ephemeral development profile
82
+
83
+ Task-store behavior that should remain stable for clients:
84
+
85
+ - once a task reaches a terminal state, later conflicting writes are dropped on a first-terminal-state-wins basis
86
+ - task-store I/O failures are surfaced as stable service errors instead of leaking backend-specific exceptions
87
+ - accepted output-mode negotiation for a task is persisted with the task so later reads keep the same filtered output contract
88
+ - adapter-managed migrations only own adapter state tables; SDK-managed task schema remains SDK-owned
89
+
90
+ The default SQLite-first profile is intended for local or controlled single-instance deployments. Wider SQLAlchemy dialect compatibility should be treated as implementation latitude rather than a strong public promise unless explicitly documented later.
91
+
92
+ ## Extension Stability
93
+
94
+ - Shared metadata and extension contracts should stay synchronized across Agent Card, OpenAPI, and runtime behavior.
95
+ - Public Agent Card should stay intentionally minimal. Detailed extension params belong in the authenticated extended card and OpenAPI, not back in the anonymous discovery surface.
96
+ - Deployment-conditional methods must be declared as conditional rather than silently disappearing.
97
+ - `opencode.sessions.prompt_async` input-part passthrough is compatibility-sensitive. Changes to supported part types, passthrough field semantics, or rejection behavior should be treated as wire-level changes.
98
+ - `opencode.sessions.shell` is compatibility-sensitive as a deployment-conditional shell snapshot surface. It should not silently widen into a general interactive shell API.
99
+ - `opencode.workspaces.*` and `opencode.worktrees.*` are boundary-sensitive and should remain explicitly provider-private, operator-scoped, and deployment-conditional where applicable.
100
+ - Interrupt callback and recovery methods are compatibility-sensitive because clients may depend on request ID lifecycle, expiry semantics, and identity scoping.
101
+ - Agent Card media modes and `acceptedOutputModes` handling are compatibility-sensitive. Changes to declared chat modes, to task-scoped negotiation persistence, or to `DataPart` -> `TextPart` downgrade behavior should be treated as wire-level changes.
102
+ - Agent Card and OpenAPI publication of `protocol_compatibility`, `service_behaviors`, and runtime feature toggles is compatibility-sensitive discoverability surface.
103
+
104
+ ## Extension Boundary Governance
105
+
106
+ When evaluating or evolving `opencode.*` methods, this repository uses the following rules:
107
+
108
+ - The adapter may document, validate, route, and normalize stable upstream-facing behavior, but it should not grow into a general replacement for upstream private runtime internals or host-level control planes.
109
+ - New `opencode.*` methods default to provider-private extension status.
110
+ - Read-only discovery, compatibility-preserving projections, and low-risk control methods are preferred over stronger mutating or destructive provider controls.
111
+ - A2A core object mappings should be used only for stable, low-ambiguity read projections.
112
+ - Subtask/subagent fan-out, task-tool internals, and similar upstream execution mechanisms should stay framed as upstream runtime behavior even when passthrough compatibility exists.
113
+
114
+ Each new extension proposal should answer:
115
+
116
+ - what client value exists beyond the current chat/session flow?
117
+ - is the upstream behavior stable enough to carry as a maintained contract?
118
+ - should the surface be provider-private, deployment-conditional, or excluded?
119
+ - are authorization and destructive-side-effect boundaries enforceable?
120
+ - can the result shape avoid overfitting OpenCode internals into fake A2A core semantics?
121
+
122
+ ## Extension Taxonomy
123
+
124
+ This repository distinguishes between three layers:
125
+
126
+ - core A2A surface
127
+ - standard send / stream / task methods
128
+ - shared extensions
129
+ - repo-family conventions such as session binding, model selection, stream hints, and interrupt callbacks
130
+ - OpenCode-specific extensions
131
+ - `opencode.*` JSON-RPC methods plus `metadata.opencode.*`
132
+
133
+ Important note:
134
+
135
+ - `urn:a2a:*` extension URIs used here should be read as shared conventions in this repository family.
136
+ - They are not a claim that those extensions are part of the A2A core baseline.
137
+ - `opencode.*` methods are intentionally product-specific. They improve OpenCode-aware workflows but should not be assumed to transfer unchanged to unrelated A2A agents.
138
+
139
+ ## Non-Goals
140
+
141
+ This repository does not currently promise:
142
+
143
+ - hard multi-tenant isolation inside one instance
144
+ - generic provider-auth orchestration on behalf of OpenCode
145
+ - a claim that all declared `1.0` protocol surfaces are fully implemented beyond the documented compatibility matrix
146
+
147
+ Those areas may evolve later, but they should not be implied by current machine-readable discovery output.
@@ -1,6 +1,6 @@
1
1
  # Extension Specifications
2
2
 
3
- This document is the stable specification surface referenced by the extension URIs published in the Agent Card. It is intentionally a compact URI/spec index, not the main consumer guide. For runtime behavior, request/response examples, and client integration guidance, see [`guide.md`](./guide.md).
3
+ This document is the stable specification surface referenced by the extension URIs published in the Agent Card. It is intentionally a compact URI/spec index, not the main consumer guide. For runtime behavior, request/response examples, and client integration guidance, see [`guide.md`](./guide.md). For compatibility-sensitive surface and contract-honesty guidance, see [`compatibility.md`](./compatibility.md).
4
4
 
5
5
  ## SDK Compatibility Note
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Usage Guide
2
2
 
3
- This guide covers configuration, authentication, API behavior, streaming re-subscription, and A2A client examples. It is the canonical document for implementation-level protocol contracts and JSON-RPC extension details; README stays at overview level.
3
+ This guide covers configuration, authentication, API behavior, streaming re-subscription, and A2A client examples. It is the canonical document for implementation-level protocol contracts and JSON-RPC extension details; [README](../README.md) stays at overview level, [architecture.md](./architecture.md) explains the service boundary, [maintainer-architecture.md](./maintainer-architecture.md) covers the internal module view for contributors, and [compatibility.md](./compatibility.md) defines the compatibility-sensitive surface.
4
4
 
5
5
  ## Transport Contracts
6
6
 
@@ -199,6 +199,8 @@ If one deployment works while another fails against the same upstream provider,
199
199
  - Main chat requests that explicitly send `configuration.acceptedOutputModes` must stay compatible with the declared chat output modes.
200
200
  - Current main chat requests must continue accepting `text/plain`; requests that only accept `application/json` or other incompatible modes are rejected before execution starts.
201
201
  - `application/json` is additive structured-output support for incremental `tool_call` payloads. It does not guarantee that ordinary assistant prose can always be losslessly represented as JSON, so consumers that expect normal chat text should keep accepting `text/plain`.
202
+ - When a client accepts `text/plain` but not `application/json`, structured `tool_call` payloads are downgraded to compact JSON text instead of being silently dropped.
203
+ - Accepted output-mode negotiation is persisted as task-scoped metadata so later `tasks/get` and `tasks/resubscribe` reads keep the same filtered response contract as the original `message/send` or `message:stream` request.
202
204
  - Main chat input supports structured A2A `parts` passthrough:
203
205
  - `TextPart` is forwarded as an OpenCode text part.
204
206
  - `FilePart(FileWithBytes)` is forwarded as a `file` part with a `data:` URL.
@@ -220,6 +222,8 @@ If one deployment works while another fails against the same upstream provider,
220
222
  - `message.part.delta` and `message.part.updated` are merged per `part_id`; out-of-order deltas are buffered and replayed when the corresponding `part.updated` arrives.
221
223
  - Structured `tool` parts are emitted as `tool_call` blocks backed by `DataPart(data={...})`, while `text` and `reasoning` continue to use `TextPart`.
222
224
  - `tool_call` block payloads are normalized structured objects that may expose fields such as `call_id`, `tool`, `status`, `title`, `subtitle`, `input`, `output`, and `error`.
225
+ - If `application/json` is not accepted but `text/plain` is still accepted, those `tool_call` blocks are downgraded to stable compact JSON text so text-only clients retain the same observable state transitions.
226
+ - When a request restricts `acceptedOutputModes`, the stream applies the same output filtering before persistence so later task snapshots do not re-expose filtered structured blocks.
223
227
  - Final status event metadata may include normalized token usage at `metadata.shared.usage` with fields such as `input_tokens`, `output_tokens`, `total_tokens`, optional `reasoning_tokens`, optional `cache_tokens.read_tokens` / `cache_tokens.write_tokens`, and optional `cost`.
224
228
  - Usage is extracted from documented info payloads and supported usage parts such as `step-finish`; non-usage parts with similar fields are ignored.
225
229
  - Interrupt events (`permission.asked` / `question.asked`) are mapped to `TaskStatusUpdateEvent(final=false, state=input-required)` with details at `metadata.shared.interrupt`, including `request_id`, interrupt `type`, `phase=asked`, and a normalized minimal callback payload.