codex-a2a 1.3.3__tar.gz → 1.3.5__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 (260) hide show
  1. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/PKG-INFO +1 -1
  2. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/maintainer-architecture.md +10 -0
  3. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/discovery_runtime.py +22 -16
  4. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/exec_runtime.py +9 -3
  5. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/review_runtime.py +33 -31
  6. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/thread_lifecycle_runtime.py +18 -16
  7. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/application.py +15 -13
  8. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/output_negotiation.py +0 -109
  9. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/request_handler.py +147 -55
  10. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/client.py +6 -4
  11. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/stream_bridge.py +2 -2
  12. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a.egg-info/PKG-INFO +1 -1
  13. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a.egg-info/SOURCES.txt +4 -0
  14. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_discovery_exec_runtime.py +100 -0
  15. codex_a2a-1.3.5/tests/execution/test_watch_lifecycle.py +69 -0
  16. codex_a2a-1.3.5/tests/fixtures/sdk_task_store_main_0a3fb68.sql +19 -0
  17. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_request_handler.py +13 -40
  18. codex_a2a-1.3.5/tests/server/test_request_handler_lifecycle.py +343 -0
  19. codex_a2a-1.3.5/tests/server/test_sdk_upgrade.py +379 -0
  20. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/upstream/test_codex_client_params.py +22 -0
  21. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/uv.lock +13 -12
  22. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/.github/dependabot.yml +0 -0
  23. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/.github/workflows/ci.yml +0 -0
  24. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/.github/workflows/compatibility.yml +0 -0
  25. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/.github/workflows/dependency-health.yml +0 -0
  26. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/.github/workflows/publish.yml +0 -0
  27. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/.gitignore +0 -0
  28. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/.pre-commit-config.yaml +0 -0
  29. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/.secrets.baseline +0 -0
  30. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/AGENTS.md +0 -0
  31. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/CONTRIBUTING.md +0 -0
  32. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/LICENSE +0 -0
  33. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/README.md +0 -0
  34. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/SECURITY.md +0 -0
  35. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/a2a-extension-baseline.md +0 -0
  36. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/architecture.md +0 -0
  37. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/compatibility.md +0 -0
  38. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/conformance-triage.md +0 -0
  39. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/conformance.md +0 -0
  40. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/extension-specifications.md +0 -0
  41. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/guide.md +0 -0
  42. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/inspection/README.md +0 -0
  43. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/inspection/error_redaction_policy.md +0 -0
  44. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/docs/inspection/release_integrity_policy.md +0 -0
  45. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/mypy.ini +0 -0
  46. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/pyproject.toml +0 -0
  47. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/README.md +0 -0
  48. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/audit_low_call_sites.py +0 -0
  49. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/check_codex_app_server_schema.py +0 -0
  50. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/check_dead_code.py +0 -0
  51. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/conformance.sh +0 -0
  52. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/dependency_health.sh +0 -0
  53. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/health_common.sh +0 -0
  54. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/publish_github_release.sh +0 -0
  55. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/smoke_live_codex_turn.py +0 -0
  56. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/smoke_test_built_cli.sh +0 -0
  57. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/smoke_test_live_codex.sh +0 -0
  58. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/sync_codex_docs.sh +0 -0
  59. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/tck_auth_plugin.py +0 -0
  60. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/validate_baseline.sh +0 -0
  61. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/scripts/validate_runtime_matrix.sh +0 -0
  62. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/setup.cfg +0 -0
  63. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/__init__.py +0 -0
  64. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/a2a_proto.py +0 -0
  65. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/auth.py +0 -0
  66. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/cli.py +0 -0
  67. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/__init__.py +0 -0
  68. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/agent_card.py +0 -0
  69. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/auth.py +0 -0
  70. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/client.py +0 -0
  71. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/config.py +0 -0
  72. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/errors.py +0 -0
  73. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/extension_negotiation.py +0 -0
  74. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/manager.py +0 -0
  75. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/network_policy.py +0 -0
  76. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/payload_text.py +0 -0
  77. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/client/request_context.py +0 -0
  78. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/config.py +0 -0
  79. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/contracts/__init__.py +0 -0
  80. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/contracts/extension_registry.py +0 -0
  81. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/contracts/extension_specs.py +0 -0
  82. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/contracts/extensions.py +0 -0
  83. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/contracts/runtime_output.py +0 -0
  84. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/__init__.py +0 -0
  85. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/executor.py +0 -0
  86. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/output_mapping.py +0 -0
  87. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/request_metadata.py +0 -0
  88. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/request_overrides.py +0 -0
  89. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/response_emitter.py +0 -0
  90. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/session_runtime.py +0 -0
  91. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/stream_chunks.py +0 -0
  92. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/stream_interrupts.py +0 -0
  93. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/stream_processor.py +0 -0
  94. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/stream_state.py +0 -0
  95. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/streaming.py +0 -0
  96. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/tool_call_payloads.py +0 -0
  97. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/execution/watch_events.py +0 -0
  98. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/input_mapping.py +0 -0
  99. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/__init__.py +0 -0
  100. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/application.py +0 -0
  101. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/discovery_control.py +0 -0
  102. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/discovery_params.py +0 -0
  103. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/discovery_payload_mapping.py +0 -0
  104. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/discovery_query.py +0 -0
  105. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/dispatch.py +0 -0
  106. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/errors.py +0 -0
  107. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/exec_control.py +0 -0
  108. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/exec_control_params.py +0 -0
  109. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/hooks.py +0 -0
  110. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/interrupt_lifecycle.py +0 -0
  111. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/interrupt_params.py +0 -0
  112. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/interrupt_recovery.py +0 -0
  113. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/interrupt_recovery_params.py +0 -0
  114. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/interrupts.py +0 -0
  115. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/owner_guard.py +0 -0
  116. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/params.py +0 -0
  117. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/params_common.py +0 -0
  118. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/payload_mapping.py +0 -0
  119. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/query_params.py +0 -0
  120. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/request_models.py +0 -0
  121. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/review_control.py +0 -0
  122. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/review_control_params.py +0 -0
  123. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/session_query.py +0 -0
  124. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/thread_lifecycle_control.py +0 -0
  125. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/thread_lifecycle_params.py +0 -0
  126. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/turn_control.py +0 -0
  127. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/jsonrpc/turn_control_params.py +0 -0
  128. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/logging_context.py +0 -0
  129. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/media_modes.py +0 -0
  130. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/metrics.py +0 -0
  131. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/payload_helpers.py +0 -0
  132. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/profile/__init__.py +0 -0
  133. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/profile/runtime.py +0 -0
  134. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/protocol_versions.py +0 -0
  135. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/py.typed +0 -0
  136. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/redact.py +0 -0
  137. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/__init__.py +0 -0
  138. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/agent_card.py +0 -0
  139. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/call_context.py +0 -0
  140. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/database.py +0 -0
  141. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/http_middlewares.py +0 -0
  142. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/migrations.py +0 -0
  143. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/openapi.py +0 -0
  144. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/openapi_contract_fragments.py +0 -0
  145. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/push_config_store.py +0 -0
  146. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/runtime_limits.py +0 -0
  147. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/runtime_state.py +0 -0
  148. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/runtime_state_schema.py +0 -0
  149. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/server/task_store.py +0 -0
  150. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/skill_handles.py +0 -0
  151. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/__init__.py +0 -0
  152. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/conversation_facade.py +0 -0
  153. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/discovery_payloads.py +0 -0
  154. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/interrupt_bridge.py +0 -0
  155. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/interrupts.py +0 -0
  156. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/models.py +0 -0
  157. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/notification_mapping.py +0 -0
  158. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/request_mapping.py +0 -0
  159. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/startup.py +0 -0
  160. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a/upstream/transport.py +0 -0
  161. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a.egg-info/dependency_links.txt +0 -0
  162. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a.egg-info/entry_points.txt +0 -0
  163. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a.egg-info/requires.txt +0 -0
  164. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/src/codex_a2a.egg-info/top_level.txt +0 -0
  165. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/__init__.py +0 -0
  166. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/__init__.py +0 -0
  167. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_agent_card.py +0 -0
  168. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_cli.py +0 -0
  169. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_client_flow.py +0 -0
  170. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_client_http_headers.py +0 -0
  171. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_client_manager.py +0 -0
  172. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_errors.py +0 -0
  173. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_lifecycle.py +0 -0
  174. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_network_policy.py +0 -0
  175. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_payload_text.py +0 -0
  176. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/client/test_request_context.py +0 -0
  177. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/config/__init__.py +0 -0
  178. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/config/test_settings.py +0 -0
  179. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/contracts/__init__.py +0 -0
  180. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/contracts/test_extension_contract_consistency.py +0 -0
  181. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/contracts/test_extension_registry.py +0 -0
  182. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/__init__.py +0 -0
  183. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_agent_errors.py +0 -0
  184. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_cancellation.py +0 -0
  185. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_codex_agent_session_binding.py +0 -0
  186. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_directory_validation.py +0 -0
  187. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_error_redaction.py +0 -0
  188. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_metrics.py +0 -0
  189. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_request_metadata.py +0 -0
  190. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_review_runtime.py +0 -0
  191. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_session_ownership.py +0 -0
  192. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_session_persistence.py +0 -0
  193. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_session_runtime.py +0 -0
  194. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_stream_chunks.py +0 -0
  195. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_stream_interrupts.py +0 -0
  196. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_streaming_output_contract.py +0 -0
  197. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_thread_lifecycle_runtime.py +0 -0
  198. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/execution/test_tool_call_payloads.py +0 -0
  199. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/fixtures/codex_app_server/command_execution_output_delta.json +0 -0
  200. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/fixtures/codex_app_server/file_change_output_delta.json +0 -0
  201. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/__init__.py +0 -0
  202. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_codex_discovery_extension.py +0 -0
  203. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_codex_exec_extension.py +0 -0
  204. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_codex_session_extension.py +0 -0
  205. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_codex_thread_lifecycle_extension.py +0 -0
  206. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_codex_turn_review_extension.py +0 -0
  207. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_dispatch.py +0 -0
  208. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_error_redaction.py +0 -0
  209. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_guard_hooks.py +0 -0
  210. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_interrupt_lifecycle.py +0 -0
  211. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_interrupt_params.py +0 -0
  212. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_interrupt_protocol_handlers.py +0 -0
  213. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_jsonrpc_models.py +0 -0
  214. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/jsonrpc/test_protocol_payload_mapping.py +0 -0
  215. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/package/__init__.py +0 -0
  216. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/package/test_logging.py +0 -0
  217. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/package/test_publish_github_release_script.py +0 -0
  218. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/package/test_release_distribution_contract.py +0 -0
  219. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/package/test_typing_contract.py +0 -0
  220. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/package/test_version.py +0 -0
  221. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/profile/__init__.py +0 -0
  222. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/profile/test_profile.py +0 -0
  223. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/scripts/__init__.py +0 -0
  224. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/scripts/test_audit_low_call_sites.py +0 -0
  225. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/scripts/test_check_codex_app_server_schema.py +0 -0
  226. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/scripts/test_script_health_contract.py +0 -0
  227. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/scripts/test_tck_auth_plugin.py +0 -0
  228. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/scripts/test_validate_baseline_script.py +0 -0
  229. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/__init__.py +0 -0
  230. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_agent_card.py +0 -0
  231. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_auth.py +0 -0
  232. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_call_context_builder.py +0 -0
  233. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_cli.py +0 -0
  234. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_database.py +0 -0
  235. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_database_app_persistence.py +0 -0
  236. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_http_boundary.py +0 -0
  237. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_migrations.py +0 -0
  238. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_output_negotiation.py +0 -0
  239. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_push_config_store.py +0 -0
  240. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_runtime_limits.py +0 -0
  241. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_runtime_state.py +0 -0
  242. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_task_store.py +0 -0
  243. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/server/test_transport_contract.py +0 -0
  244. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/support/__init__.py +0 -0
  245. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/support/context.py +0 -0
  246. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/support/dummy_clients.py +0 -0
  247. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/support/fixtures.py +0 -0
  248. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/support/http_auth.py +0 -0
  249. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/support/jsonrpc_errors.py +0 -0
  250. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/support/settings.py +0 -0
  251. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/test_a2a_proto.py +0 -0
  252. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/test_input_mapping.py +0 -0
  253. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/test_protocol_versions.py +0 -0
  254. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/test_redact.py +0 -0
  255. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/test_skill_handles.py +0 -0
  256. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/upstream/__init__.py +0 -0
  257. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/upstream/test_interrupt_bridge.py +0 -0
  258. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/upstream/test_interrupt_persistence.py +0 -0
  259. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/upstream/test_modular_upstream_components.py +0 -0
  260. {codex_a2a-1.3.3 → codex_a2a-1.3.5}/tests/upstream/test_request_mapping.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-a2a
3
- Version: 1.3.3
3
+ Version: 1.3.5
4
4
  Summary: Codex A2A runtime adapter
5
5
  Author: liujuanjuan1984@Intelligent-Internet
6
6
  License-Expression: Apache-2.0
@@ -74,6 +74,16 @@ flowchart TD
74
74
  - **Session State**: Stores the binding of `context_id` to `session_id`.
75
75
  - **Interrupt Store**: Stores pending interrupt requests to survive service restarts.
76
76
 
77
+ ## Background Streams and Shutdown
78
+
79
+ Background streams use SDK Source/Sink queues: producers persist once before
80
+ broadcasting, and slow or disconnected subscribers cannot block other consumers.
81
+ Shutdown drains SDK and adapter tasks before closing clients and stores.
82
+
83
+ Use the [standard upgrade procedure](./guide.md#released-cli-self-start) and restart;
84
+ the task-store format is unchanged. SDK upgrade regressions run in normal CI and
85
+ can be checked with `uv run pytest --no-cov tests/server/test_sdk_upgrade.py`.
86
+
77
87
  ## Configuration Layering
78
88
 
79
89
  Configuration is handled in `src/codex_a2a/config.py` using `pydantic-settings`. It is categorized by prefix:
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import asyncio
4
4
  import logging
5
5
  import uuid
6
+ from contextlib import aclosing
6
7
  from dataclasses import dataclass
7
8
  from typing import TYPE_CHECKING, Any
8
9
 
@@ -94,22 +95,27 @@ class CodexDiscoveryRuntime:
94
95
 
95
96
  async def _run_watch(self, *, handle: DiscoveryWatchHandle, event_queue) -> None: # noqa: ANN001
96
97
  append = False
97
- async for event in self._client.stream_events(stop_event=handle.stop_event):
98
- payload = self._payload_from_event(event, events=handle.events)
99
- if payload is None:
100
- continue
101
- await enqueue_artifact_update(
102
- event_queue=event_queue,
103
- task_id=handle.task_id,
104
- context_id=handle.context_id,
105
- artifact_id=f"{handle.task_id}:discovery",
106
- part=new_data_part(payload),
107
- append=append,
108
- last_chunk=None,
109
- artifact_metadata={"codex": {"discovery_watch": {"events": sorted(handle.events)}}},
110
- event_metadata={"codex": {"discovery_watch": {"events": sorted(handle.events)}}},
111
- )
112
- append = True
98
+ async with aclosing(self._client.stream_events(stop_event=handle.stop_event)) as events:
99
+ async for event in events:
100
+ payload = self._payload_from_event(event, events=handle.events)
101
+ if payload is None:
102
+ continue
103
+ await enqueue_artifact_update(
104
+ event_queue=event_queue,
105
+ task_id=handle.task_id,
106
+ context_id=handle.context_id,
107
+ artifact_id=f"{handle.task_id}:discovery",
108
+ part=new_data_part(payload),
109
+ append=append,
110
+ last_chunk=None,
111
+ artifact_metadata={
112
+ "codex": {"discovery_watch": {"events": sorted(handle.events)}}
113
+ },
114
+ event_metadata={
115
+ "codex": {"discovery_watch": {"events": sorted(handle.events)}}
116
+ },
117
+ )
118
+ append = True
113
119
 
114
120
  def _payload_from_event(
115
121
  self,
@@ -278,10 +278,16 @@ class CodexExecRuntime:
278
278
  )
279
279
  finally:
280
280
  handle.stop_event.set()
281
+ child_tasks: list[asyncio.Future] = [exec_task]
281
282
  if pending_event_task is not None:
282
- pending_event_task.cancel()
283
- with contextlib.suppress(asyncio.CancelledError):
284
- await pending_event_task
283
+ child_tasks.append(pending_event_task)
284
+ for child_task in child_tasks:
285
+ if not child_task.done() and not (
286
+ isinstance(child_task, asyncio.Task) and child_task.cancelling()
287
+ ):
288
+ child_task.cancel()
289
+ await asyncio.gather(*child_tasks, return_exceptions=True)
290
+ await stream_iter.aclose()
285
291
 
286
292
  async def _emit_output_delta(
287
293
  self,
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import asyncio
4
4
  import logging
5
5
  import uuid
6
+ from contextlib import aclosing
6
7
  from dataclasses import dataclass
7
8
  from typing import TYPE_CHECKING, Any
8
9
 
@@ -132,39 +133,40 @@ class CodexReviewRuntime:
132
133
  )
133
134
  append = True
134
135
 
135
- async for event in self._client.stream_events(stop_event=handle.stop_event):
136
- payload = self._payload_from_event(event, handle=handle)
137
- if payload is None:
138
- continue
139
- is_terminal = payload["event"] in {"review.completed", "review.failed"}
140
- await enqueue_artifact_update(
141
- event_queue=event_queue,
142
- task_id=handle.task_id,
143
- context_id=handle.context_id,
144
- artifact_id=f"{handle.task_id}:review-watch",
145
- part=new_data_part(payload),
146
- append=append,
147
- last_chunk=is_terminal,
148
- artifact_metadata=metadata,
149
- event_metadata=metadata,
150
- )
151
- append = True
152
- if is_terminal:
153
- await event_queue.enqueue_event(
154
- TaskStatusUpdateEvent(
155
- task_id=handle.task_id,
156
- context_id=handle.context_id,
157
- status=TaskStatus(
158
- state=(
159
- TaskState.TASK_STATE_COMPLETED
160
- if payload["event"] == "review.completed"
161
- else TaskState.TASK_STATE_FAILED
136
+ async with aclosing(self._client.stream_events(stop_event=handle.stop_event)) as events:
137
+ async for event in events:
138
+ payload = self._payload_from_event(event, handle=handle)
139
+ if payload is None:
140
+ continue
141
+ is_terminal = payload["event"] in {"review.completed", "review.failed"}
142
+ await enqueue_artifact_update(
143
+ event_queue=event_queue,
144
+ task_id=handle.task_id,
145
+ context_id=handle.context_id,
146
+ artifact_id=f"{handle.task_id}:review-watch",
147
+ part=new_data_part(payload),
148
+ append=append,
149
+ last_chunk=is_terminal,
150
+ artifact_metadata=metadata,
151
+ event_metadata=metadata,
152
+ )
153
+ append = True
154
+ if is_terminal:
155
+ await event_queue.enqueue_event(
156
+ TaskStatusUpdateEvent(
157
+ task_id=handle.task_id,
158
+ context_id=handle.context_id,
159
+ status=TaskStatus(
160
+ state=(
161
+ TaskState.TASK_STATE_COMPLETED
162
+ if payload["event"] == "review.completed"
163
+ else TaskState.TASK_STATE_FAILED
164
+ ),
162
165
  ),
163
- ),
164
- metadata=metadata,
166
+ metadata=metadata,
167
+ )
165
168
  )
166
- )
167
- break
169
+ break
168
170
 
169
171
  def _started_payload(self, handle: ReviewWatchHandle) -> dict[str, Any] | None:
170
172
  if "review.started" not in handle.events:
@@ -5,6 +5,7 @@ import hashlib
5
5
  import json
6
6
  import logging
7
7
  import uuid
8
+ from contextlib import aclosing
8
9
  from dataclasses import dataclass
9
10
  from typing import TYPE_CHECKING, Any, TypeGuard
10
11
 
@@ -212,22 +213,23 @@ class CodexThreadLifecycleRuntime:
212
213
  }
213
214
  }
214
215
  try:
215
- async for event in self._client.stream_events(stop_event=handle.stop_event):
216
- payload = self._payload_from_event(event, handle=handle)
217
- if payload is None:
218
- continue
219
- await enqueue_artifact_update(
220
- event_queue=event_queue,
221
- task_id=handle.task_id,
222
- context_id=handle.context_id,
223
- artifact_id=f"{handle.task_id}:thread-lifecycle",
224
- part=new_data_part(payload),
225
- append=append,
226
- last_chunk=None,
227
- artifact_metadata=metadata,
228
- event_metadata=metadata,
229
- )
230
- append = True
216
+ async with aclosing(self._client.stream_events(stop_event=handle.stop_event)) as events:
217
+ async for event in events:
218
+ payload = self._payload_from_event(event, handle=handle)
219
+ if payload is None:
220
+ continue
221
+ await enqueue_artifact_update(
222
+ event_queue=event_queue,
223
+ task_id=handle.task_id,
224
+ context_id=handle.context_id,
225
+ artifact_id=f"{handle.task_id}:thread-lifecycle",
226
+ part=new_data_part(payload),
227
+ append=append,
228
+ last_chunk=None,
229
+ artifact_metadata=metadata,
230
+ event_metadata=metadata,
231
+ )
232
+ append = True
231
233
  except asyncio.CancelledError:
232
234
  release_reason = "task_cancel"
233
235
  raise
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from contextlib import asynccontextmanager
4
+ from contextlib import AsyncExitStack, asynccontextmanager
5
5
  from typing import Any
6
6
 
7
7
  import uvicorn
@@ -288,22 +288,24 @@ def create_app(settings: Settings) -> FastAPI:
288
288
  persistence_summary["database_url"],
289
289
  persistence_summary["sqlite_tuning"],
290
290
  )
291
- await task_store_runtime.startup()
292
- await push_config_store_runtime.startup()
293
- await runtime_state_runtime.startup()
294
- try:
291
+ async with AsyncExitStack() as cleanup:
292
+ if shared_database_engine is not None:
293
+ cleanup.push_async_callback(shared_database_engine.dispose)
294
+ await task_store_runtime.startup()
295
+ cleanup.push_async_callback(task_store_runtime.shutdown)
296
+ await push_config_store_runtime.startup()
297
+ cleanup.push_async_callback(push_config_store_runtime.shutdown)
298
+ await runtime_state_runtime.startup()
299
+ cleanup.push_async_callback(runtime_state_runtime.shutdown)
300
+ cleanup.push_async_callback(client.close)
301
+ cleanup.push_async_callback(a2a_client_manager.close_all)
302
+ # Callbacks run in reverse order. Producers may still need clients
303
+ # and stores while unwinding, even if another cleanup callback fails.
304
+ cleanup.push_async_callback(handler.aclose)
295
305
  await client.restore_persisted_interrupt_requests()
296
306
  await client.startup_preflight()
297
307
  await thread_lifecycle_runtime.reconcile_persisted_watches()
298
308
  yield
299
- finally:
300
- await a2a_client_manager.close_all()
301
- await client.close()
302
- await runtime_state_runtime.shutdown()
303
- await push_config_store_runtime.shutdown()
304
- await task_store_runtime.shutdown()
305
- if shared_database_engine is not None:
306
- await shared_database_engine.dispose()
307
309
 
308
310
  context_builder = IdentityAwareCallContextBuilder()
309
311
  jsonrpc_methods = {
@@ -1,19 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
- import asyncio
4
3
  import json
5
4
  from collections.abc import Iterable
6
5
  from typing import Any, cast
7
6
 
8
- from a2a.server.events import EventConsumer
9
- from a2a.server.tasks import ResultAggregator, TaskManager
10
7
  from a2a.types import (
11
8
  Artifact,
12
9
  Message,
13
10
  Part,
14
11
  Task,
15
12
  TaskArtifactUpdateEvent,
16
- TaskState,
17
13
  TaskStatusUpdateEvent,
18
14
  )
19
15
  from google.protobuf.message import Message as ProtoMessage # type: ignore[import-untyped]
@@ -168,111 +164,6 @@ def apply_accepted_output_modes(
168
164
  return payload
169
165
 
170
166
 
171
- class NegotiatingResultAggregator(ResultAggregator):
172
- def __init__(
173
- self,
174
- task_manager: TaskManager,
175
- accepted_output_modes: Iterable[str] | None,
176
- ) -> None:
177
- super().__init__(task_manager)
178
- self._accepted_output_modes = normalize_accepted_output_modes(accepted_output_modes)
179
-
180
- def _transform_event(self, event: Any) -> Any | None:
181
- negotiated_event = apply_accepted_output_modes(event, self._accepted_output_modes)
182
- if negotiated_event is None:
183
- return None
184
- return annotate_output_negotiation_metadata(negotiated_event, self._accepted_output_modes)
185
-
186
- async def _persist_output_negotiation_metadata(self, event: Any) -> None:
187
- if not isinstance(event, TaskArtifactUpdateEvent):
188
- return
189
-
190
- accepted_output_modes = extract_accepted_output_modes_from_metadata(event.metadata)
191
- if accepted_output_modes is None:
192
- return
193
-
194
- task = await self.task_manager.ensure_task(event)
195
- merged_metadata = merge_output_negotiation_metadata(task.metadata, accepted_output_modes)
196
- if merged_metadata == task.metadata:
197
- return
198
- task.ClearField("metadata")
199
- if merged_metadata is not None:
200
- task.metadata.CopyFrom(merged_metadata)
201
- await self.task_manager._save_task(task)
202
-
203
- async def consume_and_emit(self, consumer: EventConsumer): # noqa: ANN201
204
- async for event in consumer.consume_all():
205
- transformed_event = self._transform_event(event)
206
- if transformed_event is None:
207
- continue
208
- await self._persist_output_negotiation_metadata(transformed_event)
209
- await self.task_manager.process(transformed_event)
210
- yield transformed_event
211
-
212
- async def consume_all(self, consumer: EventConsumer) -> Task | Message | None:
213
- async for event in consumer.consume_all():
214
- transformed_event = self._transform_event(event)
215
- if transformed_event is None:
216
- continue
217
- if isinstance(transformed_event, Message):
218
- self._message = transformed_event
219
- return transformed_event
220
- await self._persist_output_negotiation_metadata(transformed_event)
221
- await self.task_manager.process(transformed_event)
222
- return await self.task_manager.get_task()
223
-
224
- async def consume_and_break_on_interrupt(
225
- self,
226
- consumer: EventConsumer,
227
- blocking: bool = True,
228
- event_callback=None, # noqa: ANN001
229
- ) -> tuple[Task | Message | None, bool, asyncio.Task | None]:
230
- event_stream = consumer.consume_all()
231
- interrupted = False
232
- bg_task: asyncio.Task | None = None
233
- async for event in event_stream:
234
- transformed_event = self._transform_event(event)
235
- if transformed_event is None:
236
- continue
237
- if isinstance(transformed_event, Message):
238
- self._message = transformed_event
239
- return transformed_event, False, None
240
- await self._persist_output_negotiation_metadata(transformed_event)
241
- await self.task_manager.process(transformed_event)
242
-
243
- should_interrupt = False
244
- is_auth_required = (
245
- isinstance(transformed_event, Task | TaskStatusUpdateEvent)
246
- and transformed_event.status.state == TaskState.TASK_STATE_AUTH_REQUIRED
247
- )
248
- if is_auth_required:
249
- should_interrupt = True
250
- elif not blocking:
251
- should_interrupt = True
252
-
253
- if should_interrupt:
254
- bg_task = asyncio.create_task(
255
- self._continue_consuming(event_stream, event_callback)
256
- )
257
- interrupted = True
258
- break
259
- return await self.task_manager.get_task(), interrupted, bg_task
260
-
261
- async def _continue_consuming(
262
- self,
263
- event_stream,
264
- event_callback=None, # noqa: ANN001
265
- ) -> None:
266
- async for event in event_stream:
267
- transformed_event = self._transform_event(event)
268
- if transformed_event is None:
269
- continue
270
- await self._persist_output_negotiation_metadata(transformed_event)
271
- await self.task_manager.process(transformed_event)
272
- if event_callback:
273
- await event_callback()
274
-
275
-
276
167
  def _filter_task(task: Task, accepted_modes: frozenset[str]) -> Task:
277
168
  filtered_history: list[Message] = []
278
169
  for message in task.history or []: