@@ -124,6 +124,7 @@ async def send(
124124 types .LiveClientContentOrDict ,
125125 types .LiveClientRealtimeInputOrDict ,
126126 types .LiveClientToolResponseOrDict ,
127+ types .LiveClientContextUpdateOrDict ,
127128 types .FunctionResponseOrDict ,
128129 Sequence [types .FunctionResponseOrDict ],
129130 ]
@@ -445,6 +446,89 @@ async def send_tool_response(
445446
446447 await self ._ws .send (json .dumps ({'tool_response' : tool_response_dict }))
447448
449+ async def send_context_update (
450+ self ,
451+ * ,
452+ system_instruction : Optional [types .ContentUnion ] = None ,
453+ tools : Optional [types .ToolListUnion ] = None ,
454+ context_update : Optional [types .LiveClientContextUpdateOrDict ] = None ,
455+ ) -> None :
456+ """Send in-session context updates to the model.
457+
458+ Updates to the context of the current session. Only fields that are set will
459+ be updated. Updates are guaranteed to be processed *in order* with the rest of
460+ the inputs.
461+
462+ Note:
463+ `system_instruction` and `tools` are part of the model preamble, so updating
464+ them invalidates the prefix cache. Update them only when strictly necessary
465+ as it might have a performance impact on model generation.
466+
467+ Args:
468+ system_instruction: Updated system instruction for the model.
469+ tools: An updated list of tools the model may use to generate subsequent
470+ responses. Pass an empty list `[]` to clear all tools.
471+ context_update: A `LiveClientContextUpdate` object or dict. Cannot be
472+ combined with `system_instruction` or `tools`.
473+
474+ Example:
475+
476+ .. code-block:: python
477+
478+ # Update instructions:
479+ await session.send_context_update(
480+ system_instruction="You are now a technical expert. Be concise."
481+ )
482+
483+ # Update tools:
484+ await session.send_context_update(tools=[my_func])
485+
486+ # Clear tools:
487+ await session.send_context_update(tools=[])
488+ """
489+ update : types .LiveClientContextUpdate
490+ if context_update is not None :
491+ if system_instruction is not None or tools is not None :
492+ raise ValueError (
493+ 'Cannot set both `context_update` and `system_instruction` or'
494+ ' `tools`.'
495+ )
496+ if isinstance (context_update , types .LiveClientContextUpdate ):
497+ update = context_update
498+ elif isinstance (context_update , dict ):
499+ update = types .LiveClientContextUpdate .model_validate (context_update )
500+ else :
501+ raise ValueError (
502+ f'Unsupported context_update type "{ type (context_update )} "'
503+ )
504+ else :
505+ if system_instruction is None and tools is None :
506+ raise ValueError (
507+ 'At least one of `system_instruction`, `tools`, or `context_update`'
508+ ' must be set.'
509+ )
510+ tools_wrapper : Optional [types .LiveClientContextUpdateTools ] = None
511+ if tools is not None :
512+ tools_wrapper = types .LiveClientContextUpdateTools (tools = tools )
513+
514+ update = types .LiveClientContextUpdate (
515+ system_instruction = system_instruction ,
516+ tools = tools_wrapper ,
517+ )
518+
519+ client_message = types .LiveClientMessage (context_update = update )
520+ if self ._api_client .vertexai :
521+ message_dict = live_converters ._LiveClientMessage_to_vertex (
522+ self ._api_client , client_message
523+ )
524+ else :
525+ message_dict = live_converters ._LiveClientMessage_to_mldev (
526+ self ._api_client , client_message
527+ )
528+ message_dict = _common .convert_to_dict (message_dict )
529+ message_dict = _common .encode_unserializable_types (message_dict )
530+ await self ._ws .send (json .dumps (message_dict ))
531+
448532 async def receive (self ) -> AsyncIterator [types .LiveServerMessage ]:
449533 """Receive model responses from the server.
450534
@@ -605,6 +689,7 @@ def _parse_client_message(
605689 types .LiveClientContentOrDict ,
606690 types .LiveClientRealtimeInputOrDict ,
607691 types .LiveClientToolResponseOrDict ,
692+ types .LiveClientContextUpdateOrDict ,
608693 types .FunctionResponseOrDict ,
609694 Sequence [types .FunctionResponseOrDict ],
610695 ]
@@ -891,6 +976,41 @@ def _parse_client_message(
891976 )
892977 )
893978
979+ elif isinstance (formatted_input , types .LiveClientContextUpdate ):
980+ context_update_dict = formatted_input .model_dump (
981+ exclude_none = True , mode = 'json'
982+ )
983+ client_message = types .LiveClientMessageDict (
984+ context_update = types .LiveClientContextUpdateDict (
985+ system_instruction = context_update_dict .get ('system_instruction' ),
986+ tools = context_update_dict .get ('tools' ),
987+ )
988+ )
989+ elif isinstance (formatted_input , dict ) and (
990+ 'context_update' in formatted_input
991+ or 'system_instruction' in formatted_input
992+ or 'tools' in formatted_input
993+ ):
994+ update_val = (
995+ formatted_input ['context_update' ]
996+ if 'context_update' in formatted_input
997+ else formatted_input
998+ )
999+ if isinstance (update_val , types .LiveClientContextUpdate ):
1000+ update_dict = update_val .model_dump (exclude_none = True , mode = 'json' )
1001+ elif isinstance (update_val , dict ):
1002+ update_dict = update_val
1003+ else :
1004+ raise ValueError (
1005+ f'Unsupported context_update type "{ type (update_val )} "'
1006+ )
1007+ client_message = types .LiveClientMessageDict (
1008+ context_update = types .LiveClientContextUpdateDict (
1009+ system_instruction = update_dict .get ('system_instruction' ),
1010+ tools = update_dict .get ('tools' ),
1011+ )
1012+ )
1013+
8941014 else :
8951015 raise ValueError (
8961016 f'Unsupported input type "{ type (input )} " or input content "{ input } "'
0 commit comments