codex-a2a 1.3.2__tar.gz → 1.3.3__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 (256) hide show
  1. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.pre-commit-config.yaml +11 -2
  2. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/CONTRIBUTING.md +2 -0
  3. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/PKG-INFO +6 -6
  4. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/compatibility.md +3 -1
  5. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/conformance-triage.md +1 -1
  6. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/conformance.md +1 -1
  7. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/pyproject.toml +5 -5
  8. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/README.md +1 -0
  9. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/validate_baseline.sh +2 -1
  10. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/request_handler.py +1 -9
  11. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/PKG-INFO +6 -6
  12. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/SOURCES.txt +1 -0
  13. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/requires.txt +5 -5
  14. codex_a2a-1.3.3/tests/scripts/test_validate_baseline_script.py +89 -0
  15. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_request_handler.py +60 -3
  16. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/uv.lock +319 -247
  17. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/dependabot.yml +0 -0
  18. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/workflows/ci.yml +0 -0
  19. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/workflows/compatibility.yml +0 -0
  20. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/workflows/dependency-health.yml +0 -0
  21. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/workflows/publish.yml +0 -0
  22. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.gitignore +0 -0
  23. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.secrets.baseline +0 -0
  24. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/AGENTS.md +0 -0
  25. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/LICENSE +0 -0
  26. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/README.md +0 -0
  27. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/SECURITY.md +0 -0
  28. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/a2a-extension-baseline.md +0 -0
  29. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/architecture.md +0 -0
  30. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/extension-specifications.md +0 -0
  31. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/guide.md +0 -0
  32. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/inspection/README.md +0 -0
  33. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/inspection/error_redaction_policy.md +0 -0
  34. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/inspection/release_integrity_policy.md +0 -0
  35. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/maintainer-architecture.md +0 -0
  36. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/mypy.ini +0 -0
  37. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/audit_low_call_sites.py +0 -0
  38. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/check_codex_app_server_schema.py +0 -0
  39. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/check_dead_code.py +0 -0
  40. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/conformance.sh +0 -0
  41. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/dependency_health.sh +0 -0
  42. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/health_common.sh +0 -0
  43. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/publish_github_release.sh +0 -0
  44. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/smoke_live_codex_turn.py +0 -0
  45. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/smoke_test_built_cli.sh +0 -0
  46. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/smoke_test_live_codex.sh +0 -0
  47. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/sync_codex_docs.sh +0 -0
  48. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/tck_auth_plugin.py +0 -0
  49. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/validate_runtime_matrix.sh +0 -0
  50. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/setup.cfg +0 -0
  51. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/__init__.py +0 -0
  52. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/a2a_proto.py +0 -0
  53. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/auth.py +0 -0
  54. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/cli.py +0 -0
  55. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/__init__.py +0 -0
  56. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/agent_card.py +0 -0
  57. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/auth.py +0 -0
  58. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/client.py +0 -0
  59. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/config.py +0 -0
  60. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/errors.py +0 -0
  61. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/extension_negotiation.py +0 -0
  62. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/manager.py +0 -0
  63. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/network_policy.py +0 -0
  64. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/payload_text.py +0 -0
  65. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/request_context.py +0 -0
  66. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/config.py +0 -0
  67. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/__init__.py +0 -0
  68. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/extension_registry.py +0 -0
  69. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/extension_specs.py +0 -0
  70. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/extensions.py +0 -0
  71. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/runtime_output.py +0 -0
  72. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/__init__.py +0 -0
  73. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/discovery_runtime.py +0 -0
  74. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/exec_runtime.py +0 -0
  75. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/executor.py +0 -0
  76. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/output_mapping.py +0 -0
  77. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/request_metadata.py +0 -0
  78. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/request_overrides.py +0 -0
  79. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/response_emitter.py +0 -0
  80. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/review_runtime.py +0 -0
  81. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/session_runtime.py +0 -0
  82. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/stream_chunks.py +0 -0
  83. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/stream_interrupts.py +0 -0
  84. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/stream_processor.py +0 -0
  85. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/stream_state.py +0 -0
  86. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/streaming.py +0 -0
  87. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/thread_lifecycle_runtime.py +0 -0
  88. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/tool_call_payloads.py +0 -0
  89. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/watch_events.py +0 -0
  90. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/input_mapping.py +0 -0
  91. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/__init__.py +0 -0
  92. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/application.py +0 -0
  93. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/discovery_control.py +0 -0
  94. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/discovery_params.py +0 -0
  95. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/discovery_payload_mapping.py +0 -0
  96. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/discovery_query.py +0 -0
  97. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/dispatch.py +0 -0
  98. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/errors.py +0 -0
  99. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/exec_control.py +0 -0
  100. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/exec_control_params.py +0 -0
  101. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/hooks.py +0 -0
  102. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupt_lifecycle.py +0 -0
  103. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupt_params.py +0 -0
  104. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupt_recovery.py +0 -0
  105. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupt_recovery_params.py +0 -0
  106. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupts.py +0 -0
  107. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/owner_guard.py +0 -0
  108. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/params.py +0 -0
  109. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/params_common.py +0 -0
  110. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/payload_mapping.py +0 -0
  111. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/query_params.py +0 -0
  112. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/request_models.py +0 -0
  113. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/review_control.py +0 -0
  114. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/review_control_params.py +0 -0
  115. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/session_query.py +0 -0
  116. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/thread_lifecycle_control.py +0 -0
  117. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/thread_lifecycle_params.py +0 -0
  118. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/turn_control.py +0 -0
  119. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/turn_control_params.py +0 -0
  120. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/logging_context.py +0 -0
  121. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/media_modes.py +0 -0
  122. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/metrics.py +0 -0
  123. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/payload_helpers.py +0 -0
  124. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/profile/__init__.py +0 -0
  125. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/profile/runtime.py +0 -0
  126. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/protocol_versions.py +0 -0
  127. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/py.typed +0 -0
  128. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/redact.py +0 -0
  129. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/__init__.py +0 -0
  130. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/agent_card.py +0 -0
  131. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/application.py +0 -0
  132. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/call_context.py +0 -0
  133. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/database.py +0 -0
  134. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/http_middlewares.py +0 -0
  135. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/migrations.py +0 -0
  136. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/openapi.py +0 -0
  137. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/openapi_contract_fragments.py +0 -0
  138. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/output_negotiation.py +0 -0
  139. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/push_config_store.py +0 -0
  140. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/runtime_limits.py +0 -0
  141. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/runtime_state.py +0 -0
  142. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/runtime_state_schema.py +0 -0
  143. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/task_store.py +0 -0
  144. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/skill_handles.py +0 -0
  145. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/__init__.py +0 -0
  146. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/client.py +0 -0
  147. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/conversation_facade.py +0 -0
  148. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/discovery_payloads.py +0 -0
  149. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/interrupt_bridge.py +0 -0
  150. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/interrupts.py +0 -0
  151. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/models.py +0 -0
  152. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/notification_mapping.py +0 -0
  153. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/request_mapping.py +0 -0
  154. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/startup.py +0 -0
  155. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/stream_bridge.py +0 -0
  156. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/transport.py +0 -0
  157. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/dependency_links.txt +0 -0
  158. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/entry_points.txt +0 -0
  159. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/top_level.txt +0 -0
  160. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/__init__.py +0 -0
  161. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/__init__.py +0 -0
  162. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_agent_card.py +0 -0
  163. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_cli.py +0 -0
  164. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_client_flow.py +0 -0
  165. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_client_http_headers.py +0 -0
  166. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_client_manager.py +0 -0
  167. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_errors.py +0 -0
  168. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_lifecycle.py +0 -0
  169. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_network_policy.py +0 -0
  170. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_payload_text.py +0 -0
  171. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_request_context.py +0 -0
  172. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/config/__init__.py +0 -0
  173. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/config/test_settings.py +0 -0
  174. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/contracts/__init__.py +0 -0
  175. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/contracts/test_extension_contract_consistency.py +0 -0
  176. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/contracts/test_extension_registry.py +0 -0
  177. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/__init__.py +0 -0
  178. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_agent_errors.py +0 -0
  179. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_cancellation.py +0 -0
  180. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_codex_agent_session_binding.py +0 -0
  181. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_directory_validation.py +0 -0
  182. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_discovery_exec_runtime.py +0 -0
  183. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_error_redaction.py +0 -0
  184. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_metrics.py +0 -0
  185. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_request_metadata.py +0 -0
  186. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_review_runtime.py +0 -0
  187. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_session_ownership.py +0 -0
  188. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_session_persistence.py +0 -0
  189. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_session_runtime.py +0 -0
  190. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_stream_chunks.py +0 -0
  191. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_stream_interrupts.py +0 -0
  192. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_streaming_output_contract.py +0 -0
  193. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_thread_lifecycle_runtime.py +0 -0
  194. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_tool_call_payloads.py +0 -0
  195. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/fixtures/codex_app_server/command_execution_output_delta.json +0 -0
  196. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/fixtures/codex_app_server/file_change_output_delta.json +0 -0
  197. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/__init__.py +0 -0
  198. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_discovery_extension.py +0 -0
  199. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_exec_extension.py +0 -0
  200. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_session_extension.py +0 -0
  201. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_thread_lifecycle_extension.py +0 -0
  202. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_turn_review_extension.py +0 -0
  203. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_dispatch.py +0 -0
  204. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_error_redaction.py +0 -0
  205. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_guard_hooks.py +0 -0
  206. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_interrupt_lifecycle.py +0 -0
  207. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_interrupt_params.py +0 -0
  208. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_interrupt_protocol_handlers.py +0 -0
  209. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_jsonrpc_models.py +0 -0
  210. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_protocol_payload_mapping.py +0 -0
  211. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/__init__.py +0 -0
  212. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_logging.py +0 -0
  213. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_publish_github_release_script.py +0 -0
  214. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_release_distribution_contract.py +0 -0
  215. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_typing_contract.py +0 -0
  216. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_version.py +0 -0
  217. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/profile/__init__.py +0 -0
  218. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/profile/test_profile.py +0 -0
  219. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/__init__.py +0 -0
  220. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/test_audit_low_call_sites.py +0 -0
  221. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/test_check_codex_app_server_schema.py +0 -0
  222. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/test_script_health_contract.py +0 -0
  223. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/test_tck_auth_plugin.py +0 -0
  224. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/__init__.py +0 -0
  225. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_agent_card.py +0 -0
  226. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_auth.py +0 -0
  227. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_call_context_builder.py +0 -0
  228. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_cli.py +0 -0
  229. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_database.py +0 -0
  230. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_database_app_persistence.py +0 -0
  231. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_http_boundary.py +0 -0
  232. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_migrations.py +0 -0
  233. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_output_negotiation.py +0 -0
  234. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_push_config_store.py +0 -0
  235. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_runtime_limits.py +0 -0
  236. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_runtime_state.py +0 -0
  237. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_task_store.py +0 -0
  238. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_transport_contract.py +0 -0
  239. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/__init__.py +0 -0
  240. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/context.py +0 -0
  241. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/dummy_clients.py +0 -0
  242. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/fixtures.py +0 -0
  243. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/http_auth.py +0 -0
  244. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/jsonrpc_errors.py +0 -0
  245. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/settings.py +0 -0
  246. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_a2a_proto.py +0 -0
  247. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_input_mapping.py +0 -0
  248. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_protocol_versions.py +0 -0
  249. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_redact.py +0 -0
  250. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_skill_handles.py +0 -0
  251. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/__init__.py +0 -0
  252. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_codex_client_params.py +0 -0
  253. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_interrupt_bridge.py +0 -0
  254. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_interrupt_persistence.py +0 -0
  255. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_modular_upstream_components.py +0 -0
  256. {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_request_mapping.py +0 -0
@@ -6,12 +6,21 @@ repos:
6
6
  - id: trailing-whitespace
7
7
  - id: end-of-file-fixer
8
8
  - id: check-yaml
9
- - repo: https://github.com/astral-sh/ruff-pre-commit
10
- rev: v0.14.14
9
+ - repo: local
11
10
  hooks:
12
11
  - id: ruff
12
+ name: ruff check (uv)
13
+ entry: uv run --locked --extra dev ruff check --force-exclude
14
+ language: system
15
+ types_or: [python, pyi, jupyter]
16
+ require_serial: true
13
17
  args: ["--fix"]
14
18
  - id: ruff-format
19
+ name: ruff format (uv)
20
+ entry: uv run --locked --extra dev ruff format --force-exclude
21
+ language: system
22
+ types_or: [python, pyi, jupyter]
23
+ require_serial: true
15
24
  - repo: https://github.com/Yelp/detect-secrets
16
25
  rev: v1.5.0
17
26
  hooks:
@@ -72,6 +72,8 @@ bash -n scripts/smoke_test_built_cli.sh
72
72
 
73
73
  If `pre-commit` rewrites files, review the rewritten output and re-run the checks until the working tree is clean.
74
74
 
75
+ Ruff's version is declared in the `dev` extra in `pyproject.toml` and resolved in `uv.lock`. The local pre-commit hooks run `uv run --locked --extra dev ruff`, so direct commands, hooks, and CI use the same project dependency. To upgrade Ruff, update that dependency and regenerate `uv.lock`; there is no separate Ruff hook revision to maintain.
76
+
75
77
  ## Compatibility Expectations
76
78
 
77
79
  - The repository targets Python 3.11 through 3.14. CI uses 3.13 for the full quality gate and exercises 3.11, 3.12, and 3.14 in the runtime matrix.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-a2a
3
- Version: 1.3.2
3
+ Version: 1.3.3
4
4
  Summary: Codex A2A runtime adapter
5
5
  Author: liujuanjuan1984@Intelligent-Internet
6
6
  License-Expression: Apache-2.0
@@ -23,14 +23,14 @@ Classifier: Topic :: Internet :: WWW/HTTP
23
23
  Requires-Python: >=3.11
24
24
  Description-Content-Type: text/markdown
25
25
  License-File: LICENSE
26
- Requires-Dist: a2a-sdk==1.1.2
26
+ Requires-Dist: a2a-sdk==1.1.5
27
27
  Requires-Dist: aiosqlite<1.0,>=0.20
28
28
  Requires-Dist: fastapi<0.142,>=0.121
29
29
  Requires-Dist: httpx<0.29,>=0.28.1
30
- Requires-Dist: protobuf<7.0,>=6.33.5
30
+ Requires-Dist: protobuf<8.0,>=6.33.5
31
31
  Requires-Dist: pydantic<3.0,>=2.6
32
32
  Requires-Dist: pydantic-settings<3.0,>=2.2
33
- Requires-Dist: sqlalchemy<3.0,>=2.0
33
+ Requires-Dist: sqlalchemy[asyncio]<3.0,>=2.0
34
34
  Requires-Dist: sse-starlette<4.0,>=2.1
35
35
  Requires-Dist: uvicorn<0.53,>=0.29
36
36
  Provides-Extra: dev
@@ -40,8 +40,8 @@ Requires-Dist: pygments<3.0,>=2.20.0; extra == "dev"
40
40
  Requires-Dist: pytest>=8.0; extra == "dev"
41
41
  Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
42
42
  Requires-Dist: pytest-cov<8.0,>=5.0; extra == "dev"
43
- Requires-Dist: diff-cover<10,>=9; extra == "dev"
44
- Requires-Dist: ruff>=0.5; extra == "dev"
43
+ Requires-Dist: diff-cover<11,>=9; extra == "dev"
44
+ Requires-Dist: ruff==0.16.9; extra == "dev"
45
45
  Requires-Dist: mypy<2.4,>=1.11; extra == "dev"
46
46
  Dynamic: license-file
47
47
 
@@ -7,7 +7,9 @@ This document explains the compatibility promises this repository currently trie
7
7
  | Layer | Supported contract | Evidence and boundary |
8
8
  | --- | --- | --- |
9
9
  | Python | 3.11–3.14 | Package classifiers cover all four versions; CI runs 3.13 as the quality gate and 3.11, 3.12, and 3.14 in the runtime matrix. |
10
- | A2A Python SDK | Exactly `a2a-sdk==1.1.2` | Pinned in `pyproject.toml`; this is the [official A2A Python SDK](https://github.com/a2aproject/a2a-python), not a fork. |
10
+ | A2A Python SDK | Exactly `a2a-sdk==1.1.5` | Pinned in `pyproject.toml`; this is the [official A2A Python SDK](https://github.com/a2aproject/a2a-python), not a fork. |
11
+ | Protocol Buffers | `protobuf>=6.33.5,<8.0` | The lockfile selects 7.36.2. SDK 1.1.5 supports protobuf 7; Google API Core, common protos, and proto-plus must resolve within the same range. Task retrieval delegates validation and history trimming to the SDK. |
12
+ | SQLAlchemy | `sqlalchemy[asyncio]>=2.0,<3.0` | The `asyncio` extra explicitly installs `greenlet` for the async persistence engine, including standalone wheel installations. The lockfile selects the development version. |
11
13
  | A2A protocol | `1.0` wire line | The released upstream A2A specification is normative for portable core semantics; the current compatible release is `v1.0.1`. SDK compatibility with other protocol versions does not extend this adapter's claim. |
12
14
  | Inbound A2A transports | JSON-RPC and HTTP+JSON | Both are repository-owned runtime surfaces. gRPC is not exposed by this adapter. |
13
15
  | Codex local runtime | Codex CLI/App Server | The local [Apache-2.0 Codex CLI](https://github.com/openai/codex) is the upstream process boundary. Scheduled smoke tests install the latest stable CLI and complete a real local App Server turn. |
@@ -5,7 +5,7 @@ This document is the standing triage template for local `./scripts/conformance.s
5
5
  ## Authorities Used For Triage
6
6
 
7
7
  - The latest compatible released upstream A2A specification is authoritative; currently this is `v1.0.1` for the repository's advertised `1.0` wire line.
8
- - `a2a-sdk==1.1.2` as installed in this repository.
8
+ - `a2a-sdk==1.1.5` as installed in this repository.
9
9
  - The default A2A protocol version advertised by this repository: `1.0`.
10
10
  - TCK assertions are non-normative observations and may lag the released specification.
11
11
  - Repository compatibility policy:
@@ -74,7 +74,7 @@ When a TCK run fails, inspect the raw report before changing the runtime:
74
74
 
75
75
  - Some failures may point to real runtime gaps.
76
76
  - Some failures may reflect an outdated embedded specification or a TCK-specific interpretation. Resolve those disagreements against the latest compatible released A2A specification.
77
- - Some failures may come from TCK assumptions that do not match `a2a-sdk==1.1.2`.
77
+ - Some failures may come from TCK assumptions that do not match `a2a-sdk==1.1.5`.
78
78
  - Some failures may come from older A2A naming or schema expectations that no longer match the repository's `1.0` contract.
79
79
  - Some failures may be local experiment artifacts from the dummy-backed runtime.
80
80
 
@@ -25,14 +25,14 @@ classifiers = [
25
25
  "Topic :: Internet :: WWW/HTTP",
26
26
  ]
27
27
  dependencies = [
28
- "a2a-sdk==1.1.2",
28
+ "a2a-sdk==1.1.5",
29
29
  "aiosqlite>=0.20,<1.0",
30
30
  "fastapi>=0.121,<0.142",
31
31
  "httpx>=0.28.1,<0.29",
32
- "protobuf>=6.33.5,<7.0",
32
+ "protobuf>=6.33.5,<8.0",
33
33
  "pydantic>=2.6,<3.0",
34
34
  "pydantic-settings>=2.2,<3.0",
35
- "sqlalchemy>=2.0,<3.0",
35
+ "sqlalchemy[asyncio]>=2.0,<3.0",
36
36
  "sse-starlette>=2.1,<4.0",
37
37
  "uvicorn>=0.29,<0.53",
38
38
  ]
@@ -45,8 +45,8 @@ dev = [
45
45
  "pytest>=8.0",
46
46
  "pytest-asyncio>=0.23",
47
47
  "pytest-cov>=5.0,<8.0",
48
- "diff-cover>=9,<10",
49
- "ruff>=0.5",
48
+ "diff-cover>=9,<11",
49
+ "ruff==0.16.9",
50
50
  "mypy>=1.11,<2.4",
51
51
  ]
52
52
 
@@ -38,6 +38,7 @@ The `Publish` workflow now separates build, PyPI publish, and GitHub Release syn
38
38
  - `validate_baseline.sh` now includes a conservative private dead-code check before type-checking and test execution.
39
39
  - `audit_low_call_sites.py` is intentionally advisory only. Use it to surface low-call-count candidates, then inspect the actual consumer chain before removing an abstraction.
40
40
  - `validate_baseline.sh` now blocks on runtime dependency vulnerability audit, while `dependency_health.sh` remains focused on broader dependency review (`outdated` + dev audit).
41
+ - The baseline makes up to three runtime audit attempts (the initial attempt plus at most two retries), with a fresh cache per attempt. If every attempt fails, it returns the last audit exit code and stops before package build and wheel smoke testing. A successful retry allows validation to continue.
41
42
  - [`.github/dependabot.yml`](../.github/dependabot.yml) prefers a single weekly grouped Dependabot PR for `uv`, while the repository scripts remain the explicit audit and validation entrypoints.
42
43
  - End-user runtime startup does not use repository scripts. Prefer the published CLI command documented in [README.md](../README.md) and [docs/guide.md](../docs/guide.md).
43
44
  - Keep long-form documentation changes in `docs/` to avoid divergence.
@@ -19,8 +19,9 @@ run_pip_audit() {
19
19
  if XDG_CACHE_HOME="${audit_cache_dir}" uv run pip-audit --requirement "${requirement_file}"; then
20
20
  rm -rf "${audit_cache_dir}"
21
21
  return 0
22
+ else
23
+ status=$?
22
24
  fi
23
- status=$?
24
25
  rm -rf "${audit_cache_dir}"
25
26
  if [[ "${attempt}" -ge "${max_attempts}" ]]; then
26
27
  echo "pip-audit failed after ${attempt} attempts" >&2
@@ -10,7 +10,6 @@ from a2a.server.events import EventConsumer
10
10
  from a2a.server.events.event_queue import EventQueueLegacy
11
11
  from a2a.server.events.queue_manager import QueueManager
12
12
  from a2a.server.request_handlers import DefaultRequestHandler
13
- from a2a.server.request_handlers.default_request_handler_v2 import validate_history_length
14
13
  from a2a.server.tasks import TaskManager
15
14
  from a2a.types import (
16
15
  Artifact,
@@ -119,17 +118,10 @@ class CodexRequestHandler(DefaultRequestHandler):
119
118
  ):
120
119
  store_context = self._task_store_context(context)
121
120
  try:
122
- # The A2A SDK currently validates GetTaskRequest through a protobuf
123
- # field API that is incompatible with protobuf 7.x. Mirror the small
124
- # upstream get-task flow here so the server remains usable on current deps.
125
- validate_history_length(params)
126
- task = await self.task_store.get(params.id, store_context)
127
- if task is None:
128
- raise TaskNotFoundError()
121
+ task = await super().on_get_task(params, store_context)
129
122
  accepted_output_modes = self._accepted_output_modes_for_task(
130
123
  task_id=params.id, task=task
131
124
  )
132
- task = apply_history_length(task, params)
133
125
  return apply_accepted_output_modes(task, accepted_output_modes)
134
126
  except TaskStoreOperationError as exc:
135
127
  raise self._task_store_server_error(exc) from exc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-a2a
3
- Version: 1.3.2
3
+ Version: 1.3.3
4
4
  Summary: Codex A2A runtime adapter
5
5
  Author: liujuanjuan1984@Intelligent-Internet
6
6
  License-Expression: Apache-2.0
@@ -23,14 +23,14 @@ Classifier: Topic :: Internet :: WWW/HTTP
23
23
  Requires-Python: >=3.11
24
24
  Description-Content-Type: text/markdown
25
25
  License-File: LICENSE
26
- Requires-Dist: a2a-sdk==1.1.2
26
+ Requires-Dist: a2a-sdk==1.1.5
27
27
  Requires-Dist: aiosqlite<1.0,>=0.20
28
28
  Requires-Dist: fastapi<0.142,>=0.121
29
29
  Requires-Dist: httpx<0.29,>=0.28.1
30
- Requires-Dist: protobuf<7.0,>=6.33.5
30
+ Requires-Dist: protobuf<8.0,>=6.33.5
31
31
  Requires-Dist: pydantic<3.0,>=2.6
32
32
  Requires-Dist: pydantic-settings<3.0,>=2.2
33
- Requires-Dist: sqlalchemy<3.0,>=2.0
33
+ Requires-Dist: sqlalchemy[asyncio]<3.0,>=2.0
34
34
  Requires-Dist: sse-starlette<4.0,>=2.1
35
35
  Requires-Dist: uvicorn<0.53,>=0.29
36
36
  Provides-Extra: dev
@@ -40,8 +40,8 @@ Requires-Dist: pygments<3.0,>=2.20.0; extra == "dev"
40
40
  Requires-Dist: pytest>=8.0; extra == "dev"
41
41
  Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
42
42
  Requires-Dist: pytest-cov<8.0,>=5.0; extra == "dev"
43
- Requires-Dist: diff-cover<10,>=9; extra == "dev"
44
- Requires-Dist: ruff>=0.5; extra == "dev"
43
+ Requires-Dist: diff-cover<11,>=9; extra == "dev"
44
+ Requires-Dist: ruff==0.16.9; extra == "dev"
45
45
  Requires-Dist: mypy<2.4,>=1.11; extra == "dev"
46
46
  Dynamic: license-file
47
47
 
@@ -222,6 +222,7 @@ tests/scripts/test_audit_low_call_sites.py
222
222
  tests/scripts/test_check_codex_app_server_schema.py
223
223
  tests/scripts/test_script_health_contract.py
224
224
  tests/scripts/test_tck_auth_plugin.py
225
+ tests/scripts/test_validate_baseline_script.py
225
226
  tests/server/__init__.py
226
227
  tests/server/test_agent_card.py
227
228
  tests/server/test_auth.py
@@ -1,11 +1,11 @@
1
- a2a-sdk==1.1.2
1
+ a2a-sdk==1.1.5
2
2
  aiosqlite<1.0,>=0.20
3
3
  fastapi<0.142,>=0.121
4
4
  httpx<0.29,>=0.28.1
5
- protobuf<7.0,>=6.33.5
5
+ protobuf<8.0,>=6.33.5
6
6
  pydantic<3.0,>=2.6
7
7
  pydantic-settings<3.0,>=2.2
8
- sqlalchemy<3.0,>=2.0
8
+ sqlalchemy[asyncio]<3.0,>=2.0
9
9
  sse-starlette<4.0,>=2.1
10
10
  uvicorn<0.53,>=0.29
11
11
 
@@ -16,6 +16,6 @@ pygments<3.0,>=2.20.0
16
16
  pytest>=8.0
17
17
  pytest-asyncio>=0.23
18
18
  pytest-cov<8.0,>=5.0
19
- diff-cover<10,>=9
20
- ruff>=0.5
19
+ diff-cover<11,>=9
20
+ ruff==0.16.9
21
21
  mypy<2.4,>=1.11
@@ -0,0 +1,89 @@
1
+ import json
2
+ import os
3
+ import subprocess
4
+ import textwrap
5
+ from pathlib import Path
6
+
7
+ import pytest
8
+
9
+ BASELINE_SCRIPT = Path(__file__).resolve().parents[2] / "scripts" / "validate_baseline.sh"
10
+
11
+
12
+ @pytest.mark.parametrize(
13
+ ("audit_statuses", "expected_status"),
14
+ [([0], 0), ([7, 0], 0), ([7, 8, 0], 0), ([1, 1, 1], 1), ([2, 2, 2], 2), ([7, 8, 9], 9)],
15
+ )
16
+ def test_baseline_audit_gates_build_and_preserves_failure_status(
17
+ tmp_path: Path, audit_statuses: list[int], expected_status: int
18
+ ) -> None:
19
+ subprocess.run(["git", "init", "--quiet", str(tmp_path)], check=True)
20
+ bin_dir = tmp_path / "bin"
21
+ bin_dir.mkdir()
22
+ fake_uv = bin_dir / "uv"
23
+ fake_uv.write_text(
24
+ textwrap.dedent(
25
+ """\
26
+ #!/usr/bin/env python3
27
+ import json
28
+ import os
29
+ import sys
30
+ from pathlib import Path
31
+
32
+ args = sys.argv[1:]
33
+ log = Path("commands.jsonl")
34
+ calls = []
35
+ if log.exists():
36
+ calls = [json.loads(line) for line in log.read_text().splitlines()]
37
+ entry = {"args": args}
38
+ status = 0
39
+ if args[:2] == ["run", "pip-audit"]:
40
+ attempt = sum(call["args"][:2] == ["run", "pip-audit"] for call in calls)
41
+ status = json.loads(os.environ["AUDIT_STATUSES"])[attempt]
42
+ entry["cache"] = os.environ["XDG_CACHE_HOME"]
43
+ assert Path(entry["cache"]).is_dir()
44
+ assert Path(args[args.index("--requirement") + 1]).is_file()
45
+ elif args[0] == "export":
46
+ Path(args[args.index("--output-file") + 1]).write_text("example==1.0\\n")
47
+ elif args[0] == "build":
48
+ Path("dist").mkdir()
49
+ Path("dist/codex_a2a-0.0.0-py3-none-any.whl").touch()
50
+ with log.open("a") as handle:
51
+ handle.write(json.dumps(entry) + "\\n")
52
+ sys.exit(status)
53
+ """
54
+ )
55
+ )
56
+ fake_uv.chmod(0o755)
57
+ fake_sleep = bin_dir / "sleep"
58
+ fake_sleep.write_text("#!/usr/bin/env bash\nexit 0\n")
59
+ fake_sleep.chmod(0o755)
60
+ scripts_dir = tmp_path / "scripts"
61
+ scripts_dir.mkdir()
62
+ (scripts_dir / "smoke_test_built_cli.sh").write_text("touch smoke-ran\n")
63
+
64
+ result = subprocess.run(
65
+ ["bash", str(BASELINE_SCRIPT)],
66
+ cwd=tmp_path,
67
+ env={
68
+ **os.environ,
69
+ "PATH": f"{bin_dir}{os.pathsep}{os.environ['PATH']}",
70
+ "AUDIT_STATUSES": json.dumps(audit_statuses),
71
+ },
72
+ capture_output=True,
73
+ text=True,
74
+ check=False,
75
+ timeout=15,
76
+ )
77
+
78
+ assert result.returncode == expected_status, result.stdout + result.stderr
79
+ calls = [json.loads(line) for line in (tmp_path / "commands.jsonl").read_text().splitlines()]
80
+ audits = [call for call in calls if call["args"][:2] == ["run", "pip-audit"]]
81
+ assert len(audits) == len(audit_statuses)
82
+ assert len({call["cache"] for call in audits}) == len(audits)
83
+ assert all(not Path(call["cache"]).exists() for call in audits)
84
+ requirements = audits[0]["args"][-1]
85
+ assert not Path(requirements).exists()
86
+ assert any(call["args"][0] == "build" for call in calls) == (expected_status == 0)
87
+ assert (tmp_path / "smoke-ran").exists() == (expected_status == 0)
88
+ if expected_status:
89
+ assert "pip-audit failed after 3 attempts" in result.stderr
@@ -27,7 +27,12 @@ from a2a.types import (
27
27
  TaskStatus,
28
28
  TaskStatusUpdateEvent,
29
29
  )
30
- from a2a.utils.errors import InternalError, UnsupportedOperationError
30
+ from a2a.utils.errors import (
31
+ InternalError,
32
+ InvalidParamsError,
33
+ TaskNotFoundError,
34
+ UnsupportedOperationError,
35
+ )
31
36
 
32
37
  from codex_a2a.a2a_proto import (
33
38
  new_data_part,
@@ -542,7 +547,13 @@ async def test_message_send_stream_filters_unaccepted_output_parts_to_text() ->
542
547
 
543
548
 
544
549
  @pytest.mark.asyncio
545
- async def test_get_task_applies_stored_output_negotiation() -> None:
550
+ @pytest.mark.parametrize(
551
+ ("history_length", "expected_ids"),
552
+ [(None, ["m-1", "m-2"]), (0, []), (1, ["m-2"]), (10, ["m-1", "m-2"])],
553
+ )
554
+ async def test_get_task_applies_stored_output_negotiation(
555
+ history_length: int | None, expected_ids: list[str]
556
+ ) -> None:
546
557
  task_store = InMemoryTaskStore()
547
558
  task = Task(
548
559
  id="task-1",
@@ -561,15 +572,61 @@ async def test_get_task_applies_stored_output_negotiation() -> None:
561
572
  parts=[new_data_part({"kind": "state", "tool": "bash"})],
562
573
  )
563
574
  ],
575
+ history=[
576
+ Message(
577
+ message_id=message_id,
578
+ role=Role.ROLE_AGENT,
579
+ parts=[new_data_part({"kind": "state", "tool": "bash"})],
580
+ )
581
+ for message_id in ("m-1", "m-2")
582
+ ],
564
583
  metadata=merge_output_negotiation_metadata(None, ["text/plain"]),
565
584
  )
566
585
  await task_store.save(task, _server_context())
567
586
  handler = _make_handler(task_store=task_store)
568
587
 
569
- result = await handler.on_get_task(GetTaskRequest(id="task-1"))
588
+ params = GetTaskRequest(id="task-1")
589
+ if history_length is not None:
590
+ params.history_length = history_length
591
+ result = await handler.on_get_task(params)
570
592
 
571
593
  assert part_text(result.status.message.parts[0]) == '{"kind":"state","tool":"bash"}'
572
594
  assert part_text(result.artifacts[0].parts[0]) == '{"kind":"state","tool":"bash"}'
595
+ assert [message.message_id for message in result.history] == expected_ids
596
+ assert all(
597
+ part_text(message.parts[0]) == '{"kind":"state","tool":"bash"}'
598
+ for message in result.history
599
+ )
600
+ stored_task = await task_store.get("task-1", _server_context())
601
+ assert stored_task is not None
602
+ assert [message.message_id for message in stored_task.history] == ["m-1", "m-2"]
603
+ assert stored_task.artifacts[0].parts[0].WhichOneof("content") == "data"
604
+
605
+
606
+ @pytest.mark.asyncio
607
+ @pytest.mark.parametrize(
608
+ "params", [GetTaskRequest(), GetTaskRequest(id="task-1", history_length=-1)]
609
+ )
610
+ async def test_get_task_validates_request_before_accessing_store(params: GetTaskRequest) -> None:
611
+ task_store = _mock_task_store()
612
+ handler = _make_handler(task_store=task_store)
613
+
614
+ with pytest.raises(InvalidParamsError):
615
+ await handler.on_get_task(params)
616
+
617
+ task_store.get.assert_not_awaited()
618
+
619
+
620
+ @pytest.mark.asyncio
621
+ async def test_get_task_preserves_context_and_missing_task_error() -> None:
622
+ task_store = _mock_task_store()
623
+ handler = _make_handler(task_store=task_store)
624
+ context = _server_context()
625
+
626
+ with pytest.raises(TaskNotFoundError):
627
+ await handler.on_get_task(GetTaskRequest(id="missing"), context)
628
+
629
+ task_store.get.assert_awaited_once_with("missing", context)
573
630
 
574
631
 
575
632
  @pytest.mark.asyncio