refactor(ai): simplify Agent.fake()/record(), remove AgentBinding#188
Merged
Conversation
…kes directly Agent.fake()/record() now return AgentFake/AgentRecordFake directly instead of wrapping the latter in an AgentBinding indirection layer. AgentRecordFake gains the container-binding, cassette-resolution, and decorator behavior AgentBinding used to provide, so `with Agent.record(...) as agent:` and the `@Agent.record(...)` decorator form both keep working unchanged. AgentBinding is removed entirely, along with every reference to it (imports, __init__ exports, type hints, tests).
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Two of the example/agents record() cassettes were recorded against message text that no longer matches the tests' current wording, so their cache keys never hit and every run fell through to a live Gemini call. The new units/agents/record_stream.json fixture had the same problem in the other direction: it only captured the first turn, so the second prompt() call and the assert_response_judged() verdict both missed the cassette too. Re-recorded all three cassettes against the real code path (mocking only the network boundary and the judge, same seam test_agent_record_fluent.py uses) so every prompt/stream/judge call in test_router_agent.py and test_chat_controller.py now replays from disk with no live model calls. uv.lock refreshes the editable fastapi-startkit metadata, which was stale at 0.45.0 against the package's actual 0.50.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Simplifies
Agent.fake()/Agent.record()to return their fake objects directly instead of going through anAgentBindingindirection layer, then removesAgentBindingentirely.Agent.fake(responses)returnsAgentFakedirectly (unchanged behavior, was already direct).Agent.record(cassette, messages)now returnsAgentRecordFakedirectly — no more wrapping it inAgentBinding.AgentRecordFakegains the container-binding (app().bind(...)/app().unbind(...)), cassette auto-resolution, and decorator (__call__) behavior thatAgentBindingused to provide, so both usage forms keep working:with Agent.record(cassette) as agent: ...(fluent handle)with Agent.record(cassette): .../@Agent.record(cassette)(bare context-manager/decorator binding a stand-in into the container for code under test)AgentBindingis deleted, along with every reference to it (ai/agent.pyimport + type hint,ai/__init__.pyexport/__all__).Agent._stream()was calling_build_model(..., structured=False), butAi.get_model_for()/Ai.build()had dropped thestructuredparameter — restored it so streaming still skips structured-output wrapping.example/agents/tests/units/agents/record_stream.jsonis a legitimate new fixture: it's the cassetteRouterAgent.record("record_stream.json")resolves to forexample/agents/tests/units/agents/test_router_agent.py(cassette path resolves relative to the caller's file, distinct from the pre-existingexample/agents/tests/features/record_stream.json).Testing
uv run pytest fastapi_startkit/tests/ai -v— 273 passeduv run pytest fastapi_startkit --ignore=tests/masoniteorm/postgres— 1883 passed, 7 skippeduv run ruff check src/ tests/— clean