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.
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.pre-commit-config.yaml +11 -2
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/CONTRIBUTING.md +2 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/PKG-INFO +6 -6
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/compatibility.md +3 -1
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/conformance-triage.md +1 -1
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/conformance.md +1 -1
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/pyproject.toml +5 -5
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/README.md +1 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/validate_baseline.sh +2 -1
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/request_handler.py +1 -9
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/PKG-INFO +6 -6
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/SOURCES.txt +1 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/requires.txt +5 -5
- codex_a2a-1.3.3/tests/scripts/test_validate_baseline_script.py +89 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_request_handler.py +60 -3
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/uv.lock +319 -247
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/dependabot.yml +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/workflows/ci.yml +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/workflows/compatibility.yml +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/workflows/dependency-health.yml +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.github/workflows/publish.yml +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.gitignore +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/.secrets.baseline +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/AGENTS.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/LICENSE +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/README.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/SECURITY.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/a2a-extension-baseline.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/architecture.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/extension-specifications.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/guide.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/inspection/README.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/inspection/error_redaction_policy.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/inspection/release_integrity_policy.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/docs/maintainer-architecture.md +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/mypy.ini +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/audit_low_call_sites.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/check_codex_app_server_schema.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/check_dead_code.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/conformance.sh +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/dependency_health.sh +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/health_common.sh +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/publish_github_release.sh +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/smoke_live_codex_turn.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/smoke_test_built_cli.sh +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/smoke_test_live_codex.sh +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/sync_codex_docs.sh +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/tck_auth_plugin.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/scripts/validate_runtime_matrix.sh +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/setup.cfg +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/a2a_proto.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/auth.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/cli.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/agent_card.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/auth.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/client.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/config.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/errors.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/extension_negotiation.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/manager.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/network_policy.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/payload_text.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/client/request_context.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/config.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/extension_registry.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/extension_specs.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/extensions.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/contracts/runtime_output.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/discovery_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/exec_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/executor.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/output_mapping.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/request_metadata.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/request_overrides.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/response_emitter.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/review_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/session_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/stream_chunks.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/stream_interrupts.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/stream_processor.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/stream_state.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/streaming.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/thread_lifecycle_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/tool_call_payloads.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/execution/watch_events.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/input_mapping.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/application.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/discovery_control.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/discovery_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/discovery_payload_mapping.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/discovery_query.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/dispatch.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/errors.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/exec_control.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/exec_control_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/hooks.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupt_lifecycle.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupt_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupt_recovery.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupt_recovery_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/interrupts.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/owner_guard.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/params_common.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/payload_mapping.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/query_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/request_models.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/review_control.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/review_control_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/session_query.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/thread_lifecycle_control.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/thread_lifecycle_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/turn_control.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/jsonrpc/turn_control_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/logging_context.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/media_modes.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/metrics.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/payload_helpers.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/profile/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/profile/runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/protocol_versions.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/py.typed +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/redact.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/agent_card.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/application.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/call_context.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/database.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/http_middlewares.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/migrations.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/openapi.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/openapi_contract_fragments.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/output_negotiation.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/push_config_store.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/runtime_limits.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/runtime_state.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/runtime_state_schema.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/server/task_store.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/skill_handles.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/client.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/conversation_facade.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/discovery_payloads.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/interrupt_bridge.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/interrupts.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/models.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/notification_mapping.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/request_mapping.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/startup.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/stream_bridge.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a/upstream/transport.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/dependency_links.txt +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/entry_points.txt +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/src/codex_a2a.egg-info/top_level.txt +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_agent_card.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_cli.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_client_flow.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_client_http_headers.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_client_manager.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_errors.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_lifecycle.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_network_policy.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_payload_text.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/client/test_request_context.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/config/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/config/test_settings.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/contracts/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/contracts/test_extension_contract_consistency.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/contracts/test_extension_registry.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_agent_errors.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_cancellation.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_codex_agent_session_binding.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_directory_validation.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_discovery_exec_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_error_redaction.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_metrics.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_request_metadata.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_review_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_session_ownership.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_session_persistence.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_session_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_stream_chunks.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_stream_interrupts.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_streaming_output_contract.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_thread_lifecycle_runtime.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/execution/test_tool_call_payloads.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/fixtures/codex_app_server/command_execution_output_delta.json +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/fixtures/codex_app_server/file_change_output_delta.json +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_discovery_extension.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_exec_extension.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_session_extension.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_thread_lifecycle_extension.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_codex_turn_review_extension.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_dispatch.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_error_redaction.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_guard_hooks.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_interrupt_lifecycle.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_interrupt_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_interrupt_protocol_handlers.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_jsonrpc_models.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/jsonrpc/test_protocol_payload_mapping.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_logging.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_publish_github_release_script.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_release_distribution_contract.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_typing_contract.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/package/test_version.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/profile/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/profile/test_profile.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/test_audit_low_call_sites.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/test_check_codex_app_server_schema.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/test_script_health_contract.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/scripts/test_tck_auth_plugin.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_agent_card.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_auth.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_call_context_builder.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_cli.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_database.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_database_app_persistence.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_http_boundary.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_migrations.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_output_negotiation.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_push_config_store.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_runtime_limits.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_runtime_state.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_task_store.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/server/test_transport_contract.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/context.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/dummy_clients.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/fixtures.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/http_auth.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/jsonrpc_errors.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/support/settings.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_a2a_proto.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_input_mapping.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_protocol_versions.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_redact.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/test_skill_handles.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/__init__.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_codex_client_params.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_interrupt_bridge.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_interrupt_persistence.py +0 -0
- {codex_a2a-1.3.2 → codex_a2a-1.3.3}/tests/upstream/test_modular_upstream_components.py +0 -0
- {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:
|
|
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.
|
|
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.
|
|
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<
|
|
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<
|
|
44
|
-
Requires-Dist: ruff
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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,<
|
|
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,<
|
|
49
|
-
"ruff
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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<
|
|
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<
|
|
44
|
-
Requires-Dist: ruff
|
|
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.
|
|
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<
|
|
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<
|
|
20
|
-
ruff
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|