google-cloud-agentplatform 2.7.0__tar.gz → 2.9.0__tar.gz
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_cloud_agentplatform-2.7.0/google_cloud_agentplatform.egg-info → google_cloud_agentplatform-2.9.0}/PKG-INFO +2 -3
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_evals_common.py +31 -3
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_evals_metric_handlers.py +62 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_runtimes_utils.py +5 -66
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_transformers.py +52 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/evals.py +14 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/feedback_entries.py +2 -2
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/runtimes.py +40 -10
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/types/__init__.py +70 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/types/common.py +473 -10
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/frameworks/adk.py +17 -6
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/version.py +1 -1
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0/google_cloud_agentplatform.egg-info}/PKG-INFO +2 -3
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/google_cloud_agentplatform.egg-info/requires.txt +2 -5
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/pyproject.toml +3 -4
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/LICENSE +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/README.md +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/__init__.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/__init__.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_bigquery_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_datasets_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_evals_builtin_tools.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_evals_constant.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_evals_data_converters.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_evals_metric_loaders.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_evals_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_evals_visualization.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_gcs_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_logging_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_memory_bank_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_observability_data_converter.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_operations_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_prompt_management_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_prompt_optimizer_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/_skills_utils.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/a2a_task_events.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/a2a_tasks.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/client.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/datasets.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/endpoints.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/example_stores.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/feedback_contexts.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/live.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/live_runtimes.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/memories.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/memory_banks.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/memory_revisions.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/model_garden.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/prompt_optimizer.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/prompts.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/rag.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/runtime_revisions.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/sandbox_snapshots.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/sandbox_templates.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/sandboxes.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/serving_profiles.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/session_events.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/sessions.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/skill_revisions.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/skills.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/types/agent_engines.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/types/evals.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/types/prompt_optimizer.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/types/prompts.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/frameworks/__init__.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/frameworks/a2a.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/frameworks/ag2.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/frameworks/langchain.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/frameworks/langgraph.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/frameworks/llama_index.py +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/google_cloud_agentplatform.egg-info/SOURCES.txt +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/google_cloud_agentplatform.egg-info/dependency_links.txt +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/google_cloud_agentplatform.egg-info/top_level.txt +0 -0
- {google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: google-cloud-agentplatform
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.0
|
|
4
4
|
Summary: Google Cloud Agent Platform Client Library
|
|
5
5
|
Author-email: Google LLC <googleapis-packages@google.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -61,8 +61,7 @@ Provides-Extra: evaluation
|
|
|
61
61
|
Requires-Dist: pandas>=1.0.0; extra == "evaluation"
|
|
62
62
|
Requires-Dist: tqdm>=4.23.0; extra == "evaluation"
|
|
63
63
|
Requires-Dist: pyyaml; extra == "evaluation"
|
|
64
|
-
Requires-Dist: litellm
|
|
65
|
-
Requires-Dist: litellm<1.97.0,>=1.93.0; python_version >= "3.14" and extra == "evaluation"
|
|
64
|
+
Requires-Dist: litellm!=1.107.0,<1.110.0,>=1.106.5; python_version < "3.15" and extra == "evaluation"
|
|
66
65
|
Requires-Dist: google-cloud-storage<4.0.0,>=1.32.0; extra == "evaluation"
|
|
67
66
|
Provides-Extra: bigquery
|
|
68
67
|
Requires-Dist: google-cloud-bigquery<4.0.0,>=1.15.0; extra == "bigquery"
|
|
@@ -3238,6 +3238,31 @@ def _process_multi_turn_agent_response(
|
|
|
3238
3238
|
).model_dump(exclude_unset=True)
|
|
3239
3239
|
|
|
3240
3240
|
|
|
3241
|
+
def _extract_final_response_text(
|
|
3242
|
+
events: list[dict[str, Any]],
|
|
3243
|
+
) -> tuple[Optional[int], str]:
|
|
3244
|
+
"""Returns the index and text of the last final response in the events.
|
|
3245
|
+
|
|
3246
|
+
As in ADK's `Event.is_final_response()`, events with function calls or
|
|
3247
|
+
responses are not final responses, so they stay in the intermediate events.
|
|
3248
|
+
Thought parts are not part of the response text.
|
|
3249
|
+
"""
|
|
3250
|
+
for index in range(len(events) - 1, -1, -1):
|
|
3251
|
+
parts = (events[index].get("content") or {}).get("parts") or []
|
|
3252
|
+
if any(
|
|
3253
|
+
part.get("function_call") or part.get("function_response") for part in parts
|
|
3254
|
+
):
|
|
3255
|
+
continue
|
|
3256
|
+
texts = [
|
|
3257
|
+
part["text"]
|
|
3258
|
+
for part in parts
|
|
3259
|
+
if part.get("text") and not part.get("thought")
|
|
3260
|
+
]
|
|
3261
|
+
if texts:
|
|
3262
|
+
return index, "".join(texts)
|
|
3263
|
+
return None, ""
|
|
3264
|
+
|
|
3265
|
+
|
|
3241
3266
|
def _process_single_turn_agent_response(
|
|
3242
3267
|
resp_item: Any,
|
|
3243
3268
|
agent_data_agents: Optional[dict[str, Any]],
|
|
@@ -3253,8 +3278,10 @@ def _process_single_turn_agent_response(
|
|
|
3253
3278
|
|
|
3254
3279
|
if isinstance(resp_item, list):
|
|
3255
3280
|
try:
|
|
3256
|
-
response_row = resp_item
|
|
3257
|
-
for intermediate_event in resp_item
|
|
3281
|
+
response_index, response_row = _extract_final_response_text(resp_item)
|
|
3282
|
+
for index, intermediate_event in enumerate(resp_item):
|
|
3283
|
+
if index == response_index:
|
|
3284
|
+
continue
|
|
3258
3285
|
intermediate_events_row.append(
|
|
3259
3286
|
{
|
|
3260
3287
|
"event_id": intermediate_event.get("id"),
|
|
@@ -3263,7 +3290,7 @@ def _process_single_turn_agent_response(
|
|
|
3263
3290
|
"author": intermediate_event.get("author"),
|
|
3264
3291
|
}
|
|
3265
3292
|
)
|
|
3266
|
-
|
|
3293
|
+
# Construct AgentData natively for single-turn runs
|
|
3267
3294
|
agent_events = []
|
|
3268
3295
|
for event_dict in resp_item:
|
|
3269
3296
|
content_dict = event_dict.get("content")
|
|
@@ -3288,6 +3315,7 @@ def _process_single_turn_agent_response(
|
|
|
3288
3315
|
agents=agent_data_agents,
|
|
3289
3316
|
).model_dump(exclude_unset=True)
|
|
3290
3317
|
except Exception as e: # pylint: disable=broad-exception-caught
|
|
3318
|
+
intermediate_events_row = []
|
|
3291
3319
|
error_payload = {
|
|
3292
3320
|
"error": (
|
|
3293
3321
|
f"Failed to parse agent run response {str(resp_item)} to "
|
|
@@ -846,6 +846,66 @@ class LLMMetricHandler(MetricHandler[types.LLMMetric]):
|
|
|
846
846
|
return _default_aggregate_scores(self.metric.name, eval_case_metric_results)
|
|
847
847
|
|
|
848
848
|
|
|
849
|
+
class StepBasedLLMMetricHandler(LLMMetricHandler):
|
|
850
|
+
"""Metric handler for step-based LLM metrics."""
|
|
851
|
+
|
|
852
|
+
@override
|
|
853
|
+
def get_metric_result(
|
|
854
|
+
self, eval_case: types.EvalCase, response_index: int
|
|
855
|
+
) -> types.EvalCaseMetricResult:
|
|
856
|
+
"""Evaluates one case with the step-based LLM metric."""
|
|
857
|
+
try:
|
|
858
|
+
response_content = _get_response_from_eval_case(
|
|
859
|
+
eval_case, response_index, self.metric_name
|
|
860
|
+
)
|
|
861
|
+
if not response_content and not getattr(eval_case, "agent_data", None):
|
|
862
|
+
raise ValueError(
|
|
863
|
+
f"Response content missing for candidate {response_index}."
|
|
864
|
+
)
|
|
865
|
+
|
|
866
|
+
# Joined so dataset columns referenced by any step reach other_data.
|
|
867
|
+
prompt_templates = "\n".join(
|
|
868
|
+
step.prompt_template or "" for step in self.metric.steps or []
|
|
869
|
+
)
|
|
870
|
+
instance = _build_evaluation_instance(
|
|
871
|
+
eval_case, response_content, prompt_template=prompt_templates
|
|
872
|
+
)
|
|
873
|
+
api_response = _call_with_retry(
|
|
874
|
+
lambda: self.module._evaluate_instances(
|
|
875
|
+
metrics=[self.metric],
|
|
876
|
+
instance=instance,
|
|
877
|
+
allow_cross_region_model=self.allow_cross_region_model,
|
|
878
|
+
),
|
|
879
|
+
self.metric_name,
|
|
880
|
+
)
|
|
881
|
+
|
|
882
|
+
if api_response and api_response.metric_results:
|
|
883
|
+
result = api_response.metric_results[0]
|
|
884
|
+
error_msg = None
|
|
885
|
+
if result.error and getattr(result.error, "code"):
|
|
886
|
+
error_msg = f"Error in metric result: {result.error}"
|
|
887
|
+
return types.EvalCaseMetricResult(
|
|
888
|
+
metric_name=self.metric_name,
|
|
889
|
+
score=result.score,
|
|
890
|
+
explanation=result.explanation,
|
|
891
|
+
error_message=error_msg,
|
|
892
|
+
)
|
|
893
|
+
return types.EvalCaseMetricResult(
|
|
894
|
+
metric_name=self.metric_name,
|
|
895
|
+
error_message="Metric results missing in API response.",
|
|
896
|
+
)
|
|
897
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
898
|
+
logger.error(
|
|
899
|
+
"Error processing metric %s for case %s.",
|
|
900
|
+
self.metric_name,
|
|
901
|
+
eval_case.eval_case_id,
|
|
902
|
+
exc_info=True,
|
|
903
|
+
)
|
|
904
|
+
return types.EvalCaseMetricResult(
|
|
905
|
+
metric_name=self.metric_name, error_message=str(e)
|
|
906
|
+
)
|
|
907
|
+
|
|
908
|
+
|
|
849
909
|
class CustomMetricHandler(MetricHandler[types.Metric]):
|
|
850
910
|
"""Metric handler for custom metrics."""
|
|
851
911
|
|
|
@@ -1375,6 +1435,7 @@ _METRIC_HANDLER_MAPPING = [
|
|
|
1375
1435
|
lambda m: getattr(m, "metric_resource_name", None) is not None,
|
|
1376
1436
|
RegisteredMetricHandler,
|
|
1377
1437
|
),
|
|
1438
|
+
(lambda m: getattr(m, "steps", None), StepBasedLLMMetricHandler),
|
|
1378
1439
|
(
|
|
1379
1440
|
lambda m: m.name in ComputationMetricHandler.SUPPORTED_COMPUTATION_METRICS,
|
|
1380
1441
|
ComputationMetricHandler,
|
|
@@ -1395,6 +1456,7 @@ MetricHandlerType = TypeVar(
|
|
|
1395
1456
|
ComputationMetricHandler,
|
|
1396
1457
|
TranslationMetricHandler,
|
|
1397
1458
|
LLMMetricHandler,
|
|
1459
|
+
StepBasedLLMMetricHandler,
|
|
1398
1460
|
CustomMetricHandler,
|
|
1399
1461
|
CustomCodeExecutionMetricHandler,
|
|
1400
1462
|
PredefinedMetricHandler,
|
|
@@ -1322,6 +1322,8 @@ def _upload_extra_packages(
|
|
|
1322
1322
|
tar_fileobj = io.BytesIO()
|
|
1323
1323
|
with tarfile.open(fileobj=tar_fileobj, mode="w|gz") as tar:
|
|
1324
1324
|
for file in extra_packages:
|
|
1325
|
+
# Note: tar.add(file) preserves each path relative to the current
|
|
1326
|
+
# working directory in the archive (extracted into /code).
|
|
1325
1327
|
tar.add(file)
|
|
1326
1328
|
tar_fileobj.seek(0)
|
|
1327
1329
|
blob = gcs_bucket.blob(f"{gcs_dir_name}/{_EXTRA_PACKAGES_FILE}")
|
|
@@ -1360,78 +1362,14 @@ def _validate_packages_or_raise(
|
|
|
1360
1362
|
build_options: Optional[Dict[str, Sequence[str]]] = None,
|
|
1361
1363
|
) -> Sequence[str]:
|
|
1362
1364
|
"""Tries to validates the packages."""
|
|
1365
|
+
del build_options
|
|
1363
1366
|
packages = packages or []
|
|
1364
|
-
if build_options and _INSTALLATION_SUBDIR in build_options:
|
|
1365
|
-
_validate_installation_scripts_or_raise(
|
|
1366
|
-
script_paths=build_options[_INSTALLATION_SUBDIR],
|
|
1367
|
-
packages=packages,
|
|
1368
|
-
)
|
|
1369
1367
|
for package in packages:
|
|
1370
1368
|
if not os.path.exists(package):
|
|
1371
1369
|
raise FileNotFoundError(f"Package specified but not found: {package=}")
|
|
1372
1370
|
return packages
|
|
1373
1371
|
|
|
1374
1372
|
|
|
1375
|
-
def _validate_installation_scripts_or_raise(
|
|
1376
|
-
*,
|
|
1377
|
-
script_paths: Sequence[str],
|
|
1378
|
-
packages: Sequence[str],
|
|
1379
|
-
) -> None:
|
|
1380
|
-
"""Validates the installation scripts' path explicitly provided by the user.
|
|
1381
|
-
|
|
1382
|
-
Args:
|
|
1383
|
-
script_paths (Sequence[str]):
|
|
1384
|
-
Required. The paths to the installation scripts.
|
|
1385
|
-
packages (Sequence[str]):
|
|
1386
|
-
Required. The user-provided packages.
|
|
1387
|
-
|
|
1388
|
-
Raises:
|
|
1389
|
-
ValueError: If a user-defined script is not under the expected
|
|
1390
|
-
subdirectory, or not in `packages`, or if a package is
|
|
1391
|
-
in the installation scripts subdirectory, but is not specified as an
|
|
1392
|
-
installation script.
|
|
1393
|
-
"""
|
|
1394
|
-
for script_path in script_paths:
|
|
1395
|
-
if not script_path.startswith(_INSTALLATION_SUBDIR):
|
|
1396
|
-
logger.warning(
|
|
1397
|
-
f"User-defined installation script '{script_path}' is not in "
|
|
1398
|
-
f"the expected '{_INSTALLATION_SUBDIR}' subdirectory. "
|
|
1399
|
-
f"Ensure it is placed in '{_INSTALLATION_SUBDIR}' within your "
|
|
1400
|
-
f"'extra_packages' or 'source_packages'."
|
|
1401
|
-
)
|
|
1402
|
-
raise ValueError(
|
|
1403
|
-
f"Required installation script '{script_path}' "
|
|
1404
|
-
f"is not under '{_INSTALLATION_SUBDIR}'"
|
|
1405
|
-
)
|
|
1406
|
-
|
|
1407
|
-
if script_path not in packages:
|
|
1408
|
-
logger.warning(
|
|
1409
|
-
f"User-defined installation script '{script_path}' is not in "
|
|
1410
|
-
f"'extra_packages' or 'source_packages'. Ensure it is added to "
|
|
1411
|
-
f"'extra_packages' or 'source_packages'."
|
|
1412
|
-
)
|
|
1413
|
-
raise ValueError(
|
|
1414
|
-
f"User-defined installation script '{script_path}' "
|
|
1415
|
-
f"does not exist in 'extra_packages' or 'source_packages'."
|
|
1416
|
-
)
|
|
1417
|
-
|
|
1418
|
-
for package in packages:
|
|
1419
|
-
if package.startswith(_INSTALLATION_SUBDIR) and package not in script_paths:
|
|
1420
|
-
logger.warning(
|
|
1421
|
-
f"Package '{package}' is in the installation "
|
|
1422
|
-
"scripts subdirectory, but is not specified as an installation "
|
|
1423
|
-
"script in `build_options`. "
|
|
1424
|
-
"Ensure it is added to installation_scripts for "
|
|
1425
|
-
"automatic execution."
|
|
1426
|
-
)
|
|
1427
|
-
raise ValueError(
|
|
1428
|
-
f"Package '{package}' is in the installation "
|
|
1429
|
-
"scripts subdirectory, but is not specified as an installation "
|
|
1430
|
-
"script in `build_options`."
|
|
1431
|
-
)
|
|
1432
|
-
return
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
1373
|
def _validate_staging_bucket_or_raise(*, staging_bucket: str) -> str:
|
|
1436
1374
|
"""Tries to validate the staging bucket."""
|
|
1437
1375
|
if not staging_bucket:
|
|
@@ -1875,7 +1813,8 @@ def _wrap_a2a_operation(method_name: str, agent_card: str) -> Callable[..., list
|
|
|
1875
1813
|
f"Bearer {self.api_client._api_client._credentials.token}"
|
|
1876
1814
|
)
|
|
1877
1815
|
},
|
|
1878
|
-
timeout=(
|
|
1816
|
+
timeout=kwargs.pop("timeout", None)
|
|
1817
|
+
or (
|
|
1879
1818
|
self.api_client._api_client._http_options.timeout / 1000.0
|
|
1880
1819
|
if self.api_client._api_client._http_options.timeout
|
|
1881
1820
|
else None
|
|
@@ -89,6 +89,11 @@ def t_metrics(
|
|
|
89
89
|
metric_payload_item["custom_code_execution_spec"] = {
|
|
90
90
|
"evaluation_function": metric.custom_function
|
|
91
91
|
}
|
|
92
|
+
# Step-based LLM metrics
|
|
93
|
+
elif getv(metric, ["steps"]):
|
|
94
|
+
metric_payload_item["step_based_llm_metric_spec"] = (
|
|
95
|
+
_step_based_llm_metric_spec(metric)
|
|
96
|
+
)
|
|
92
97
|
# LLM-based metrics
|
|
93
98
|
elif hasattr(metric, "prompt_template") and metric.prompt_template:
|
|
94
99
|
llm_based_spec: dict[str, Any] = {
|
|
@@ -145,6 +150,47 @@ def t_metrics(
|
|
|
145
150
|
return metrics_payload
|
|
146
151
|
|
|
147
152
|
|
|
153
|
+
def _dump(value: Any) -> Any:
|
|
154
|
+
if hasattr(value, "model_dump"):
|
|
155
|
+
return value.model_dump(exclude_none=True)
|
|
156
|
+
return value
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _step_based_llm_metric_spec(metric: Any) -> dict[str, Any]:
|
|
160
|
+
"""Builds a StepBasedLlmMetricSpec payload.
|
|
161
|
+
|
|
162
|
+
autorater_config fields a step leaves unset fall back to the metric's judge
|
|
163
|
+
model settings.
|
|
164
|
+
"""
|
|
165
|
+
default_autorater_config: dict[str, Any] = {}
|
|
166
|
+
if getv(metric, ["judge_model"]):
|
|
167
|
+
default_autorater_config["autorater_model"] = getv(metric, ["judge_model"])
|
|
168
|
+
if getv(metric, ["judge_model_generation_config"]):
|
|
169
|
+
default_autorater_config["generation_config"] = _dump(
|
|
170
|
+
getv(metric, ["judge_model_generation_config"])
|
|
171
|
+
)
|
|
172
|
+
if getv(metric, ["judge_model_sampling_count"]):
|
|
173
|
+
default_autorater_config["sampling_count"] = getv(
|
|
174
|
+
metric, ["judge_model_sampling_count"]
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
steps = []
|
|
178
|
+
for step in getv(metric, ["steps"]):
|
|
179
|
+
step_payload = _dump(step)
|
|
180
|
+
if default_autorater_config:
|
|
181
|
+
step_payload["autorater_config"] = {
|
|
182
|
+
**default_autorater_config,
|
|
183
|
+
**step_payload.get("autorater_config", {}),
|
|
184
|
+
}
|
|
185
|
+
steps.append(step_payload)
|
|
186
|
+
|
|
187
|
+
spec: dict[str, Any] = {"steps": steps}
|
|
188
|
+
preprocessor = getv(metric, ["preprocessor"])
|
|
189
|
+
if preprocessor:
|
|
190
|
+
spec["preprocessor"] = _dump(preprocessor)
|
|
191
|
+
return spec
|
|
192
|
+
|
|
193
|
+
|
|
148
194
|
def t_metric_sources(metrics: list[Any]) -> list[dict[str, Any]]:
|
|
149
195
|
"""Prepares the MetricSource payload."""
|
|
150
196
|
sources_payload = []
|
|
@@ -217,6 +263,12 @@ def t_metric_for_registry(
|
|
|
217
263
|
"evaluation_function": metric.custom_function
|
|
218
264
|
}
|
|
219
265
|
|
|
266
|
+
# Step-based LLM metric
|
|
267
|
+
elif getv(metric, ["steps"]):
|
|
268
|
+
metric_payload_item["step_based_llm_metric_spec"] = _step_based_llm_metric_spec(
|
|
269
|
+
metric
|
|
270
|
+
)
|
|
271
|
+
|
|
220
272
|
# LLM-based metric
|
|
221
273
|
elif (hasattr(metric, "prompt_template") and metric.prompt_template) or (
|
|
222
274
|
hasattr(metric, "rubric_group_name") and metric.rubric_group_name
|
{google_cloud_agentplatform-2.7.0 → google_cloud_agentplatform-2.9.0}/agentplatform/_genai/evals.py
RENAMED
|
@@ -1172,6 +1172,13 @@ def _UnifiedMetric_from_vertex(
|
|
|
1172
1172
|
getv(from_object, ["computationBasedMetricSpec"]),
|
|
1173
1173
|
)
|
|
1174
1174
|
|
|
1175
|
+
if getv(from_object, ["stepBasedLlmMetricSpec"]) is not None:
|
|
1176
|
+
setv(
|
|
1177
|
+
to_object,
|
|
1178
|
+
["step_based_llm_metric_spec"],
|
|
1179
|
+
getv(from_object, ["stepBasedLlmMetricSpec"]),
|
|
1180
|
+
)
|
|
1181
|
+
|
|
1175
1182
|
return to_object
|
|
1176
1183
|
|
|
1177
1184
|
|
|
@@ -1223,6 +1230,13 @@ def _UnifiedMetric_to_vertex(
|
|
|
1223
1230
|
getv(from_object, ["computation_based_metric_spec"]),
|
|
1224
1231
|
)
|
|
1225
1232
|
|
|
1233
|
+
if getv(from_object, ["step_based_llm_metric_spec"]) is not None:
|
|
1234
|
+
setv(
|
|
1235
|
+
to_object,
|
|
1236
|
+
["stepBasedLlmMetricSpec"],
|
|
1237
|
+
getv(from_object, ["step_based_llm_metric_spec"]),
|
|
1238
|
+
)
|
|
1239
|
+
|
|
1226
1240
|
return to_object
|
|
1227
1241
|
|
|
1228
1242
|
|
|
@@ -532,7 +532,7 @@ class FeedbackEntries(_api_module.BaseModule):
|
|
|
532
532
|
Args:
|
|
533
533
|
name (str): Required. Name of the Feedback Entry to update. Format:
|
|
534
534
|
`projects/{project}/locations/{location}/reasoningEngines/{resource_id}/feedbackEntries/{feedback_entry_id}`.
|
|
535
|
-
feedback_type (
|
|
535
|
+
feedback_type (FeedbackType): Optional. The type of feedback provided.
|
|
536
536
|
config (UpdateRuntimeFeedbackEntryConfig): Optional. The configuration for updating the Feedback Entry.
|
|
537
537
|
|
|
538
538
|
Returns:
|
|
@@ -1245,7 +1245,7 @@ class AsyncFeedbackEntries(_api_module.BaseModule):
|
|
|
1245
1245
|
Args:
|
|
1246
1246
|
name (str): Required. Name of the Feedback Entry to update. Format:
|
|
1247
1247
|
`projects/{project}/locations/{location}/reasoningEngines/{resource_id}/feedbackEntries/{feedback_entry_id}`.
|
|
1248
|
-
feedback_type (
|
|
1248
|
+
feedback_type (FeedbackType): Optional. The type of feedback provided.
|
|
1249
1249
|
config (UpdateRuntimeFeedbackEntryConfig): Optional. The configuration for updating the Feedback Entry.
|
|
1250
1250
|
|
|
1251
1251
|
Returns:
|
|
@@ -1607,6 +1607,7 @@ class Runtimes(_api_module.BaseModule):
|
|
|
1607
1607
|
agent
|
|
1608
1608
|
or config.source_packages
|
|
1609
1609
|
or config.developer_connect_source
|
|
1610
|
+
or config.git_source
|
|
1610
1611
|
or config.agent_config_source
|
|
1611
1612
|
or config.container_spec
|
|
1612
1613
|
):
|
|
@@ -1860,6 +1861,9 @@ class Runtimes(_api_module.BaseModule):
|
|
|
1860
1861
|
developer_connect_source = json.loads(
|
|
1861
1862
|
developer_connect_source.model_dump_json()
|
|
1862
1863
|
)
|
|
1864
|
+
git_source = config.git_source
|
|
1865
|
+
if git_source is not None:
|
|
1866
|
+
git_source = json.loads(git_source.model_dump_json(exclude_none=True))
|
|
1863
1867
|
agent_config_source = config.agent_config_source
|
|
1864
1868
|
if agent_config_source is not None:
|
|
1865
1869
|
agent_config_source = json.loads(agent_config_source.model_dump_json())
|
|
@@ -1900,6 +1904,7 @@ class Runtimes(_api_module.BaseModule):
|
|
|
1900
1904
|
class_methods=config.class_methods,
|
|
1901
1905
|
source_packages=config.source_packages,
|
|
1902
1906
|
developer_connect_source=developer_connect_source,
|
|
1907
|
+
git_source=git_source,
|
|
1903
1908
|
entrypoint_module=config.entrypoint_module,
|
|
1904
1909
|
entrypoint_object=config.entrypoint_object,
|
|
1905
1910
|
requirements_file=config.requirements_file,
|
|
@@ -1969,6 +1974,9 @@ class Runtimes(_api_module.BaseModule):
|
|
|
1969
1974
|
developer_connect_source: Optional[
|
|
1970
1975
|
types.ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict
|
|
1971
1976
|
] = None,
|
|
1977
|
+
git_source: Optional[
|
|
1978
|
+
types.ReasoningEngineSpecSourceCodeSpecGitSourceDict
|
|
1979
|
+
] = None,
|
|
1972
1980
|
class_methods: Optional[Sequence[dict[str, Any]]] = None,
|
|
1973
1981
|
entrypoint_module: Optional[str] = None,
|
|
1974
1982
|
entrypoint_object: Optional[str] = None,
|
|
@@ -2000,10 +2008,13 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2000
2008
|
source_code_spec["developer_connect_source"] = {
|
|
2001
2009
|
"config": developer_connect_source
|
|
2002
2010
|
}
|
|
2011
|
+
elif git_source:
|
|
2012
|
+
update_masks.append("spec.source_code_spec.git_source")
|
|
2013
|
+
source_code_spec["git_source"] = git_source
|
|
2003
2014
|
elif not agent_config_source:
|
|
2004
2015
|
raise ValueError(
|
|
2005
2016
|
"Please specify one of `source_packages`, `developer_connect_source`, "
|
|
2006
|
-
"or `agent_config_source`."
|
|
2017
|
+
"`git_source`, or `agent_config_source`."
|
|
2007
2018
|
)
|
|
2008
2019
|
if class_methods is not None:
|
|
2009
2020
|
update_masks.append("spec.class_methods")
|
|
@@ -2019,8 +2030,8 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2019
2030
|
elif image_spec is None:
|
|
2020
2031
|
raise ValueError(
|
|
2021
2032
|
"`class_methods` must be specified if `source_packages`, "
|
|
2022
|
-
"`developer_connect_source`, or `agent_config_source`
|
|
2023
|
-
"specified without a Dockerfile or `image_spec`."
|
|
2033
|
+
"`developer_connect_source`, `git_source`, or `agent_config_source` "
|
|
2034
|
+
"is specified without a Dockerfile or `image_spec`."
|
|
2024
2035
|
)
|
|
2025
2036
|
if image_spec is not None:
|
|
2026
2037
|
if entrypoint_module or entrypoint_object or requirements_file:
|
|
@@ -2077,13 +2088,13 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2077
2088
|
|
|
2078
2089
|
if not entrypoint_module:
|
|
2079
2090
|
raise ValueError(
|
|
2080
|
-
"`entrypoint_module` must be specified if `source_packages` or `
|
|
2091
|
+
"`entrypoint_module` must be specified if `source_packages`, `developer_connect_source`, or `git_source` is specified."
|
|
2081
2092
|
)
|
|
2082
2093
|
update_masks.append("spec.source_code_spec.python_spec.entrypoint_module")
|
|
2083
2094
|
python_spec["entrypoint_module"] = entrypoint_module
|
|
2084
2095
|
if not entrypoint_object:
|
|
2085
2096
|
raise ValueError(
|
|
2086
|
-
"`entrypoint_object` must be specified if `source_packages` or `
|
|
2097
|
+
"`entrypoint_object` must be specified if `source_packages`, `developer_connect_source`, or `git_source` is specified."
|
|
2087
2098
|
)
|
|
2088
2099
|
update_masks.append("spec.source_code_spec.python_spec.entrypoint_object")
|
|
2089
2100
|
python_spec["entrypoint_object"] = entrypoint_object
|
|
@@ -2215,6 +2226,9 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2215
2226
|
developer_connect_source: Optional[
|
|
2216
2227
|
types.ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict
|
|
2217
2228
|
] = None,
|
|
2229
|
+
git_source: Optional[
|
|
2230
|
+
types.ReasoningEngineSpecSourceCodeSpecGitSourceDict
|
|
2231
|
+
] = None,
|
|
2218
2232
|
entrypoint_module: Optional[str] = None,
|
|
2219
2233
|
entrypoint_object: Optional[str] = None,
|
|
2220
2234
|
requirements_file: Optional[str] = None,
|
|
@@ -2284,9 +2298,18 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2284
2298
|
"do not specify `agent` in `runtimes.create()` or "
|
|
2285
2299
|
"`runtimes.update()`."
|
|
2286
2300
|
)
|
|
2287
|
-
|
|
2301
|
+
if git_source:
|
|
2302
|
+
raise ValueError(
|
|
2303
|
+
"If you have provided `git_source` in `config`, please "
|
|
2304
|
+
"do not specify `agent` in `runtimes.create()` or "
|
|
2305
|
+
"`runtimes.update()`."
|
|
2306
|
+
)
|
|
2307
|
+
elif (
|
|
2308
|
+
sum(map(bool, (source_packages, developer_connect_source, git_source))) > 1
|
|
2309
|
+
):
|
|
2288
2310
|
raise ValueError(
|
|
2289
|
-
"Please specify only one of `source_packages
|
|
2311
|
+
"Please specify only one of `source_packages`, "
|
|
2312
|
+
"`developer_connect_source`, or `git_source` in `config`."
|
|
2290
2313
|
)
|
|
2291
2314
|
|
|
2292
2315
|
if container_spec:
|
|
@@ -2296,10 +2319,11 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2296
2319
|
"do not specify `agent` in `runtimes.create()` or "
|
|
2297
2320
|
"`runtimes.update()`."
|
|
2298
2321
|
)
|
|
2299
|
-
if source_packages or developer_connect_source:
|
|
2322
|
+
if source_packages or developer_connect_source or git_source:
|
|
2300
2323
|
raise ValueError(
|
|
2301
2324
|
"If you have provided `container_spec` in `config`, please "
|
|
2302
|
-
"do not specify `source_packages
|
|
2325
|
+
"do not specify `source_packages`, `developer_connect_source`, or "
|
|
2326
|
+
"`git_source` in `config`."
|
|
2303
2327
|
)
|
|
2304
2328
|
|
|
2305
2329
|
runtime_spec: Any = None
|
|
@@ -2323,6 +2347,7 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2323
2347
|
elif (
|
|
2324
2348
|
source_packages
|
|
2325
2349
|
or developer_connect_source
|
|
2350
|
+
or git_source
|
|
2326
2351
|
or image_spec
|
|
2327
2352
|
or agent_config_source
|
|
2328
2353
|
):
|
|
@@ -2332,6 +2357,7 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2332
2357
|
update_masks=update_masks,
|
|
2333
2358
|
source_packages=source_packages,
|
|
2334
2359
|
developer_connect_source=developer_connect_source,
|
|
2360
|
+
git_source=git_source,
|
|
2335
2361
|
class_methods=class_methods,
|
|
2336
2362
|
entrypoint_module=entrypoint_module,
|
|
2337
2363
|
entrypoint_object=entrypoint_object,
|
|
@@ -2373,7 +2399,7 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2373
2399
|
"`max_instances`, `resource_limits`, `container_concurrency`, or "
|
|
2374
2400
|
"`keep_alive_probe`, you must also provide the `agent` variable or "
|
|
2375
2401
|
"the source code options (`source_packages`, "
|
|
2376
|
-
"`developer_connect_source` or `agent_config_source`)."
|
|
2402
|
+
"`developer_connect_source`, `git_source` or `agent_config_source`)."
|
|
2377
2403
|
)
|
|
2378
2404
|
|
|
2379
2405
|
if runtime_spec is not None:
|
|
@@ -2672,6 +2698,9 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2672
2698
|
developer_connect_source = json.loads(
|
|
2673
2699
|
developer_connect_source.model_dump_json()
|
|
2674
2700
|
)
|
|
2701
|
+
git_source = config.git_source
|
|
2702
|
+
if git_source is not None:
|
|
2703
|
+
git_source = json.loads(git_source.model_dump_json(exclude_none=True))
|
|
2675
2704
|
agent_config_source = config.agent_config_source
|
|
2676
2705
|
if agent_config_source is not None:
|
|
2677
2706
|
agent_config_source = json.loads(agent_config_source.model_dump_json())
|
|
@@ -2721,6 +2750,7 @@ class Runtimes(_api_module.BaseModule):
|
|
|
2721
2750
|
class_methods=config.class_methods,
|
|
2722
2751
|
source_packages=config.source_packages,
|
|
2723
2752
|
developer_connect_source=developer_connect_source,
|
|
2753
|
+
git_source=git_source,
|
|
2724
2754
|
entrypoint_module=config.entrypoint_module,
|
|
2725
2755
|
entrypoint_object=config.entrypoint_object,
|
|
2726
2756
|
requirements_file=config.requirements_file,
|