@@ -400,6 +400,7 @@ async def run_async(
400400 new_message : Optional [types .Content ] = None ,
401401 state_delta : Optional [dict [str , Any ]] = None ,
402402 run_config : Optional [RunConfig ] = None ,
403+ metadata : Optional [dict [str , Any ]] = None ,
403404 ) -> AsyncGenerator [Event , None ]:
404405 """Main entry method to run the agent in this runner.
405406
@@ -417,6 +418,9 @@ async def run_async(
417418 new_message: A new message to append to the session.
418419 state_delta: Optional state changes to apply to the session.
419420 run_config: The run config for the agent.
421+ metadata: Optional per-request metadata that will be passed to callbacks.
422+ This allows passing request-specific context such as user_id, trace_id,
423+ or memory context keys to before_model_callback and other callbacks.
420424
421425 Yields:
422426 The events generated by the agent.
@@ -433,6 +437,7 @@ async def run_async(
433437 async def _run_with_trace (
434438 new_message : Optional [types .Content ] = None ,
435439 invocation_id : Optional [str ] = None ,
440+ metadata : Optional [dict [str , Any ]] = None ,
436441 ) -> AsyncGenerator [Event , None ]:
437442 with tracer .start_as_current_span ('invocation' ):
438443 session = await self .session_service .get_session (
@@ -463,6 +468,7 @@ async def _run_with_trace(
463468 invocation_id = invocation_id ,
464469 run_config = run_config ,
465470 state_delta = state_delta ,
471+ metadata = metadata ,
466472 )
467473 if invocation_context .end_of_agents .get (
468474 invocation_context .agent .name
@@ -476,6 +482,7 @@ async def _run_with_trace(
476482 new_message = new_message , # new_message is not None.
477483 run_config = run_config ,
478484 state_delta = state_delta ,
485+ metadata = metadata ,
479486 )
480487
481488 async def execute (ctx : InvocationContext ) -> AsyncGenerator [Event ]:
@@ -502,7 +509,9 @@ async def execute(ctx: InvocationContext) -> AsyncGenerator[Event]:
502509 self .app , session , self .session_service
503510 )
504511
505- async with Aclosing (_run_with_trace (new_message , invocation_id )) as agen :
512+ async with Aclosing (
513+ _run_with_trace (new_message , invocation_id , metadata )
514+ ) as agen :
506515 async for event in agen :
507516 yield event
508517
@@ -1186,6 +1195,7 @@ async def _setup_context_for_new_invocation(
11861195 new_message : types .Content ,
11871196 run_config : RunConfig ,
11881197 state_delta : Optional [dict [str , Any ]],
1198+ metadata : Optional [dict [str , Any ]] = None ,
11891199 ) -> InvocationContext :
11901200 """Sets up the context for a new invocation.
11911201
@@ -1194,6 +1204,7 @@ async def _setup_context_for_new_invocation(
11941204 new_message: The new message to process and append to the session.
11951205 run_config: The run config of the agent.
11961206 state_delta: Optional state changes to apply to the session.
1207+ metadata: Optional per-request metadata to pass to callbacks.
11971208
11981209 Returns:
11991210 The invocation context for the new invocation.
@@ -1203,6 +1214,7 @@ async def _setup_context_for_new_invocation(
12031214 session ,
12041215 new_message = new_message ,
12051216 run_config = run_config ,
1217+ metadata = metadata ,
12061218 )
12071219 # Step 2: Handle new message, by running callbacks and appending to
12081220 # session.
@@ -1225,6 +1237,7 @@ async def _setup_context_for_resumed_invocation(
12251237 invocation_id : Optional [str ],
12261238 run_config : RunConfig ,
12271239 state_delta : Optional [dict [str , Any ]],
1240+ metadata : Optional [dict [str , Any ]] = None ,
12281241 ) -> InvocationContext :
12291242 """Sets up the context for a resumed invocation.
12301243
@@ -1234,6 +1247,7 @@ async def _setup_context_for_resumed_invocation(
12341247 invocation_id: The invocation id to resume.
12351248 run_config: The run config of the agent.
12361249 state_delta: Optional state changes to apply to the session.
1250+ metadata: Optional per-request metadata to pass to callbacks.
12371251
12381252 Returns:
12391253 The invocation context for the resumed invocation.
@@ -1259,6 +1273,7 @@ async def _setup_context_for_resumed_invocation(
12591273 new_message = user_message ,
12601274 run_config = run_config ,
12611275 invocation_id = invocation_id ,
1276+ metadata = metadata ,
12621277 )
12631278 # Step 3: Maybe handle new message.
12641279 if new_message :
@@ -1303,6 +1318,7 @@ def _new_invocation_context(
13031318 new_message : Optional [types .Content ] = None ,
13041319 live_request_queue : Optional [LiveRequestQueue ] = None ,
13051320 run_config : Optional [RunConfig ] = None ,
1321+ metadata : Optional [dict [str , Any ]] = None ,
13061322 ) -> InvocationContext :
13071323 """Creates a new invocation context.
13081324
@@ -1312,6 +1328,7 @@ def _new_invocation_context(
13121328 new_message: The new message for the context.
13131329 live_request_queue: The live request queue for the context.
13141330 run_config: The run config for the context.
1331+ metadata: Optional per-request metadata for the context.
13151332
13161333 Returns:
13171334 The new invocation context.
@@ -1343,6 +1360,7 @@ def _new_invocation_context(
13431360 live_request_queue = live_request_queue ,
13441361 run_config = run_config ,
13451362 resumability_config = self .resumability_config ,
1363+ metadata = metadata ,
13461364 )
13471365
13481366 def _new_invocation_context_for_live (
0 commit comments