From c99f060d383ef42aa88f84ee6481caa5446e648d Mon Sep 17 00:00:00 2001 From: jariy17 Date: Fri, 23 Oct 2026 17:51:26 +0000 Subject: [PATCH 1/4] ci: run Python SDK CI on CodeBuild runners --- .github/workflows/ci.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 38b6e13a..947e8d74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,10 @@ permissions: jobs: lint: name: Lint and Format - runs-on: ubuntu-latest + # Distinct job labels keep each ephemeral runner assigned to its intended job. + runs-on: + - codebuild-agentcore-sdk-python-ci-${{ github.run_id }}-${{ github.run_attempt }} + - ci-lint steps: - uses: actions/checkout@v6 @@ -43,7 +46,9 @@ jobs: test: name: Test Python ${{ matrix.python-version }} - runs-on: ubuntu-latest + runs-on: + - codebuild-agentcore-sdk-python-ci-${{ github.run_id }}-${{ github.run_attempt }} + - ci-test-${{ matrix.python-version }} strategy: matrix: python-version: ['3.10', '3.11', '3.12', '3.13'] @@ -83,7 +88,9 @@ jobs: build: name: Build Distribution - runs-on: ubuntu-latest + runs-on: + - codebuild-agentcore-sdk-python-ci-${{ github.run_id }}-${{ github.run_attempt }} + - ci-build needs: [lint, test] steps: - uses: actions/checkout@v6 @@ -118,7 +125,9 @@ jobs: test-install: name: Test Package Installation - runs-on: ubuntu-latest + runs-on: + - codebuild-agentcore-sdk-python-ci-${{ github.run_id }}-${{ github.run_attempt }} + - ci-install-${{ matrix.python-version }} needs: build strategy: matrix: From 70a9e00eb321f2cc7d3c098d368bf2ee36431492 Mon Sep 17 00:00:00 2001 From: jariy17 Date: Fri, 23 Oct 2026 20:16:35 +0000 Subject: [PATCH 2/4] ci: isolate host assumptions and select each matrix interpreter --- .github/workflows/ci.yml | 2 +- .../evaluation/runner/batch/test_batch_evaluation_runner.py | 3 ++- tests/bedrock_agentcore/runtime/test_app.py | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 947e8d74..5da25c89 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,7 +68,7 @@ jobs: # Add virtual environment creation - name: Create virtual environment - run: uv venv + run: uv venv --python "${{ matrix.python-version }}" - name: Install dependencies with uv run: | diff --git a/tests/bedrock_agentcore/evaluation/runner/batch/test_batch_evaluation_runner.py b/tests/bedrock_agentcore/evaluation/runner/batch/test_batch_evaluation_runner.py index a13158a9..7a0ec21f 100644 --- a/tests/bedrock_agentcore/evaluation/runner/batch/test_batch_evaluation_runner.py +++ b/tests/bedrock_agentcore/evaluation/runner/batch/test_batch_evaluation_runner.py @@ -6,6 +6,7 @@ import pytest from pydantic import ValidationError +from bedrock_agentcore._utils.endpoints import DEFAULT_REGION from bedrock_agentcore.evaluation.runner.batch.batch_evaluation_models import ( BatchEvaluationRunConfig, BatchEvaluatorConfig, @@ -39,7 +40,7 @@ class TestRegionName: ({"region": "us-west-2", "region_name": "eu-west-1"}, "us-east-1", "us-west-2"), ({"region": "", "region_name": "eu-west-1"}, "us-east-1", "eu-west-1"), ({}, "us-east-1", "us-east-1"), - ({}, None, "us-west-2"), + ({}, None, DEFAULT_REGION), ], ) def test_region_precedence(self, kwargs, session_region, expected): diff --git a/tests/bedrock_agentcore/runtime/test_app.py b/tests/bedrock_agentcore/runtime/test_app.py index edc0ff6a..60169a5a 100644 --- a/tests/bedrock_agentcore/runtime/test_app.py +++ b/tests/bedrock_agentcore/runtime/test_app.py @@ -231,8 +231,10 @@ def test_serve_with_dockerenv_file(self, mock_uvicorn, mock_exists): bedrock_agentcore, host="0.0.0.0", port=8080, access_log=False, log_level="warning" ) + @patch.dict(os.environ, {"DOCKER_CONTAINER": ""}) + @patch("os.path.exists", return_value=False) @patch("uvicorn.run") - def test_serve_localhost(self, mock_uvicorn): + def test_serve_localhost(self, mock_uvicorn, mock_exists): """Test serve method uses localhost when not in Docker.""" bedrock_agentcore = BedrockAgentCoreApp() bedrock_agentcore.run(port=8080) From f1353edf42988385fa956d2356d895c05411ad6f Mon Sep 17 00:00:00 2001 From: jariy17 Date: Fri, 23 Oct 2026 20:18:31 +0000 Subject: [PATCH 3/4] ci: retain matrix Python selection across all uv commands --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5da25c89..5eb36c70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,8 @@ jobs: test: name: Test Python ${{ matrix.python-version }} + env: + UV_PYTHON: ${{ matrix.python-version }} runs-on: - codebuild-agentcore-sdk-python-ci-${{ github.run_id }}-${{ github.run_attempt }} - ci-test-${{ matrix.python-version }} @@ -68,7 +70,7 @@ jobs: # Add virtual environment creation - name: Create virtual environment - run: uv venv --python "${{ matrix.python-version }}" + run: uv venv - name: Install dependencies with uv run: | From e14e1e201c7b7dd64e0805b1ce12f6f36fd390d5 Mon Sep 17 00:00:00 2001 From: jariy17 Date: Fri, 23 Oct 2026 20:25:25 +0000 Subject: [PATCH 4/4] test: make memory-store checks portable across Python versions --- .../strands/memorystore/test_sender.py | 15 +++++++++------ .../strands/memorystore/test_static_typing.py | 13 ++++++++++++- .../strands/memorystore/test_types.py | 6 ++++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_sender.py b/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_sender.py index a9c5acf3..491af9f7 100644 --- a/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_sender.py +++ b/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_sender.py @@ -86,7 +86,8 @@ async def test_chunks_batch_at_max_turns() -> None: client.create_event.return_value = {} await make_sender(client, max_turns_per_event=2).send_batch([user_message(value) for value in "abcde"]) assert client.create_event.call_count == 3 - assert [[turn["text"] for turn in turns(call)] for call in client.create_event.call_args_list] == [ + # Events are sent concurrently, but turns within each event retain their order. + assert sorted([turn["text"] for turn in turns(call)] for call in client.create_event.call_args_list) == [ ["a", "b"], ["c", "d"], ["e"], @@ -133,13 +134,14 @@ async def test_sequence_range_token_is_stable_and_chunk_specific() -> None: sender = make_sender(client, max_turns_per_event=2) batch = [user_message("a"), user_message("b"), user_message("c")] await sender.send_batch(batch, [1, 2, 3]) - assert [call.kwargs["clientToken"] for call in client.create_event.call_args_list] == [ + expected_tokens = [ "mem-1-actor-1-run-1-1-2", "mem-1-actor-1-run-1-3-3", ] + assert sorted(call.kwargs["clientToken"] for call in client.create_event.call_args_list) == expected_tokens client.reset_mock() await sender.send_batch(batch, [1, 2, 3]) - assert client.create_event.call_args_list[0].kwargs["clientToken"] == "mem-1-actor-1-run-1-1-2" + assert sorted(call.kwargs["clientToken"] for call in client.create_event.call_args_list) == expected_tokens async def test_explicit_empty_run_id_is_preserved() -> None: @@ -179,13 +181,14 @@ def provider(message: Message) -> dict[str, MetadataValue]: [user_message(value) for value in ["A", "A", "B", "C", "B"]] ) assert client.create_event.call_count == 4 - assert [[turn["text"] for turn in turns(call)] for call in client.create_event.call_args_list] == [ + assert sorted([turn["text"] for turn in turns(call)] for call in client.create_event.call_args_list) == [ ["A", "A"], ["B"], - ["C"], ["B"], + ["C"], ] - assert client.create_event.call_args_list[0].kwargs["metadata"] == {"topic": {"stringValue": "A"}} + for call in client.create_event.call_args_list: + assert call.kwargs["metadata"] == {"topic": {"stringValue": turns(call)[0]["text"]}} async def test_constant_metadata_is_mapped_and_empty_bag_omitted() -> None: diff --git a/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_static_typing.py b/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_static_typing.py index 339cedd4..8da4f122 100644 --- a/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_static_typing.py +++ b/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_static_typing.py @@ -8,8 +8,19 @@ def _run_mypy(fixture: str) -> subprocess.CompletedProcess[str]: + # Installed dependency stubs target this interpreter; Python 3.10 is + # checked by its own CI matrix entry. return subprocess.run( - [sys.executable, "-m", "mypy", "--no-incremental", "--show-error-codes", str(FIXTURES / fixture)], + [ + sys.executable, + "-m", + "mypy", + "--python-version", + f"{sys.version_info.major}.{sys.version_info.minor}", + "--no-incremental", + "--show-error-codes", + str(FIXTURES / fixture), + ], check=False, capture_output=True, text=True, diff --git a/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_types.py b/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_types.py index 14fe889a..b2edbd4e 100644 --- a/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_types.py +++ b/tests/bedrock_agentcore/memory/integrations/strands/memorystore/test_types.py @@ -28,7 +28,9 @@ def test_connection_config_runtime_typed_dict_keys_and_hints() -> None: "client", } ) - assert get_args(get_type_hints(_AgentCoreMemoryConnectionConfig)["boto3_session"]) == (boto3.Session,) + assert get_args(get_type_hints(_AgentCoreMemoryConnectionConfig, include_extras=True)["boto3_session"]) == ( + boto3.Session, + ) def test_public_factory_typed_dict_keys_are_correct_at_runtime() -> None: @@ -39,7 +41,7 @@ def test_public_factory_typed_dict_keys_are_correct_at_runtime() -> None: assert CreateAgentCoreMemoryStoresInput.__optional_keys__ == frozenset( {"extraction", "metadata_provider", "max_turns_per_event", "region_name", "boto3_session", "client"} ) - hints = get_type_hints(CreateAgentCoreMemoryStoresInput) + hints = get_type_hints(CreateAgentCoreMemoryStoresInput, include_extras=True) assert get_args(hints["boto3_session"]) == (boto3.Session,) assert "extraction_mode" not in hints