@@ -120,6 +120,7 @@ async def ret_a(x: str) -> str:
120120 requests = 2 ,
121121 input_tokens = 103 ,
122122 output_tokens = 5 ,
123+ tool_calls = 1 ,
123124 )
124125 )
125126 succeeded = True
@@ -151,26 +152,26 @@ async def delegate_to_other_agent1(ctx: RunContext[None], sentence: str) -> int:
151152 delegate_result = await delegate_agent .run (sentence )
152153 delegate_usage = delegate_result .usage ()
153154 run_1_usages .append (delegate_usage )
154- assert delegate_usage == snapshot (RunUsage (requests = 1 , input_tokens = 51 , output_tokens = 4 ))
155+ assert delegate_usage == snapshot (RunUsage (requests = 1 , input_tokens = 51 , output_tokens = 4 , tool_calls = 1 ))
155156 return delegate_result .output
156157
157158 result1 = await controller_agent1 .run ('foobar' )
158159 assert result1 .output == snapshot ('{"delegate_to_other_agent1":0}' )
159160 run_1_usages .append (result1 .usage ())
160- assert result1 .usage () == snapshot (RunUsage (requests = 2 , input_tokens = 103 , output_tokens = 13 ))
161+ assert result1 .usage () == snapshot (RunUsage (requests = 2 , input_tokens = 103 , output_tokens = 13 , tool_calls = 1 ))
161162
162163 controller_agent2 = Agent (TestModel ())
163164
164165 @controller_agent2 .tool
165166 async def delegate_to_other_agent2 (ctx : RunContext [None ], sentence : str ) -> int :
166167 delegate_result = await delegate_agent .run (sentence , usage = ctx .usage )
167168 delegate_usage = delegate_result .usage ()
168- assert delegate_usage == snapshot (RunUsage (requests = 2 , input_tokens = 102 , output_tokens = 9 ))
169+ assert delegate_usage == snapshot (RunUsage (requests = 2 , input_tokens = 102 , output_tokens = 9 , tool_calls = 2 ))
169170 return delegate_result .output
170171
171172 result2 = await controller_agent2 .run ('foobar' )
172173 assert result2 .output == snapshot ('{"delegate_to_other_agent2":0}' )
173- assert result2 .usage () == snapshot (RunUsage (requests = 3 , input_tokens = 154 , output_tokens = 17 ))
174+ assert result2 .usage () == snapshot (RunUsage (requests = 3 , input_tokens = 154 , output_tokens = 17 , tool_calls = 2 ))
174175
175176 # confirm the usage from result2 is the sum of the usage from result1
176177 assert result2 .usage () == functools .reduce (operator .add , run_1_usages )
@@ -197,7 +198,7 @@ def delegate_to_other_agent(ctx: RunContext[None], sentence: str) -> int:
197198
198199 result = await controller_agent .run ('foobar' )
199200 assert result .output == snapshot ('{"delegate_to_other_agent":0}' )
200- assert result .usage () == snapshot (RunUsage (requests = 7 , input_tokens = 105 , output_tokens = 16 ))
201+ assert result .usage () == snapshot (RunUsage (requests = 7 , input_tokens = 105 , output_tokens = 16 , tool_calls = 1 ))
201202
202203
203204def test_request_usage_basics ():
@@ -215,6 +216,7 @@ def test_add_usages():
215216 cache_write_tokens = 40 ,
216217 input_audio_tokens = 50 ,
217218 cache_audio_read_tokens = 60 ,
219+ tool_calls = 3 ,
218220 details = {
219221 'custom1' : 10 ,
220222 'custom2' : 20 ,
@@ -229,13 +231,27 @@ def test_add_usages():
229231 cache_read_tokens = 60 ,
230232 input_audio_tokens = 100 ,
231233 cache_audio_read_tokens = 120 ,
234+ tool_calls = 6 ,
232235 details = {'custom1' : 20 , 'custom2' : 40 },
233236 )
234237 )
235238 assert usage + RunUsage () == usage
236239 assert RunUsage () + RunUsage () == RunUsage ()
237240
238241
242+ async def test_tool_call_limit () -> None :
243+ test_agent = Agent (TestModel ())
244+
245+ @test_agent .tool_plain
246+ async def ret_a (x : str ) -> str :
247+ return f'{ x } -apple'
248+
249+ with pytest .raises (
250+ UsageLimitExceeded , match = re .escape ('The next tool call would exceed the tool_calls_limit of 0 (tool_calls=0)' )
251+ ):
252+ await test_agent .run ('Hello' , usage_limits = UsageLimits (tool_calls_limit = 0 ))
253+
254+
239255def test_deprecated_usage_limits ():
240256 with warns (
241257 snapshot (['DeprecationWarning: `request_tokens_limit` is deprecated, use `input_tokens_limit` instead' ])
0 commit comments