Skip to content

Commit c8a38a0

Browse files
jsondaicopybara-github
authored andcommitted
feat: GenAI Client(evals) - add Gemini Agents API related eval types
PiperOrigin-RevId: 942246076
1 parent e169af9 commit c8a38a0

4 files changed

Lines changed: 169 additions & 17 deletions

File tree

agentplatform/_genai/_evals_common.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,12 +556,31 @@ def _resolve_inference_configs(
556556
return inference_configs
557557

558558

559+
def _is_gemini_agent_resource(agent: str) -> bool:
560+
"""Returns True if `agent` is a Gemini Agent resource name.
561+
562+
A Gemini Agent resource name has the format
563+
`projects/{project}/locations/{location}/agents/{agent}`, as opposed to an
564+
Agent Engine resource name which uses `.../reasoningEngines/{id}`.
565+
"""
566+
parts = agent.split("/")
567+
return (
568+
len(parts) == 6
569+
and parts[0] == "projects"
570+
and parts[2] == "locations"
571+
and parts[4] == "agents"
572+
and bool(parts[1])
573+
and bool(parts[3])
574+
and bool(parts[5])
575+
)
576+
577+
559578
def _add_evaluation_run_labels(
560579
labels: Optional[dict[str, str]] = None,
561580
agent: Optional[str] = None,
562581
) -> Optional[dict[str, str]]:
563582
"""Adds labels to the evaluation run."""
564-
if agent:
583+
if agent and "reasoningEngines/" in agent and not _is_gemini_agent_resource(agent):
565584
labels = labels or {}
566585
labels["vertex-ai-evaluation-agent-engine-id"] = agent.split(
567586
"reasoningEngines/"

agentplatform/_genai/evals.py

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,13 @@ def _EvaluationInstance_to_vertex(
340340
if getv(from_object, ["rubric_groups"]) is not None:
341341
setv(to_object, ["rubricGroups"], getv(from_object, ["rubric_groups"]))
342342

343+
if getv(from_object, ["interactions_data_source"]) is not None:
344+
setv(
345+
to_object,
346+
["interactionsDataSource"],
347+
getv(from_object, ["interactions_data_source"]),
348+
)
349+
343350
return to_object
344351

345352

@@ -2645,10 +2652,15 @@ def create_evaluation_run(
26452652
display_name: The display name of the evaluation run.
26462653
agent_info: The agent info to evaluate. Mutually exclusive with
26472654
`inference_configs`.
2648-
agent: The agent engine resource name in str type, with format
2649-
`projects/{project}/locations/{location}/reasoningEngines/{reasoning_engine_id}`.
2650-
If provided, runs inference with the deployed agent to get agent responses
2651-
for evaluation. This is required if `agent_info` is provided.
2655+
agent: The agent resource name in str type. Accepts either an Agent
2656+
Engine resource name
2657+
`projects/{project}/locations/{location}/reasoningEngines/{reasoning_engine_id}`
2658+
or a Gemini Agent (Vertex AI Agent) resource name
2659+
`projects/{project}/locations/{location}/agents/{agent}`. When a Gemini
2660+
Agent resource is provided, the backend scrapes the agent to produce
2661+
agent responses. If an Agent Engine resource name is provided, runs
2662+
inference with the deployed agent to get agent responses for evaluation.
2663+
The `agent` parameter is required if `agent_info` is provided.
26522664
user_simulator_config: The user simulator configuration for agent evaluation.
26532665
If `agent_info` is provided without `inference_configs`, this config is used
26542666
to automatically construct the inference configuration. If not specified,
@@ -2730,13 +2742,20 @@ def create_evaluation_run(
27302742
parsed_user_simulator_config.max_turn = 5
27312743

27322744
candidate_name = parsed_agent_info.name or "candidate-1"
2745+
if agent and _evals_common._is_gemini_agent_resource(agent):
2746+
agent_run_config = types.AgentRunConfig(
2747+
gemini_agent_config=types.GeminiAgentConfig(gemini_agent=agent),
2748+
user_simulator_config=parsed_user_simulator_config,
2749+
)
2750+
else:
2751+
agent_run_config = types.AgentRunConfig(
2752+
agent_engine=agent,
2753+
user_simulator_config=parsed_user_simulator_config,
2754+
)
27332755
inference_configs = {
27342756
candidate_name: types.EvaluationRunInferenceConfig(
27352757
agent_configs=parsed_agent_info.agents,
2736-
agent_run_config=types.AgentRunConfig(
2737-
agent_engine=agent,
2738-
user_simulator_config=parsed_user_simulator_config,
2739-
),
2758+
agent_run_config=agent_run_config,
27402759
)
27412760
}
27422761

@@ -4439,10 +4458,15 @@ async def create_evaluation_run(
44394458
display_name: The display name of the evaluation run.
44404459
agent_info: The agent info to evaluate. Mutually exclusive with
44414460
`inference_configs`.
4442-
agent: The agent engine resource name in str type, with format
4443-
`projects/{project}/locations/{location}/reasoningEngines/{reasoning_engine_id}`.
4444-
If provided, runs inference with the deployed agent to get agent responses
4445-
for evaluation. This is required if `agent_info` is provided.
4461+
agent: The agent resource name in str type. Accepts either an Agent
4462+
Engine resource name
4463+
`projects/{project}/locations/{location}/reasoningEngines/{reasoning_engine_id}`
4464+
or a Gemini Agent (Vertex AI Agent) resource name
4465+
`projects/{project}/locations/{location}/agents/{agent}`. When a Gemini
4466+
Agent resource is provided, the backend scrapes the agent to produce
4467+
agent responses. If an Agent Engine resource name is provided, runs
4468+
inference with the deployed agent to get agent responses for evaluation.
4469+
The `agent` parameter is required if `agent_info` is provided.
44464470
user_simulator_config: The user simulator configuration for agent evaluation.
44474471
If `agent_info` is provided without `inference_configs`, this config is used
44484472
to automatically construct the inference configuration. If not specified,
@@ -4524,13 +4548,20 @@ async def create_evaluation_run(
45244548
parsed_user_simulator_config.max_turn = 5
45254549

45264550
candidate_name = parsed_agent_info.name or "candidate-1"
4551+
if agent and _evals_common._is_gemini_agent_resource(agent):
4552+
agent_run_config = types.AgentRunConfig(
4553+
gemini_agent_config=types.GeminiAgentConfig(gemini_agent=agent),
4554+
user_simulator_config=parsed_user_simulator_config,
4555+
)
4556+
else:
4557+
agent_run_config = types.AgentRunConfig(
4558+
agent_engine=agent,
4559+
user_simulator_config=parsed_user_simulator_config,
4560+
)
45274561
inference_configs = {
45284562
candidate_name: types.EvaluationRunInferenceConfig(
45294563
agent_configs=parsed_agent_info.agents,
4530-
agent_run_config=types.AgentRunConfig(
4531-
agent_engine=agent,
4532-
user_simulator_config=parsed_user_simulator_config,
4533-
),
4564+
agent_run_config=agent_run_config,
45344565
)
45354566
}
45364567

agentplatform/_genai/types/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,9 @@
603603
from .common import FlexStartDict
604604
from .common import FlexStartOrDict
605605
from .common import Framework
606+
from .common import GeminiAgentConfig
607+
from .common import GeminiAgentConfigDict
608+
from .common import GeminiAgentConfigOrDict
606609
from .common import GeminiExample
607610
from .common import GeminiExampleDict
608611
from .common import GeminiExampleOrDict
@@ -771,6 +774,9 @@
771774
from .common import IngestionDirectContentsSourceEventDict
772775
from .common import IngestionDirectContentsSourceEventOrDict
773776
from .common import IngestionDirectContentsSourceOrDict
777+
from .common import InteractionsDataSource
778+
from .common import InteractionsDataSourceDict
779+
from .common import InteractionsDataSourceOrDict
774780
from .common import IntermediateExtractedMemory
775781
from .common import IntermediateExtractedMemoryDict
776782
from .common import IntermediateExtractedMemoryOrDict
@@ -1980,6 +1986,9 @@
19801986
"EvaluationRunAgentConfig",
19811987
"EvaluationRunAgentConfigDict",
19821988
"EvaluationRunAgentConfigOrDict",
1989+
"GeminiAgentConfig",
1990+
"GeminiAgentConfigDict",
1991+
"GeminiAgentConfigOrDict",
19831992
"AgentRunConfig",
19841993
"AgentRunConfigDict",
19851994
"AgentRunConfigOrDict",
@@ -2043,6 +2052,9 @@
20432052
"ResponseCandidate",
20442053
"ResponseCandidateDict",
20452054
"ResponseCandidateOrDict",
2055+
"InteractionsDataSource",
2056+
"InteractionsDataSourceDict",
2057+
"InteractionsDataSourceOrDict",
20462058
"EvalCase",
20472059
"EvalCaseDict",
20482060
"EvalCaseOrDict",

agentplatform/_genai/types/common.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,35 @@ class EvaluationRunAgentConfigDict(TypedDict, total=False):
26072607
]
26082608

26092609

2610+
class GeminiAgentConfig(_common.BaseModel):
2611+
"""Config for scraping a Gemini Agent.
2612+
2613+
A Gemini Agent is a Vertex AI Agent resource scraped via the Vertex
2614+
Interactions API.
2615+
"""
2616+
2617+
gemini_agent: Optional[str] = Field(
2618+
default=None,
2619+
description="""The resource name of the Gemini Agent.
2620+
Format: `projects/{project}/locations/{location}/agents/{agent}`.""",
2621+
)
2622+
2623+
2624+
class GeminiAgentConfigDict(TypedDict, total=False):
2625+
"""Config for scraping a Gemini Agent.
2626+
2627+
A Gemini Agent is a Vertex AI Agent resource scraped via the Vertex
2628+
Interactions API.
2629+
"""
2630+
2631+
gemini_agent: Optional[str]
2632+
"""The resource name of the Gemini Agent.
2633+
Format: `projects/{project}/locations/{location}/agents/{agent}`."""
2634+
2635+
2636+
GeminiAgentConfigOrDict = Union[GeminiAgentConfig, GeminiAgentConfigDict]
2637+
2638+
26102639
class AgentRunConfig(_common.BaseModel):
26112640
"""Configuration for an Agent Run."""
26122641

@@ -2622,6 +2651,11 @@ class AgentRunConfig(_common.BaseModel):
26222651
Contains configuration for a user simulator that
26232652
uses an LLM to generate messages on behalf of the user.""",
26242653
)
2654+
gemini_agent_config: Optional[GeminiAgentConfig] = Field(
2655+
default=None,
2656+
description="""Config for scraping a Gemini Agent (Vertex AI Agent resource).
2657+
Used to target a Gemini agent for an evaluation run.""",
2658+
)
26252659

26262660

26272661
class AgentRunConfigDict(TypedDict, total=False):
@@ -2638,6 +2672,10 @@ class AgentRunConfigDict(TypedDict, total=False):
26382672
Contains configuration for a user simulator that
26392673
uses an LLM to generate messages on behalf of the user."""
26402674

2675+
gemini_agent_config: Optional[GeminiAgentConfigDict]
2676+
"""Config for scraping a Gemini Agent (Vertex AI Agent resource).
2677+
Used to target a Gemini agent for an evaluation run."""
2678+
26412679

26422680
AgentRunConfigOrDict = Union[AgentRunConfig, AgentRunConfigDict]
26432681

@@ -3370,6 +3408,38 @@ class ResponseCandidateDict(TypedDict, total=False):
33703408
ResponseCandidateOrDict = Union[ResponseCandidate, ResponseCandidateDict]
33713409

33723410

3411+
class InteractionsDataSource(_common.BaseModel):
3412+
"""Source for populating agent data from an Interactions API interaction."""
3413+
3414+
gemini_agent_config: Optional[GeminiAgentConfig] = Field(
3415+
default=None,
3416+
description="""The Gemini Agent (Vertex AI Agent resource) that produced the
3417+
interaction.""",
3418+
)
3419+
interaction: Optional[str] = Field(
3420+
default=None,
3421+
description="""The interaction to evaluate. Required by the backend.
3422+
Format:
3423+
`projects/{project}/locations/{location}/interactions/{interaction}`.""",
3424+
)
3425+
3426+
3427+
class InteractionsDataSourceDict(TypedDict, total=False):
3428+
"""Source for populating agent data from an Interactions API interaction."""
3429+
3430+
gemini_agent_config: Optional[GeminiAgentConfigDict]
3431+
"""The Gemini Agent (Vertex AI Agent resource) that produced the
3432+
interaction."""
3433+
3434+
interaction: Optional[str]
3435+
"""The interaction to evaluate. Required by the backend.
3436+
Format:
3437+
`projects/{project}/locations/{location}/interactions/{interaction}`."""
3438+
3439+
3440+
InteractionsDataSourceOrDict = Union[InteractionsDataSource, InteractionsDataSourceDict]
3441+
3442+
33733443
class EvalCase(_common.BaseModel):
33743444
"""A comprehensive representation of a GenAI interaction for evaluation."""
33753445

@@ -3414,6 +3484,10 @@ class EvalCase(_common.BaseModel):
34143484
default=None,
34153485
description="""This field is experimental and may change in future versions. The user scenario for the evaluation case.""",
34163486
)
3487+
interactions_data_source: Optional[InteractionsDataSource] = Field(
3488+
default=None,
3489+
description="""This field is experimental and may change in future versions. Source for populating agent data from an Interactions API interaction. When set, the backend fetches the interaction (and the Gemini Agent config) and parses it into agent data for evaluation; agent_data must not also be set.""",
3490+
)
34173491
# Allow extra fields to support custom metric prompts and stay backward compatible.
34183492
model_config = ConfigDict(frozen=True, extra="allow")
34193493

@@ -3454,6 +3528,9 @@ class EvalCaseDict(TypedDict, total=False):
34543528
user_scenario: Optional[evals_types.UserScenario]
34553529
"""This field is experimental and may change in future versions. The user scenario for the evaluation case."""
34563530

3531+
interactions_data_source: Optional[InteractionsDataSourceDict]
3532+
"""This field is experimental and may change in future versions. Source for populating agent data from an Interactions API interaction. When set, the backend fetches the interaction (and the Gemini Agent config) and parses it into agent data for evaluation; agent_data must not also be set."""
3533+
34573534

34583535
EvalCaseOrDict = Union[EvalCase, EvalCaseDict]
34593536

@@ -4593,6 +4670,13 @@ class EvaluationInstance(_common.BaseModel):
45934670
default=None,
45944671
description="""Named groups of rubrics associated with this prompt. The key is a user-defined name for the rubric group.""",
45954672
)
4673+
interactions_data_source: Optional[InteractionsDataSource] = Field(
4674+
default=None,
4675+
description="""Source for populating agent data from an Interactions API
4676+
interaction. If set, no other agent data source may be set. The backend
4677+
fetches the interaction (and the agent that produced it) and parses it
4678+
into agent data for grading.""",
4679+
)
45964680

45974681

45984682
class EvaluationInstanceDict(TypedDict, total=False):
@@ -4616,6 +4700,12 @@ class EvaluationInstanceDict(TypedDict, total=False):
46164700
rubric_groups: Optional[dict[str, "RubricGroupDict"]]
46174701
"""Named groups of rubrics associated with this prompt. The key is a user-defined name for the rubric group."""
46184702

4703+
interactions_data_source: Optional[InteractionsDataSourceDict]
4704+
"""Source for populating agent data from an Interactions API
4705+
interaction. If set, no other agent data source may be set. The backend
4706+
fetches the interaction (and the agent that produced it) and parses it
4707+
into agent data for grading."""
4708+
46194709

46204710
EvaluationInstanceOrDict = Union[EvaluationInstance, EvaluationInstanceDict]
46214711

0 commit comments

Comments
 (0)