google-genai 1.9.0__py3-none-any.whl → 1.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- google/genai/_api_client.py +117 -28
- google/genai/_automatic_function_calling_util.py +1 -1
- google/genai/_extra_utils.py +1 -1
- google/genai/_replay_api_client.py +32 -8
- google/genai/_transformers.py +43 -59
- google/genai/files.py +22 -6
- google/genai/live.py +545 -46
- google/genai/models.py +23 -9
- google/genai/operations.py +17 -9
- google/genai/tunings.py +0 -3
- google/genai/types.py +555 -57
- google/genai/version.py +1 -1
- {google_genai-1.9.0.dist-info → google_genai-1.10.0.dist-info}/METADATA +1 -1
- google_genai-1.10.0.dist-info/RECORD +27 -0
- google_genai-1.9.0.dist-info/RECORD +0 -27
- {google_genai-1.9.0.dist-info → google_genai-1.10.0.dist-info}/WHEEL +0 -0
- {google_genai-1.9.0.dist-info → google_genai-1.10.0.dist-info}/licenses/LICENSE +0 -0
- {google_genai-1.9.0.dist-info → google_genai-1.10.0.dist-info}/top_level.txt +0 -0
google/genai/live.py
CHANGED
@@ -13,14 +13,14 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
#
|
15
15
|
|
16
|
-
"""Live client.
|
16
|
+
"""[Preview] Live API client."""
|
17
17
|
|
18
18
|
import asyncio
|
19
19
|
import base64
|
20
20
|
import contextlib
|
21
21
|
import json
|
22
22
|
import logging
|
23
|
-
from typing import Any, AsyncIterator, Dict, Optional, Sequence, Union, get_args
|
23
|
+
from typing import Any, AsyncIterator, Dict, Optional, Sequence, Union, cast, get_args
|
24
24
|
import warnings
|
25
25
|
|
26
26
|
import google.auth
|
@@ -109,6 +109,13 @@ def _ToolResponse_to_vertex(
|
|
109
109
|
tool_response = from_object.model_dump(exclude_none=True, mode='json')
|
110
110
|
return tool_response
|
111
111
|
|
112
|
+
def _AudioTranscriptionConfig_to_mldev(
|
113
|
+
api_client: BaseApiClient,
|
114
|
+
from_object: types.AudioTranscriptionConfig,
|
115
|
+
) -> dict:
|
116
|
+
audio_transcription: dict[str, Any] = {}
|
117
|
+
return audio_transcription
|
118
|
+
|
112
119
|
|
113
120
|
def _AudioTranscriptionConfig_to_vertex(
|
114
121
|
api_client: BaseApiClient,
|
@@ -119,7 +126,7 @@ def _AudioTranscriptionConfig_to_vertex(
|
|
119
126
|
|
120
127
|
|
121
128
|
class AsyncSession:
|
122
|
-
"""AsyncSession.
|
129
|
+
"""[Preview] AsyncSession."""
|
123
130
|
|
124
131
|
def __init__(
|
125
132
|
self, api_client: client.BaseApiClient, websocket: ClientConnection
|
@@ -143,7 +150,12 @@ class AsyncSession:
|
|
143
150
|
] = None,
|
144
151
|
end_of_turn: Optional[bool] = False,
|
145
152
|
):
|
146
|
-
"""Send input to the model.
|
153
|
+
"""[Deprecated] Send input to the model.
|
154
|
+
|
155
|
+
> **Warning**: This method is deprecated and will be removed in a future
|
156
|
+
version (not before Q3 2025). Please use one of the more specific methods:
|
157
|
+
`send_client_content`, `send_realtime_input`, or `send_tool_response`
|
158
|
+
instead.
|
147
159
|
|
148
160
|
The method will send the input request to the server.
|
149
161
|
|
@@ -162,6 +174,14 @@ class AsyncSession:
|
|
162
174
|
async for message in session.receive():
|
163
175
|
print(message)
|
164
176
|
"""
|
177
|
+
warnings.warn(
|
178
|
+
'The `session.send` method is deprecated and will be removed in a '
|
179
|
+
'future version (not before Q3 2025).\n'
|
180
|
+
'Please use one of the more specific methods: `send_client_content`, '
|
181
|
+
'`send_realtime_input`, or `send_tool_response` instead.',
|
182
|
+
DeprecationWarning,
|
183
|
+
stacklevel=2,
|
184
|
+
)
|
165
185
|
client_message = self._parse_client_message(input, end_of_turn)
|
166
186
|
await self._ws.send(json.dumps(client_message))
|
167
187
|
|
@@ -375,8 +395,6 @@ class AsyncSession:
|
|
375
395
|
is function call, user must call `send` with the function response to
|
376
396
|
continue the turn.
|
377
397
|
|
378
|
-
The live module is experimental.
|
379
|
-
|
380
398
|
Yields:
|
381
399
|
The model responses from the server.
|
382
400
|
|
@@ -401,15 +419,18 @@ class AsyncSession:
|
|
401
419
|
async def start_stream(
|
402
420
|
self, *, stream: AsyncIterator[bytes], mime_type: str
|
403
421
|
) -> AsyncIterator[types.LiveServerMessage]:
|
404
|
-
"""
|
422
|
+
"""[Deprecated] Start a live session from a data stream.
|
423
|
+
|
424
|
+
> **Warning**: This method is deprecated and will be removed in a future
|
425
|
+
version (not before Q2 2025). Please use one of the more specific methods:
|
426
|
+
`send_client_content`, `send_realtime_input`, or `send_tool_response`
|
427
|
+
instead.
|
405
428
|
|
406
429
|
The interaction terminates when the input stream is complete.
|
407
430
|
This method will start two async tasks. One task will be used to send the
|
408
431
|
input stream to the model and the other task will be used to receive the
|
409
432
|
responses from the model.
|
410
433
|
|
411
|
-
The live module is experimental.
|
412
|
-
|
413
434
|
Args:
|
414
435
|
stream: An iterator that yields the model response.
|
415
436
|
mime_type: The MIME type of the data in the stream.
|
@@ -432,6 +453,13 @@ class AsyncSession:
|
|
432
453
|
mime_type = 'audio/pcm'):
|
433
454
|
play_audio_chunk(audio.data)
|
434
455
|
"""
|
456
|
+
warnings.warn(
|
457
|
+
'Setting `AsyncSession.start_stream` is deprecated, '
|
458
|
+
'and will be removed in a future release (not before Q3 2025). '
|
459
|
+
'Please use the `receive`, and `send_realtime_input`, methods instead.',
|
460
|
+
DeprecationWarning,
|
461
|
+
stacklevel=4,
|
462
|
+
)
|
435
463
|
stop_event = asyncio.Event()
|
436
464
|
# Start the send loop. When stream is complete stop_event is set.
|
437
465
|
asyncio.create_task(self._send_loop(stream, mime_type, stop_event))
|
@@ -465,7 +493,7 @@ class AsyncSession:
|
|
465
493
|
try:
|
466
494
|
raw_response = await self._ws.recv(decode=False)
|
467
495
|
except TypeError:
|
468
|
-
raw_response = await self._ws.recv()
|
496
|
+
raw_response = await self._ws.recv() # type: ignore[assignment]
|
469
497
|
if raw_response:
|
470
498
|
try:
|
471
499
|
response = json.loads(raw_response)
|
@@ -473,6 +501,7 @@ class AsyncSession:
|
|
473
501
|
raise ValueError(f'Failed to parse response: {raw_response!r}')
|
474
502
|
else:
|
475
503
|
response = {}
|
504
|
+
|
476
505
|
if self._api_client.vertexai:
|
477
506
|
response_dict = self._LiveServerMessage_from_vertex(response)
|
478
507
|
else:
|
@@ -514,14 +543,26 @@ class AsyncSession:
|
|
514
543
|
)
|
515
544
|
if getv(from_object, ['turnComplete']) is not None:
|
516
545
|
setv(to_object, ['turn_complete'], getv(from_object, ['turnComplete']))
|
517
|
-
if getv(from_object, ['interrupted']) is not None:
|
518
|
-
setv(to_object, ['interrupted'], getv(from_object, ['interrupted']))
|
519
546
|
if getv(from_object, ['generationComplete']) is not None:
|
520
547
|
setv(
|
521
548
|
to_object,
|
522
549
|
['generation_complete'],
|
523
550
|
getv(from_object, ['generationComplete']),
|
524
551
|
)
|
552
|
+
if getv(from_object, ['inputTranscription']) is not None:
|
553
|
+
setv(
|
554
|
+
to_object,
|
555
|
+
['input_transcription'],
|
556
|
+
getv(from_object, ['inputTranscription']),
|
557
|
+
)
|
558
|
+
if getv(from_object, ['outputTranscription']) is not None:
|
559
|
+
setv(
|
560
|
+
to_object,
|
561
|
+
['output_transcription'],
|
562
|
+
getv(from_object, ['outputTranscription']),
|
563
|
+
)
|
564
|
+
if getv(from_object, ['interrupted']) is not None:
|
565
|
+
setv(to_object, ['interrupted'], getv(from_object, ['interrupted']))
|
525
566
|
return to_object
|
526
567
|
|
527
568
|
def _LiveToolCall_from_mldev(
|
@@ -550,6 +591,128 @@ class AsyncSession:
|
|
550
591
|
)
|
551
592
|
return to_object
|
552
593
|
|
594
|
+
def _LiveServerGoAway_from_mldev(
|
595
|
+
self,
|
596
|
+
from_object: Union[dict, object],
|
597
|
+
parent_object: Optional[dict] = None,
|
598
|
+
) -> dict:
|
599
|
+
to_object: dict[str, Any] = {}
|
600
|
+
if getv(from_object, ['timeLeft']) is not None:
|
601
|
+
setv(to_object, ['time_left'], getv(from_object, ['timeLeft']))
|
602
|
+
|
603
|
+
return to_object
|
604
|
+
|
605
|
+
def _LiveServerSessionResumptionUpdate_from_mldev(
|
606
|
+
self,
|
607
|
+
from_object: Union[dict, object],
|
608
|
+
parent_object: Optional[dict] = None,
|
609
|
+
) -> dict:
|
610
|
+
to_object: dict[str, Any] = {}
|
611
|
+
if getv(from_object, ['newHandle']) is not None:
|
612
|
+
setv(to_object, ['new_handle'], getv(from_object, ['newHandle']))
|
613
|
+
|
614
|
+
if getv(from_object, ['resumable']) is not None:
|
615
|
+
setv(to_object, ['resumable'], getv(from_object, ['resumable']))
|
616
|
+
|
617
|
+
if getv(from_object, ['lastConsumedClientMessageIndex']) is not None:
|
618
|
+
setv(
|
619
|
+
to_object,
|
620
|
+
['last_consumed_client_message_index'],
|
621
|
+
getv(from_object, ['lastConsumedClientMessageIndex']),
|
622
|
+
)
|
623
|
+
|
624
|
+
return to_object
|
625
|
+
|
626
|
+
def _ModalityTokenCount_from_mldev(
|
627
|
+
self,
|
628
|
+
from_object: Union[dict, object],
|
629
|
+
) -> Dict[str, Any]:
|
630
|
+
to_object: Dict[str, Any] = {}
|
631
|
+
if getv(from_object, ['modality']) is not None:
|
632
|
+
setv(to_object, ['modality'], getv(from_object, ['modality']))
|
633
|
+
if getv(from_object, ['tokenCount']) is not None:
|
634
|
+
setv(to_object, ['token_count'], getv(from_object, ['tokenCount']))
|
635
|
+
return to_object
|
636
|
+
|
637
|
+
def _UsageMetadata_from_mldev(
|
638
|
+
self,
|
639
|
+
from_object: Union[dict, object],
|
640
|
+
) -> Dict[str, Any]:
|
641
|
+
to_object: dict[str, Any] = {}
|
642
|
+
if getv(from_object, ['promptTokenCount']) is not None:
|
643
|
+
setv(
|
644
|
+
to_object,
|
645
|
+
['prompt_token_count'],
|
646
|
+
getv(from_object, ['promptTokenCount']),
|
647
|
+
)
|
648
|
+
if getv(from_object, ['cachedContentTokenCount']) is not None:
|
649
|
+
setv(
|
650
|
+
to_object,
|
651
|
+
['cached_content_token_count'],
|
652
|
+
getv(from_object, ['cachedContentTokenCount']),
|
653
|
+
)
|
654
|
+
if getv(from_object, ['responseTokenCount']) is not None:
|
655
|
+
setv(
|
656
|
+
to_object,
|
657
|
+
['response_token_count'],
|
658
|
+
getv(from_object, ['responseTokenCount']),
|
659
|
+
)
|
660
|
+
if getv(from_object, ['toolUsePromptTokenCount']) is not None:
|
661
|
+
setv(
|
662
|
+
to_object,
|
663
|
+
['tool_use_prompt_token_count'],
|
664
|
+
getv(from_object, ['toolUsePromptTokenCount']),
|
665
|
+
)
|
666
|
+
if getv(from_object, ['thoughtsTokenCount']) is not None:
|
667
|
+
setv(
|
668
|
+
to_object,
|
669
|
+
['thoughts_token_count'],
|
670
|
+
getv(from_object, ['thoughtsTokenCount']),
|
671
|
+
)
|
672
|
+
if getv(from_object, ['totalTokenCount']) is not None:
|
673
|
+
setv(
|
674
|
+
to_object,
|
675
|
+
['total_token_count'],
|
676
|
+
getv(from_object, ['totalTokenCount']),
|
677
|
+
)
|
678
|
+
if getv(from_object, ['promptTokensDetails']) is not None:
|
679
|
+
setv(
|
680
|
+
to_object,
|
681
|
+
['prompt_tokens_details'],
|
682
|
+
[
|
683
|
+
self._ModalityTokenCount_from_mldev(item)
|
684
|
+
for item in getv(from_object, ['promptTokensDetails'])
|
685
|
+
],
|
686
|
+
)
|
687
|
+
if getv(from_object, ['cacheTokensDetails']) is not None:
|
688
|
+
setv(
|
689
|
+
to_object,
|
690
|
+
['cache_tokens_details'],
|
691
|
+
[
|
692
|
+
self._ModalityTokenCount_from_mldev(item)
|
693
|
+
for item in getv(from_object, ['cacheTokensDetails'])
|
694
|
+
],
|
695
|
+
)
|
696
|
+
if getv(from_object, ['responseTokensDetails']) is not None:
|
697
|
+
setv(
|
698
|
+
to_object,
|
699
|
+
['response_tokens_details'],
|
700
|
+
[
|
701
|
+
self._ModalityTokenCount_from_mldev(item)
|
702
|
+
for item in getv(from_object, ['responseTokensDetails'])
|
703
|
+
],
|
704
|
+
)
|
705
|
+
if getv(from_object, ['toolUsePromptTokensDetails']) is not None:
|
706
|
+
setv(
|
707
|
+
to_object,
|
708
|
+
['tool_use_prompt_tokens_details'],
|
709
|
+
[
|
710
|
+
self._ModalityTokenCount_from_mldev(item)
|
711
|
+
for item in getv(from_object, ['toolUsePromptTokensDetails'])
|
712
|
+
],
|
713
|
+
)
|
714
|
+
return to_object
|
715
|
+
|
553
716
|
def _LiveServerMessage_from_mldev(
|
554
717
|
self,
|
555
718
|
from_object: Union[dict, object],
|
@@ -575,6 +738,34 @@ class AsyncSession:
|
|
575
738
|
['tool_call_cancellation'],
|
576
739
|
getv(from_object, ['toolCallCancellation']),
|
577
740
|
)
|
741
|
+
|
742
|
+
if getv(from_object, ['goAway']) is not None:
|
743
|
+
setv(
|
744
|
+
to_object,
|
745
|
+
['go_away'],
|
746
|
+
self._LiveServerGoAway_from_mldev(
|
747
|
+
getv(from_object, ['goAway']), to_object
|
748
|
+
),
|
749
|
+
)
|
750
|
+
|
751
|
+
if getv(from_object, ['sessionResumptionUpdate']) is not None:
|
752
|
+
setv(
|
753
|
+
to_object,
|
754
|
+
['session_resumption_update'],
|
755
|
+
self._LiveServerSessionResumptionUpdate_from_mldev(
|
756
|
+
getv(from_object, ['sessionResumptionUpdate']),
|
757
|
+
to_object,
|
758
|
+
),
|
759
|
+
)
|
760
|
+
|
761
|
+
return to_object
|
762
|
+
|
763
|
+
if getv(from_object, ['usageMetadata']) is not None:
|
764
|
+
setv(
|
765
|
+
to_object,
|
766
|
+
['usage_metadata'],
|
767
|
+
self._UsageMetadata_from_mldev(getv(from_object, ['usageMetadata'])),
|
768
|
+
)
|
578
769
|
return to_object
|
579
770
|
|
580
771
|
def _LiveServerContent_from_vertex(
|
@@ -599,7 +790,6 @@ class AsyncSession:
|
|
599
790
|
['generation_complete'],
|
600
791
|
getv(from_object, ['generationComplete']),
|
601
792
|
)
|
602
|
-
# Vertex supports transcription.
|
603
793
|
if getv(from_object, ['inputTranscription']) is not None:
|
604
794
|
setv(
|
605
795
|
to_object,
|
@@ -616,6 +806,133 @@ class AsyncSession:
|
|
616
806
|
setv(to_object, ['interrupted'], getv(from_object, ['interrupted']))
|
617
807
|
return to_object
|
618
808
|
|
809
|
+
def _LiveServerGoAway_from_vertex(
|
810
|
+
self,
|
811
|
+
from_object: Union[dict, object],
|
812
|
+
) -> dict:
|
813
|
+
to_object: dict[str, Any] = {}
|
814
|
+
if getv(from_object, ['timeLeft']) is not None:
|
815
|
+
setv(to_object, ['time_left'], getv(from_object, ['timeLeft']))
|
816
|
+
|
817
|
+
return to_object
|
818
|
+
|
819
|
+
def _LiveServerSessionResumptionUpdate_from_vertex(
|
820
|
+
self,
|
821
|
+
from_object: Union[dict, object],
|
822
|
+
) -> dict:
|
823
|
+
to_object: dict[str, Any] = {}
|
824
|
+
if getv(from_object, ['newHandle']) is not None:
|
825
|
+
setv(to_object, ['new_handle'], getv(from_object, ['newHandle']))
|
826
|
+
|
827
|
+
if getv(from_object, ['resumable']) is not None:
|
828
|
+
setv(to_object, ['resumable'], getv(from_object, ['resumable']))
|
829
|
+
|
830
|
+
if getv(from_object, ['lastConsumedClientMessageIndex']) is not None:
|
831
|
+
setv(
|
832
|
+
to_object,
|
833
|
+
['last_consumed_client_message_index'],
|
834
|
+
getv(from_object, ['lastConsumedClientMessageIndex']),
|
835
|
+
)
|
836
|
+
|
837
|
+
return to_object
|
838
|
+
|
839
|
+
|
840
|
+
def _ModalityTokenCount_from_vertex(
|
841
|
+
self,
|
842
|
+
from_object: Union[dict, object],
|
843
|
+
) -> Dict[str, Any]:
|
844
|
+
to_object: Dict[str, Any] = {}
|
845
|
+
if getv(from_object, ['modality']) is not None:
|
846
|
+
setv(to_object, ['modality'], getv(from_object, ['modality']))
|
847
|
+
if getv(from_object, ['tokenCount']) is not None:
|
848
|
+
setv(to_object, ['token_count'], getv(from_object, ['tokenCount']))
|
849
|
+
return to_object
|
850
|
+
|
851
|
+
def _UsageMetadata_from_vertex(
|
852
|
+
self,
|
853
|
+
from_object: Union[dict, object],
|
854
|
+
) -> Dict[str, Any]:
|
855
|
+
to_object: dict[str, Any] = {}
|
856
|
+
if getv(from_object, ['promptTokenCount']) is not None:
|
857
|
+
setv(
|
858
|
+
to_object,
|
859
|
+
['prompt_token_count'],
|
860
|
+
getv(from_object, ['promptTokenCount']),
|
861
|
+
)
|
862
|
+
if getv(from_object, ['cachedContentTokenCount']) is not None:
|
863
|
+
setv(
|
864
|
+
to_object,
|
865
|
+
['cached_content_token_count'],
|
866
|
+
getv(from_object, ['cachedContentTokenCount']),
|
867
|
+
)
|
868
|
+
if getv(from_object, ['candidatesTokenCount']) is not None:
|
869
|
+
setv(
|
870
|
+
to_object,
|
871
|
+
['response_token_count'],
|
872
|
+
getv(from_object, ['candidatesTokenCount']),
|
873
|
+
)
|
874
|
+
if getv(from_object, ['toolUsePromptTokenCount']) is not None:
|
875
|
+
setv(
|
876
|
+
to_object,
|
877
|
+
['tool_use_prompt_token_count'],
|
878
|
+
getv(from_object, ['toolUsePromptTokenCount']),
|
879
|
+
)
|
880
|
+
if getv(from_object, ['thoughtsTokenCount']) is not None:
|
881
|
+
setv(
|
882
|
+
to_object,
|
883
|
+
['thoughts_token_count'],
|
884
|
+
getv(from_object, ['thoughtsTokenCount']),
|
885
|
+
)
|
886
|
+
if getv(from_object, ['totalTokenCount']) is not None:
|
887
|
+
setv(
|
888
|
+
to_object,
|
889
|
+
['total_token_count'],
|
890
|
+
getv(from_object, ['totalTokenCount']),
|
891
|
+
)
|
892
|
+
if getv(from_object, ['promptTokensDetails']) is not None:
|
893
|
+
setv(
|
894
|
+
to_object,
|
895
|
+
['prompt_tokens_details'],
|
896
|
+
[
|
897
|
+
self._ModalityTokenCount_from_vertex(item)
|
898
|
+
for item in getv(from_object, ['promptTokensDetails'])
|
899
|
+
],
|
900
|
+
)
|
901
|
+
if getv(from_object, ['cacheTokensDetails']) is not None:
|
902
|
+
setv(
|
903
|
+
to_object,
|
904
|
+
['cache_tokens_details'],
|
905
|
+
[
|
906
|
+
self._ModalityTokenCount_from_vertex(item)
|
907
|
+
for item in getv(from_object, ['cacheTokensDetails'])
|
908
|
+
],
|
909
|
+
)
|
910
|
+
if getv(from_object, ['toolUsePromptTokensDetails']) is not None:
|
911
|
+
setv(
|
912
|
+
to_object,
|
913
|
+
['tool_use_prompt_tokens_details'],
|
914
|
+
[
|
915
|
+
self._ModalityTokenCount_from_vertex(item)
|
916
|
+
for item in getv(from_object, ['toolUsePromptTokensDetails'])
|
917
|
+
],
|
918
|
+
)
|
919
|
+
if getv(from_object, ['candidatesTokensDetails']) is not None:
|
920
|
+
setv(
|
921
|
+
to_object,
|
922
|
+
['response_tokens_details'],
|
923
|
+
[
|
924
|
+
self._ModalityTokenCount_from_vertex(item)
|
925
|
+
for item in getv(from_object, ['candidatesTokensDetails'])
|
926
|
+
],
|
927
|
+
)
|
928
|
+
if getv(from_object, ['trafficType']) is not None:
|
929
|
+
setv(
|
930
|
+
to_object,
|
931
|
+
['traffic_type'],
|
932
|
+
getv(from_object, ['trafficType']),
|
933
|
+
)
|
934
|
+
return to_object
|
935
|
+
|
619
936
|
def _LiveServerMessage_from_vertex(
|
620
937
|
self,
|
621
938
|
from_object: Union[dict, object],
|
@@ -629,7 +946,6 @@ class AsyncSession:
|
|
629
946
|
getv(from_object, ['serverContent'])
|
630
947
|
),
|
631
948
|
)
|
632
|
-
|
633
949
|
if getv(from_object, ['toolCall']) is not None:
|
634
950
|
setv(
|
635
951
|
to_object,
|
@@ -642,6 +958,31 @@ class AsyncSession:
|
|
642
958
|
['tool_call_cancellation'],
|
643
959
|
getv(from_object, ['toolCallCancellation']),
|
644
960
|
)
|
961
|
+
|
962
|
+
if getv(from_object, ['goAway']) is not None:
|
963
|
+
setv(
|
964
|
+
to_object,
|
965
|
+
['go_away'],
|
966
|
+
self._LiveServerGoAway_from_vertex(
|
967
|
+
getv(from_object, ['goAway'])
|
968
|
+
),
|
969
|
+
)
|
970
|
+
|
971
|
+
if getv(from_object, ['sessionResumptionUpdate']) is not None:
|
972
|
+
setv(
|
973
|
+
to_object,
|
974
|
+
['session_resumption_update'],
|
975
|
+
self._LiveServerSessionResumptionUpdate_from_vertex(
|
976
|
+
getv(from_object, ['sessionResumptionUpdate']),
|
977
|
+
),
|
978
|
+
)
|
979
|
+
|
980
|
+
if getv(from_object, ['usageMetadata']) is not None:
|
981
|
+
setv(
|
982
|
+
to_object,
|
983
|
+
['usage_metadata'],
|
984
|
+
self._UsageMetadata_from_vertex(getv(from_object, ['usageMetadata'])),
|
985
|
+
)
|
645
986
|
return to_object
|
646
987
|
|
647
988
|
def _parse_client_message(
|
@@ -1026,7 +1367,7 @@ def _t_tool_response(
|
|
1026
1367
|
|
1027
1368
|
|
1028
1369
|
class AsyncLive(_api_module.BaseModule):
|
1029
|
-
"""AsyncLive.
|
1370
|
+
"""[Preview] AsyncLive."""
|
1030
1371
|
|
1031
1372
|
def _LiveSetup_to_mldev(
|
1032
1373
|
self, model: str, config: Optional[types.LiveConnectConfig] = None
|
@@ -1099,6 +1440,15 @@ class AsyncLive(_api_module.BaseModule):
|
|
1099
1440
|
to_object['generationConfig'] = {
|
1100
1441
|
'maxOutputTokens': getv(config, ['max_output_tokens'])
|
1101
1442
|
}
|
1443
|
+
if getv(config, ['media_resolution']) is not None:
|
1444
|
+
if getv(to_object, ['generationConfig']) is not None:
|
1445
|
+
to_object['generationConfig']['mediaResolution'] = getv(
|
1446
|
+
config, ['media_resolution']
|
1447
|
+
)
|
1448
|
+
else:
|
1449
|
+
to_object['generationConfig'] = {
|
1450
|
+
'mediaResolution': getv(config, ['media_resolution'])
|
1451
|
+
}
|
1102
1452
|
if getv(config, ['seed']) is not None:
|
1103
1453
|
if getv(to_object, ['generationConfig']) is not None:
|
1104
1454
|
to_object['generationConfig']['seed'] = getv(config, ['seed'])
|
@@ -1127,11 +1477,84 @@ class AsyncLive(_api_module.BaseModule):
|
|
1127
1477
|
for item in t.t_tools(self._api_client, getv(config, ['tools']))
|
1128
1478
|
],
|
1129
1479
|
)
|
1480
|
+
if getv(config, ['input_audio_transcription']) is not None:
|
1481
|
+
raise ValueError('input_audio_transcription is not supported in MLDev '
|
1482
|
+
'API.')
|
1483
|
+
if getv(config, ['output_audio_transcription']) is not None:
|
1484
|
+
setv(
|
1485
|
+
to_object,
|
1486
|
+
['outputAudioTranscription'],
|
1487
|
+
_AudioTranscriptionConfig_to_mldev(
|
1488
|
+
self._api_client,
|
1489
|
+
getv(config, ['output_audio_transcription']),
|
1490
|
+
),
|
1491
|
+
)
|
1492
|
+
|
1493
|
+
if getv(config, ['session_resumption']) is not None:
|
1494
|
+
setv(
|
1495
|
+
to_object,
|
1496
|
+
['sessionResumption'],
|
1497
|
+
self._LiveClientSessionResumptionConfig_to_mldev(
|
1498
|
+
getv(config, ['session_resumption'])
|
1499
|
+
),
|
1500
|
+
)
|
1501
|
+
|
1502
|
+
if getv(config, ['context_window_compression']) is not None:
|
1503
|
+
setv(
|
1504
|
+
to_object,
|
1505
|
+
['contextWindowCompression'],
|
1506
|
+
self._ContextWindowCompressionConfig_to_mldev(
|
1507
|
+
getv(config, ['context_window_compression']),
|
1508
|
+
),
|
1509
|
+
)
|
1130
1510
|
|
1131
1511
|
return_value = {'setup': {'model': model}}
|
1132
1512
|
return_value['setup'].update(to_object)
|
1133
1513
|
return return_value
|
1134
1514
|
|
1515
|
+
def _SlidingWindow_to_mldev(
|
1516
|
+
self,
|
1517
|
+
from_object: Union[dict, object],
|
1518
|
+
) -> dict:
|
1519
|
+
to_object: dict[str, Any] = {}
|
1520
|
+
if getv(from_object, ['target_tokens']) is not None:
|
1521
|
+
setv(to_object, ['targetTokens'], getv(from_object, ['target_tokens']))
|
1522
|
+
|
1523
|
+
return to_object
|
1524
|
+
|
1525
|
+
|
1526
|
+
def _ContextWindowCompressionConfig_to_mldev(
|
1527
|
+
self,
|
1528
|
+
from_object: Union[dict, object],
|
1529
|
+
) -> dict:
|
1530
|
+
to_object: dict[str, Any] = {}
|
1531
|
+
if getv(from_object, ['trigger_tokens']) is not None:
|
1532
|
+
setv(to_object, ['triggerTokens'], getv(from_object, ['trigger_tokens']))
|
1533
|
+
|
1534
|
+
if getv(from_object, ['sliding_window']) is not None:
|
1535
|
+
setv(
|
1536
|
+
to_object,
|
1537
|
+
['slidingWindow'],
|
1538
|
+
self._SlidingWindow_to_mldev(
|
1539
|
+
getv(from_object, ['sliding_window'])
|
1540
|
+
),
|
1541
|
+
)
|
1542
|
+
|
1543
|
+
return to_object
|
1544
|
+
|
1545
|
+
def _LiveClientSessionResumptionConfig_to_mldev(
|
1546
|
+
self,
|
1547
|
+
from_object: Union[dict, object]
|
1548
|
+
) -> dict:
|
1549
|
+
to_object: dict[str, Any] = {}
|
1550
|
+
if getv(from_object, ['handle']) is not None:
|
1551
|
+
setv(to_object, ['handle'], getv(from_object, ['handle']))
|
1552
|
+
|
1553
|
+
if getv(from_object, ['transparent']) is not None:
|
1554
|
+
raise ValueError('The `transparent` field is not supported in MLDev API')
|
1555
|
+
|
1556
|
+
return to_object
|
1557
|
+
|
1135
1558
|
def _LiveSetup_to_vertex(
|
1136
1559
|
self, model: str, config: Optional[types.LiveConnectConfig] = None
|
1137
1560
|
):
|
@@ -1212,6 +1635,15 @@ class AsyncLive(_api_module.BaseModule):
|
|
1212
1635
|
to_object['generationConfig'] = {
|
1213
1636
|
'maxOutputTokens': getv(config, ['max_output_tokens'])
|
1214
1637
|
}
|
1638
|
+
if getv(config, ['media_resolution']) is not None:
|
1639
|
+
if getv(to_object, ['generationConfig']) is not None:
|
1640
|
+
to_object['generationConfig']['mediaResolution'] = getv(
|
1641
|
+
config, ['media_resolution']
|
1642
|
+
)
|
1643
|
+
else:
|
1644
|
+
to_object['generationConfig'] = {
|
1645
|
+
'mediaResolution': getv(config, ['media_resolution'])
|
1646
|
+
}
|
1215
1647
|
if getv(config, ['seed']) is not None:
|
1216
1648
|
if getv(to_object, ['generationConfig']) is not None:
|
1217
1649
|
to_object['generationConfig']['seed'] = getv(config, ['seed'])
|
@@ -1259,13 +1691,70 @@ class AsyncLive(_api_module.BaseModule):
|
|
1259
1691
|
),
|
1260
1692
|
)
|
1261
1693
|
|
1694
|
+
if getv(config, ['session_resumption']) is not None:
|
1695
|
+
setv(
|
1696
|
+
to_object,
|
1697
|
+
['sessionResumption'],
|
1698
|
+
self._LiveClientSessionResumptionConfig_to_vertex(
|
1699
|
+
getv(config, ['session_resumption'])
|
1700
|
+
),
|
1701
|
+
)
|
1702
|
+
|
1703
|
+
if getv(config, ['context_window_compression']) is not None:
|
1704
|
+
setv(
|
1705
|
+
to_object,
|
1706
|
+
['contextWindowCompression'],
|
1707
|
+
self._ContextWindowCompressionConfig_to_vertex(
|
1708
|
+
getv(config, ['context_window_compression']),
|
1709
|
+
),
|
1710
|
+
)
|
1711
|
+
|
1262
1712
|
return_value = {'setup': {'model': model}}
|
1263
1713
|
return_value['setup'].update(to_object)
|
1264
1714
|
return return_value
|
1265
1715
|
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1716
|
+
def _SlidingWindow_to_vertex(
|
1717
|
+
self,
|
1718
|
+
from_object: Union[dict, object],
|
1719
|
+
) -> dict:
|
1720
|
+
to_object: dict[str, Any] = {}
|
1721
|
+
if getv(from_object, ['target_tokens']) is not None:
|
1722
|
+
setv(to_object, ['targetTokens'], getv(from_object, ['target_tokens']))
|
1723
|
+
|
1724
|
+
return to_object
|
1725
|
+
|
1726
|
+
def _ContextWindowCompressionConfig_to_vertex(
|
1727
|
+
self,
|
1728
|
+
from_object: Union[dict, object],
|
1729
|
+
) -> dict:
|
1730
|
+
to_object: dict[str, Any] = {}
|
1731
|
+
if getv(from_object, ['trigger_tokens']) is not None:
|
1732
|
+
setv(to_object, ['triggerTokens'], getv(from_object, ['trigger_tokens']))
|
1733
|
+
|
1734
|
+
if getv(from_object, ['sliding_window']) is not None:
|
1735
|
+
setv(
|
1736
|
+
to_object,
|
1737
|
+
['slidingWindow'],
|
1738
|
+
self._SlidingWindow_to_mldev(
|
1739
|
+
getv(from_object, ['sliding_window'])
|
1740
|
+
),
|
1741
|
+
)
|
1742
|
+
|
1743
|
+
return to_object
|
1744
|
+
|
1745
|
+
def _LiveClientSessionResumptionConfig_to_vertex(
|
1746
|
+
self,
|
1747
|
+
from_object: Union[dict, object]
|
1748
|
+
) -> dict:
|
1749
|
+
to_object: dict[str, Any] = {}
|
1750
|
+
if getv(from_object, ['handle']) is not None:
|
1751
|
+
setv(to_object, ['handle'], getv(from_object, ['handle']))
|
1752
|
+
|
1753
|
+
if getv(from_object, ['transparent']) is not None:
|
1754
|
+
setv(to_object, ['transparent'], getv(from_object, ['transparent']))
|
1755
|
+
|
1756
|
+
return to_object
|
1757
|
+
|
1269
1758
|
@contextlib.asynccontextmanager
|
1270
1759
|
async def connect(
|
1271
1760
|
self,
|
@@ -1273,9 +1762,9 @@ class AsyncLive(_api_module.BaseModule):
|
|
1273
1762
|
model: str,
|
1274
1763
|
config: Optional[types.LiveConnectConfigOrDict] = None,
|
1275
1764
|
) -> AsyncIterator[AsyncSession]:
|
1276
|
-
"""Connect to the live server.
|
1765
|
+
"""[Preview] Connect to the live server.
|
1277
1766
|
|
1278
|
-
|
1767
|
+
Note: the live API is currently in preview.
|
1279
1768
|
|
1280
1769
|
Usage:
|
1281
1770
|
|
@@ -1290,32 +1779,8 @@ class AsyncLive(_api_module.BaseModule):
|
|
1290
1779
|
"""
|
1291
1780
|
base_url = self._api_client._websocket_base_url()
|
1292
1781
|
transformed_model = t.t_model(self._api_client, model)
|
1293
|
-
|
1294
|
-
|
1295
|
-
parameter_model = types.LiveConnectConfig()
|
1296
|
-
elif isinstance(config, dict):
|
1297
|
-
if config.get('system_instruction') is None:
|
1298
|
-
system_instruction = None
|
1299
|
-
else:
|
1300
|
-
system_instruction = t.t_content(
|
1301
|
-
self._api_client, config.get('system_instruction')
|
1302
|
-
)
|
1303
|
-
parameter_model = types.LiveConnectConfig(
|
1304
|
-
generation_config=config.get('generation_config'),
|
1305
|
-
response_modalities=config.get('response_modalities'),
|
1306
|
-
speech_config=config.get('speech_config'),
|
1307
|
-
temperature=config.get('temperature'),
|
1308
|
-
top_p=config.get('top_p'),
|
1309
|
-
top_k=config.get('top_k'),
|
1310
|
-
max_output_tokens=config.get('max_output_tokens'),
|
1311
|
-
seed=config.get('seed'),
|
1312
|
-
system_instruction=system_instruction,
|
1313
|
-
tools=config.get('tools'),
|
1314
|
-
input_audio_transcription=config.get('input_audio_transcription'),
|
1315
|
-
output_audio_transcription=config.get('output_audio_transcription'),
|
1316
|
-
)
|
1317
|
-
else:
|
1318
|
-
parameter_model = config
|
1782
|
+
|
1783
|
+
parameter_model = _t_live_connect_config(self._api_client, config)
|
1319
1784
|
|
1320
1785
|
if self._api_client.api_key:
|
1321
1786
|
api_key = self._api_client.api_key
|
@@ -1374,3 +1839,37 @@ class AsyncLive(_api_module.BaseModule):
|
|
1374
1839
|
logger.info(await ws.recv())
|
1375
1840
|
|
1376
1841
|
yield AsyncSession(api_client=self._api_client, websocket=ws)
|
1842
|
+
|
1843
|
+
|
1844
|
+
def _t_live_connect_config(
|
1845
|
+
api_client: BaseApiClient,
|
1846
|
+
config: Optional[types.LiveConnectConfigOrDict],
|
1847
|
+
) -> types.LiveConnectConfig:
|
1848
|
+
# Ensure the config is a LiveConnectConfig.
|
1849
|
+
if config is None:
|
1850
|
+
parameter_model = types.LiveConnectConfig()
|
1851
|
+
elif isinstance(config, dict):
|
1852
|
+
system_instruction = config.pop('system_instruction', None)
|
1853
|
+
if system_instruction is not None:
|
1854
|
+
converted_system_instruction = t.t_content(
|
1855
|
+
api_client, content=system_instruction
|
1856
|
+
)
|
1857
|
+
else:
|
1858
|
+
converted_system_instruction = None
|
1859
|
+
parameter_model = types.LiveConnectConfig(
|
1860
|
+
system_instruction=converted_system_instruction,
|
1861
|
+
**config
|
1862
|
+
) # type: ignore
|
1863
|
+
else:
|
1864
|
+
parameter_model = config
|
1865
|
+
|
1866
|
+
if parameter_model.generation_config is not None:
|
1867
|
+
warnings.warn(
|
1868
|
+
'Setting `LiveConnectConfig.generation_config` is deprecated, '
|
1869
|
+
'please set the fields on `LiveConnectConfig` directly. This will '
|
1870
|
+
'become an error in a future version (not before Q3 2025)',
|
1871
|
+
DeprecationWarning,
|
1872
|
+
stacklevel=4,
|
1873
|
+
)
|
1874
|
+
|
1875
|
+
return parameter_model
|