codex-a2a 1.3.3__tar.gz → 1.3.4__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.
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/PKG-INFO +1 -1
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/maintainer-architecture.md +10 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/discovery_runtime.py +22 -16
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/exec_runtime.py +9 -3
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/review_runtime.py +33 -31
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/thread_lifecycle_runtime.py +18 -16
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/application.py +15 -13
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/output_negotiation.py +0 -109
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/request_handler.py +147 -55
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/client.py +6 -4
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/stream_bridge.py +2 -2
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a.egg-info/PKG-INFO +1 -1
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a.egg-info/SOURCES.txt +4 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_discovery_exec_runtime.py +100 -0
- codex_a2a-1.3.4/tests/execution/test_watch_lifecycle.py +69 -0
- codex_a2a-1.3.4/tests/fixtures/sdk_task_store_main_0a3fb68.sql +19 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_request_handler.py +13 -40
- codex_a2a-1.3.4/tests/server/test_request_handler_lifecycle.py +343 -0
- codex_a2a-1.3.4/tests/server/test_sdk_upgrade.py +379 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/upstream/test_codex_client_params.py +22 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/.github/dependabot.yml +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/.github/workflows/ci.yml +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/.github/workflows/compatibility.yml +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/.github/workflows/dependency-health.yml +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/.github/workflows/publish.yml +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/.gitignore +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/.pre-commit-config.yaml +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/.secrets.baseline +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/AGENTS.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/CONTRIBUTING.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/LICENSE +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/README.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/SECURITY.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/a2a-extension-baseline.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/architecture.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/compatibility.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/conformance-triage.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/conformance.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/extension-specifications.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/guide.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/inspection/README.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/inspection/error_redaction_policy.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/docs/inspection/release_integrity_policy.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/mypy.ini +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/pyproject.toml +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/README.md +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/audit_low_call_sites.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/check_codex_app_server_schema.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/check_dead_code.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/conformance.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/dependency_health.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/health_common.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/publish_github_release.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/smoke_live_codex_turn.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/smoke_test_built_cli.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/smoke_test_live_codex.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/sync_codex_docs.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/tck_auth_plugin.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/validate_baseline.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/scripts/validate_runtime_matrix.sh +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/setup.cfg +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/a2a_proto.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/auth.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/cli.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/agent_card.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/auth.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/client.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/config.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/errors.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/extension_negotiation.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/manager.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/network_policy.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/payload_text.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/client/request_context.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/config.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/contracts/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/contracts/extension_registry.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/contracts/extension_specs.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/contracts/extensions.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/contracts/runtime_output.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/executor.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/output_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/request_metadata.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/request_overrides.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/response_emitter.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/session_runtime.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/stream_chunks.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/stream_interrupts.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/stream_processor.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/stream_state.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/streaming.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/tool_call_payloads.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/execution/watch_events.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/input_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/application.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/discovery_control.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/discovery_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/discovery_payload_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/discovery_query.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/dispatch.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/errors.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/exec_control.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/exec_control_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/hooks.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/interrupt_lifecycle.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/interrupt_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/interrupt_recovery.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/interrupt_recovery_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/interrupts.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/owner_guard.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/params_common.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/payload_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/query_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/request_models.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/review_control.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/review_control_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/session_query.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/thread_lifecycle_control.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/thread_lifecycle_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/turn_control.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/jsonrpc/turn_control_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/logging_context.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/media_modes.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/metrics.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/payload_helpers.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/profile/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/profile/runtime.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/protocol_versions.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/py.typed +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/redact.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/agent_card.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/call_context.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/database.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/http_middlewares.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/migrations.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/openapi.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/openapi_contract_fragments.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/push_config_store.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/runtime_limits.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/runtime_state.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/runtime_state_schema.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/server/task_store.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/skill_handles.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/conversation_facade.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/discovery_payloads.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/interrupt_bridge.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/interrupts.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/models.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/notification_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/request_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/startup.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a/upstream/transport.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a.egg-info/dependency_links.txt +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a.egg-info/entry_points.txt +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a.egg-info/requires.txt +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/src/codex_a2a.egg-info/top_level.txt +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_agent_card.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_cli.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_client_flow.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_client_http_headers.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_client_manager.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_errors.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_lifecycle.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_network_policy.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_payload_text.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/client/test_request_context.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/config/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/config/test_settings.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/contracts/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/contracts/test_extension_contract_consistency.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/contracts/test_extension_registry.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_agent_errors.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_cancellation.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_codex_agent_session_binding.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_directory_validation.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_error_redaction.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_metrics.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_request_metadata.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_review_runtime.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_session_ownership.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_session_persistence.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_session_runtime.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_stream_chunks.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_stream_interrupts.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_streaming_output_contract.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_thread_lifecycle_runtime.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/execution/test_tool_call_payloads.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/fixtures/codex_app_server/command_execution_output_delta.json +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/fixtures/codex_app_server/file_change_output_delta.json +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_codex_discovery_extension.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_codex_exec_extension.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_codex_session_extension.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_codex_thread_lifecycle_extension.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_codex_turn_review_extension.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_dispatch.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_error_redaction.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_guard_hooks.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_interrupt_lifecycle.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_interrupt_params.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_interrupt_protocol_handlers.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_jsonrpc_models.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/jsonrpc/test_protocol_payload_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/package/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/package/test_logging.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/package/test_publish_github_release_script.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/package/test_release_distribution_contract.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/package/test_typing_contract.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/package/test_version.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/profile/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/profile/test_profile.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/scripts/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/scripts/test_audit_low_call_sites.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/scripts/test_check_codex_app_server_schema.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/scripts/test_script_health_contract.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/scripts/test_tck_auth_plugin.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/scripts/test_validate_baseline_script.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_agent_card.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_auth.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_call_context_builder.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_cli.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_database.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_database_app_persistence.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_http_boundary.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_migrations.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_output_negotiation.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_push_config_store.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_runtime_limits.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_runtime_state.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_task_store.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/server/test_transport_contract.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/support/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/support/context.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/support/dummy_clients.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/support/fixtures.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/support/http_auth.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/support/jsonrpc_errors.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/support/settings.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/test_a2a_proto.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/test_input_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/test_protocol_versions.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/test_redact.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/test_skill_handles.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/upstream/__init__.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/upstream/test_interrupt_bridge.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/upstream/test_interrupt_persistence.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/upstream/test_modular_upstream_components.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/tests/upstream/test_request_mapping.py +0 -0
- {codex_a2a-1.3.3 → codex_a2a-1.3.4}/uv.lock +0 -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
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
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
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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 []:
|