@@ -184,6 +184,7 @@ async def run(
184
184
deps : AgentDeps = None ,
185
185
model_settings : ModelSettings | None = None ,
186
186
usage_limits : UsageLimits | None = None ,
187
+ usage : result .Usage | None = None ,
187
188
infer_name : bool = True ,
188
189
) -> result .RunResult [ResultData ]:
189
190
"""Run the agent with a user prompt in async mode.
@@ -206,6 +207,7 @@ async def run(
206
207
deps: Optional dependencies to use for this run.
207
208
model_settings: Optional settings to use for this model's request.
208
209
usage_limits: Optional limits on model request count or token usage.
210
+ usage: Optional usage to start with, useful for resuming a conversation or agents used in tools.
209
211
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
210
212
211
213
Returns:
@@ -226,20 +228,19 @@ async def run(
226
228
model_name = model_used .name (),
227
229
agent_name = self .name or 'agent' ,
228
230
) as run_span :
229
- run_context = RunContext (deps , 0 , [], None , model_used )
231
+ run_context = RunContext (deps , 0 , [], None , model_used , usage or result . Usage () )
230
232
messages = await self ._prepare_messages (user_prompt , message_history , run_context )
231
233
run_context .messages = messages
232
234
233
235
for tool in self ._function_tools .values ():
234
236
tool .current_retry = 0
235
237
236
- usage = result .Usage (requests = 0 )
237
238
model_settings = merge_model_settings (self .model_settings , model_settings )
238
239
usage_limits = usage_limits or UsageLimits ()
239
240
240
241
run_step = 0
241
242
while True :
242
- usage_limits .check_before_request (usage )
243
+ usage_limits .check_before_request (run_context . usage )
243
244
244
245
run_step += 1
245
246
with _logfire .span ('preparing model and tools {run_step=}' , run_step = run_step ):
@@ -251,9 +252,8 @@ async def run(
251
252
model_req_span .set_attribute ('usage' , request_usage )
252
253
253
254
messages .append (model_response )
254
- usage += request_usage
255
- usage .requests += 1
256
- usage_limits .check_tokens (request_usage )
255
+ run_context .usage .incr (request_usage , requests = 1 )
256
+ usage_limits .check_tokens (run_context .usage )
257
257
258
258
with _logfire .span ('handle model response' , run_step = run_step ) as handle_span :
259
259
final_result , tool_responses = await self ._handle_model_response (model_response , run_context )
@@ -266,10 +266,10 @@ async def run(
266
266
if final_result is not None :
267
267
result_data = final_result .data
268
268
run_span .set_attribute ('all_messages' , messages )
269
- run_span .set_attribute ('usage' , usage )
269
+ run_span .set_attribute ('usage' , run_context . usage )
270
270
handle_span .set_attribute ('result' , result_data )
271
271
handle_span .message = 'handle model response -> final result'
272
- return result .RunResult (messages , new_message_index , result_data , usage )
272
+ return result .RunResult (messages , new_message_index , result_data , run_context . usage )
273
273
else :
274
274
# continue the conversation
275
275
handle_span .set_attribute ('tool_responses' , tool_responses )
@@ -285,6 +285,7 @@ def run_sync(
285
285
deps : AgentDeps = None ,
286
286
model_settings : ModelSettings | None = None ,
287
287
usage_limits : UsageLimits | None = None ,
288
+ usage : result .Usage | None = None ,
288
289
infer_name : bool = True ,
289
290
) -> result .RunResult [ResultData ]:
290
291
"""Run the agent with a user prompt synchronously.
@@ -311,6 +312,7 @@ async def main():
311
312
deps: Optional dependencies to use for this run.
312
313
model_settings: Optional settings to use for this model's request.
313
314
usage_limits: Optional limits on model request count or token usage.
315
+ usage: Optional usage to start with, useful for resuming a conversation or agents used in tools.
314
316
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
315
317
316
318
Returns:
@@ -326,6 +328,7 @@ async def main():
326
328
deps = deps ,
327
329
model_settings = model_settings ,
328
330
usage_limits = usage_limits ,
331
+ usage = usage ,
329
332
infer_name = False ,
330
333
)
331
334
)
@@ -340,6 +343,7 @@ async def run_stream(
340
343
deps : AgentDeps = None ,
341
344
model_settings : ModelSettings | None = None ,
342
345
usage_limits : UsageLimits | None = None ,
346
+ usage : result .Usage | None = None ,
343
347
infer_name : bool = True ,
344
348
) -> AsyncIterator [result .StreamedRunResult [AgentDeps , ResultData ]]:
345
349
"""Run the agent with a user prompt in async mode, returning a streamed response.
@@ -363,6 +367,7 @@ async def main():
363
367
deps: Optional dependencies to use for this run.
364
368
model_settings: Optional settings to use for this model's request.
365
369
usage_limits: Optional limits on model request count or token usage.
370
+ usage: Optional usage to start with, useful for resuming a conversation or agents used in tools.
366
371
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
367
372
368
373
Returns:
@@ -385,28 +390,27 @@ async def main():
385
390
model_name = model_used .name (),
386
391
agent_name = self .name or 'agent' ,
387
392
) as run_span :
388
- run_context = RunContext (deps , 0 , [], None , model_used )
393
+ run_context = RunContext (deps , 0 , [], None , model_used , usage or result . Usage () )
389
394
messages = await self ._prepare_messages (user_prompt , message_history , run_context )
390
395
run_context .messages = messages
391
396
392
397
for tool in self ._function_tools .values ():
393
398
tool .current_retry = 0
394
399
395
- usage = result .Usage ()
396
400
model_settings = merge_model_settings (self .model_settings , model_settings )
397
401
usage_limits = usage_limits or UsageLimits ()
398
402
399
403
run_step = 0
400
404
while True :
401
405
run_step += 1
402
- usage_limits .check_before_request (usage )
406
+ usage_limits .check_before_request (run_context . usage )
403
407
404
408
with _logfire .span ('preparing model and tools {run_step=}' , run_step = run_step ):
405
409
agent_model = await self ._prepare_model (run_context )
406
410
407
411
with _logfire .span ('model request {run_step=}' , run_step = run_step ) as model_req_span :
408
412
async with agent_model .request_stream (messages , model_settings ) as model_response :
409
- usage .requests += 1
413
+ run_context . usage .requests += 1
410
414
model_req_span .set_attribute ('response_type' , model_response .__class__ .__name__ )
411
415
# We want to end the "model request" span here, but we can't exit the context manager
412
416
# in the traditional way
@@ -442,7 +446,6 @@ async def on_complete():
442
446
yield result .StreamedRunResult (
443
447
messages ,
444
448
new_message_index ,
445
- usage ,
446
449
usage_limits ,
447
450
result_stream ,
448
451
self ._result_schema ,
@@ -466,8 +469,8 @@ async def on_complete():
466
469
handle_span .message = f'handle model response -> { tool_responses_str } '
467
470
# the model_response should have been fully streamed by now, we can add its usage
468
471
model_response_usage = model_response .usage ()
469
- usage += model_response_usage
470
- usage_limits .check_tokens (usage )
472
+ run_context . usage . incr ( model_response_usage )
473
+ usage_limits .check_tokens (run_context . usage )
471
474
472
475
@contextmanager
473
476
def override (
0 commit comments