Skip to content

Commit bd2309e

Browse files
committed
code review: update track_cost handling in ModelSettings and add related tests
1 parent e10ed7a commit bd2309e

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

src/agents/model_settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ class ModelSettings:
120120
"""Whether to include usage chunk.
121121
Only available for Chat Completions API."""
122122

123-
track_cost: bool = False
123+
track_cost: bool | None = None
124124
"""Whether to track and calculate cost for model calls.
125125
When enabled, the SDK will populate `Usage.cost` with cost estimates.
126126
Currently only supported for LiteLLM models. For other providers, cost will remain None.
127-
Defaults to False."""
127+
If not provided (i.e., set to None), cost tracking is disabled (defaults to False)."""
128128

129129
# TODO: revisit ResponseIncludable | str if ResponseIncludable covers more cases
130130
# We've added str to support missing ones like

tests/model_settings/test_serialization.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def test_all_fields_serialization() -> None:
5757
metadata={"foo": "bar"},
5858
store=False,
5959
include_usage=False,
60+
track_cost=False,
6061
response_include=["reasoning.encrypted_content"],
6162
top_logprobs=1,
6263
verbosity="low",

tests/models/test_litellm_cost_tracking.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def fake_completion_cost(completion_response):
4949
@pytest.mark.allow_call_model_methods
5050
@pytest.mark.asyncio
5151
async def test_cost_none_when_track_cost_disabled(monkeypatch):
52-
"""Test that cost is None when track_cost=False (default)."""
52+
"""Test that cost is None when track_cost is not set (defaults to None/False)."""
5353

5454
async def fake_acompletion(model, messages=None, **kwargs):
5555
msg = Message(role="assistant", content="Test response")
@@ -61,13 +61,13 @@ async def fake_acompletion(model, messages=None, **kwargs):
6161
return response
6262

6363
monkeypatch.setattr(litellm, "acompletion", fake_acompletion)
64-
# Note: completion_cost should not be called when track_cost=False
64+
# Note: completion_cost should not be called when track_cost is None (default)
6565

6666
model = LitellmModel(model="test-model", api_key="test-key")
6767
result = await model.get_response(
6868
system_instructions=None,
6969
input=[],
70-
model_settings=ModelSettings(track_cost=False), # Disabled (default)
70+
model_settings=ModelSettings(), # track_cost defaults to None (disabled)
7171
tools=[],
7272
output_schema=None,
7373
handoffs=[],
@@ -192,3 +192,29 @@ def fake_completion_cost(completion_response):
192192
assert result.usage.total_tokens == 150
193193
assert result.usage.cost == 0.001
194194
assert result.usage.requests == 1
195+
196+
197+
def test_track_cost_sticky_through_resolve():
198+
"""Test that track_cost=True is not overwritten by resolve() with empty override."""
199+
base = ModelSettings(track_cost=True, temperature=0.7)
200+
override = ModelSettings(max_tokens=100) # Only setting max_tokens, track_cost is None
201+
202+
resolved = base.resolve(override)
203+
204+
# track_cost should remain True because override's track_cost is None (not False)
205+
assert resolved.track_cost is True
206+
assert resolved.temperature == 0.7
207+
assert resolved.max_tokens == 100
208+
209+
210+
def test_track_cost_can_be_explicitly_disabled():
211+
"""Test that track_cost=True can be explicitly overridden to False."""
212+
base = ModelSettings(track_cost=True, temperature=0.7)
213+
override = ModelSettings(track_cost=False, max_tokens=100)
214+
215+
resolved = base.resolve(override)
216+
217+
# track_cost should be False because override explicitly set it to False
218+
assert resolved.track_cost is False
219+
assert resolved.temperature == 0.7
220+
assert resolved.max_tokens == 100

0 commit comments

Comments
 (0)