google-genai 0.0.1__py3-none-any.whl → 0.1.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/models.py CHANGED
@@ -1116,8 +1116,15 @@ def _EmbedContentConfig_to_mldev(
1116
1116
  parent_object: dict = None,
1117
1117
  ) -> dict:
1118
1118
  to_object = {}
1119
+ if getv(from_object, ['http_options']) is not None:
1120
+ setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
1121
+
1119
1122
  if getv(from_object, ['task_type']) is not None:
1120
- setv(parent_object, ['requests[]'], getv(from_object, ['task_type']))
1123
+ setv(
1124
+ parent_object,
1125
+ ['requests[]', 'taskType'],
1126
+ getv(from_object, ['task_type']),
1127
+ )
1121
1128
 
1122
1129
  if getv(from_object, ['title']) is not None:
1123
1130
  setv(parent_object, ['requests[]', 'title'], getv(from_object, ['title']))
@@ -1144,10 +1151,13 @@ def _EmbedContentConfig_to_vertex(
1144
1151
  parent_object: dict = None,
1145
1152
  ) -> dict:
1146
1153
  to_object = {}
1154
+ if getv(from_object, ['http_options']) is not None:
1155
+ setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
1156
+
1147
1157
  if getv(from_object, ['task_type']) is not None:
1148
1158
  setv(
1149
1159
  parent_object,
1150
- ['instances[]', 'taskType'],
1160
+ ['instances[]', 'task_type'],
1151
1161
  getv(from_object, ['task_type']),
1152
1162
  )
1153
1163
 
@@ -1253,6 +1263,9 @@ def _GenerateImageConfig_to_mldev(
1253
1263
  parent_object: dict = None,
1254
1264
  ) -> dict:
1255
1265
  to_object = {}
1266
+ if getv(from_object, ['http_options']) is not None:
1267
+ setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
1268
+
1256
1269
  if getv(from_object, ['output_gcs_uri']):
1257
1270
  raise ValueError('output_gcs_uri parameter is not supported in Google AI.')
1258
1271
 
@@ -1348,6 +1361,9 @@ def _GenerateImageConfig_to_vertex(
1348
1361
  parent_object: dict = None,
1349
1362
  ) -> dict:
1350
1363
  to_object = {}
1364
+ if getv(from_object, ['http_options']) is not None:
1365
+ setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
1366
+
1351
1367
  if getv(from_object, ['output_gcs_uri']) is not None:
1352
1368
  setv(
1353
1369
  parent_object,
@@ -1778,6 +1794,9 @@ def _EditImageConfig_to_mldev(
1778
1794
  parent_object: dict = None,
1779
1795
  ) -> dict:
1780
1796
  to_object = {}
1797
+ if getv(from_object, ['http_options']) is not None:
1798
+ setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
1799
+
1781
1800
  if getv(from_object, ['output_gcs_uri']):
1782
1801
  raise ValueError('output_gcs_uri parameter is not supported in Google AI.')
1783
1802
 
@@ -1870,6 +1889,9 @@ def _EditImageConfig_to_vertex(
1870
1889
  parent_object: dict = None,
1871
1890
  ) -> dict:
1872
1891
  to_object = {}
1892
+ if getv(from_object, ['http_options']) is not None:
1893
+ setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
1894
+
1873
1895
  if getv(from_object, ['output_gcs_uri']) is not None:
1874
1896
  setv(
1875
1897
  parent_object,
@@ -2042,6 +2064,9 @@ def _UpscaleImageAPIConfig_to_mldev(
2042
2064
  parent_object: dict = None,
2043
2065
  ) -> dict:
2044
2066
  to_object = {}
2067
+ if getv(from_object, ['http_options']) is not None:
2068
+ setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
2069
+
2045
2070
  if getv(from_object, ['upscale_factor']) is not None:
2046
2071
  setv(
2047
2072
  parent_object,
@@ -2089,6 +2114,9 @@ def _UpscaleImageAPIConfig_to_vertex(
2089
2114
  parent_object: dict = None,
2090
2115
  ) -> dict:
2091
2116
  to_object = {}
2117
+ if getv(from_object, ['http_options']) is not None:
2118
+ setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
2119
+
2092
2120
  if getv(from_object, ['upscale_factor']) is not None:
2093
2121
  setv(
2094
2122
  parent_object,
@@ -3695,6 +3723,28 @@ class Models(_common.BaseModule):
3695
3723
  contents: Union[types.ContentListUnion, types.ContentListUnionDict],
3696
3724
  config: Optional[types.EmbedContentConfigOrDict] = None,
3697
3725
  ) -> types.EmbedContentResponse:
3726
+ """Calculates embeddings for the given contents(only text is supported).
3727
+
3728
+ Args:
3729
+ model (str): The model to use.
3730
+ contents (list[Content]): The contents to embed.
3731
+ config (EmbedContentConfig): Optional configuration for embeddings.
3732
+
3733
+ Usage:
3734
+
3735
+ .. code-block:: python
3736
+ embeddings = client.models.embed_content(
3737
+ model= 'text-embedding-004',
3738
+ contents=[
3739
+ 'What is your name?',
3740
+ 'What is your favorite color?',
3741
+ ],
3742
+ config={
3743
+ 'output_dimensionality': 64
3744
+ },
3745
+ )
3746
+ """
3747
+
3698
3748
  parameter_model = types._EmbedContentParameters(
3699
3749
  model=model,
3700
3750
  contents=contents,
@@ -4327,6 +4377,7 @@ class Models(_common.BaseModule):
4327
4377
  logging.info(
4328
4378
  f'AFC is enabled with max remote calls: {remaining_remote_calls_afc}.'
4329
4379
  )
4380
+ automatic_function_calling_history = []
4330
4381
  while remaining_remote_calls_afc > 0:
4331
4382
  response = self._generate_content(
4332
4383
  model=model, contents=contents, config=config
@@ -4351,11 +4402,17 @@ class Models(_common.BaseModule):
4351
4402
  break
4352
4403
  contents = t.t_contents(self.api_client, contents)
4353
4404
  contents.append(response.candidates[0].content)
4354
- contents.append({
4355
- 'role': 'user',
4356
- 'parts': func_response_parts,
4357
- })
4358
-
4405
+ contents.append(
4406
+ types.Content(
4407
+ role='user',
4408
+ parts=func_response_parts,
4409
+ )
4410
+ )
4411
+ automatic_function_calling_history.extend(contents)
4412
+ if _extra_utils.should_append_afc_history(config):
4413
+ response.automatic_function_calling_history = (
4414
+ automatic_function_calling_history
4415
+ )
4359
4416
  return response
4360
4417
 
4361
4418
  def upscale_image(
@@ -4563,6 +4620,28 @@ class AsyncModels(_common.BaseModule):
4563
4620
  contents: Union[types.ContentListUnion, types.ContentListUnionDict],
4564
4621
  config: Optional[types.EmbedContentConfigOrDict] = None,
4565
4622
  ) -> types.EmbedContentResponse:
4623
+ """Calculates embeddings for the given contents(only text is supported).
4624
+
4625
+ Args:
4626
+ model (str): The model to use.
4627
+ contents (list[Content]): The contents to embed.
4628
+ config (EmbedContentConfig): Optional configuration for embeddings.
4629
+
4630
+ Usage:
4631
+
4632
+ .. code-block:: python
4633
+ embeddings = client.models.embed_content(
4634
+ model= 'text-embedding-004',
4635
+ contents=[
4636
+ 'What is your name?',
4637
+ 'What is your favorite color?',
4638
+ ],
4639
+ config={
4640
+ 'output_dimensionality': 64
4641
+ },
4642
+ )
4643
+ """
4644
+
4566
4645
  parameter_model = types._EmbedContentParameters(
4567
4646
  model=model,
4568
4647
  contents=contents,
@@ -5185,6 +5264,7 @@ class AsyncModels(_common.BaseModule):
5185
5264
  logging.info(
5186
5265
  f'AFC is enabled with max remote calls: {remaining_remote_calls_afc}.'
5187
5266
  )
5267
+ automatic_function_calling_history = []
5188
5268
  while remaining_remote_calls_afc > 0:
5189
5269
  response = await self._generate_content(
5190
5270
  model=model, contents=contents, config=config
@@ -5209,11 +5289,18 @@ class AsyncModels(_common.BaseModule):
5209
5289
  break
5210
5290
  contents = t.t_contents(self.api_client, contents)
5211
5291
  contents.append(response.candidates[0].content)
5212
- contents.append({
5213
- 'role': 'user',
5214
- 'parts': func_response_parts,
5215
- })
5292
+ contents.append(
5293
+ types.Content(
5294
+ role='user',
5295
+ parts=func_response_parts,
5296
+ )
5297
+ )
5298
+ automatic_function_calling_history.extend(contents)
5216
5299
 
5300
+ if _extra_utils.should_append_afc_history(config):
5301
+ response.automatic_function_calling_history = (
5302
+ automatic_function_calling_history
5303
+ )
5217
5304
  return response
5218
5305
 
5219
5306
  async def list(
google/genai/tunings.py CHANGED
@@ -896,7 +896,7 @@ def _TuningJobOrOperation_from_vertex(
896
896
 
897
897
  class Tunings(_common.BaseModule):
898
898
 
899
- def get(self, *, name: str) -> types.TuningJob:
899
+ def _get(self, *, name: str) -> types.TuningJob:
900
900
  """Gets a TuningJob.
901
901
 
902
902
  Args:
@@ -998,7 +998,7 @@ class Tunings(_common.BaseModule):
998
998
  self.api_client._verify_response(return_value)
999
999
  return return_value
1000
1000
 
1001
- def tune(
1001
+ def _tune(
1002
1002
  self,
1003
1003
  *,
1004
1004
  base_model: str,
@@ -1129,10 +1129,35 @@ class Tunings(_common.BaseModule):
1129
1129
  config,
1130
1130
  )
1131
1131
 
1132
+ def get(self, *, name: str) -> types.TuningJob:
1133
+ job = self._get(name=name)
1134
+ if job.experiment and self.api_client.vertexai:
1135
+ _IpythonUtils.display_experiment_button(
1136
+ experiment=job.experiment,
1137
+ project=self.api_client.project,
1138
+ )
1139
+ return job
1140
+
1141
+ def tune(
1142
+ self,
1143
+ *,
1144
+ base_model: str,
1145
+ training_dataset: types.TuningDatasetOrDict,
1146
+ config: Optional[types.CreateTuningJobConfigOrDict] = None,
1147
+ ) -> types.TuningJobOrOperation:
1148
+ result = self._tune(
1149
+ base_model=base_model,
1150
+ training_dataset=training_dataset,
1151
+ config=config,
1152
+ )
1153
+ if result.name and self.api_client.vertexai:
1154
+ _IpythonUtils.display_model_tuning_button(tuning_job_resource=result.name)
1155
+ return result
1156
+
1132
1157
 
1133
1158
  class AsyncTunings(_common.BaseModule):
1134
1159
 
1135
- async def get(self, *, name: str) -> types.TuningJob:
1160
+ async def _get(self, *, name: str) -> types.TuningJob:
1136
1161
  """Gets a TuningJob.
1137
1162
 
1138
1163
  Args:
@@ -1234,7 +1259,7 @@ class AsyncTunings(_common.BaseModule):
1234
1259
  self.api_client._verify_response(return_value)
1235
1260
  return return_value
1236
1261
 
1237
- async def tune(
1262
+ async def _tune(
1238
1263
  self,
1239
1264
  *,
1240
1265
  base_model: str,
@@ -1364,3 +1389,215 @@ class AsyncTunings(_common.BaseModule):
1364
1389
  await self._list(config=config),
1365
1390
  config,
1366
1391
  )
1392
+
1393
+ async def get(self, *, name: str) -> types.TuningJob:
1394
+ job = await self._get(name=name)
1395
+ if job.experiment and self.api_client.vertexai:
1396
+ _IpythonUtils.display_experiment_button(
1397
+ experiment=job.experiment,
1398
+ project=self.api_client.project,
1399
+ )
1400
+ return job
1401
+
1402
+ async def tune(
1403
+ self,
1404
+ *,
1405
+ base_model: str,
1406
+ training_dataset: types.TuningDatasetOrDict,
1407
+ config: Optional[types.CreateTuningJobConfigOrDict] = None,
1408
+ ) -> types.TuningJobOrOperation:
1409
+ result = await self._tune(
1410
+ base_model=base_model,
1411
+ training_dataset=training_dataset,
1412
+ config=config,
1413
+ )
1414
+ if result.name and self.api_client.vertexai:
1415
+ _IpythonUtils.display_model_tuning_button(tuning_job_resource=result.name)
1416
+ return result
1417
+
1418
+
1419
+ class _IpythonUtils:
1420
+ """Temporary class to hold the IPython related functions."""
1421
+
1422
+ displayed_experiments = set()
1423
+
1424
+ @staticmethod
1425
+ def _get_ipython_shell_name() -> str:
1426
+ import sys
1427
+
1428
+ if 'IPython' in sys.modules:
1429
+ from IPython import get_ipython
1430
+
1431
+ return get_ipython().__class__.__name__
1432
+ return ''
1433
+
1434
+ @staticmethod
1435
+ def is_ipython_available() -> bool:
1436
+ return bool(_IpythonUtils._get_ipython_shell_name())
1437
+
1438
+ @staticmethod
1439
+ def _get_styles() -> None:
1440
+ """Returns the HTML style markup to support custom buttons."""
1441
+ return """
1442
+ <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
1443
+ <style>
1444
+ .view-vertex-resource,
1445
+ .view-vertex-resource:hover,
1446
+ .view-vertex-resource:visited {
1447
+ position: relative;
1448
+ display: inline-flex;
1449
+ flex-direction: row;
1450
+ height: 32px;
1451
+ padding: 0 12px;
1452
+ margin: 4px 18px;
1453
+ gap: 4px;
1454
+ border-radius: 4px;
1455
+
1456
+ align-items: center;
1457
+ justify-content: center;
1458
+ background-color: rgb(255, 255, 255);
1459
+ color: rgb(51, 103, 214);
1460
+
1461
+ font-family: Roboto,"Helvetica Neue",sans-serif;
1462
+ font-size: 13px;
1463
+ font-weight: 500;
1464
+ text-transform: uppercase;
1465
+ text-decoration: none !important;
1466
+
1467
+ transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1) 0s;
1468
+ box-shadow: 0px 3px 1px -2px rgba(0,0,0,0.2), 0px 2px 2px 0px rgba(0,0,0,0.14), 0px 1px 5px 0px rgba(0,0,0,0.12);
1469
+ }
1470
+ .view-vertex-resource:active {
1471
+ box-shadow: 0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12);
1472
+ }
1473
+ .view-vertex-resource:active .view-vertex-ripple::before {
1474
+ position: absolute;
1475
+ top: 0;
1476
+ bottom: 0;
1477
+ left: 0;
1478
+ right: 0;
1479
+ border-radius: 4px;
1480
+ pointer-events: none;
1481
+
1482
+ content: '';
1483
+ background-color: rgb(51, 103, 214);
1484
+ opacity: 0.12;
1485
+ }
1486
+ .view-vertex-icon {
1487
+ font-size: 18px;
1488
+ }
1489
+ </style>
1490
+ """
1491
+
1492
+ @staticmethod
1493
+ def _parse_resource_name(marker: str, resource_parts: list[str]) -> str:
1494
+ """Returns the part after the marker text part."""
1495
+ for i in range(len(resource_parts)):
1496
+ if resource_parts[i] == marker and i + 1 < len(resource_parts):
1497
+ return resource_parts[i + 1]
1498
+ return ''
1499
+
1500
+ @staticmethod
1501
+ def _display_link(
1502
+ text: str, url: str, icon: Optional[str] = 'open_in_new'
1503
+ ) -> None:
1504
+ """Creates and displays the link to open the Vertex resource.
1505
+
1506
+ Args:
1507
+ text: The text displayed on the clickable button.
1508
+ url: The url that the button will lead to. Only cloud console URIs are
1509
+ allowed.
1510
+ icon: The icon name on the button (from material-icons library)
1511
+ """
1512
+ CLOUD_UI_URL = 'https://console.cloud.google.com' # pylint: disable=invalid-name
1513
+ if not url.startswith(CLOUD_UI_URL):
1514
+ raise ValueError(f'Only urls starting with {CLOUD_UI_URL} are allowed.')
1515
+
1516
+ import uuid
1517
+
1518
+ button_id = f'view-vertex-resource-{str(uuid.uuid4())}'
1519
+
1520
+ # Add the markup for the CSS and link component
1521
+ html = f"""
1522
+ {_IpythonUtils._get_styles()}
1523
+ <a class="view-vertex-resource" id="{button_id}" href="#view-{button_id}">
1524
+ <span class="material-icons view-vertex-icon">{icon}</span>
1525
+ <span>{text}</span>
1526
+ </a>
1527
+ """
1528
+
1529
+ # Add the click handler for the link
1530
+ html += f"""
1531
+ <script>
1532
+ (function () {{
1533
+ const link = document.getElementById('{button_id}');
1534
+ link.addEventListener('click', (e) => {{
1535
+ if (window.google?.colab?.openUrl) {{
1536
+ window.google.colab.openUrl('{url}');
1537
+ }} else {{
1538
+ window.open('{url}', '_blank');
1539
+ }}
1540
+ e.stopPropagation();
1541
+ e.preventDefault();
1542
+ }});
1543
+ }})();
1544
+ </script>
1545
+ """
1546
+
1547
+ from IPython.core.display import display
1548
+ from IPython.display import HTML
1549
+
1550
+ display(HTML(html))
1551
+
1552
+ @staticmethod
1553
+ def display_experiment_button(experiment: str, project: str) -> None:
1554
+ """Function to generate a link bound to the Vertex experiment.
1555
+
1556
+ Args:
1557
+ experiment: The Vertex experiment name. Example format:
1558
+ projects/{project_id}/locations/{location}/metadataStores/default/contexts/{experiment_name}
1559
+ project: The project (alphanumeric) name.
1560
+ """
1561
+ if (
1562
+ not _IpythonUtils.is_ipython_available()
1563
+ or experiment in _IpythonUtils.displayed_experiments
1564
+ ):
1565
+ return
1566
+ # Experiment gives the numeric id, but we need the alphanumeric project
1567
+ # name. So we get the project from the api client object as an argument.
1568
+ resource_parts = experiment.split('/')
1569
+ location = resource_parts[3]
1570
+ experiment_name = resource_parts[-1]
1571
+
1572
+ uri = (
1573
+ 'https://console.cloud.google.com/vertex-ai/experiments/locations/'
1574
+ + f'{location}/experiments/{experiment_name}/'
1575
+ + f'runs?project={project}'
1576
+ )
1577
+ _IpythonUtils._display_link('View Experiment', uri, 'science')
1578
+
1579
+ # Avoid repeatedly showing the button
1580
+ _IpythonUtils.displayed_experiments.add(experiment)
1581
+
1582
+ @staticmethod
1583
+ def display_model_tuning_button(tuning_job_resource: str) -> None:
1584
+ """Function to generate a link bound to the Vertex model tuning job.
1585
+
1586
+ Args:
1587
+ tuning_job_resource: The Vertex tuning job name. Example format:
1588
+ projects/{project_id}/locations/{location}/tuningJobs/{tuning_job_id}
1589
+ """
1590
+ if not _IpythonUtils.is_ipython_available():
1591
+ return
1592
+
1593
+ resource_parts = tuning_job_resource.split('/')
1594
+ project = resource_parts[1]
1595
+ location = resource_parts[3]
1596
+ tuning_job_id = resource_parts[-1]
1597
+
1598
+ uri = (
1599
+ 'https://console.cloud.google.com/vertex-ai/generative/language/'
1600
+ + f'locations/{location}/tuning/tuningJob/{tuning_job_id}'
1601
+ + f'?project={project}'
1602
+ )
1603
+ _IpythonUtils._display_link('View Tuning Job', uri, 'tune')