google-cloud-agentplatform 1.165.1.dev0__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.
Files changed (62) hide show
  1. agentplatform/__init__.py +72 -0
  2. agentplatform/_genai/__init__.py +43 -0
  3. agentplatform/_genai/_agent_engines_utils.py +2341 -0
  4. agentplatform/_genai/_bigquery_utils.py +49 -0
  5. agentplatform/_genai/_datasets_utils.py +344 -0
  6. agentplatform/_genai/_evals_builtin_tools.py +209 -0
  7. agentplatform/_genai/_evals_common.py +4268 -0
  8. agentplatform/_genai/_evals_constant.py +122 -0
  9. agentplatform/_genai/_evals_data_converters.py +926 -0
  10. agentplatform/_genai/_evals_metric_handlers.py +1783 -0
  11. agentplatform/_genai/_evals_metric_loaders.py +401 -0
  12. agentplatform/_genai/_evals_utils.py +1043 -0
  13. agentplatform/_genai/_evals_visualization.py +2070 -0
  14. agentplatform/_genai/_gcs_utils.py +262 -0
  15. agentplatform/_genai/_logging_utils.py +47 -0
  16. agentplatform/_genai/_memory_bank_utils.py +206 -0
  17. agentplatform/_genai/_observability_data_converter.py +186 -0
  18. agentplatform/_genai/_operations_utils.py +94 -0
  19. agentplatform/_genai/_prompt_management_utils.py +147 -0
  20. agentplatform/_genai/_prompt_optimizer_utils.py +215 -0
  21. agentplatform/_genai/_skills_utils.py +69 -0
  22. agentplatform/_genai/_transformers.py +628 -0
  23. agentplatform/_genai/a2a_task_events.py +509 -0
  24. agentplatform/_genai/a2a_tasks.py +861 -0
  25. agentplatform/_genai/agent_engines.py +3931 -0
  26. agentplatform/_genai/client.py +519 -0
  27. agentplatform/_genai/datasets.py +3045 -0
  28. agentplatform/_genai/endpoints.py +1149 -0
  29. agentplatform/_genai/evals.py +6883 -0
  30. agentplatform/_genai/example_stores.py +1445 -0
  31. agentplatform/_genai/feedback_contexts.py +700 -0
  32. agentplatform/_genai/feedback_entries.py +1644 -0
  33. agentplatform/_genai/live.py +64 -0
  34. agentplatform/_genai/live_agent_engines.py +179 -0
  35. agentplatform/_genai/memories.py +2962 -0
  36. agentplatform/_genai/memory_banks.py +1927 -0
  37. agentplatform/_genai/memory_revisions.py +465 -0
  38. agentplatform/_genai/model_garden.py +2638 -0
  39. agentplatform/_genai/prompt_optimizer.py +995 -0
  40. agentplatform/_genai/prompts.py +4515 -0
  41. agentplatform/_genai/rag.py +4961 -0
  42. agentplatform/_genai/runtime_revisions.py +1257 -0
  43. agentplatform/_genai/runtimes.py +78 -0
  44. agentplatform/_genai/sandbox_snapshots.py +1015 -0
  45. agentplatform/_genai/sandbox_templates.py +1088 -0
  46. agentplatform/_genai/sandboxes.py +1604 -0
  47. agentplatform/_genai/session_events.py +543 -0
  48. agentplatform/_genai/sessions.py +1449 -0
  49. agentplatform/_genai/skill_revisions.py +377 -0
  50. agentplatform/_genai/skills.py +1708 -0
  51. agentplatform/_genai/types/__init__.py +4695 -0
  52. agentplatform/_genai/types/agent_engines.py +16 -0
  53. agentplatform/_genai/types/common.py +32784 -0
  54. agentplatform/_genai/types/evals.py +1031 -0
  55. agentplatform/_genai/types/prompt_optimizer.py +107 -0
  56. agentplatform/_genai/types/prompts.py +107 -0
  57. agentplatform/version.py +17 -0
  58. google_cloud_agentplatform-1.165.1.dev0.dist-info/METADATA +79 -0
  59. google_cloud_agentplatform-1.165.1.dev0.dist-info/RECORD +62 -0
  60. google_cloud_agentplatform-1.165.1.dev0.dist-info/WHEEL +5 -0
  61. google_cloud_agentplatform-1.165.1.dev0.dist-info/licenses/LICENSE +202 -0
  62. google_cloud_agentplatform-1.165.1.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1708 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+
16
+ # Code generated by the Google Gen AI SDK generator DO NOT EDIT.
17
+
18
+ import asyncio
19
+ import base64
20
+ import importlib
21
+ import json
22
+ import logging
23
+ import typing
24
+ from typing import Any, Optional, Union
25
+ from urllib.parse import urlencode
26
+
27
+ from google.genai import _api_module
28
+ from google.genai import _common
29
+ from google.genai._common import get_value_by_path as getv
30
+ from google.genai._common import set_value_by_path as setv
31
+ from google.genai.pagers import AsyncPager, Pager
32
+
33
+ from . import _operations_utils
34
+ from . import _skills_utils
35
+ from . import types
36
+
37
+ if typing.TYPE_CHECKING:
38
+ from . import skill_revisions as skill_revisions_module
39
+
40
+ _ = skill_revisions_module
41
+
42
+
43
+ logger = logging.getLogger("agentplatform_genai.skills")
44
+
45
+
46
+ def _CreateSkillConfig_to_vertex(
47
+ from_object: Union[dict[str, Any], object],
48
+ parent_object: Optional[dict[str, Any]] = None,
49
+ ) -> dict[str, Any]:
50
+ to_object: dict[str, Any] = {}
51
+
52
+ if getv(from_object, ["zipped_filesystem"]) is not None:
53
+ setv(
54
+ parent_object,
55
+ ["zippedFilesystem"],
56
+ getv(from_object, ["zipped_filesystem"]),
57
+ )
58
+
59
+ return to_object
60
+
61
+
62
+ def _CreateSkillRequestParameters_to_vertex(
63
+ from_object: Union[dict[str, Any], object],
64
+ parent_object: Optional[dict[str, Any]] = None,
65
+ ) -> dict[str, Any]:
66
+ to_object: dict[str, Any] = {}
67
+ if getv(from_object, ["display_name"]) is not None:
68
+ setv(to_object, ["displayName"], getv(from_object, ["display_name"]))
69
+
70
+ if getv(from_object, ["description"]) is not None:
71
+ setv(to_object, ["description"], getv(from_object, ["description"]))
72
+
73
+ if getv(from_object, ["config"]) is not None:
74
+ _CreateSkillConfig_to_vertex(getv(from_object, ["config"]), to_object)
75
+
76
+ if getv(from_object, ["skill_id"]) is not None:
77
+ setv(to_object, ["_query", "skillId"], getv(from_object, ["skill_id"]))
78
+
79
+ return to_object
80
+
81
+
82
+ def _DeleteSkillRequestParameters_to_vertex(
83
+ from_object: Union[dict[str, Any], object],
84
+ parent_object: Optional[dict[str, Any]] = None,
85
+ ) -> dict[str, Any]:
86
+ to_object: dict[str, Any] = {}
87
+ if getv(from_object, ["name"]) is not None:
88
+ setv(to_object, ["_url", "name"], getv(from_object, ["name"]))
89
+
90
+ return to_object
91
+
92
+
93
+ def _GetSkillOperationParameters_to_vertex(
94
+ from_object: Union[dict[str, Any], object],
95
+ parent_object: Optional[dict[str, Any]] = None,
96
+ ) -> dict[str, Any]:
97
+ to_object: dict[str, Any] = {}
98
+ if getv(from_object, ["operation_name"]) is not None:
99
+ setv(
100
+ to_object, ["_url", "operationName"], getv(from_object, ["operation_name"])
101
+ )
102
+
103
+ return to_object
104
+
105
+
106
+ def _GetSkillRequestParameters_to_vertex(
107
+ from_object: Union[dict[str, Any], object],
108
+ parent_object: Optional[dict[str, Any]] = None,
109
+ ) -> dict[str, Any]:
110
+ to_object: dict[str, Any] = {}
111
+ if getv(from_object, ["name"]) is not None:
112
+ setv(to_object, ["_url", "name"], getv(from_object, ["name"]))
113
+
114
+ if getv(from_object, ["config"]) is not None:
115
+ setv(to_object, ["config"], getv(from_object, ["config"]))
116
+
117
+ return to_object
118
+
119
+
120
+ def _ListSkillsConfig_to_vertex(
121
+ from_object: Union[dict[str, Any], object],
122
+ parent_object: Optional[dict[str, Any]] = None,
123
+ ) -> dict[str, Any]:
124
+ to_object: dict[str, Any] = {}
125
+
126
+ if getv(from_object, ["page_size"]) is not None:
127
+ setv(parent_object, ["_query", "pageSize"], getv(from_object, ["page_size"]))
128
+
129
+ if getv(from_object, ["page_token"]) is not None:
130
+ setv(parent_object, ["_query", "pageToken"], getv(from_object, ["page_token"]))
131
+
132
+ if getv(from_object, ["filter"]) is not None:
133
+ setv(parent_object, ["_query", "filter"], getv(from_object, ["filter"]))
134
+
135
+ return to_object
136
+
137
+
138
+ def _ListSkillsRequestParameters_to_vertex(
139
+ from_object: Union[dict[str, Any], object],
140
+ parent_object: Optional[dict[str, Any]] = None,
141
+ ) -> dict[str, Any]:
142
+ to_object: dict[str, Any] = {}
143
+ if getv(from_object, ["config"]) is not None:
144
+ setv(
145
+ to_object,
146
+ ["config"],
147
+ _ListSkillsConfig_to_vertex(getv(from_object, ["config"]), to_object),
148
+ )
149
+
150
+ return to_object
151
+
152
+
153
+ def _RetrieveSkillsConfig_to_vertex(
154
+ from_object: Union[dict[str, Any], object],
155
+ parent_object: Optional[dict[str, Any]] = None,
156
+ ) -> dict[str, Any]:
157
+ to_object: dict[str, Any] = {}
158
+
159
+ if getv(from_object, ["top_k"]) is not None:
160
+ setv(parent_object, ["_query", "topK"], getv(from_object, ["top_k"]))
161
+
162
+ return to_object
163
+
164
+
165
+ def _RetrieveSkillsRequestParameters_to_vertex(
166
+ from_object: Union[dict[str, Any], object],
167
+ parent_object: Optional[dict[str, Any]] = None,
168
+ ) -> dict[str, Any]:
169
+ to_object: dict[str, Any] = {}
170
+ if getv(from_object, ["query"]) is not None:
171
+ setv(to_object, ["_query", "query"], getv(from_object, ["query"]))
172
+
173
+ if getv(from_object, ["config"]) is not None:
174
+ setv(
175
+ to_object,
176
+ ["config"],
177
+ _RetrieveSkillsConfig_to_vertex(getv(from_object, ["config"]), to_object),
178
+ )
179
+
180
+ return to_object
181
+
182
+
183
+ def _UpdateSkillConfig_to_vertex(
184
+ from_object: Union[dict[str, Any], object],
185
+ parent_object: Optional[dict[str, Any]] = None,
186
+ ) -> dict[str, Any]:
187
+ to_object: dict[str, Any] = {}
188
+
189
+ if getv(from_object, ["display_name"]) is not None:
190
+ setv(parent_object, ["displayName"], getv(from_object, ["display_name"]))
191
+
192
+ if getv(from_object, ["description"]) is not None:
193
+ setv(parent_object, ["description"], getv(from_object, ["description"]))
194
+
195
+ if getv(from_object, ["zipped_filesystem"]) is not None:
196
+ setv(
197
+ parent_object,
198
+ ["zippedFilesystem"],
199
+ getv(from_object, ["zipped_filesystem"]),
200
+ )
201
+
202
+ if getv(from_object, ["update_mask"]) is not None:
203
+ setv(
204
+ parent_object, ["_query", "updateMask"], getv(from_object, ["update_mask"])
205
+ )
206
+
207
+ return to_object
208
+
209
+
210
+ def _UpdateSkillRequestParameters_to_vertex(
211
+ from_object: Union[dict[str, Any], object],
212
+ parent_object: Optional[dict[str, Any]] = None,
213
+ ) -> dict[str, Any]:
214
+ to_object: dict[str, Any] = {}
215
+ if getv(from_object, ["name"]) is not None:
216
+ setv(to_object, ["_url", "name"], getv(from_object, ["name"]))
217
+
218
+ if getv(from_object, ["config"]) is not None:
219
+ _UpdateSkillConfig_to_vertex(getv(from_object, ["config"]), to_object)
220
+
221
+ return to_object
222
+
223
+
224
+ class Skills(_api_module.BaseModule):
225
+ """Class for managing Skills in the Skill Registry."""
226
+
227
+ def get(
228
+ self, *, name: str, config: Optional[types.GetSkillConfigOrDict] = None
229
+ ) -> types.Skill:
230
+ """
231
+ Gets a Skill.
232
+ """
233
+
234
+ parameter_model = types._GetSkillRequestParameters(
235
+ name=name,
236
+ config=config,
237
+ )
238
+
239
+ request_url_dict: Optional[dict[str, str]]
240
+ if not self._api_client.vertexai:
241
+ raise ValueError(
242
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
243
+ )
244
+ else:
245
+ request_dict = _GetSkillRequestParameters_to_vertex(parameter_model)
246
+ request_url_dict = request_dict.get("_url")
247
+ if request_url_dict:
248
+ path = "{name}".format_map(request_url_dict)
249
+ else:
250
+ path = "{name}"
251
+
252
+ query_params = request_dict.get("_query")
253
+ if query_params:
254
+ path = f"{path}?{urlencode(query_params)}"
255
+ # TODO: remove the hack that pops config.
256
+ request_dict.pop("config", None)
257
+
258
+ http_options: Optional[types.HttpOptions] = None
259
+ if (
260
+ parameter_model.config is not None
261
+ and parameter_model.config.http_options is not None
262
+ ):
263
+ http_options = parameter_model.config.http_options
264
+
265
+ request_dict = _common.convert_to_dict(request_dict)
266
+ request_dict = _common.encode_unserializable_types(request_dict)
267
+
268
+ response = self._api_client.request("get", path, request_dict, http_options)
269
+
270
+ response_dict = {} if not response.body else json.loads(response.body)
271
+
272
+ return_value = types.Skill._from_response(
273
+ response=response_dict,
274
+ kwargs=(
275
+ {
276
+ "config": {
277
+ "response_schema": getattr(
278
+ parameter_model.config, "response_schema", None
279
+ ),
280
+ "response_json_schema": getattr(
281
+ parameter_model.config, "response_json_schema", None
282
+ ),
283
+ "include_all_fields": getattr(
284
+ parameter_model.config, "include_all_fields", None
285
+ ),
286
+ }
287
+ }
288
+ if getattr(parameter_model, "config", None)
289
+ else {}
290
+ ),
291
+ )
292
+
293
+ self._api_client._verify_response(return_value)
294
+ return return_value
295
+
296
+ def retrieve(
297
+ self, *, query: str, config: Optional[types.RetrieveSkillsConfigOrDict] = None
298
+ ) -> types.RetrieveSkillsResponse:
299
+ """
300
+ Retrieves skills semantically matched to a query.
301
+ """
302
+
303
+ parameter_model = types._RetrieveSkillsRequestParameters(
304
+ query=query,
305
+ config=config,
306
+ )
307
+
308
+ request_url_dict: Optional[dict[str, str]]
309
+ if not self._api_client.vertexai:
310
+ raise ValueError(
311
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
312
+ )
313
+ else:
314
+ request_dict = _RetrieveSkillsRequestParameters_to_vertex(parameter_model)
315
+ request_url_dict = request_dict.get("_url")
316
+ if request_url_dict:
317
+ path = "skills:retrieve".format_map(request_url_dict)
318
+ else:
319
+ path = "skills:retrieve"
320
+
321
+ query_params = request_dict.get("_query")
322
+ if query_params:
323
+ path = f"{path}?{urlencode(query_params)}"
324
+ # TODO: remove the hack that pops config.
325
+ request_dict.pop("config", None)
326
+
327
+ http_options: Optional[types.HttpOptions] = None
328
+ if (
329
+ parameter_model.config is not None
330
+ and parameter_model.config.http_options is not None
331
+ ):
332
+ http_options = parameter_model.config.http_options
333
+
334
+ request_dict = _common.convert_to_dict(request_dict)
335
+ request_dict = _common.encode_unserializable_types(request_dict)
336
+
337
+ response = self._api_client.request("get", path, request_dict, http_options)
338
+
339
+ response_dict = {} if not response.body else json.loads(response.body)
340
+
341
+ return_value = types.RetrieveSkillsResponse._from_response(
342
+ response=response_dict,
343
+ kwargs=(
344
+ {
345
+ "config": {
346
+ "response_schema": getattr(
347
+ parameter_model.config, "response_schema", None
348
+ ),
349
+ "response_json_schema": getattr(
350
+ parameter_model.config, "response_json_schema", None
351
+ ),
352
+ "include_all_fields": getattr(
353
+ parameter_model.config, "include_all_fields", None
354
+ ),
355
+ }
356
+ }
357
+ if getattr(parameter_model, "config", None)
358
+ else {}
359
+ ),
360
+ )
361
+
362
+ self._api_client._verify_response(return_value)
363
+ return return_value
364
+
365
+ def _create(
366
+ self,
367
+ *,
368
+ display_name: str,
369
+ description: str,
370
+ config: Optional[types.CreateSkillConfigOrDict] = None,
371
+ skill_id: str,
372
+ ) -> types.SkillOperation:
373
+ """
374
+ Creates a new Skill.
375
+ """
376
+
377
+ parameter_model = types._CreateSkillRequestParameters(
378
+ display_name=display_name,
379
+ description=description,
380
+ config=config,
381
+ skill_id=skill_id,
382
+ )
383
+
384
+ request_url_dict: Optional[dict[str, str]]
385
+ if not self._api_client.vertexai:
386
+ raise ValueError(
387
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
388
+ )
389
+ else:
390
+ request_dict = _CreateSkillRequestParameters_to_vertex(parameter_model)
391
+ request_url_dict = request_dict.get("_url")
392
+ if request_url_dict:
393
+ path = "skills".format_map(request_url_dict)
394
+ else:
395
+ path = "skills"
396
+
397
+ query_params = request_dict.get("_query")
398
+ if query_params:
399
+ path = f"{path}?{urlencode(query_params)}"
400
+ # TODO: remove the hack that pops config.
401
+ request_dict.pop("config", None)
402
+
403
+ http_options: Optional[types.HttpOptions] = None
404
+ if (
405
+ parameter_model.config is not None
406
+ and parameter_model.config.http_options is not None
407
+ ):
408
+ http_options = parameter_model.config.http_options
409
+
410
+ request_dict = _common.convert_to_dict(request_dict)
411
+ request_dict = _common.encode_unserializable_types(request_dict)
412
+
413
+ response = self._api_client.request("post", path, request_dict, http_options)
414
+
415
+ response_dict = {} if not response.body else json.loads(response.body)
416
+
417
+ return_value = types.SkillOperation._from_response(
418
+ response=response_dict,
419
+ kwargs=(
420
+ {
421
+ "config": {
422
+ "response_schema": getattr(
423
+ parameter_model.config, "response_schema", None
424
+ ),
425
+ "response_json_schema": getattr(
426
+ parameter_model.config, "response_json_schema", None
427
+ ),
428
+ "include_all_fields": getattr(
429
+ parameter_model.config, "include_all_fields", None
430
+ ),
431
+ }
432
+ }
433
+ if getattr(parameter_model, "config", None)
434
+ else {}
435
+ ),
436
+ )
437
+
438
+ self._api_client._verify_response(return_value)
439
+ return return_value
440
+
441
+ def _update(
442
+ self, *, name: str, config: Optional[types.UpdateSkillConfigOrDict] = None
443
+ ) -> types.SkillOperation:
444
+ """
445
+ Updates a Skill.
446
+ """
447
+
448
+ parameter_model = types._UpdateSkillRequestParameters(
449
+ name=name,
450
+ config=config,
451
+ )
452
+
453
+ request_url_dict: Optional[dict[str, str]]
454
+ if not self._api_client.vertexai:
455
+ raise ValueError(
456
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
457
+ )
458
+ else:
459
+ request_dict = _UpdateSkillRequestParameters_to_vertex(parameter_model)
460
+ request_url_dict = request_dict.get("_url")
461
+ if request_url_dict:
462
+ path = "{name}".format_map(request_url_dict)
463
+ else:
464
+ path = "{name}"
465
+
466
+ query_params = request_dict.get("_query")
467
+ if query_params:
468
+ path = f"{path}?{urlencode(query_params)}"
469
+ # TODO: remove the hack that pops config.
470
+ request_dict.pop("config", None)
471
+
472
+ http_options: Optional[types.HttpOptions] = None
473
+ if (
474
+ parameter_model.config is not None
475
+ and parameter_model.config.http_options is not None
476
+ ):
477
+ http_options = parameter_model.config.http_options
478
+
479
+ request_dict = _common.convert_to_dict(request_dict)
480
+ request_dict = _common.encode_unserializable_types(request_dict)
481
+
482
+ response = self._api_client.request("patch", path, request_dict, http_options)
483
+
484
+ response_dict = {} if not response.body else json.loads(response.body)
485
+
486
+ return_value = types.SkillOperation._from_response(
487
+ response=response_dict,
488
+ kwargs=(
489
+ {
490
+ "config": {
491
+ "response_schema": getattr(
492
+ parameter_model.config, "response_schema", None
493
+ ),
494
+ "response_json_schema": getattr(
495
+ parameter_model.config, "response_json_schema", None
496
+ ),
497
+ "include_all_fields": getattr(
498
+ parameter_model.config, "include_all_fields", None
499
+ ),
500
+ }
501
+ }
502
+ if getattr(parameter_model, "config", None)
503
+ else {}
504
+ ),
505
+ )
506
+
507
+ self._api_client._verify_response(return_value)
508
+ return return_value
509
+
510
+ def _list(
511
+ self, *, config: Optional[types.ListSkillsConfigOrDict] = None
512
+ ) -> types.ListSkillsResponse:
513
+ parameter_model = types._ListSkillsRequestParameters(
514
+ config=config,
515
+ )
516
+
517
+ request_url_dict: Optional[dict[str, str]]
518
+ if not self._api_client.vertexai:
519
+ raise ValueError(
520
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
521
+ )
522
+ else:
523
+ request_dict = _ListSkillsRequestParameters_to_vertex(parameter_model)
524
+ request_url_dict = request_dict.get("_url")
525
+ if request_url_dict:
526
+ path = "skills".format_map(request_url_dict)
527
+ else:
528
+ path = "skills"
529
+
530
+ query_params = request_dict.get("_query")
531
+ if query_params:
532
+ path = f"{path}?{urlencode(query_params)}"
533
+ # TODO: remove the hack that pops config.
534
+ request_dict.pop("config", None)
535
+
536
+ http_options: Optional[types.HttpOptions] = None
537
+ if (
538
+ parameter_model.config is not None
539
+ and parameter_model.config.http_options is not None
540
+ ):
541
+ http_options = parameter_model.config.http_options
542
+
543
+ request_dict = _common.convert_to_dict(request_dict)
544
+ request_dict = _common.encode_unserializable_types(request_dict)
545
+
546
+ response = self._api_client.request("get", path, request_dict, http_options)
547
+
548
+ response_dict = {} if not response.body else json.loads(response.body)
549
+
550
+ return_value = types.ListSkillsResponse._from_response(
551
+ response=response_dict,
552
+ kwargs=(
553
+ {
554
+ "config": {
555
+ "response_schema": getattr(
556
+ parameter_model.config, "response_schema", None
557
+ ),
558
+ "response_json_schema": getattr(
559
+ parameter_model.config, "response_json_schema", None
560
+ ),
561
+ "include_all_fields": getattr(
562
+ parameter_model.config, "include_all_fields", None
563
+ ),
564
+ }
565
+ }
566
+ if getattr(parameter_model, "config", None)
567
+ else {}
568
+ ),
569
+ )
570
+
571
+ self._api_client._verify_response(return_value)
572
+ return return_value
573
+
574
+ def _delete(
575
+ self, *, name: str, config: Optional[types.DeleteSkillConfigOrDict] = None
576
+ ) -> types.DeleteSkillOperation:
577
+ """
578
+ Deletes a Skill.
579
+ """
580
+
581
+ parameter_model = types._DeleteSkillRequestParameters(
582
+ name=name,
583
+ config=config,
584
+ )
585
+
586
+ request_url_dict: Optional[dict[str, str]]
587
+ if not self._api_client.vertexai:
588
+ raise ValueError(
589
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
590
+ )
591
+ else:
592
+ request_dict = _DeleteSkillRequestParameters_to_vertex(parameter_model)
593
+ request_url_dict = request_dict.get("_url")
594
+ if request_url_dict:
595
+ path = "{name}".format_map(request_url_dict)
596
+ else:
597
+ path = "{name}"
598
+
599
+ query_params = request_dict.get("_query")
600
+ if query_params:
601
+ path = f"{path}?{urlencode(query_params)}"
602
+ # TODO: remove the hack that pops config.
603
+ request_dict.pop("config", None)
604
+
605
+ http_options: Optional[types.HttpOptions] = None
606
+ if (
607
+ parameter_model.config is not None
608
+ and parameter_model.config.http_options is not None
609
+ ):
610
+ http_options = parameter_model.config.http_options
611
+
612
+ request_dict = _common.convert_to_dict(request_dict)
613
+ request_dict = _common.encode_unserializable_types(request_dict)
614
+
615
+ response = self._api_client.request("delete", path, request_dict, http_options)
616
+
617
+ response_dict = {} if not response.body else json.loads(response.body)
618
+
619
+ return_value = types.DeleteSkillOperation._from_response(
620
+ response=response_dict,
621
+ kwargs=(
622
+ {
623
+ "config": {
624
+ "response_schema": getattr(
625
+ parameter_model.config, "response_schema", None
626
+ ),
627
+ "response_json_schema": getattr(
628
+ parameter_model.config, "response_json_schema", None
629
+ ),
630
+ "include_all_fields": getattr(
631
+ parameter_model.config, "include_all_fields", None
632
+ ),
633
+ }
634
+ }
635
+ if getattr(parameter_model, "config", None)
636
+ else {}
637
+ ),
638
+ )
639
+
640
+ self._api_client._verify_response(return_value)
641
+ return return_value
642
+
643
+ def _get_skill_operation(
644
+ self,
645
+ *,
646
+ operation_name: str,
647
+ config: Optional[types.GetSkillOperationConfigOrDict] = None,
648
+ ) -> types.SkillOperation:
649
+ parameter_model = types._GetSkillOperationParameters(
650
+ operation_name=operation_name,
651
+ config=config,
652
+ )
653
+
654
+ request_url_dict: Optional[dict[str, str]]
655
+ if not self._api_client.vertexai:
656
+ raise ValueError(
657
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
658
+ )
659
+ else:
660
+ request_dict = _GetSkillOperationParameters_to_vertex(parameter_model)
661
+ request_url_dict = request_dict.get("_url")
662
+ if request_url_dict:
663
+ path = "{operationName}".format_map(request_url_dict)
664
+ else:
665
+ path = "{operationName}"
666
+
667
+ query_params = request_dict.get("_query")
668
+ if query_params:
669
+ path = f"{path}?{urlencode(query_params)}"
670
+ # TODO: remove the hack that pops config.
671
+ request_dict.pop("config", None)
672
+
673
+ http_options: Optional[types.HttpOptions] = None
674
+ if (
675
+ parameter_model.config is not None
676
+ and parameter_model.config.http_options is not None
677
+ ):
678
+ http_options = parameter_model.config.http_options
679
+
680
+ request_dict = _common.convert_to_dict(request_dict)
681
+ request_dict = _common.encode_unserializable_types(request_dict)
682
+
683
+ response = self._api_client.request("get", path, request_dict, http_options)
684
+
685
+ response_dict = {} if not response.body else json.loads(response.body)
686
+
687
+ return_value = types.SkillOperation._from_response(
688
+ response=response_dict,
689
+ kwargs=(
690
+ {
691
+ "config": {
692
+ "response_schema": getattr(
693
+ parameter_model.config, "response_schema", None
694
+ ),
695
+ "response_json_schema": getattr(
696
+ parameter_model.config, "response_json_schema", None
697
+ ),
698
+ "include_all_fields": getattr(
699
+ parameter_model.config, "include_all_fields", None
700
+ ),
701
+ }
702
+ }
703
+ if getattr(parameter_model, "config", None)
704
+ else {}
705
+ ),
706
+ )
707
+
708
+ self._api_client._verify_response(return_value)
709
+ return return_value
710
+
711
+ def create(
712
+ self,
713
+ *,
714
+ skill_id: str,
715
+ display_name: str,
716
+ description: str,
717
+ config: Optional[types.CreateSkillConfigOrDict] = None,
718
+ ) -> Union[types.Skill, types.SkillOperation]:
719
+ """Creates a new Skill.
720
+
721
+ Args:
722
+ skill_id (str):
723
+ Required. The ID to use for the Skill, which will become the final
724
+ component of the Skill's resource name.
725
+ display_name (str):
726
+ Required. The display name of the Skill.
727
+ description (str):
728
+ Required. The description of the Skill.
729
+ config (CreateSkillConfigOrDict):
730
+ Optional. The configuration for creating the Skill.
731
+
732
+ Returns:
733
+ Skill: The created Skill if wait_for_completion is True.
734
+ SkillOperation: The operation for creating the Skill if
735
+ wait_for_completion is False.
736
+ """
737
+ if config is None:
738
+ config = types.CreateSkillConfig()
739
+ elif isinstance(config, dict):
740
+ config = types.CreateSkillConfig.model_validate(config)
741
+ elif not isinstance(config, types.CreateSkillConfig):
742
+ raise TypeError(
743
+ f"config must be a dict or CreateSkillConfig, but got {type(config)}."
744
+ )
745
+
746
+ config = config.model_copy()
747
+
748
+ local_path = config.local_path
749
+ zipped_filesystem = config.zipped_filesystem
750
+
751
+ if local_path and zipped_filesystem:
752
+ raise ValueError(
753
+ "Only one of `local_path` or `zipped_filesystem` can be provided in config."
754
+ )
755
+ if not local_path and not zipped_filesystem:
756
+ raise ValueError(
757
+ "Either `local_path` or `zipped_filesystem` must be provided in config."
758
+ )
759
+
760
+ if local_path:
761
+ zipped_filesystem_payload = _skills_utils.get_zipped_filesystem_payload(
762
+ local_path
763
+ )
764
+ else:
765
+ # Narrow type for mypy
766
+ if zipped_filesystem is None:
767
+ raise ValueError(
768
+ "zipped_filesystem is required if local_path is not provided."
769
+ )
770
+ if isinstance(zipped_filesystem, bytes):
771
+ zipped_filesystem_payload = base64.b64encode(zipped_filesystem).decode(
772
+ "utf-8"
773
+ )
774
+ else:
775
+ zipped_filesystem_payload = zipped_filesystem
776
+
777
+ # Mutate the config object to populate the zipped_filesystem payload
778
+ config.zipped_filesystem = zipped_filesystem_payload
779
+
780
+ operation = self._create(
781
+ skill_id=skill_id,
782
+ display_name=display_name,
783
+ description=description,
784
+ config=config,
785
+ )
786
+
787
+ if config.wait_for_completion:
788
+ operation = _operations_utils.await_operation(
789
+ operation_name=operation.name,
790
+ get_operation_fn=self._get_skill_operation,
791
+ )
792
+ if operation.error:
793
+ raise RuntimeError(f"Failed to create Skill: {operation.error}")
794
+ # Fetch the fully populated Skill resource from the server
795
+ return self.get(name=operation.response.name)
796
+
797
+ return operation
798
+
799
+ def update(
800
+ self,
801
+ *,
802
+ name: str,
803
+ config: Optional[types.UpdateSkillConfigOrDict] = None,
804
+ ) -> Union[types.Skill, types.SkillOperation]:
805
+ """Updates an existing Skill.
806
+
807
+ Args:
808
+ name (str):
809
+ Required. The resource name of the Skill to update.
810
+ Format: projects/{project}/locations/{location}/skills/{skill}
811
+ config (UpdateSkillConfigOrDict):
812
+ Optional. The configuration for updating the Skill.
813
+
814
+ Returns:
815
+ Skill: The updated Skill if wait_for_completion is True.
816
+ SkillOperation: The operation for updating the Skill if
817
+ wait_for_completion is False.
818
+ """
819
+ if config is None:
820
+ config = types.UpdateSkillConfig()
821
+ elif isinstance(config, dict):
822
+ config = types.UpdateSkillConfig.model_validate(config)
823
+ elif not isinstance(config, types.UpdateSkillConfig):
824
+ raise TypeError(
825
+ f"config must be a dict or UpdateSkillConfig, but got {type(config)}."
826
+ )
827
+
828
+ config = config.model_copy()
829
+
830
+ display_name = config.display_name
831
+ description = config.description
832
+ local_path = config.local_path
833
+ zipped_filesystem = config.zipped_filesystem
834
+
835
+ if local_path and zipped_filesystem:
836
+ raise ValueError(
837
+ "Only one of `local_path` or `zipped_filesystem` can be provided in config."
838
+ )
839
+
840
+ # Construct update_mask and prepare payload
841
+ update_mask_paths = []
842
+ zipped_filesystem_payload = None
843
+
844
+ if display_name is not None:
845
+ update_mask_paths.append("displayName")
846
+
847
+ if description is not None:
848
+ update_mask_paths.append("description")
849
+
850
+ if local_path:
851
+ zipped_filesystem_payload = _skills_utils.get_zipped_filesystem_payload(
852
+ local_path
853
+ )
854
+ update_mask_paths.append("zippedFilesystem")
855
+ elif zipped_filesystem is not None:
856
+ if isinstance(zipped_filesystem, bytes):
857
+ zipped_filesystem_payload = base64.b64encode(zipped_filesystem).decode(
858
+ "utf-8"
859
+ )
860
+ else:
861
+ zipped_filesystem_payload = zipped_filesystem
862
+ update_mask_paths.append("zippedFilesystem")
863
+
864
+ if not update_mask_paths:
865
+ raise ValueError(
866
+ "At least one of `display_name`, `description`, `local_path`, or "
867
+ "`zipped_filesystem` must be provided for update in config."
868
+ )
869
+
870
+ update_mask = ",".join(update_mask_paths)
871
+
872
+ # Mutate config in place to populate the generated update_mask and zipped_filesystem
873
+ config.update_mask = update_mask
874
+ config.zipped_filesystem = zipped_filesystem_payload
875
+
876
+ operation = self._update(
877
+ name=name,
878
+ config=config,
879
+ )
880
+
881
+ if config.wait_for_completion:
882
+ operation = _operations_utils.await_operation(
883
+ operation_name=operation.name,
884
+ get_operation_fn=self._get_skill_operation,
885
+ )
886
+ if operation.error:
887
+ raise RuntimeError(f"Failed to update Skill: {operation.error}")
888
+ # Fetch the fully populated Skill resource from the server
889
+ return self.get(name=name)
890
+
891
+ return operation
892
+
893
+ def delete(
894
+ self,
895
+ *,
896
+ name: str,
897
+ config: Optional[types.DeleteSkillConfigOrDict] = None,
898
+ ) -> Optional[types.DeleteSkillOperation]:
899
+ """Deletes a Skill.
900
+
901
+ Args:
902
+ name (str):
903
+ Required. The resource name of the Skill to delete.
904
+ Format: projects/{project}/locations/{location}/skills/{skill}
905
+ config (DeleteSkillConfigOrDict):
906
+ Optional. Additional configuration for the delete operation.
907
+
908
+ Returns:
909
+ DeleteSkillOperation: The pending LRO if wait_for_completion is False,
910
+ otherwise None (blocks until done).
911
+ """
912
+ if config is None:
913
+ config = types.DeleteSkillConfig()
914
+ elif isinstance(config, dict):
915
+ config = types.DeleteSkillConfig.model_validate(config)
916
+ elif not isinstance(config, types.DeleteSkillConfig):
917
+ raise TypeError(
918
+ f"config must be a dict or DeleteSkillConfig, but got {type(config)}."
919
+ )
920
+
921
+ operation = self._delete(name=name, config=config)
922
+
923
+ if config.wait_for_completion:
924
+ operation = _operations_utils.await_operation(
925
+ operation_name=operation.name,
926
+ get_operation_fn=self._get_skill_operation,
927
+ )
928
+ if operation.error:
929
+ raise RuntimeError(f"Failed to delete Skill: {operation.error}")
930
+ return None
931
+
932
+ return operation
933
+
934
+ _revisions = None
935
+
936
+ @property
937
+ def revisions(self) -> "skill_revisions_module.SkillRevisions":
938
+ """Returns the revisions sub-module."""
939
+ if self._revisions is None:
940
+ # Lazy load to avoid circular imports
941
+ self._revisions = importlib.import_module(".skill_revisions", __package__)
942
+ return self._revisions.SkillRevisions(self._api_client) # type: ignore[no-any-return]
943
+
944
+ def list(
945
+ self, *, config: Optional[types.ListSkillsConfigOrDict] = None
946
+ ) -> Pager[types.Skill]:
947
+ """
948
+ Lists Skills in the Skill Registry.
949
+
950
+ Args:
951
+ config: Optional configuration override.
952
+
953
+ """
954
+
955
+ list_request = self._list
956
+ return Pager(
957
+ "skills",
958
+ list_request,
959
+ self._list(config=config),
960
+ config,
961
+ )
962
+
963
+
964
+ class AsyncSkills(_api_module.BaseModule):
965
+ """Class for managing Skills in the Skill Registry."""
966
+
967
+ async def get(
968
+ self, *, name: str, config: Optional[types.GetSkillConfigOrDict] = None
969
+ ) -> types.Skill:
970
+ """
971
+ Gets a Skill.
972
+ """
973
+
974
+ parameter_model = types._GetSkillRequestParameters(
975
+ name=name,
976
+ config=config,
977
+ )
978
+
979
+ request_url_dict: Optional[dict[str, str]]
980
+ if not self._api_client.vertexai:
981
+ raise ValueError(
982
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
983
+ )
984
+ else:
985
+ request_dict = _GetSkillRequestParameters_to_vertex(parameter_model)
986
+ request_url_dict = request_dict.get("_url")
987
+ if request_url_dict:
988
+ path = "{name}".format_map(request_url_dict)
989
+ else:
990
+ path = "{name}"
991
+
992
+ query_params = request_dict.get("_query")
993
+ if query_params:
994
+ path = f"{path}?{urlencode(query_params)}"
995
+ # TODO: remove the hack that pops config.
996
+ request_dict.pop("config", None)
997
+
998
+ http_options: Optional[types.HttpOptions] = None
999
+ if (
1000
+ parameter_model.config is not None
1001
+ and parameter_model.config.http_options is not None
1002
+ ):
1003
+ http_options = parameter_model.config.http_options
1004
+
1005
+ request_dict = _common.convert_to_dict(request_dict)
1006
+ request_dict = _common.encode_unserializable_types(request_dict)
1007
+
1008
+ response = await self._api_client.async_request(
1009
+ "get", path, request_dict, http_options
1010
+ )
1011
+
1012
+ response_dict = {} if not response.body else json.loads(response.body)
1013
+
1014
+ return_value = types.Skill._from_response(
1015
+ response=response_dict,
1016
+ kwargs=(
1017
+ {
1018
+ "config": {
1019
+ "response_schema": getattr(
1020
+ parameter_model.config, "response_schema", None
1021
+ ),
1022
+ "response_json_schema": getattr(
1023
+ parameter_model.config, "response_json_schema", None
1024
+ ),
1025
+ "include_all_fields": getattr(
1026
+ parameter_model.config, "include_all_fields", None
1027
+ ),
1028
+ }
1029
+ }
1030
+ if getattr(parameter_model, "config", None)
1031
+ else {}
1032
+ ),
1033
+ )
1034
+
1035
+ self._api_client._verify_response(return_value)
1036
+ return return_value
1037
+
1038
+ async def retrieve(
1039
+ self, *, query: str, config: Optional[types.RetrieveSkillsConfigOrDict] = None
1040
+ ) -> types.RetrieveSkillsResponse:
1041
+ """
1042
+ Retrieves skills semantically matched to a query.
1043
+ """
1044
+
1045
+ parameter_model = types._RetrieveSkillsRequestParameters(
1046
+ query=query,
1047
+ config=config,
1048
+ )
1049
+
1050
+ request_url_dict: Optional[dict[str, str]]
1051
+ if not self._api_client.vertexai:
1052
+ raise ValueError(
1053
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
1054
+ )
1055
+ else:
1056
+ request_dict = _RetrieveSkillsRequestParameters_to_vertex(parameter_model)
1057
+ request_url_dict = request_dict.get("_url")
1058
+ if request_url_dict:
1059
+ path = "skills:retrieve".format_map(request_url_dict)
1060
+ else:
1061
+ path = "skills:retrieve"
1062
+
1063
+ query_params = request_dict.get("_query")
1064
+ if query_params:
1065
+ path = f"{path}?{urlencode(query_params)}"
1066
+ # TODO: remove the hack that pops config.
1067
+ request_dict.pop("config", None)
1068
+
1069
+ http_options: Optional[types.HttpOptions] = None
1070
+ if (
1071
+ parameter_model.config is not None
1072
+ and parameter_model.config.http_options is not None
1073
+ ):
1074
+ http_options = parameter_model.config.http_options
1075
+
1076
+ request_dict = _common.convert_to_dict(request_dict)
1077
+ request_dict = _common.encode_unserializable_types(request_dict)
1078
+
1079
+ response = await self._api_client.async_request(
1080
+ "get", path, request_dict, http_options
1081
+ )
1082
+
1083
+ response_dict = {} if not response.body else json.loads(response.body)
1084
+
1085
+ return_value = types.RetrieveSkillsResponse._from_response(
1086
+ response=response_dict,
1087
+ kwargs=(
1088
+ {
1089
+ "config": {
1090
+ "response_schema": getattr(
1091
+ parameter_model.config, "response_schema", None
1092
+ ),
1093
+ "response_json_schema": getattr(
1094
+ parameter_model.config, "response_json_schema", None
1095
+ ),
1096
+ "include_all_fields": getattr(
1097
+ parameter_model.config, "include_all_fields", None
1098
+ ),
1099
+ }
1100
+ }
1101
+ if getattr(parameter_model, "config", None)
1102
+ else {}
1103
+ ),
1104
+ )
1105
+
1106
+ self._api_client._verify_response(return_value)
1107
+ return return_value
1108
+
1109
+ async def _create(
1110
+ self,
1111
+ *,
1112
+ display_name: str,
1113
+ description: str,
1114
+ config: Optional[types.CreateSkillConfigOrDict] = None,
1115
+ skill_id: str,
1116
+ ) -> types.SkillOperation:
1117
+ """
1118
+ Creates a new Skill.
1119
+ """
1120
+
1121
+ parameter_model = types._CreateSkillRequestParameters(
1122
+ display_name=display_name,
1123
+ description=description,
1124
+ config=config,
1125
+ skill_id=skill_id,
1126
+ )
1127
+
1128
+ request_url_dict: Optional[dict[str, str]]
1129
+ if not self._api_client.vertexai:
1130
+ raise ValueError(
1131
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
1132
+ )
1133
+ else:
1134
+ request_dict = _CreateSkillRequestParameters_to_vertex(parameter_model)
1135
+ request_url_dict = request_dict.get("_url")
1136
+ if request_url_dict:
1137
+ path = "skills".format_map(request_url_dict)
1138
+ else:
1139
+ path = "skills"
1140
+
1141
+ query_params = request_dict.get("_query")
1142
+ if query_params:
1143
+ path = f"{path}?{urlencode(query_params)}"
1144
+ # TODO: remove the hack that pops config.
1145
+ request_dict.pop("config", None)
1146
+
1147
+ http_options: Optional[types.HttpOptions] = None
1148
+ if (
1149
+ parameter_model.config is not None
1150
+ and parameter_model.config.http_options is not None
1151
+ ):
1152
+ http_options = parameter_model.config.http_options
1153
+
1154
+ request_dict = _common.convert_to_dict(request_dict)
1155
+ request_dict = _common.encode_unserializable_types(request_dict)
1156
+
1157
+ response = await self._api_client.async_request(
1158
+ "post", path, request_dict, http_options
1159
+ )
1160
+
1161
+ response_dict = {} if not response.body else json.loads(response.body)
1162
+
1163
+ return_value = types.SkillOperation._from_response(
1164
+ response=response_dict,
1165
+ kwargs=(
1166
+ {
1167
+ "config": {
1168
+ "response_schema": getattr(
1169
+ parameter_model.config, "response_schema", None
1170
+ ),
1171
+ "response_json_schema": getattr(
1172
+ parameter_model.config, "response_json_schema", None
1173
+ ),
1174
+ "include_all_fields": getattr(
1175
+ parameter_model.config, "include_all_fields", None
1176
+ ),
1177
+ }
1178
+ }
1179
+ if getattr(parameter_model, "config", None)
1180
+ else {}
1181
+ ),
1182
+ )
1183
+
1184
+ self._api_client._verify_response(return_value)
1185
+ return return_value
1186
+
1187
+ async def _update(
1188
+ self, *, name: str, config: Optional[types.UpdateSkillConfigOrDict] = None
1189
+ ) -> types.SkillOperation:
1190
+ """
1191
+ Updates a Skill.
1192
+ """
1193
+
1194
+ parameter_model = types._UpdateSkillRequestParameters(
1195
+ name=name,
1196
+ config=config,
1197
+ )
1198
+
1199
+ request_url_dict: Optional[dict[str, str]]
1200
+ if not self._api_client.vertexai:
1201
+ raise ValueError(
1202
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
1203
+ )
1204
+ else:
1205
+ request_dict = _UpdateSkillRequestParameters_to_vertex(parameter_model)
1206
+ request_url_dict = request_dict.get("_url")
1207
+ if request_url_dict:
1208
+ path = "{name}".format_map(request_url_dict)
1209
+ else:
1210
+ path = "{name}"
1211
+
1212
+ query_params = request_dict.get("_query")
1213
+ if query_params:
1214
+ path = f"{path}?{urlencode(query_params)}"
1215
+ # TODO: remove the hack that pops config.
1216
+ request_dict.pop("config", None)
1217
+
1218
+ http_options: Optional[types.HttpOptions] = None
1219
+ if (
1220
+ parameter_model.config is not None
1221
+ and parameter_model.config.http_options is not None
1222
+ ):
1223
+ http_options = parameter_model.config.http_options
1224
+
1225
+ request_dict = _common.convert_to_dict(request_dict)
1226
+ request_dict = _common.encode_unserializable_types(request_dict)
1227
+
1228
+ response = await self._api_client.async_request(
1229
+ "patch", path, request_dict, http_options
1230
+ )
1231
+
1232
+ response_dict = {} if not response.body else json.loads(response.body)
1233
+
1234
+ return_value = types.SkillOperation._from_response(
1235
+ response=response_dict,
1236
+ kwargs=(
1237
+ {
1238
+ "config": {
1239
+ "response_schema": getattr(
1240
+ parameter_model.config, "response_schema", None
1241
+ ),
1242
+ "response_json_schema": getattr(
1243
+ parameter_model.config, "response_json_schema", None
1244
+ ),
1245
+ "include_all_fields": getattr(
1246
+ parameter_model.config, "include_all_fields", None
1247
+ ),
1248
+ }
1249
+ }
1250
+ if getattr(parameter_model, "config", None)
1251
+ else {}
1252
+ ),
1253
+ )
1254
+
1255
+ self._api_client._verify_response(return_value)
1256
+ return return_value
1257
+
1258
+ async def _list(
1259
+ self, *, config: Optional[types.ListSkillsConfigOrDict] = None
1260
+ ) -> types.ListSkillsResponse:
1261
+ parameter_model = types._ListSkillsRequestParameters(
1262
+ config=config,
1263
+ )
1264
+
1265
+ request_url_dict: Optional[dict[str, str]]
1266
+ if not self._api_client.vertexai:
1267
+ raise ValueError(
1268
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
1269
+ )
1270
+ else:
1271
+ request_dict = _ListSkillsRequestParameters_to_vertex(parameter_model)
1272
+ request_url_dict = request_dict.get("_url")
1273
+ if request_url_dict:
1274
+ path = "skills".format_map(request_url_dict)
1275
+ else:
1276
+ path = "skills"
1277
+
1278
+ query_params = request_dict.get("_query")
1279
+ if query_params:
1280
+ path = f"{path}?{urlencode(query_params)}"
1281
+ # TODO: remove the hack that pops config.
1282
+ request_dict.pop("config", None)
1283
+
1284
+ http_options: Optional[types.HttpOptions] = None
1285
+ if (
1286
+ parameter_model.config is not None
1287
+ and parameter_model.config.http_options is not None
1288
+ ):
1289
+ http_options = parameter_model.config.http_options
1290
+
1291
+ request_dict = _common.convert_to_dict(request_dict)
1292
+ request_dict = _common.encode_unserializable_types(request_dict)
1293
+
1294
+ response = await self._api_client.async_request(
1295
+ "get", path, request_dict, http_options
1296
+ )
1297
+
1298
+ response_dict = {} if not response.body else json.loads(response.body)
1299
+
1300
+ return_value = types.ListSkillsResponse._from_response(
1301
+ response=response_dict,
1302
+ kwargs=(
1303
+ {
1304
+ "config": {
1305
+ "response_schema": getattr(
1306
+ parameter_model.config, "response_schema", None
1307
+ ),
1308
+ "response_json_schema": getattr(
1309
+ parameter_model.config, "response_json_schema", None
1310
+ ),
1311
+ "include_all_fields": getattr(
1312
+ parameter_model.config, "include_all_fields", None
1313
+ ),
1314
+ }
1315
+ }
1316
+ if getattr(parameter_model, "config", None)
1317
+ else {}
1318
+ ),
1319
+ )
1320
+
1321
+ self._api_client._verify_response(return_value)
1322
+ return return_value
1323
+
1324
+ async def _delete(
1325
+ self, *, name: str, config: Optional[types.DeleteSkillConfigOrDict] = None
1326
+ ) -> types.DeleteSkillOperation:
1327
+ """
1328
+ Deletes a Skill.
1329
+ """
1330
+
1331
+ parameter_model = types._DeleteSkillRequestParameters(
1332
+ name=name,
1333
+ config=config,
1334
+ )
1335
+
1336
+ request_url_dict: Optional[dict[str, str]]
1337
+ if not self._api_client.vertexai:
1338
+ raise ValueError(
1339
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
1340
+ )
1341
+ else:
1342
+ request_dict = _DeleteSkillRequestParameters_to_vertex(parameter_model)
1343
+ request_url_dict = request_dict.get("_url")
1344
+ if request_url_dict:
1345
+ path = "{name}".format_map(request_url_dict)
1346
+ else:
1347
+ path = "{name}"
1348
+
1349
+ query_params = request_dict.get("_query")
1350
+ if query_params:
1351
+ path = f"{path}?{urlencode(query_params)}"
1352
+ # TODO: remove the hack that pops config.
1353
+ request_dict.pop("config", None)
1354
+
1355
+ http_options: Optional[types.HttpOptions] = None
1356
+ if (
1357
+ parameter_model.config is not None
1358
+ and parameter_model.config.http_options is not None
1359
+ ):
1360
+ http_options = parameter_model.config.http_options
1361
+
1362
+ request_dict = _common.convert_to_dict(request_dict)
1363
+ request_dict = _common.encode_unserializable_types(request_dict)
1364
+
1365
+ response = await self._api_client.async_request(
1366
+ "delete", path, request_dict, http_options
1367
+ )
1368
+
1369
+ response_dict = {} if not response.body else json.loads(response.body)
1370
+
1371
+ return_value = types.DeleteSkillOperation._from_response(
1372
+ response=response_dict,
1373
+ kwargs=(
1374
+ {
1375
+ "config": {
1376
+ "response_schema": getattr(
1377
+ parameter_model.config, "response_schema", None
1378
+ ),
1379
+ "response_json_schema": getattr(
1380
+ parameter_model.config, "response_json_schema", None
1381
+ ),
1382
+ "include_all_fields": getattr(
1383
+ parameter_model.config, "include_all_fields", None
1384
+ ),
1385
+ }
1386
+ }
1387
+ if getattr(parameter_model, "config", None)
1388
+ else {}
1389
+ ),
1390
+ )
1391
+
1392
+ self._api_client._verify_response(return_value)
1393
+ return return_value
1394
+
1395
+ async def _get_skill_operation(
1396
+ self,
1397
+ *,
1398
+ operation_name: str,
1399
+ config: Optional[types.GetSkillOperationConfigOrDict] = None,
1400
+ ) -> types.SkillOperation:
1401
+ parameter_model = types._GetSkillOperationParameters(
1402
+ operation_name=operation_name,
1403
+ config=config,
1404
+ )
1405
+
1406
+ request_url_dict: Optional[dict[str, str]]
1407
+ if not self._api_client.vertexai:
1408
+ raise ValueError(
1409
+ "This method is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode."
1410
+ )
1411
+ else:
1412
+ request_dict = _GetSkillOperationParameters_to_vertex(parameter_model)
1413
+ request_url_dict = request_dict.get("_url")
1414
+ if request_url_dict:
1415
+ path = "{operationName}".format_map(request_url_dict)
1416
+ else:
1417
+ path = "{operationName}"
1418
+
1419
+ query_params = request_dict.get("_query")
1420
+ if query_params:
1421
+ path = f"{path}?{urlencode(query_params)}"
1422
+ # TODO: remove the hack that pops config.
1423
+ request_dict.pop("config", None)
1424
+
1425
+ http_options: Optional[types.HttpOptions] = None
1426
+ if (
1427
+ parameter_model.config is not None
1428
+ and parameter_model.config.http_options is not None
1429
+ ):
1430
+ http_options = parameter_model.config.http_options
1431
+
1432
+ request_dict = _common.convert_to_dict(request_dict)
1433
+ request_dict = _common.encode_unserializable_types(request_dict)
1434
+
1435
+ response = await self._api_client.async_request(
1436
+ "get", path, request_dict, http_options
1437
+ )
1438
+
1439
+ response_dict = {} if not response.body else json.loads(response.body)
1440
+
1441
+ return_value = types.SkillOperation._from_response(
1442
+ response=response_dict,
1443
+ kwargs=(
1444
+ {
1445
+ "config": {
1446
+ "response_schema": getattr(
1447
+ parameter_model.config, "response_schema", None
1448
+ ),
1449
+ "response_json_schema": getattr(
1450
+ parameter_model.config, "response_json_schema", None
1451
+ ),
1452
+ "include_all_fields": getattr(
1453
+ parameter_model.config, "include_all_fields", None
1454
+ ),
1455
+ }
1456
+ }
1457
+ if getattr(parameter_model, "config", None)
1458
+ else {}
1459
+ ),
1460
+ )
1461
+
1462
+ self._api_client._verify_response(return_value)
1463
+ return return_value
1464
+
1465
+ async def create(
1466
+ self,
1467
+ *,
1468
+ skill_id: str,
1469
+ display_name: str,
1470
+ description: str,
1471
+ config: Optional[types.CreateSkillConfigOrDict] = None,
1472
+ ) -> Union[types.Skill, types.SkillOperation]:
1473
+ """Creates a new Skill asynchronously.
1474
+
1475
+ Args:
1476
+ skill_id (str):
1477
+ Required. The ID to use for the Skill, which will become the final
1478
+ component of the Skill's resource name.
1479
+ display_name (str):
1480
+ Required. The display name of the Skill.
1481
+ description (str):
1482
+ Required. The description of the Skill.
1483
+ config (CreateSkillConfigOrDict):
1484
+ Optional. The configuration for creating the Skill.
1485
+
1486
+ Returns:
1487
+ Skill: The created Skill if wait_for_completion is True.
1488
+ SkillOperation: The operation for creating the Skill if
1489
+ wait_for_completion is False.
1490
+ """
1491
+ if config is None:
1492
+ config = types.CreateSkillConfig()
1493
+ elif isinstance(config, dict):
1494
+ config = types.CreateSkillConfig.model_validate(config)
1495
+ elif not isinstance(config, types.CreateSkillConfig):
1496
+ raise TypeError(
1497
+ f"config must be a dict or CreateSkillConfig, but got {type(config)}."
1498
+ )
1499
+
1500
+ config = config.model_copy()
1501
+
1502
+ local_path = config.local_path
1503
+ zipped_filesystem = config.zipped_filesystem
1504
+
1505
+ if local_path and zipped_filesystem:
1506
+ raise ValueError(
1507
+ "Only one of `local_path` or `zipped_filesystem` can be provided in config."
1508
+ )
1509
+ if not local_path and not zipped_filesystem:
1510
+ raise ValueError(
1511
+ "Either `local_path` or `zipped_filesystem` must be provided in config."
1512
+ )
1513
+
1514
+ if local_path:
1515
+ loop = asyncio.get_running_loop()
1516
+ zipped_filesystem_payload = await loop.run_in_executor(
1517
+ None, _skills_utils.get_zipped_filesystem_payload, local_path
1518
+ )
1519
+ else:
1520
+ # Narrow type for mypy
1521
+ if zipped_filesystem is None:
1522
+ raise ValueError(
1523
+ "zipped_filesystem is required if local_path is not provided."
1524
+ )
1525
+ if isinstance(zipped_filesystem, bytes):
1526
+ zipped_filesystem_payload = base64.b64encode(zipped_filesystem).decode(
1527
+ "utf-8"
1528
+ )
1529
+ else:
1530
+ zipped_filesystem_payload = zipped_filesystem
1531
+
1532
+ # Mutate the config object to populate the zipped_filesystem payload
1533
+ config.zipped_filesystem = zipped_filesystem_payload
1534
+
1535
+ operation = await self._create(
1536
+ skill_id=skill_id,
1537
+ display_name=display_name,
1538
+ description=description,
1539
+ config=config,
1540
+ )
1541
+
1542
+ if config.wait_for_completion:
1543
+ operation = await _operations_utils.await_operation_async(
1544
+ operation_name=operation.name,
1545
+ get_operation_fn=self._get_skill_operation,
1546
+ )
1547
+ if operation.error:
1548
+ raise RuntimeError(f"Failed to create Skill: {operation.error}")
1549
+ # Fetch the fully populated Skill resource asynchronously
1550
+ return await self.get(name=operation.response.name)
1551
+
1552
+ return operation
1553
+
1554
+ async def update(
1555
+ self,
1556
+ *,
1557
+ name: str,
1558
+ config: Optional[types.UpdateSkillConfigOrDict] = None,
1559
+ ) -> Union[types.Skill, types.SkillOperation]:
1560
+ """Updates an existing Skill asynchronously.
1561
+
1562
+ Args:
1563
+ name (str):
1564
+ Required. The resource name of the Skill to update.
1565
+ Format: projects/{project}/locations/{location}/skills/{skill}
1566
+ config (UpdateSkillConfigOrDict):
1567
+ Optional. The configuration for updating the Skill.
1568
+
1569
+ Returns:
1570
+ Skill: The updated Skill if wait_for_completion is True.
1571
+ SkillOperation: The operation for updating the Skill if
1572
+ wait_for_completion is False.
1573
+ """
1574
+ if config is None:
1575
+ config = types.UpdateSkillConfig()
1576
+ elif isinstance(config, dict):
1577
+ config = types.UpdateSkillConfig.model_validate(config)
1578
+ elif not isinstance(config, types.UpdateSkillConfig):
1579
+ raise TypeError(
1580
+ f"config must be a dict or UpdateSkillConfig, but got {type(config)}."
1581
+ )
1582
+
1583
+ config = config.model_copy()
1584
+
1585
+ display_name = config.display_name
1586
+ description = config.description
1587
+ local_path = config.local_path
1588
+ zipped_filesystem = config.zipped_filesystem
1589
+
1590
+ if local_path and zipped_filesystem:
1591
+ raise ValueError(
1592
+ "Only one of `local_path` or `zipped_filesystem` can be provided in config."
1593
+ )
1594
+
1595
+ # Construct update_mask and prepare payload
1596
+ update_mask_paths = []
1597
+ zipped_filesystem_payload = None
1598
+
1599
+ if display_name is not None:
1600
+ update_mask_paths.append("displayName")
1601
+
1602
+ if description is not None:
1603
+ update_mask_paths.append("description")
1604
+
1605
+ if local_path:
1606
+ loop = asyncio.get_running_loop()
1607
+ zipped_filesystem_payload = await loop.run_in_executor(
1608
+ None, _skills_utils.get_zipped_filesystem_payload, local_path
1609
+ )
1610
+ update_mask_paths.append("zippedFilesystem")
1611
+ elif zipped_filesystem is not None:
1612
+ if isinstance(zipped_filesystem, bytes):
1613
+ zipped_filesystem_payload = base64.b64encode(zipped_filesystem).decode(
1614
+ "utf-8"
1615
+ )
1616
+ else:
1617
+ zipped_filesystem_payload = zipped_filesystem
1618
+ update_mask_paths.append("zippedFilesystem")
1619
+
1620
+ if not update_mask_paths:
1621
+ raise ValueError(
1622
+ "At least one of `display_name`, `description`, `local_path`, or "
1623
+ "`zipped_filesystem` must be provided for update in config."
1624
+ )
1625
+
1626
+ update_mask = ",".join(update_mask_paths)
1627
+
1628
+ # Mutate config in place to populate the generated update_mask and zipped_filesystem
1629
+ config.update_mask = update_mask
1630
+ config.zipped_filesystem = zipped_filesystem_payload
1631
+
1632
+ operation = await self._update(
1633
+ name=name,
1634
+ config=config,
1635
+ )
1636
+
1637
+ if config.wait_for_completion:
1638
+ operation = await _operations_utils.await_operation_async(
1639
+ operation_name=operation.name,
1640
+ get_operation_fn=self._get_skill_operation,
1641
+ )
1642
+ if operation.error:
1643
+ raise RuntimeError(f"Failed to update Skill: {operation.error}")
1644
+ # Fetch the fully populated Skill resource asynchronously
1645
+ return await self.get(name=name)
1646
+
1647
+ return operation
1648
+
1649
+ async def delete(
1650
+ self,
1651
+ *,
1652
+ name: str,
1653
+ config: Optional[types.DeleteSkillConfigOrDict] = None,
1654
+ ) -> Optional[types.DeleteSkillOperation]:
1655
+ """Deletes a Skill asynchronously.
1656
+
1657
+ Args:
1658
+ name (str):
1659
+ Required. The resource name of the Skill to delete.
1660
+ Format: projects/{project}/locations/{location}/skills/{skill}
1661
+ config (DeleteSkillConfigOrDict):
1662
+ Optional. Additional configuration for the delete operation.
1663
+
1664
+ Returns:
1665
+ DeleteSkillOperation: The pending LRO if wait_for_completion is False,
1666
+ otherwise None (blocks until done).
1667
+ """
1668
+ if config is None:
1669
+ config = types.DeleteSkillConfig()
1670
+ elif isinstance(config, dict):
1671
+ config = types.DeleteSkillConfig.model_validate(config)
1672
+ elif not isinstance(config, types.DeleteSkillConfig):
1673
+ raise TypeError(
1674
+ f"config must be a dict or DeleteSkillConfig, but got {type(config)}."
1675
+ )
1676
+
1677
+ operation = await self._delete(name=name, config=config)
1678
+
1679
+ if config.wait_for_completion:
1680
+ operation = await _operations_utils.await_operation_async(
1681
+ operation_name=operation.name,
1682
+ get_operation_fn=self._get_skill_operation,
1683
+ )
1684
+ if operation.error:
1685
+ raise RuntimeError(f"Failed to delete Skill: {operation.error}")
1686
+ return None
1687
+
1688
+ return operation
1689
+
1690
+ _revisions = None
1691
+
1692
+ @property
1693
+ def revisions(self) -> "skill_revisions_module.AsyncSkillRevisions":
1694
+ """Returns the revisions sub-module asynchronously."""
1695
+ if self._revisions is None:
1696
+ self._revisions = importlib.import_module(".skill_revisions", __package__)
1697
+ return self._revisions.AsyncSkillRevisions(self._api_client) # type: ignore[no-any-return]
1698
+
1699
+ async def list(
1700
+ self, *, config: Optional[types.ListSkillsConfigOrDict] = None
1701
+ ) -> AsyncPager[types.Skill]:
1702
+ list_request = self._list
1703
+ return AsyncPager(
1704
+ "skills",
1705
+ list_request,
1706
+ await self._list(config=config),
1707
+ config,
1708
+ )