Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -43,7 +46,11 @@ jobs:

test:
name: Test Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
env:
UV_PYTHON: ${{ matrix.python-version }}
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']
Expand Down Expand Up @@ -83,7 +90,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
Expand Down Expand Up @@ -118,7 +127,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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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

Expand Down
4 changes: 3 additions & 1 deletion tests/bedrock_agentcore/runtime/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading